Sunteți pe pagina 1din 247

All info gathered here is brought to you by V0ID(@Dark_Fed)

Never in a hundred years would I think I'd be attacking seaworld.com. As a small


child, I used to go there, enjoy the rides that they give, and that sailor act
with the funny clown guy. I'd always sit in the front row to get wet and feel th
e heat of the fire. Well, that was when seaworld was fun.
Now I say to you seaworld
From V0ID with love
#OpSeaworld
============================================
Target = Seaworld
Domain: seaworld.com
Using HTTP, really? Should sue their asses for not providing a safe and secure l
ogin system(HTTPS)
HOSTS/Subdomains:
blueworldproject.seaworld.com
ezticket.seaworld.com
mail.seaworld.com
seaworld.com

199.83.129.174
204.232.234.169
173.227.205.22
173.203.153.81

OS: Windows
ROBOTS:
#seaworld_com
User-agent: *
Disallow: /ajax/
Disallow: /customerrors/
Disallow: /layouts/
Disallow: /sitecore/modules/
Disallow: /sitecore/service/
Disallow: /sitecore/media library/
Disallow: /sitecore/shell/
Disallow: /sitecore/content/
Web admin login: www.seaworld.com/sitecore/login
Website Security Team Email: websec@seaworld.com
Want some site sourcecode: http://seaworld.com/_assets/ParkSites/Scripts/site.js
============================================
OPEN PORTS (seaworld.com)
PORT
80/tcp
81/tcp
82/tcp
84/tcp
85/tcp
86/tcp
89/tcp
90/tcp
100/tcp

STATE
open
open
open
open
open
open
open
open
open

SERVICE
http
tcpwrapped
http
tcpwrapped
tcpwrapped
http
http
tcpwrapped
tcpwrapped

VERSION
Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)

101/tcp open tcpwrapped


443/tcp open ssl/http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
CPE: cpe:/o:microsoft:windows
=============================================
DNS INFO
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61403
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2
;; QUESTION SECTION:
;seaworld.com.

IN

;; ANSWER SECTION:
seaworld.com.

IN

173.203.153.81

;; AUTHORITY SECTION:
seaworld.com.
seaworld.com.

5
5

IN
IN

NS
NS

ns.rackspace.com.
ns2.rackspace.com.

;; ADDITIONAL SECTION:
ns.rackspace.com.
5
ns2.rackspace.com.
5

IN
IN

A
A

69.20.95.4
65.61.188.4

Name servers:
ns.rackspace.com
ns2.rackspace.com
ns.rackspace.com
Server:
Address:

ns.rackspace.com
69.20.95.4

seaworld.com
origin = ns.rackspace.com
mail addr = hostmaster.rackspace.com
serial = 1422856890
refresh = 3600
retry = 300
expire = 1814400
minimum = 300
Name: seaworld.com
Address: 173.203.153.81
seaworld.com
nameserver = ns.rackspace.com.
seaworld.com
nameserver = ns2.rackspace.com.
seaworld.com
mail exchanger = 20 mx2.seaworld.iphmx.com.
seaworld.com
mail exchanger = 10 mx1.seaworld.iphmx.com.
seaworld.com
text = "v=spf1 ip4:74.121.52.31 ip4:74.121.52.30 mx include:emai
lsrvr.com include:veinteractive.biz ~all"
seaworld.com
text = "MS=ms88175766"
seaworld.com
text = "MS=ms66101206"
ns2.rackspace.com
Server:
Address:

ns2.rackspace.com
65.61.188.4#53

seaworld.com
origin = ns.rackspace.com
mail addr = hostmaster.rackspace.com
serial = 1422856890
refresh = 3600
retry = 300
expire = 1814400
minimum = 300
Name: seaworld.com
Address: 173.203.153.81
seaworld.com
nameserver = ns2.rackspace.com.
seaworld.com
nameserver = ns.rackspace.com.
seaworld.com
mail exchanger = 10 mx1.seaworld.iphmx.com.
seaworld.com
mail exchanger = 20 mx2.seaworld.iphmx.com.
seaworld.com
text = "v=spf1 ip4:74.121.52.31 ip4:74.121.52.30 mx include:emai
lsrvr.com include:veinteractive.biz ~all"
seaworld.com
text = "MS=ms88175766"
seaworld.com
text = "MS=ms66101206"
================================================================================
=========
VULNERABILITIES
PORT
STATE SERVICE
VERSION
80/tcp open http
Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-csrf: Couldn't find any CSRF vulnerabilities.
|_http-dombased-xss: Couldn't find any DOM based XSS.
| http-enum:
| /sitecore/shell/sitecore.version.xml: 6.5.0 (rev. 120427)
|_ /sitecore/shell/Applications/shell.xml: Sitecore.NET (CMS)
|_http-fileupload-exploiter:
|_http-frontpage-login: false
| http-phpmyadmin-dir-traversal:
| VULNERABLE:
| phpMyAdmin grab_globals.lib.php subform Parameter Traversal Local File Inclu
sion
|
State: LIKELY VULNERABLE
|
IDs: CVE:CVE-2005-3299
|
Description:
|
PHP file inclusion vulnerability in grab_globals.lib.php in phpMyAdmin 2
.6.4 and 2.6.4-pl1 allows remote attackers to include local files via the $__red
irect parameter, possibly involving the subform array.
|
|
Disclosure date: 2005-10-nil
|
Extra information:
|
../../../../../etc/passwd not found.
|
|
References:
|
http://www.exploit-db.com/exploits/1244/
|_
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-3299
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
81/tcp open tcpwrapped
82/tcp open http
Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| http-csrf:
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=seaworld.com
| Found the following possible CSRF vulnerabilities:
|
|
Path: http://seaworld.com:82/
|
Form id: mainform
|
Form action: /
|

|
Path: http://seaworld.com:82/#
|
Form id: mainform
|
Form action: /
|
|
Path: http://seaworld.com:82/#modal-image-carousel
|
Form id: mainform
|_
Form action: /
| http-dombased-xss:
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=seaworld.com
| Found the following indications of potential DOM based XSS:
|
|
Source: window.open(e,"","width=1024,height=768,toolbar=0,menubar=1,locati
on=0,status=0,scrollbars=1,resizable=1,left=0,top=0")
|_
Pages: http://seaworld.com:82/_assets/ConsumerPortal/js/sharelinks.min.js
| http-enum:
| /login.aspx: Possible admin folder
| /robots.txt: Robots file
| /crossdomain.xml: Adobe Flash crossdomain policy
| /sitecore/shell/sitecore.version.xml: 6.5.0 (rev. 120427)
| /sitecore/login/default.aspx: Sitecore.NET login page
| /sitecore/admin/unlock_admin.aspx: Sitecore.NET (CMS)
|_ /sitecore/shell/Applications/shell.xml: Sitecore.NET (CMS)
| http-fileupload-exploiter:
|
|_
Couldn't find a file-type field.
|_http-frontpage-login: false
| http-slowloris-check:
| VULNERABLE:
| Slowloris DOS attack
|
State: VULNERABLE
|
Description:
|
Slowloris tries to keep many connections to the target web server open a
nd hold them open as long as possible.
|
It accomplishes this by opening connections to the target web server and
sending a partial request. By doing
|
so, it starves the http server's resources causing Denial Of Service.
|
|
Disclosure date: 2009-09-17
|
References:
|_
http://ha.ckers.org/slowloris/
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
83/tcp open tcpwrapped
84/tcp open tcpwrapped
85/tcp open tcpwrapped
86/tcp open http
Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| http-csrf:
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=seaworld.com
| Found the following possible CSRF vulnerabilities:
|
|
Path: http://seaworld.com:86/
|
Form id: mainform
|
Form action: /
|
|
Path: http://seaworld.com:86/#modal-image-carousel
|
Form id: mainform
|_
Form action: /

| http-dombased-xss:
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=seaworld.com
| Found the following indications of potential DOM based XSS:
|
|
Source: window.open(e,"","width=1024,height=768,toolbar=0,menubar=1,locati
on=0,status=0,scrollbars=1,resizable=1,left=0,top=0")
|_
Pages: http://seaworld.com:86/_assets/ConsumerPortal/js/sharelinks.min.js
| http-enum:
| /login.aspx: Possible admin folder
| /robots.txt: Robots file
| /crossdomain.xml: Adobe Flash crossdomain policy
| /sitecore/shell/sitecore.version.xml: 6.5.0 (rev. 120427)
| /sitecore/login/default.aspx: Sitecore.NET login page
| /sitecore/admin/unlock_admin.aspx: Sitecore.NET (CMS)
|_ /sitecore/shell/Applications/shell.xml: Sitecore.NET (CMS)
| http-fileupload-exploiter:
|
|_
Couldn't find a file-type field.
|_http-frontpage-login: false
| http-slowloris-check:
| VULNERABLE:
| Slowloris DOS attack
|
State: VULNERABLE
|
Description:
|
Slowloris tries to keep many connections to the target web server open a
nd hold them open as long as possible.
|
It accomplishes this by opening connections to the target web server and
sending a partial request. By doing so, it starves the http server's resources
causing Denial Of Service.
|
|
Disclosure date: 2009-09-17
|
References:
|_
http://ha.ckers.org/slowloris/
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
89/tcp open http
Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| http-csrf:
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=seaworld.com
| Found the following possible CSRF vulnerabilities:
|
|
Path: http://seaworld.com:89/
|
Form id: loginform
|
Form action: /login.aspx?ReturnUrl=%2f
|
|
Path: http://seaworld.com:89/login.aspx?ReturnUrl=%2f
|
Form id: loginform
|_
Form action: /login.aspx?ReturnUrl=%2f
|_http-dombased-xss: Couldn't find any DOM based XSS.
| http-enum:
| /login.aspx: Possible admin folder
| /crossdomain.xml: Adobe Flash crossdomain policy
| /sitecore/shell/sitecore.version.xml: 6.5.0 (rev. 120427)
| /sitecore/login/default.aspx: Sitecore.NET login page
| /sitecore/admin/unlock_admin.aspx: Sitecore.NET (CMS)
|_ /sitecore/shell/Applications/shell.xml: Sitecore.NET (CMS)
|_http-fileupload-exploiter:
|_http-frontpage-login: false
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
| http-vuln-cve2010-0738:
|_ /jmx-console/: Authentication was not required

90/tcp open tcpwrapped


100/tcp open tcpwrapped
101/tcp open tcpwrapped
443/tcp open ssl/http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| http-csrf:
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=seaworld.com
| Found the following possible CSRF vulnerabilities:
|
|
Path: https://seaworld.com:443/
|
Form id: mainform
|
Form action: /
|
|
Path: https://seaworld.com/#
|
Form id: mainform
|
Form action: /
|
|
Path: https://seaworld.com/#modal-image-carousel
|
Form id: mainform
|_
Form action: /
| http-dombased-xss:
| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=seaworld.com
| Found the following indications of potential DOM based XSS:
|
|
Source: window.open(e,"","width=1024,height=768,toolbar=0,menubar=1,locati
on=0,status=0,scrollbars=1,resizable=1,left=0,top=0")
|_
Pages: https://seaworld.com/_assets/ConsumerPortal/js/sharelinks.min.js
| http-enum:
| /login.aspx: Possible admin folder
| /robots.txt: Robots file
| /crossdomain.xml: Adobe Flash crossdomain policy
| /sitecore/shell/sitecore.version.xml: 6.5.0 (rev. 120427)
| /sitecore/login/default.aspx: Sitecore.NET login page
| /sitecore/admin/unlock_admin.aspx: Sitecore.NET (CMS)
|_ /sitecore/shell/Applications/shell.xml: Sitecore.NET (CMS)
| http-fileupload-exploiter:
|
|_
Couldn't find a file-type field.
|_http-frontpage-login: false
| http-slowloris-check:
| VULNERABLE:
| Slowloris DOS attack
|
State: VULNERABLE
|
Description:
|
Slowloris tries to keep many connections to the target web server open a
nd hold them open as long as possible.
|
It accomplishes this by opening connections to the target web server and
sending a partial request. By doing
|
so, it starves the http server's resources causing Denial Of Service.
|
|
Disclosure date: 2009-09-17
|
References:
|_
http://ha.ckers.org/slowloris/
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
POSSIBLE SQL INJECTION:
seaworld.com/System/?item=/~/&user=extranet\Anonymous&si

te=SeaWorldCom'"
seaworld.com/System/ErrorPages?item=/~/&user=extranet\An
onymous&site=SeaWorldCom'"
seaworld.com/System/ErrorPages/Global404Page?item=/~/&us
er=extranet\Anonymous&site=SeaWorldCom'"
seaworld.com/System/?item=/~/&user=extranet\Anonymous&si
te=SeaWorldCom'"
=============================================
ON SITE EMAILS
brad.andrews@seaworld.com
corp.communications@seaworld.com
employment@seaworld.com
groupevents@seaworld.com
investors@seaworld.com
lawrence@seaworld.com
leymaster@seaworld.com
manager@seaworld.com
parts@seaworld.com
poletopolefunrun@seaworld.com
sales@seaworld.com
sanantonio@seaworld.com
sea.bpts@seaworld.com
@seaworld.com
shamu21@seaworld.com
spencer.tong@seaworld.com
swc.guestrelations@seaworld.com
swf.pr@seaworld.com
swo.pr@seaworld.com
================================================
========================================
NAMES
Albers, Melissa
Allen, Carl
Arenas, Nicole
Bailey, Jennifer
Balliet, Hayley
Baracz, Robert
Bilinski, Julie
Boggs, Chris
Bowman, Angela
Boyd, Scott
Brindel, Jason
Brown, Chris
Byrd, Holly

Chavez, Pablo
Chong, Evan
Coe, Andrew
Davis, Eric
Denninger, Mike
Deveney, Renee
De, Victor
Dewitt, Stephanie
Duffek, Deana
E, Gabriel
Farrar, Benjamin
Fichthorn, Andrew
Fischer, Anne
Foerster, Ryan
Fornasier, Jessica
Friedrich, John
Garry, Christopher
Gracen, Michael
Gregory, Brandon
Guerrina, Jim
Gusewelle, James
Gustafson, Lori
Henson, Maria
Hillman, Tamika
Hope, Josh
Howell, Kenny
Howes, Branden
Hurst, Shelly
Johansen, Hanna
Johnson, Marcus

Kaman, Mike
Kittleson, Kyle
Kolowski, Mike
Lembke, Kevin
Lepre, Robbi
Logan, Allison
Mac, Cari
Manning, Monique
Mantegna, Robby
Mari, Adam
M, Brian
Morrow, Tim
Nabielec, Tom
Nennelli, Anjali
Parham, Hal
Parrocha, Adam
Paul, Karen
Plazewski, Jonathan
Post, Allison
Quinn, Ann
Ramos, Cristina
Rayfield, Dave
Reynolds, Katie
Richey, Michael
Rosas, Mariana
Rose, Scott
Schmadebeck, Ross
Schmitz, Tad
Schwartz, Jeff
Shaban, Marwan

Smith, Joe
Stagner, Doug
Synnott, Robert
Tong, Spencer
Tripoli, Scott
Turner, Matt
W, Abdul
Walker, John
Walsh, Kimberly
Warner, Janet
Welch, Steve
Wolfson, Sharon
Young, Heather
===============================================
WHOIS
Domain Name: seaworld.com
Registry Domain ID: 2551807_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.markmonitor.com
Registrar URL: http://www.markmonitor.com
Updated Date: 2015-02-28T04:00:30-0800
Creation Date: 1997-01-21T21:00:00-0800
Registrar Registration Expiration Date: 2017-01-22T21:00:00-0800
Registrar: MarkMonitor, Inc.
Registrar IANA ID: 292
Registrar Abuse Contact Email: abusecomplaints@markmonitor.com
Registrar Abuse Contact Phone: +1.2083895740
Domain Status: clientUpdateProhibited (https://www.icann.org/epp#clientUpdatePro
hibited)
Domain Status: clientTransferProhibited (https://www.icann.org/epp#clientTransfe
rProhibited)
Domain Status: clientDeleteProhibited (https://www.icann.org/epp#clientDeletePro
hibited)
Registry Registrant ID:
Registrant Name: Domain Administrator
Registrant Organization: SeaWorld Parks and Entertainment
Registrant Street: 9205 South Park Center Loop, Suite 400
Registrant City: Orlando
Registrant State/Province: FL
Registrant Postal Code: 32819
Registrant Country: US
Registrant Phone: +1.8888005447
Registrant Phone Ext:
Registrant Fax: +1.8888005448
Registrant Fax Ext:
Registrant Email: domain.admin@seaworld.com
Registry Admin ID:
Admin Name: Domain Administrator

Admin Organization: SeaWorld Parks and Entertainment


Admin Street: 9205 South Park Center Loop, Suite 400
Admin City: Orlando
Admin State/Province: FL
Admin Postal Code: 32819
Admin Country: US
Admin Phone: +1.8888005447
Admin Phone Ext:
Admin Fax: +1.8888005448
Admin Fax Ext:
Admin Email: domain.admin@seaworld.com
Registry Tech ID:
Tech Name: Domain Administrator
Tech Organization: SeaWorld Parks and Entertainment
Tech Street: 9205 South Park Center Loop, Suite 400
Tech City: Orlando
Tech State/Province: FL
Tech Postal Code: 32819
Tech Country: US
Tech Phone: +1.8888005447
Tech Phone Ext:
Tech Fax: +1.8888005448
Tech Fax Ext:
Tech Email: domain.admin@seaworld.com
Name Server: ns.rackspace.com
Name Server: ns2.rackspace.com
DNSSEC: unsigned
================================================================================
=============================================
SQUATTING
Character Omission
l.dovemail.com
Character Omission
Character Omission
Character Omission
l.b-io.co
Character Omission
Character Omission
Character Repeat
Character Repeat
Character Swap
p.secureserver.net
Character Swap
l.b-io.co
Character Swap
Character Swap
Character Swap
Character Swap

saworld.com
com
seaorld.com
com
seaword.com
com
seaworl.com
com
seawrld.com
com
seworld.com
com
seaworrld.com
com
seawworld.com
com
esaworld.com
com
saeworld.com
com
seaowrld.com
com
seawolrd.com
com
seawordl.com
com
seawrold.com
com

174.37.172.162

United States

mai

69.43.161.148

United States

69.43.161.168

United States

72.52.4.119

United States

85.17.25.202

Netherlands

69.43.160.151

United States

46.137.117.167

Ireland

69.43.161.168

United States

50.63.202.60

United States

smt

141.8.224.25

Switzerland

mai

69.43.161.168

United States

74.200.250.164

United States

95.211.117.206

Netherlands

69.43.161.182

United States

mai

Character Replacement aeaworld.com


p.secureserver.net
com
Character Replacement deaworld.com
com
Character Replacement seawoeld.com
com
Character Replacement seaworkd.com
l.post-host.net
com
Character Replacement seaworls.com
com
Character Replacement sesworld.com
com
Character Replacement swaworld.com
l.b-io.co
com
Character Insertion
seasworld.com
com
Character Insertion
seaworlds.com
com
Character Insertion
seraworld.com
lstore1.secureserver.net
com
Missing Dot
wwwseaworld.com
com
Vowel Swap
saaworld.com
world.com
com
Vowel Swap
seeworld.com
com
Vowel Swap
seiworld.com
lstore1.secureserver.net
com
Vowel Swap
seoworld.com
MX5.GOOGLEMAIL.com
com
Vowel Swap
siaworld.com
1.colt-engine.it
com
Vowel Swap
soaworld.com
l.soaworld.com
com
Bit Flipping
ceaworld.com
iz1.qq.com
com
Bit Flipping
reaworld.com
lmx.reaworld.com
com
Bit Flipping
sdaworld.com
MX2.GOOGLEMAIL.com
com
Bit Flipping
secworld.com
.secworld.com
com
Bit Flipping
seqworld.com
com
Bit Flipping
sgaworld.com
com
Bit Flipping
smaworld.com
10247-2119.cudamail.com
com
Bit Flipping
weaworld.com
p.rzone.de
com
Homoglyphs
seavvorld.com
com
Wrong TLD
seaworld.ca
-000c8e01.gslb.pphosted.com
ca
Wrong TLD
seaworld.de
0.kundenserver.de
de
Wrong TLD
seaworld.it
it
Wrong TLD
seaworld.net
l.b-io.co
net

50.63.202.50

United States

74.117.221.21

Cayman Islands

141.8.224.245

Switzerland

69.43.161.162

United States

smt

mai

185.53.177.30
50.63.202.104

United States

8.5.1.35

United States

107.23.199.14

United States

69.172.201.208

United States

97.74.215.17

United States

69.162.80.50

United States

208.131.141.222 United States

mai

mai

saa

208.73.211.70

United States

72.167.131.1

United States

mai

174.127.126.227 United States

ASP

81.31.155.7

Italy

mx0

183.111.141.59

Republic of Korea

mai

101.226.179.160 China

mxb

54.225.167.121

United States

nul

65.61.203.49

Canada

ASP

65.19.141.202

United States

mx1

216.34.181.97

United States

54.236.76.172

United States

198.252.106.131
81.169.145.151

Germany

smt

54.246.123.138

United States

173.203.153.81

United States

mxa

217.160.70.120

Germany

mx0

United States

mai

185.53.177.6
72.52.4.119

Wrong TLD
seaworld.nl
217.18.76.139
Netherlands
mx.
qfilter.nl
nl
Wrong TLD
seaworld.no
185.53.178.8
mail.b-io.co
no
Wrong TLD
seaworld.org
173.203.153.81 United States
mxa
-000c8e01.gslb.pphosted.com
org
Wrong TLD
seaworld.ru
188.120.232.174 Russia
ru
Wrong TLD
seaworld.se
194.63.248.52
Norway
se
================================================================================
==================================================================
================================================================================
=============================================
LOADBALANCING
DNS-Loadbalancing: NOT FOUND
HTTP-Loadbalancing [Server]:
NOT FOUND
HTTP-Loadbalancing [Date]:
50:35, 15:50:41, 15:50:41,
51:09, 15:51:10, 15:51:10,
51:14, 15:51:20, 15:51:20,
51:33, 15:51:34, 15:51:37,
51:45, 15:51:45, 15:51:45,
51:53, 15:51:54, 15:51:54,

15:50:18,
15:50:43,
15:51:10,
15:51:21,
15:51:37,
15:51:46,
15:52:01,

15:50:31,
15:50:50,
15:51:12,
15:51:32,
15:51:38,
15:51:46,
15:52:02,

15:50:31,
15:51:00,
15:51:12,
15:51:32,
15:51:38,
15:51:47,
NOT FOUND

15:50:35,
15:51:03,
15:51:14,
15:51:33,
15:51:39,
15:51:47,

15:50:35,
15:51:04,
15:51:14,
15:51:33,
15:51:44,
15:51:47,

15:
15:
15:
15:
15:
15:

HTTP-Loadbalancing [Diff]: FOUND


< x-wily-info: Clear guid=6B6206140AE1C8A6038CD6537BA9B526
< x-wily-servlet: Encrypt1 hR/KG2GOR16aRfvv3/q1ARcyhylSyfAh0WAGnia8QXD+VfItLmAYN
k0p0QhHxkCF20XQfm2fMgFFijpK2mdAv6yB59jUG6vEiIVo1adsB5qwOMzFQEUJbhnaqzARQCDjNQyVu
7gZ554bukx8LFResIUDvKDDKxSz8+kyYDqypPGcSkI4SdJH++BjR96bl/Yf8kgLqdR+1OYzOmpMIZsFO
+GuVW3hik9FgcBvOxYioTAzso4Cv9l+eLLw7qC7CvDq
> x-wily-info: Clear guid=6B621B420AE1C8A6038CD653396BCB44
> x-wily-servlet: Encrypt1 hR/KG2GOR16aRfvv3/q1ARcyhylSyfAh0WAGnia8QXD+VfItLmAYN
k0p0QhHxkCF20XQfm2fMgFFijpK2mdAv6yB59jUG6vEiIVo1adsB5qwOMzFQEUJbhnaqzARQCDjNQyVu
7gZ554bukx8LFResH6PCpCQzu/EdPmxjzaBIB/TV0ibETbRN4H495yZ2lD99cHcjDubXxsrmB9j6XaGI
ynLkoWLAL8gk6tAANUMeW4nWhGtT/F2Mo8W/Z301kBb
================================================================================
=============================================
Web Application Firewall
The site seems to be behind a WAF
Reason: The server returned a different response code when a string trigged the
blacklist.
Normal response code is "400", while the response code to an attack is "500"
================================================================================
============================================
http://pastebin.com/T2HNKZDb

Want some site sourcecode: http://seaworld.com/_assets/ParkSites/Scripts/site.js

/// <reference path="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.js" />


// ColorBox v1.3.10 - a full featured, light-weight, customizable lightbox based
on jQuery 1.3
// Copyright (c) 2010 Jack Moore - jack@colorpowered.com
// Licensed under the MIT license: http://www.opensource.org/licenses/mit-licens
e.php
var isiPad = navigator.userAgent.match(/iPad/i) != null;
(function ($, window) {
var
// ColorBox Default Settings.
// See http://colorpowered.com/colorbox for details.
defaults = {
transition: "elastic",
speed: 300,
width: false,
initialWidth: "600",
innerWidth: false,
maxWidth: false,
height: false,
initialHeight: "450",
innerHeight: false,
maxHeight: false,
scalePhotos: true,
scrolling: true,
inline: false,
html: false,
iframe: false,
photo: false,
href: false,
title: false,
rel: false,
opacity: 0.9,
preloading: true,
current: "image {current} of {total}",
previous: "previous",
next: "next",
close: "close",
open: false,
loop: true,
slideshow: false,
slideshowAuto: true,
slideshowSpeed: 2500,
slideshowStart: "start slideshow",
slideshowStop: "stop slideshow",
onOpen: false,
onLoad: false,
onComplete: false,
onCleanup: false,
onClosed: false,
overlayClose: true,
escKey: true,
arrowKey: true
},
// Abstracting the HTML and event identifiers for easy rebranding
colorbox = 'colorbox',

prefix = 'cbox',
// Events
event_open = prefix + '_open',
event_load = prefix + '_load',
event_complete = prefix + '_complete',
event_cleanup = prefix + '_cleanup',
event_closed = prefix + '_closed',
event_purge = prefix + '_purge',
event_loaded = prefix + '_loaded',
// Special Handling for IE
isIE = $.browser.msie && !$.support.opacity, // feature detection alone
gave a false positive on at least one phone browser and on some development vers
ions of Chrome.
isIE6 = isIE && $.browser.version < 7,
event_ie6 = prefix + '_IE6',
// Cached jQuery Object Variables
$overlay,
$box,
$wrap,
$content,
$topBorder,
$leftBorder,
$rightBorder,
$bottomBorder,
$related,
$window,
$loaded,
$loadingBay,
$loadingOverlay,
$title,
$current,
$slideshow,
$next,
$prev,
$close,
// Variables for cached values or use across multiple functions
interfaceHeight,
interfaceWidth,
loadedHeight,
loadedWidth,
element,
bookmark,
index,
settings,
open,
active,
closing = false,
publicMethod,
boxElement = prefix + 'Element';
// ****************
// HELPER FUNCTIONS
// ****************
// jQuery object generator to reduce code size

function $div(id, css) {


id = id ? ' id="' + prefix + id + '"' : '';
css = css ? ' style="' + css + '"' : '';
return $('<div' + id + css + '/>');
}
// Convert % values to pixels
function setSize(size, dimension) {
dimension = dimension === 'x' ? $window.width() : $window.height();
return (typeof size === 'string') ? Math.round((size.match(/%/) ? (dimen
sion / 100) * parseInt(size, 10) : parseInt(size, 10))) : size;
}
// Checks an href to see if it is a photo.
// There is a force photo option (photo: true) for hrefs that cannot be matc
hed by this regex.
function isImage(url, target) {
url = $.isFunction(url) ? url.call(target) : url;
return settings.photo || url.match(/\.(gif|png|jpg|jpeg|bmp)(?:\?([^#]*)
)?(?:#(\.*))?$/i);
}
// Assigns function results to their respective settings. This allows funct
ions to be used as values.
function process(settings) {
for (var i in settings) {
if ($.isFunction(settings[i]) && i.substring(0, 2) !== 'on') { // ch
ecks to make sure the function isn't one of the callbacks, they will be handled
at the appropriate time.
settings[i] = settings[i].call(element);
}
}
settings.rel = settings.rel || element.rel || 'nofollow';
settings.href = settings.href || $(element).attr('href');
settings.title = settings.title || element.title;
return settings;
}
function trigger(event, callback) {
if (callback) {
callback.call(element);
}
$.event.trigger(event);
}
// Slideshow functionality
function slideshow() {
var
timeOut,
className = prefix + 'Slideshow_',
start,
stop,
clear;
if (settings.slideshow && $related[1]) {
start = function () {
$slideshow
.text(settings.slideshowStop)
.bind(event_complete, function () {
timeOut = setTimeout(publicMethod.ne

xt, settings.slideshowSpeed);
})
.bind(event_load, function () {
clearTimeout(timeOut);
}).one("click", function () {
stop();
});
$box.removeClass(className + "off").addClass(className + "on");
};
stop = function () {
clearTimeout(timeOut);
$slideshow
.text(settings.slideshowStart)
.unbind(event_complete + ' ' + event_loa
d)
.one("click", function () {
start();
timeOut = setTimeout(publicMethod.ne
xt, settings.slideshowSpeed);
});
$box.removeClass(className + "on").addClass(className + "off");
};
$slideshow.bind(event_closed, function () {
$slideshow.unbind();
clearTimeout(timeOut);
$box.removeClass(className + "off " + className + "on");
});
if (settings.slideshowAuto) {
start();
} else {
stop();
}
}
}
function launch(elem) {
if (!closing) {
element = elem;
settings = process($.extend({}, $.data(element, colorbox)));
$related = $(element);
index = 0;
if (settings.rel !== 'nofollow') {
$related = $('.' + boxElement).filter(function () {
var relRelated = $.data(this, colorbox).rel || this.rel;
return (relRelated === settings.rel);
});
index = $related.index(element);
// Check direct calls to ColorBox.
if (index === -1) {
$related = $related.add(element);
index = $related.length - 1;

}
}
if (!open) {
open = active = true; // Prevents the page-change action from qu
euing up if the visitor holds down the left or right keys.
$box.show();
bookmark = element;
try {
bookmark.blur(); // Remove the focus from the calling elemen
t.
} catch (e) { }
// +settings.opacity avoids a problem in IE when using non-zeroprefixed-string-values, like '.5'
$overlay.css({ "opacity": +settings.opacity, "cursor": settings.
overlayClose ? "pointer" : "auto" }).show();
// Opens inital empty ColorBox prior to content being loaded.
settings.w = setSize(settings.initialWidth, 'x');
settings.h = setSize(settings.initialHeight, 'y');
publicMethod.position(0);
if (isIE6) {
$window.bind('resize.' + event_ie6 + ' scroll.' + event_ie6,
function () {
$overlay.css({ width: $window.width(), height: $window.h
eight(), top: $window.scrollTop(), left: $window.scrollLeft() });
}).trigger('scroll.' + event_ie6);
}
trigger(event_open, settings.onOpen);
$current.add($prev).add($next).add($slideshow).add($title).hide(
);
$close.html(settings.close).show();
}
publicMethod.load(true);
}
}
//
//
//
//
//

****************
PUBLIC FUNCTIONS
Usage format: $.fn.colorbox.close();
Usage from within an iframe: parent.$.fn.colorbox.close();
****************

publicMethod = $.fn[colorbox] = $[colorbox] = function (options, callback) {


var $this = this, autoOpen;
if (!$this[0] && $this.selector) { // if a selector was given and it did
n't match any elements, go ahead and exit.
return $this;
}

options = options || {};


if (callback) {
options.onComplete = callback;
}
if (!$this[0] || $this.selector === undefined) { // detects $.colorbox()
and $.fn.colorbox()
$this = $('<a/>');
options.open = true; // assume an immediate open
}
$this.each(function () {
$.data(this, colorbox, $.extend({}, $.data(this, colorbox) || defaul
ts, options));
$(this).addClass(boxElement);
});
autoOpen = options.open;
if ($.isFunction(autoOpen)) {
autoOpen = autoOpen.call($this);
}
if (autoOpen) {
launch($this[0]);
}
return $this;
};
// Initialize ColorBox: store common calculations, preload the interface gra
phics, append the html.
// This preps colorbox for a speedy open when clicked, and lightens the burd
on on the browser by only
// having to run once, instead of each time colorbox is opened.
publicMethod.init = function () {
// Create & Append jQuery Objects
$window = $(window);
$box = $div().attr({ id: colorbox, 'class': isIE ? prefix + 'IE' : '' })
;
$overlay = $div("Overlay", isIE6 ? 'position:absolute' : '').hide();
$wrap = $div("Wrapper");
$content = $div("Content").append(
$loaded = $div("LoadedContent", 'width:0; height:0; over
flow:hidden'),
$loadingOverlay = $div("LoadingOverlay").add($div("Loadi
ngGraphic")),
$title = $div("Title"),
$current = $div("Current"),
$next = $div("Next"),
$prev = $div("Previous"),
$slideshow = $div("Slideshow").bind(event_open, slidesho
w),
$close = $div("Close")
);
$wrap.append( // The 3x3 Grid that makes up ColorBox
$div().append(
$div("TopLeft"),

$topBorder = $div("TopCenter"),
$div("TopRight")
),
$div(false, 'clear:left').append(
$leftBorder = $div("MiddleLeft"),
$content,
$rightBorder = $div("MiddleRight")
),
$div(false, 'clear:left').append(
$div("BottomLeft"),
$bottomBorder = $div("BottomCenter"),
$div("BottomRight")
)
).children().children().css({ 'float': 'left' });
$loadingBay = $div(false, 'position:absolute; width:9999px; visibility:h
idden; display:none');
$('.content-container').append($overlay, $box.append($wrap, $loadingBay)
);
$content.children()
.hover(function () {
$(this).addClass('hover');
}, function () {
$(this).removeClass('hover');
}).addClass('hover');
// Cache values needed for size calculations
interfaceHeight = $topBorder.height() + $bottomBorder.height() + $conten
t.outerHeight(true) - $content.height(); //Subtraction needed for IE6
interfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.o
uterWidth(true) - $content.width();
loadedHeight = $loaded.outerHeight(true);
loadedWidth = $loaded.outerWidth(true);
// Setting padding to remove the need to do size conversions during the
animation step.
$box.css({ "padding-bottom": interfaceHeight, "padding-right": interface
Width }).hide();
// Setup button events.
$next.click(publicMethod.next);
$prev.click(publicMethod.prev);
$close.click(publicMethod.close);
// Adding the 'hover' class allowed the browser to load the hover-state
// background graphics. The class can now can be removed.
$content.children().removeClass('hover');
$('.' + boxElement).live('click', function (e) {
// checks to see if it was a non-left mouse-click and for clicks mod
ified with ctrl, shift, or alt.
if (!((e.button !== 0 && typeof e.button !== 'undefined') || e.ctrlK
ey || e.shiftKey || e.altKey)) {
e.preventDefault();
launch(this);
}
});

$overlay.click(function () {
if (settings.overlayClose) {
publicMethod.close();
}
});
// Set Navigation Key Bindings
$(document).bind("keydown", function (e) {
if (open && settings.escKey && e.keyCode === 27) {
e.preventDefault();
publicMethod.close();
}
if (open && settings.arrowKey && !active && $related[1]) {
if (e.keyCode === 37 && (index || settings.loop)) {
e.preventDefault();
$prev.click();
} else if (e.keyCode === 39 && (index < $related.length - 1 || s
ettings.loop)) {
e.preventDefault();
$next.click();
}
}
});
};
publicMethod.remove = function () {
$box.add($overlay).remove();
$('.' + boxElement).die('click').removeData(colorbox).removeClass(boxEle
ment);
};
publicMethod.position = function (speed, loadedCallback) {
var
animate_speed,
// keeps the top and left positions within the browser's viewport.
posTop = Math.max(document.documentElement.clientHeight - settin
gs.h - loadedHeight - interfaceHeight, 0) / 2 + $window.scrollTop(),
posLeft = Math.max($window.width() - settings.w - loadedWidth interfaceWidth, 0) / 2 + $window.scrollLeft();
// setting the speed to 0 to reduce the delay between same-sized content
.
animate_speed = ($box.width() === settings.w + loadedWidth && $box.heigh
t() === settings.h + loadedHeight) ? 0 : speed;
// this gives the wrapper plenty of breathing room so it's floated conte
nts can move around smoothly,
// but it has to be shrank down around the size of div#colorbox when it'
s done. If not,
// it can invoke an obscure IE bug when using iframes.
$wrap[0].style.width = $wrap[0].style.height = "9999px";
function modalDimensions(that) {
// loading overlay height has to be explicitly set for IE6.
$topBorder[0].style.width = $bottomBorder[0].style.width = $content[
0].style.width = that.style.width;
$loadingOverlay[0].style.height = $loadingOverlay[1].style.height =
$content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.h
eight = that.style.height;
}

$box.dequeue().animate({ width: settings.w + loadedWidth, height: settin


gs.h + loadedHeight, top: posTop, left: posLeft }, {
duration: animate_speed,
complete: function () {
modalDimensions(this);
active = false;
// shrink the wrapper down to exactly the size of colorbox to av
oid a bug in IE's iframe implementation.
$wrap[0].style.width = (settings.w + loadedWidth + interfaceWidt
h) + "px";
$wrap[0].style.height = (settings.h + loadedHeight + interfaceHe
ight) + "px";
if (loadedCallback) {
loadedCallback();
}
},
step: function () {
modalDimensions(this);
}
});
};
publicMethod.resize = function (options) {
if (open) {
options = options || {};
if (options.width) {
settings.w = setSize(options.width, 'x') - loadedWidth - interfa
ceWidth;
}
if (options.innerWidth) {
settings.w = setSize(options.innerWidth, 'x');
}
$loaded.css({ width: settings.w });
if (options.height) {
settings.h = setSize(options.height, 'y') - loadedHeight - inter
faceHeight;
}
if (options.innerHeight) {
settings.h = setSize(options.innerHeight, 'y');
}
if (!options.innerHeight && !options.height) {
var $child = $loaded.wrapInner("<div style='overflow:auto'></div
>").children(); // temporary wrapper to get an accurate estimate of just how hig
h the total content should be.
settings.h = $child.height();
$child.replaceWith($child.children()); // ditch the temporary wr
apper div used in height calculation
}
$loaded.css({ height: settings.h });
publicMethod.position(settings.transition === "none" ? 0 : settings.
speed);
}
};

publicMethod.prep = function (object) {


if (!open) {
return;
}
var photo,
speed = settings.transition === "none" ? 0 : settings.speed;
$window.unbind('resize.' + prefix);
$loaded.remove();
$loaded = $div('LoadedContent').html(object);
function getWidth() {
settings.w = settings.w || $loaded.width();
settings.w = settings.mw && settings.mw < settings.w ? settings.mw :
settings.w;
return settings.w;
}
function getHeight() {
settings.h = settings.h || $loaded.height();
settings.h = settings.mh && settings.mh < settings.h ? settings.mh :
settings.h;
return settings.h;
}
$loaded.hide()
.appendTo($loadingBay.show())// content has to be appended to th
e DOM for accurate size calculations.
.css({ width: getWidth(), overflow: settings.scrolling ? 'auto'
: 'hidden' })
.css({ height: getHeight() })// sets the height independently fr
om the width in case the new width influences the value of height.
.prependTo($content);
$loadingBay.hide();
// floating the IMG removes the bottom line-height and fixed a problem w
here IE miscalculates the width of the parent element as 100% of the document wi
dth.
$('#' + prefix + 'Photo').css({ cssFloat: 'none', marginLeft: 'auto', ma
rginRight: 'auto' });
// Hides SELECT elements in IE6 because they would otherwise sit on top
of the overlay.
if (isIE6) {
$('select').not($box.find('select')).filter(function () {
return this.style.visibility !== 'hidden';
}).css({ 'visibility': 'hidden' }).one(event_cleanup, function () {
this.style.visibility = 'inherit';
});
}
function setPosition(s) {
var prev, prevSrc, next, nextSrc, total = $related.length, loop = se
ttings.loop;
publicMethod.position(s, function () {
function defilter() {
if (isIE) {
//IE adds a filter when ColorBox fades in and out that c

an cause problems if the loaded content contains transparent pngs.


$box[0].style.filter = false;
}
}
if (!open) {
return;
}
if (isIE) {
//This fadeIn helps the bicubic resampling to kick-in.
if (photo) {
$loaded.fadeIn(100);
}
}
$loaded.show();
trigger(event_loaded);
$title.show().html(settings.title);
if (total > 1) { // handle grouping
$current.html(settings.current.replace(/\{current\}/, index
+ 1).replace(/\{total\}/, total)).show();
$next[(loop || index < total - 1) ? "show" : "hide"]().html(
settings.next);
$prev[(loop || index) ? "show" : "hide"]().html(settings.pre
vious);
prev = index ? $related[index - 1] : $related[total - 1];
next = index < total - 1 ? $related[index + 1] : $related[0]
;
if (settings.slideshow) {
$slideshow.show();
if (index === total - 1 && !loop && $box.is('.' + prefix
+ 'Slideshow_on')) {
$slideshow.click();
}
}
// Preloads images within a rel group
if (settings.preloading) {
nextSrc = $.data(next, colorbox).href || next.href;
prevSrc = $.data(prev, colorbox).href || prev.href;
if (isImage(nextSrc, next)) {
$('<img/>')[0].src = nextSrc;
}
if (isImage(prevSrc, prev)) {
$('<img/>')[0].src = prevSrc;
}
}
}
$loadingOverlay.hide();

if (settings.transition === 'fade') {


$box.fadeTo(speed, 1, function () {
defilter();
});
} else {
defilter();
}
$window.bind('resize.' + prefix, function () {
publicMethod.position(0);
});
trigger(event_complete, settings.onComplete);
});
}
if (settings.transition === 'fade') {
$box.fadeTo(speed, 0, function () {
setPosition(0);
});
} else {
setPosition(speed);
}
};
publicMethod.load = function (launched) {
var href, img, setResize, prep = publicMethod.prep;
active = true;
element = $related[index];
if (!launched) {
settings = process($.extend({}, $.data(element, colorbox)));
}
trigger(event_purge);
trigger(event_load, settings.onLoad);
settings.h = settings.height ?
setSize(settings.height, 'y') - loadedHeight - i
nterfaceHeight :
settings.innerHeight && setSize(settings.innerHe
ight, 'y');
settings.w = settings.width ?
setSize(settings.width, 'x') - loadedWidth - int
erfaceWidth :
settings.innerWidth && setSize(settings.innerWid
th, 'x');
// Sets the minimum dimensions for use in image scaling
settings.mw = settings.w;
settings.mh = settings.h;
// Re-evaluate the minimum width and height based on maxWidth and maxHei
ght values.
// If the width or height exceed the maxWidth or maxHeight, use the maxi
mum values instead.
if (settings.maxWidth) {

settings.mw = setSize(settings.maxWidth, 'x') - loadedWidth - interf


aceWidth;
settings.mw = settings.w && settings.w < settings.mw ? settings.w :
settings.mw;
}
if (settings.maxHeight) {
settings.mh = setSize(settings.maxHeight, 'y') - loadedHeight - inte
rfaceHeight;
settings.mh = settings.h && settings.h < settings.mh ? settings.h :
settings.mh;
}
href = settings.href;
$loadingOverlay.show();
if (settings.inline) {
// Inserts an empty placeholder where inline content is being pulled
from.
// An event is bound to put inline content back when ColorBox closes
or loads new content.
$div().hide().insertBefore($(href)[0]).one(event_purge, function ()
{
$(this).replaceWith($loaded.children());
});
prep($(href));
} else if (settings.iframe) {
// IFrame element won't be added to the DOM until it is ready to be
displayed,
// to avoid problems with DOM-ready JS that might be trying to run i
n that iframe.
$box.one(event_loaded, function () {
var $iframe = $("<iframe name='" + new Date().getTime() + "' fra
meborder=0" + (settings.scrolling ? "" : " scrolling='no'") + (isIE ? " allowtra
nsparency='true'" : '') + " style='width:100%; height:100%; border:0; display:bl
ock;'/>");
$iframe[0].src = settings.href;
$iframe.appendTo($loaded).one(event_purge, function () {
$iframe[0].src = 'about:blank';
});
});
prep(" ");
} else if (settings.html) {
prep(settings.html);
} else if (isImage(href, element)) {
img = new Image();
img.onload = function () {
var percent;
img.onload = null;
img.id = prefix + 'Photo';
$(img).css({ border: 'none', display: 'block', cssFloat: 'left'
});
if (settings.scalePhotos) {
setResize = function () {
img.height -= img.height * percent;
img.width -= img.width * percent;
};
if (settings.mw && img.width > settings.mw) {
percent = (img.width - settings.mw) / img.width;

setResize();
}
if (settings.mh && img.height > settings.mh) {
percent = (img.height - settings.mh) / img.height;
setResize();
}
}
if (settings.h) {
img.style.marginTop = Math.max(settings.h - img.height, 0) /
2 + 'px';
}
if ($related[1] && (index < $related.length - 1 || settings.loop
)) {
$(img).css({ cursor: 'pointer' }).click(publicMethod.next);
}
if (isIE) {
img.style.msInterpolationMode = 'bicubic';
}
setTimeout(function () { // Chrome will sometimes report a 0 by
0 size if there isn't pause in execution
prep(img);
}, 1);
};
setTimeout(function () { // Opera 10.6+ will sometimes load the src
before the onload function is set
img.src = href;
}, 1);
} else {
$div().appendTo($loadingBay).load(href, function (data, status, xhr)
{
prep(status === 'error' ? 'Request unsuccessful: ' + xhr.statusT
ext : this);
});
}
};
// Navigates to the next page/image in a set.
publicMethod.next = function () {
if (!active) {
index = index < $related.length - 1 ? index + 1 : 0;
publicMethod.load();
}
};
publicMethod.prev = function () {
if (!active) {
index = index ? index - 1 : $related.length - 1;
publicMethod.load();
}
};
// Note: to use this within an iframe use the following format: parent.$.fn.
colorbox.close();
publicMethod.close = function () {

if (open && !closing) {


closing = true;
open = false;
trigger(event_cleanup, settings.onCleanup);
$window.unbind('.' + prefix + ' .' + event_ie6);
$overlay.fadeTo('fast', 0);
$box.stop().fadeTo('fast', 0, function () {
trigger(event_purge);
$loaded.remove();
$box.add($overlay).css({ 'opacity': 1, cursor: 'auto' }).hide();
try {
bookmark.focus();
} catch (e) {
// do nothing
}
setTimeout(function () {
closing = false;
trigger(event_closed, settings.onClosed);
}, 1);
});
}
};
// A method for fetching the current element ColorBox is referencing.
// returns a jQuery object.
publicMethod.element = function () {
return $(element);
};
publicMethod.settings = defaults;
// Initializes ColorBox when the DOM has loaded
$(publicMethod.init);
}(jQuery, this));
; (function ($) {
$.fn.trimWhiteSpace = function (recursive) {
recursive = typeof (recursive) != 'undefined' ? recursive : false;
this.contents().filter(function () {
if (this.nodeType != 3 && recursive) {
$(this).trimWhiteSpace();
return false;
}
else {
return !/\S/.test(this.nodeValue);
}
}).remove().css('word-spacing', 'normal');

return this;
}
})(jQuery);
/*
* jQuery carouselFrame 1.0
* Adds fly-up info tabs to carousel frames
*/
; (function ($) {
$.fn.carouselFrame = function () {
// define hoverIntent plugin as hover if it does not exist
$.fn.hoverIntent = $.fn.hoverIntent || $.fn.hover;
// handle hover on each frame
this.hoverIntent(function () {
// create reference variables
var info = $('.info', this);
var content = $('.content', info);
// check if content exists
if (content.text().length > 0) {
// reposition the info container, store the top value and show t
he content
info.not('.positioned').positionAbsolute()
.data('top', parseInt(info.css('top')));
// get height of content
var contentHeight = parseInt($(content).outerHeight(true));
// create initial value for top offset
var offsetTop = 0;
// add value to top offset if carousel is large style
if ($(this).parents('.carousel-image-large').length > 0) {
offsetTop = 13;
}
// check if content height is greater than the image height
if (contentHeight > (info.data('top') - offsetTop)) {
// set content height to same as image height
contentHeight = (info.data('top') - offsetTop);
}
// show content
content.show();
// show carousel item content
$(info).animate({ top: '-=' + contentHeight }, {
duration: 100,
easing: 'easeOutCubic'
});
}
}, function () {
// create reference variables
var info = $('.info', this);
var content = $('.content', info);
// check if content exists
if (content.text().length > 0) {
// hide carousel item content

$(info).animate({ top: info.data('top') }, 100, 'easeOutCubic',


function () {
// hide content
content.hide();
});
}
}).bind('click', function (e) {
e.preventDefault();
// get href from frame header
var href = $('.info > h3 a', this).attr('href');
// check if href is set
if (typeof href != 'undefined') {
// redirect to href location
if ((href.toLowerCase().indexOf('http://') == 0 || href.toLowerC
ase().indexOf('https://') == 0) && href.indexOf(window.location.hostname) == -1)
{
window.open(href);
} else {
self.document.location = href;
}
}
}).each(function () {
// get href from frame header
var href = $('.info > h3 a', this).attr('href');
// check if href is set
if (typeof href != 'undefined') {
$(this).addClass('frame-linked');
}
}).find('.info').not('.info-structured').addClass('info-structured').aft
er('<div class="info-b"><div class="info-bl"><div class="info-br"></div></div></
div>');
return this;
};
})(jQuery);
/*
* jQuery statusFill 1.0
* Fills status bar based on specified percent value
*/
; (function ($) {
$.fn.statusFill = function (fill) {
// set default for static fill
var staticFill = true;
// check if fill variable was passed
if (typeof fill == 'undefined') {
staticFill = false;
}
// iterate through each status bar
this.each(function (i) {
// default the "fill" variable to 0 if not passed
if (!staticFill) {
var currentVal = parseInt($(this).text());
if (isNaN(currentVal)) {
fill = 0;

}
else {
fill = currentVal;
}
}
// set a max fill of 100
if (fill > 100) {
fill = 100;
}
// set default width
var width = 'auto';
// set width
if (fill < 99) {
width = fill + '%';
}
// set new width and add text value
$(this).width(width).text(fill + '%');
});
return this;
}
})(jQuery);
/*
* jQuery Form Example Plugin 1.4.3
* Populate form inputs with example text that disappears on focus.
*
* e.g.
* $('input#name').example('Bob Smith');
* $('input[@title]').example(function() {
*
return $(this).attr('title');
* });
* $('textarea#message').example('Type your message here', {
*
className: 'example_text'
* });
*
* Copyright (c) Paul Mucur (http://mucur.name), 2007-2008.
* Dual-licensed under the BSD (BSD-LICENSE.txt) and GPL (GPL-LICENSE.txt)
* licenses.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
(function ($) {
$.fn.example = function (text, args) {
/* Only calculate once whether a callback has been used. */
var isCallback = $.isFunction(text);

/* Merge the arguments and given example text into one options object. *
/
var options = $.extend({}, args, { example: text });
return this.each(function () {
/* Reduce method calls by saving the current jQuery object. */
var $this = $(this);
/* Merge the plugin defaults with the given options and, if present,
* any metadata.
*/
if ($.metadata) {
var o = $.extend({}, $.fn.example.defaults, $this.metadata(), op
tions);
} else {
var o = $.extend({}, $.fn.example.defaults, options);
}
/* The following event handlers only need to be bound once
* per class name. In order to do this, an array of used
* class names is stored and checked on each use of the plugin.
* If the class name is in the array then this whole section
* is skipped. If not, the events are bound and the class name
* added to the array.
*
* As of 1.3.2, the class names are stored as keys in the
* array, rather than as elements. This removes the need for
* $.inArray().
*/
if (!$.fn.example.boundClassNames[o.className]) {
/* Because Gecko-based browsers cache form values
* but ignore all other attributes such as class, all example
* values must be cleared on page unload to prevent them from
* being saved.
*/
$(window).unload(function () {
$('.' + o.className).val('');
});
/* Clear fields that are still examples before any form is submi
tted
* otherwise those examples will
*
* Prior to 1.3, this would only
* parents of example fields but
* multiple forms would not work
*/
$('form').submit(function () {

be sent along as well.


be bound to forms that were
this meant that a page with
correctly.

/* Clear only the fields inside this particular form. */


$(this).find('.' + o.className).val('');
});
/* Add the class name to the array. */
$.fn.example.boundClassNames[o.className] = true;
}
/* Several browsers will cache form values even if they are cleared

* on unload, so this will clear any value that matches the example
* text and hasn't been specified in the value attribute.
*
* If a callback is used, it is not possible or safe to predict
* what the example text is going to be so all non-default values
* are cleared. This means that caching is effectively disabled for
* that field.
*
* Many thanks to Klaus Hartl for helping resolve this issue.
*/
if (!$this.attr('defaultValue') && (isCallback || $this.val() == o.e
xample))
$this.val('');
/* Initially place the example text in the field if it is empty
* and doesn't have focus yet.
*/
if ($this.val() == '' && this != document.activeElement) {
$this.addClass(o.className);
/* The text argument can now be a function; if this is the case,
* call it, passing the current element as `this`.
*/
$this.val(isCallback ? o.example.call(this) : o.example);
}
/* Make the example text disappear when someone focuses.
*
* To determine whether the value of the field is an example or not,
* check for the example class name only; comparing the actual value
* seems wasteful and can stop people from using example values as re
al
* input.
*/
$this.focus(function () {
/* jQuery 1.1 has no hasClass(), so is() must be used instead. *
/
if ($(this).is('.' + o.className)) {
$(this).val('');
$(this).removeClass(o.className);
}
});
/* Detect a change event to the field and remove the example class.
*/
$this.change(function () {
if ($(this).is('.' + o.className)) {
$(this).removeClass(o.className);
}
});
/* Make the example text reappear if the input is blank on blurring.
*/
$this.blur(function () {
if ($(this).val() == '') {
$(this).addClass(o.className);
/* Re-evaluate the callback function every time the user
* blurs the field without entering anything. While this

* is not as efficient as caching the value, it allows for


* more dynamic applications of the plugin.
*/
$(this).val(isCallback ? o.example.call(this) : o.example);
}
});
});
};
/* Users can override the defaults for the plugin like so:
*
* $.fn.example.defaults.className = 'not_example';
*/
$.fn.example.defaults = {
className: 'example'
};
/* All the class names used are stored as keys in the following array. */
$.fn.example.boundClassNames = [];
})(jQuery);
/*
* Provides methods for structuring common site-specific markup.
*/
; (function ($) {
// create structure for stylization of navigation
$.fn.structureMenuItem = function () {
this.not('.structured').addClass('structured').wrapInner('<span><span><s
pan><span></span></span></span></span>').each(function (index) {
if ($(this).siblings('ul').length <= 0) {
$('> span', this).addClass('no-sub');
}
});
return this;
}
// create structure for stylization of tabs
$.fn.structureTabs = function () {
this.not('.ui-tabs-structured').addClass('ui-tabs-structured')
.find('> .ui-tabs-nav li')
.filter(':first-child').addClass('first').end()
.filter(':last-child').addClass('last').end()
.find('a').wrapInner('<span><span><span></span></span></
span>').end().end()
.find('> .ui-tabs-panel').wrapInner('<div class="ui-tabs
-panel-l"><div class="ui-tabs-panel-r"><div class="ui-tabs-panel-b"><div class="
ui-tabs-panel-t"></div></div></div>');
return this;
}
// create structure for breadcrumb
$.fn.structureBreadcrumb = function () {
var breadcrumbs = this.not('.structured').addClass('structured').find('>
a, > span').not('.home').wrapInner('<span><span></span></span>').parent().find(
'> a, > span');
var breaddcrumbCount = breadcrumbs.length;
breadcrumbs.each(function (i) {

$(this).css('z-index', breaddcrumbCount - i);


});
return this;
};
// create structure for stylization of tables
$.fn.structureTable = function () {
$('tr, tr th, tr td', this)
.filter(':first-child').addClass('first').end()
.filter(':last-child').addClass('last').end()
.filter(':nth-child(odd)').addClass('odd').end()
.filter(':nth-child(even)').addClass('even');
$('thead tr th.first, thead tr th.last', this).wrapInner('<span />');
return this;
};
})(jQuery);
/*
* jQuery positionAbsolute 1.0
* Asbsolute positions elements
*/
; (function ($) {
$.fn.positionAbsolute = function () {
// create array of positions
var entryPositions = new Array();
// get height of parent
var parentHeight = this.parent().height('auto').height();
// do not continue if parent height is null
if (parentHeight != null) {
// set a relative position on the parent element and loop through ea
ch element twice
// first, storing the element's position value and then setting it's
styles
// this is needed to negate the position changing before calculation
this.not('.positioned').parent().css('position', 'relative').height(
parentHeight).end().each(function (i) {
// add position to entryPositions array
entryPositions.push($(this).position());
}).each(function (i) {
// set the CSS for the element
$(this).css({
position: 'absolute',
top: entryPositions[i].top,
left: entryPositions[i].left,
zIndex: entryPositions.length - i
});
}).addClass('positioned');
}
return this;
}
})(jQuery);
/**
* hoverIntent is similar to jQuery's built-in "hover" function except that
* instead of firing the onMouseOver event immediately, hoverIntent checks
* to see if the user's mouse has slowed down (beneath the sensitivity

* threshold) before firing the onMouseOver event.


*
* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
*
* hoverIntent is currently available for use in all personal or commercial
* projects under both MIT and GPL licenses. This means that you can choose
* the license that best suits your project, and use it accordingly.
*
* // basic usage (just like .hover) receives onMouseOver and onMouseOut function
s
* $("ul li").hoverIntent( showNav , hideNav );
*
* // advanced usage receives configuration object only
* $("ul li").hoverIntent({
*
sensitivity: 7, // number = sensitivity threshold (must be 1 or higher)
*
interval: 100, // number = milliseconds of polling interval
*
over: showNav, // function = onMouseOver callback (required)
*
timeout: 0, // number = milliseconds delay before onMouseOut function
call
*
out: hideNav
// function = onMouseOut callback (required)
* });
*
* @param f onMouseOver function || An object with configuration options
* @param g onMouseOut function || Nothing (use configuration options object)
* @author
Brian Cherne <brian@cherne.net>
*/
; (function ($) {
$.fn.hoverIntent = function (f, g, c) {
// default configuration options
var cfg = {
sensitivity: 7,
interval: 25,
timeout: 0
};
// override configuration options with user supplied object
cfg = $.extend(cfg, g ? { over: f, out: g } : f, c || {});
// instantiate variables
// cX, cY = current X and Y position of mouse, updated by mousemove even
t
// pX, pY = previous X and Y position of mouse, set by mouseover and pol
ling interval
var cX, cY, pX, pY;
// A private function for getting mouse position
var track = function (ev) {
cX = ev.pageX;
cY = ev.pageY;
};
// A private function for comparing current and previous mouse position
var compare = function (ev, ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
// compare mouse positions to see if they've crossed the threshold
if ((Math.abs(pX - cX) + Math.abs(pY - cY)) < cfg.sensitivity) {
$(ob).unbind("mousemove", track);
// set hoverIntent state to true (so mouseOut can be called)

ob.hoverIntent_s = 1;
return cfg.over.apply(ob, [ev]);
} else {
// set previous coordinates for next time
pX = cX; pY = cY;
// use self-calling timeout, guarantees intervals are spaced out
properly (avoids JavaScript timer bugs)
ob.hoverIntent_t = setTimeout(function () { compare(ev, ob); },
cfg.interval);
}
};
// A private function for delaying the mouseOut function
var delay = function (ev, ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
ob.hoverIntent_s = 0;
return cfg.out.apply(ob, [ev]);
};
// A private function for handling mouse 'hovering'
var handleHover = function (e) {
// next three lines copied from jQuery.hover, ignore children onMous
eOver/onMouseOut
var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.r
elatedTarget;
while (p && p != this) { try { p = p.parentNode; } catch (e) { p = t
his; } }
if (p == this) { return false; }
// copy objects to be passed into t (required for event object to be
passed in IE)
var ev = jQuery.extend({}, e);
var ob = this;
// cancel hoverIntent timer if it exists
if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverInte
nt_t); }
// else e.type == "onmouseover"
if (e.type == "mouseover") {
// set "previous" X and Y position based on initial entry point
pX = ev.pageX; pY = ev.pageY;
// update "current" X and Y position based on mousemove
$(ob).bind("mousemove", track);
// start polling interval (self-calling timeout) to compare mous
e coordinates over time
if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout(funct
ion () { compare(ev, ob); }, cfg.interval); }
// else e.type == "onmouseout"
} else {
// unbind expensive mousemove event
$(ob).unbind("mousemove", track);
// if hoverIntent state is true, then call the mouseOut function
after the specified delay
if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout(funct
ion () { delay(ev, ob); }, cfg.timeout); }
}
};

// bind the function to the two event listeners


return this.mouseover(handleHover).mouseout(handleHover);
};
})(jQuery);
/*
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
*
* Uses the built in easing capabilities added In jQuery 1.1
* to offer multiple easing options
*
* TERMS OF USE - jQuery Easing
*
* Open source under the BSD License.
*
* Copyright 2008 George McGinley Smith
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modificatio
n,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this li
st of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list
* of conditions and the following disclaimer in the documentation and/or other m
aterials
* provided with the distribution.
*
* Neither the name of the author nor the names of contributors may be used to en
dorse
* or promote products derived from this software without specific prior written
permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN
D ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARR
ANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVE
NT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTA
L, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREME
NT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) H
OWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// t: current time, b: begInnIng value, c: change In value, d: duration
jQuery.easing['jswing'] = jQuery.easing['swing'];
jQuery.extend(jQuery.easing,
{

def: 'easeOutQuad',
swing: function (x, t, b, c, d) {
//alert(jQuery.easing.default);
return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
},
easeInQuad: function (x, t, b, c, d) {
return c * (t /= d) * t + b;
},
easeOutQuad: function (x, t, b, c, d) {
return -c * (t /= d) * (t - 2) + b;
},
easeInOutQuad: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t + b;
return -c / 2 * ((--t) * (t - 2) - 1) + b;
},
easeInCubic: function (x, t, b, c, d) {
return c * (t /= d) * t * t + b;
},
easeOutCubic: function (x, t, b, c, d) {
return c * ((t = t / d - 1) * t * t + 1) + b;
},
easeInOutCubic: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
return c / 2 * ((t -= 2) * t * t + 2) + b;
},
easeInQuart: function (x, t, b, c, d) {
return c * (t /= d) * t * t * t + b;
},
easeOutQuart: function (x, t, b, c, d) {
return -c * ((t = t / d - 1) * t * t * t - 1) + b;
},
easeInOutQuart: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
},
easeInQuint: function (x, t, b, c, d) {
return c * (t /= d) * t * t * t * t + b;
},
easeOutQuint: function (x, t, b, c, d) {
return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
},
easeInOutQuint: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
},
easeInSine: function (x, t, b, c, d) {
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
},
easeOutSine: function (x, t, b, c, d) {
return c * Math.sin(t / d * (Math.PI / 2)) + b;
},
easeInOutSine: function (x, t, b, c, d) {
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
},
easeInExpo: function (x, t, b, c, d) {
return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
},
easeOutExpo: function (x, t, b, c, d) {
return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
},

easeInOutExpo: function (x, t, b, c, d) {


if (t == 0) return b;
if (t == d) return b + c;
if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
},
easeInCirc: function (x, t, b, c, d) {
return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
},
easeOutCirc: function (x, t, b, c, d) {
return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
},
easeInOutCirc: function (x, t, b, c, d) {
if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
},
easeInElastic: function (x, t, b, c, d) {
var s = 1.70158; var p = 0; var a = c;
if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .
3;
if (a < Math.abs(c)) { a = c; var s = p / 4; }
else var s = p / (2 * Math.PI) * Math.asin(c / a);
return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Ma
th.PI) / p)) + b;
},
easeOutElastic: function (x, t, b, c, d) {
var s = 1.70158; var p = 0; var a = c;
if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .
3;
if (a < Math.abs(c)) { a = c; var s = p / 4; }
else var s = p / (2 * Math.PI) * Math.asin(c / a);
return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) /
p) + c + b;
},
easeInOutElastic: function (x, t, b, c, d) {
var s = 1.70158; var p = 0; var a = c;
if (t == 0) return b; if ((t /= d / 2) == 2) return b + c; if (!p) p = d
* (.3 * 1.5);
if (a < Math.abs(c)) { a = c; var s = p / 4; }
else var s = p / (2 * Math.PI) * Math.asin(c / a);
if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t *
d - s) * (2 * Math.PI) / p)) + b;
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Mat
h.PI) / p) * .5 + c + b;
},
easeInBack: function (x, t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c * (t /= d) * t * ((s + 1) * t - s) + b;
},
easeOutBack: function (x, t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
},
easeInOutBack: function (x, t, b, c, d, s) {
if (s == undefined) s = 1.70158;
if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t
- s)) + b;
return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
},
easeInBounce: function (x, t, b, c, d) {

return c - jQuery.easing.easeOutBounce(x, d - t, 0, c, d) + b;
},
easeOutBounce: function (x, t, b, c, d) {
if ((t /= d) < (1 / 2.75)) {
return c * (7.5625 * t * t) + b;
} else if (t < (2 / 2.75)) {
return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
} else if (t < (2.5 / 2.75)) {
return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
} else {
return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
}
},
easeInOutBounce: function (x, t, b, c, d) {
if (t < d / 2) return jQuery.easing.easeInBounce(x, t * 2, 0, c, d) * .5
+ b;
return jQuery.easing.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5
+ b;
}
});
/*
*
* TERMS OF USE - EASING EQUATIONS
*
* Open source under the BSD License.
*
* Copyright 2001 Robert Penner
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modificatio
n,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this li
st of
* conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list
* of conditions and the following disclaimer in the documentation and/or other m
aterials
* provided with the distribution.
*
* Neither the name of the author nor the names of contributors may be used to en
dorse
* or promote products derived from this software without specific prior written
permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN
D ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARR
ANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVE
NT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTA
L, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREME
NT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) H
OWEVER CAUSED

* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT


(INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* jQuery dateCalendar 1.0
* Extends jQuery UI DatePicker to allow for dynmically highlighted dates and bin
ding of the select event for each date.
*/
; (function ($) {
$.fn.dateCalendar = function (options) {
var $this = this;
// create carousel data object if not set
if ($this.length > 0 && $this.data('calendar') == null) {
// create calendar data object
var calendar = $this.data('calendar', {
options: new Object(),
url: options.url,
dates: new Array(),
events: new Array()
}).data('calendar');
// merge default options object with that of the supplied options
$.extend(true, calendar.options, $.fn.dateCalendar.options, (typeof
options == 'undefined') ? {} : options);
// overwrite datePicker events with custom ones
$.extend(true, calendar.options.datePicker, $.fn.dateCalendar.events
);
// get current date
var time = new Date();
var monthYear = {
month: time.getMonth() + 1,
year: time.getFullYear()
};
// set data and create datePicker
$this.datepicker(calendar.options.datePicker);
$.fn.dateCalendar.setData.call($this, calendar.options.url, monthYea
r);
}
return this;
}
// set data from JSON source
$.fn.dateCalendar.setData = function (url, monthYear, callback) {
var $this = this;
var calendar = $this.data('calendar');
$.ajax({
url: url,
type: 'GET',
dataType: 'json',
data: $.param(monthYear),

success: function (events) {


calendar.events = events;
calendar.dates = new Array();
numEvents = events.length;
$.each(events, function (i) {
var date = new Date(events[i].date);
var dateStr = $.datepicker.formatDate('yy-mm-dd', date);
calendar.dates.push(dateStr);
if ((i + 1) == numEvents) {
$.fn.dateCalendar.highlightDays.call($this, calendar);
}
});
},
complete: function () {
if ($.isFunction(callback)) {
callback.call();
}
}
});
};
$.fn.dateCalendar.highlightDays = function (calendar) {
var datePickerInst = this.data('datepicker');
var year = $.fn.dateCalendar.zeroFill(datePickerInst.drawYear, 2);
var month = $.fn.dateCalendar.zeroFill(datePickerInst.drawMonth + 1, 2);
$('table.ui-datepicker-calendar tbody tr td span', this).each(function (
i) {
var day = $(this).text();
var dateStr = year + '-' + month + '-' + $.fn.dateCalendar.zeroFill(
day, 2);
var eventIndex = $.inArray(dateStr, calendar.dates);
if (eventIndex > -1 && eventIndex < numEvents) {
var anchor = $('<a />', {
href: calendar.events[eventIndex].url,
text: day
});
var addClass = '';
var removeClass = 'ui-state-disabled';
if (typeof calendar.events[eventIndex].url == 'string') {
addClass = 'ui-datepicker-selectable';
removeClass += ' ui-datepicker-unselectable';
}
$(this).parent('td').removeClass(removeClass).addClass(addClass)
.end().replaceWith(anchor);
}
});
}
$.fn.dateCalendar.zeroFill = function (n, l) {

n = n.toString();
var fill = '';
if (l > n.length) {
for (i = 0; i < (l - n.length) ; i++) {
fill += '0';
}
}
return fill + n;
}
// create datePicker events
$.fn.dateCalendar.events = {
beforeShowDay: function (date) {
var selectable = [
false,
''
];
return selectable;
},
onChangeMonthYear: function (year, month, inst) {
var $this = $(this);
var monthYear = {
month: month,
year: year
}
var url = $(this).data('calendar').url;
$.fn.dateCalendar.setData.call($this, url, monthYear);
}
}
// set default options
$.fn.dateCalendar.options = {
url: '',
datePicker: {
dayNamesMin: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
nextText: '&#x25B6;',
prevText: '&#x25C0;'
}
};
})(jQuery);
// jQuery URL Toolbox beta
// Created by Mark Perkins - mark@allmarkedup.com
(function ($) {
// a few helper functions
var isStr = function (item) { return typeof item === 'string'; };
var isObj = function (item) { return typeof item === 'object'; };
var isfunc = function (item) { return typeof item === 'function'; };
var isGetter = function (args) { return (args.length == 1 && !isObj(args[0])
); }

var isSetter = function (args) { return (args.length >= 2 || (args.length ==


1 && isObj(args[0]))); }
var stripQ = function (str) { return str.replace(/\?.*$/, ''); }
var stripH = function (str) { return str.replace(/^#/, ''); }
// set up a few constants & shortcuts
var loc = document.location,
tag2attr = { a: 'href', img: 'src', form: 'action', base: 'href', script
: 'src', iframe: 'src', link: 'href' };
// split up a query sting
function splitQuery(string) {
var ret = {},
seg = string.replace(/^\?/, '').split('&'),
len = seg.length, i = 0, s;
for (; i < len; i++) {
if (!seg[i]) { continue; }
s = seg[i].split('=');
ret[s[0]] = s[1];
}
return ret;
}
// reconstructs a query string from an object of key:value pairs
var combineQuery = function (params, prefixQM) {
var queryString = (prefixQM === true) ? '?' : '';
for (i in params) queryString += i + '=' + params[i] + '&';
return queryString.slice(0, -1);
};
// reconstructs a path string from an array of parts
var combinePath = function (segments) {
return segments.join('/');
};
function splitHashSegments(hash) {
if (hash.indexOf('=') === -1) {
if (hash.charAt(hash.length - 1) == '/') hash = hash.slice(0, -1);
return hash.replace(/^\//, '').split('/');
}
return null;
}
function splitHashParams(hash) {
if (hash.indexOf('=') !== -1) return splitQuery(hash);
return null;
}
// utility function to get tag name of $ objects
var getTagName = function (elm) {
var tg = $(elm).get(0).tagName;
if (tg !== undefined) return tg.toLowerCase();
return tg;
}
var throwParserError = function (msg) {
if (msg === undefined) msg = 'url parser error';
// console.log( msg );
};

var getHost = function (hostname, port) {


// deals with non-standard port name issues, mostly in safari
var portRegex = new RegExp(':' + port); // need to strip the non-standar
d ports out of safari
return hostname.replace(portRegex, '');
}
////////////////////////////////////////////////////////////////////////////
////////////////////
// create :internal and :external URL filters
$.extend($.expr[':'], {
external: function (elm, i, m) {
var tagName = elm.tagName;
if (tagName !== undefined) {
var tg = tagName.toLowerCase();
var attr = tag2attr[tg];
if (elm[attr]) {
if (tg !== 'a') {
var a = document.createElement('a');
a.href = elm[attr];
}
else var a = elm;
return a.hostname && getHost(a.hostname, a.port) !== getHost
(loc.hostname, loc.port);
}
}
return false;
},
internal: function (elm, i, m) {
var tagName = elm.tagName;
if (tagName !== undefined) {
var tg = tagName.toLowerCase();
var attr = tag2attr[tg];
if (elm[attr]) {
if (tg !== 'a') {
var a = document.createElement('a');
a.href = elm[attr];
}
else var a = elm;
return a.hostname && getHost(a.hostname, a.port) === getHost
(loc.hostname, loc.port);
}
}
return false;
}
});
/////// two essentially analagous functions to return an activeUrl object (j
ust in different ways) ////////
// this one is for when you just want to use a manually passed in URL string
$.url = function (urlString) {
return new activeUrl(urlString);
};
// this one is when using DOM objects as the source for the URL

$.fn.url = function () {
if (this.size() > 1) {
// more than one object, return a collection of activeUrls
var activeUrls = {};
this.each(function (i) {
activeUrls[i] = new activeUrl($(this));
});
return activeUrls;
}
else {
// just one item, return just the one active url
return new activeUrl(this);
}
};
/////// guts of the parser /////////////////////////////////////////////////
////////////
function parseUrl(url) {
var urlRegEx = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^
:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?
:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
var keys = ["source", "protocol", "authority", "userInfo", "user", "pass
word", "host", "port", "relative", "path", "directory", "file", "query", "anchor
"];
var m = urlRegEx.exec(url);
var uri = {};
var i = keys.length;
while (i--) {
uri[keys[i]] = m[i] || '';
}
var a = $('<a />').attr('href', url).get(0);
a.hostname = (a.hostname == '') ? self.document.location.hostname : a.ho
stname;
a.protocol = (a.protocol == '') ? self.document.location.protocol : a.pr
otocol;
uri = $.extend(true, uri, {
host: getHost(a.hostname, a.port),
base: (function () {
if (a.port != 0 && a.port !== null && a.port !== "") return a.pr
otocol + "//" + getHost(a.hostname, a.port) + ":" + a.port;
return a.protocol + "//" + a.hostname;
})(),
params: splitQuery(uri.query),
hash: stripH(a.hash),
segments: uri.path.replace(/^\//, '').split('/'),
hashSegments: splitHashSegments(stripH(a.hash)),
hashParams: splitHashParams(stripH(a.hash))
});
return uri;
};

// this is the 'active' URL object that gets returned


var activeUrl = function (source) {
var sourceType = null, // elm | doc | str
ref = null, // if it is attached to a $ object, keep the
reference here
parsed = {}; // the parsed url
// reconstructs the hash
var makeHash = function (prefixHash) {
var hash = '';
if (parsed.hashParams != null) {
// treated as query string
hash = makeQueryString(parsed.hashParams);
}
else if (parsed.hashSegments != null) {
//treat as segments
hash = makePathString(parsed.hashSegments);
}
if (hash !== '') {
if (parsed.hash.charAt(0) == '/') hash = '/' + hash;
if (prefixHash === true) return '#' + hash;
return hash;
}
return '';
};
/////////////////////////////////
var updateElement = function () {
if (sourceType == 'elm') {
ref.attr(tag2attr[getTagName(ref)], parsed.source);
}
else if (sourceType == 'doc') {
loc.href = parsed.source;
}
};
var updateSource = function () {
parsed.source = parsed.base + parsed.path + parsed.query;
if (parsed.hash && parsed.hash != '') parsed.source += '#' + parsed.
hash;
}
var updateParsedAttrs = function (key, val) {
switch (key) {
case 'source':
parsed = parseUrl(val); // need to reparse the entire URL
break;
case 'base':
// need to update: host, protocol, port
if (val.charAt(val.length - 1) == '/') val = val.slice(0, -1
); // remove the trailing slash if present
var a = document.createElement('a');
a.href = parsed.base = val;

parsed.protocol = a.protocol.replace(':', '');


parsed.host = getHost(a.hostname, a.port);
parsed.port = a.port;
break;
case 'protocol':
case 'host':
case 'port':
// need to update: base
parsed[key] = val;
if (a.port != 0 && a.port !== null && a.port !== "") parsed.
base = a.protocol + "//" + getHost(a.hostname, a.port) + ":" + a.port;
else parsed.base = a.protocol + "//" + a.host;
break;
case 'query':
// need to update: params
parsed.query = '?' + val.replace(/\?/, '');
parsed.params = splitQuery(val);
break;
case 'file':
// need to update: path, segments
parsed.path = parsed.path.replace(new RegExp(parsed.file + '
$'), val);
parsed.file = val;
break;
case 'hash':
// need to update: hashParams, hashSegments
parsed.hash = val;
parsed.hashSegments = splitHashSegments(val);
parsed.hashParams = splitHashParams(val);
break;
case 'path':
// need to update: file, segments
if (val.charAt(0) != '/') val = '/' + val;
parsed.path = val;
parsed.file = (val.match(/\/([^\/?#]+)$/i) || [, ''])[1];
parsed.segments = val.replace(/^\//, '').split('/');
break;
default:
throwParserError('you can\'t update this property directly')
;
break;
}
updateSource(); // update the source
};
var updateParsedParams = function (key, val) {
// set the value, then update the query string
parsed.params[key] = val;
parsed.query = combineQuery(parsed.params, true);
updateSource();
};
var updateParsedSegments = function (key, val) {

// set the value, then update the segments


parsed.segments[key] = val;
parsed.path = '/' + combinePath(parsed.segments);
parsed.file = (parsed.path.match(/\/([^\/?#]+)$/i) || [, ''])[1];
updateSource();
};
var updateHashParams = function (key, val) {
parsed.hashParams[key] = val;
parsed.hash = combineQuery(parsed.hashParams, true);
updateSource();
};
var updateHashSegments = function (key, val) {
var slash = (parsed.hash.charAt(0) == '/') ? '/' : '';
parsed.hashSegments[key] = val;
parsed.hash = slash + combinePath(parsed.hashSegments);
updateSource();
};
var action = function (gettObj, sett, args) {
if (isGetter(args)) {
var key = args[0];
return (gettObj === undefined || gettObj[key] === undefined || g
ettObj[key] === "") ? null : gettObj[key];
}
else if (isSetter(args)) {
if (isObj(args[0])) {
for (var key in args[0]) sett(key, args[0][key]); // set mul
tiple properties
if (args[1] !== false) updateElement(); // now update the va
lue of the attached element
}
else {
sett(args[0], args[1]); // set a single property
if (args[2] !== false) updateElement(); // now update the va
lue of the attached element
}
return this; // return reference to this object
}
};
var init = function () {
if (isObj(source) && source.size()) {
urlAttr = undefined;
var tagName = getTagName(source);
if (tagName !== undefined) urlAttr = tag2attr[tagName];
if (tagName !== undefined && urlAttr !== undefined) {
// using a valid $ element as the source of the URL
sourceType = 'elm';
ref = source;
var url = source.attr(urlAttr);
}
else if (tagName !== undefined && urlAttr === undefined) {
// passed a $ element, but not one that can contain a URL. t
hrow an error.
throwParserError('no valid URL on object');

return;
}
else {
// use the document location as the source
sourceType = 'doc';
var url = loc.href;
$(window).bind('hashchange', function (hash) {
// listen out for hashChanges, if one is triggered then
update the hash
updateParsedAttrs('hash', stripH(loc.hash));
});
}
}
else if (!isObj(source)) {
// just a URL string
sourceType = 'str';
var url = source;
}
else {
// passed an empty $ item.... don't return anything
throwParserError('no valid item');
return;
}
parsed = parseUrl(url); // parse the URL.
}();
return {
// set/get attributes of the URL
attr: function () { return action(parsed, updateParsedAttrs, argumen
ts) },
// get/set query string parameters
param: function () { return action(parsed.params, updateParsedParams
, arguments) },
// get/set segments in the URL
segment: function () { return action(parsed.segments, updateParsedSe
gments, arguments) },
// get/set 'query string' parameters in the FRAGMENT
hashParam: function () { return action(parsed.hashParams, updateHash
Params, arguments) },
// get/set segments in the FRAGMENT
hashSegment: function () { return action(parsed.hashSegments, update
HashSegments, arguments) },
// apply some tests
is: function (test) {
if (test === 'internal' || test === ':internal') {
return parsed.host && parsed.host === getHost(loc.hostname);
}
else if (test === 'external' || test === ':external') {
return parsed.host && parsed.host !== getHost(loc.hostname);
}
},

// return the current URL as a string


toString: function () { return parsed.source; }
};
};
})(jQuery);
/**
* Cookie plugin
*
* Copyright (c) 2006 Klaus Hartl (stilbuero.de)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
/**
* Create a cookie with the given name and value and other optional parameters.
*
* @example $.cookie('the_cookie', 'the_value');
* @desc Set the value of a cookie.
* @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain:
'jquery.com', secure: true });
* @desc Create a cookie with all available options.
* @example $.cookie('the_cookie', 'the_value');
* @desc Create a session cookie.
* @example $.cookie('the_cookie', null);
* @desc Delete a cookie by passing null as value. Keep in mind that you have to
use the same path and domain
*
used when the cookie was set.
*
* @param String name The name of the cookie.
* @param String value The value of the cookie.
* @param Object options An object literal containing key/value pairs to provide
optional cookie attributes.
* @option Number|Date expires Either an integer specifying the expiration date f
rom now on in days or a Date object.
*
If a negative value is specified (e.g. a date in t
he past), the cookie will be deleted.
*
If set to null or omitted, the cookie will be a se
ssion cookie and will not be retained
*
when the the browser exits.
* @option String path The value of the path atribute of the cookie (default: pat
h of page that created the cookie).
* @option String domain The value of the domain attribute of the cookie (default
: domain of page that created the cookie).
* @option Boolean secure If true, the secure attribute of the cookie will be set
and the cookie transmission will
*
require a secure protocol (like HTTPS).
* @type undefined
*
* @name $.cookie
* @cat Plugins/Cookie
* @author Klaus Hartl/klaus.hartl@stilbuero.de
*/
/**
* Get the value of a cookie with the given name.

*
* @example $.cookie('the_cookie');
* @desc Get the value of a cookie.
*
* @param String name The name of the cookie.
* @return The value of the cookie.
* @type String
*
* @name $.cookie
* @cat Plugins/Cookie
* @author Klaus Hartl/klaus.hartl@stilbuero.de
*/
jQuery.cookie = function (name, value, options) {
if (typeof value != 'undefined') { // name and value given, set cookie
options = options || {};
if (value === null) {
value = '';
options.expires = -1;
}
var expires = '';
if (options.expires && (typeof options.expires == 'number' || options.ex
pires.toUTCString)) {
var date;
if (typeof options.expires == 'number') {
date = new Date();
date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 *
1000));
} else {
date = options.expires;
}
expires = '; expires=' + date.toUTCString(); // use expires attribut
e, max-age is not supported by IE
}
// CAUTION: Needed to parenthesize options.path and options.domain
// in the following expressions, otherwise they evaluate to undefined
// in the packed version for some reason...
var path = options.path ? '; path=' + (options.path) : '';
var domain = options.domain ? '; domain=' + (options.domain) : '';
var secure = options.secure ? '; secure' : '';
document.cookie = [name, '=', encodeURIComponent(value), expires, path,
domain, secure].join('');
} else { // only name given, get cookie
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.lengt
h + 1));
break;
}
}
}
return cookieValue;
}
};
/*
* jQuery hoverClass

* Adds hover classes for use with IE6


*/
; (function ($) {
$.fn.hoverClass = function (config) {
// set default, empty, config object
var config = config || {};
// define hoverIntent plugin as hover if it does not exist
$.fn.hoverIntent = $.fn.hoverIntent || $.fn.hover;
// return object with hoverIntent event bound
return this.hoverIntent(function () {
var hoverClasses = $(this).data('hoverClass');
if (typeof hoverClasses === 'undefined') {
if (typeof $(this).attr('class') == "undefined") {
$(this).attr("class", "");
}
// get all classes for element
hoverClasses = $(this).attr('class').split(' ');
// add "-hover" to each class and add to
$.each(hoverClasses, function (i) {
hoverClasses[i] += (hoverClasses[i] == '') ? '' : '-hover';
});
// add default "hover" class
hoverClasses.push('hover');
// store hoverClasses for element
$(this).data('hoverClass', hoverClasses.join(' '));
// retrieve hover Classes
hoverClasses = $(this).data('hoverClass');
}
$(this).addClass(hoverClasses);
}, function () {
var hoverClasses = $(this).data('hoverClass');
$(this).removeClass(hoverClasses);
}, config);
}
})(jQuery);
/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
* Licensed under the MIT License (LICENSE.txt).
*
* Version 2.1.3-pre
*/
; (function ($) {
$.fn.bgiframe = ($.browser.msie && /msie 6\.0/i.test(navigator.userAgent) ?
function (s) {
s = $.extend({
top: 'auto', // auto == .currentStyle.borderTopWidth
left: 'auto', // auto == .currentStyle.borderLeftWidth
width: 'auto', // auto == offsetWidth
height: 'auto', // auto == offsetHeight

opacity: true,
src: 'javascript:false;'
}, s);
var html = '<iframe class="bgiframe"frameborder="0"tabindex="-1"src="' +
s.src + '"' +
'style="display:block;position:absolute;z-index:-1;' +
(s.opacity !== false ? 'filter:Alpha(Opacity=\'0\');' : '
') +
'top:' + (s.top == 'auto' ? 'expression(((parseInt(this.p
arentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')' : prop(s.top)) + ';' +
'left:' + (s.left == 'auto' ? 'expression(((parseInt(this
.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')' : prop(s.left)) + ';'
+
'width:' + (s.width == 'auto' ? 'expression(this.parentNo
de.offsetWidth+\'px\')' : prop(s.width)) + ';' +
'height:' + (s.height == 'auto' ? 'expression(this.parent
Node.offsetHeight+\'px\')' : prop(s.height)) + ';' +
'"/>';
return this.each(function () {
if ($(this).children('iframe.bgiframe').length === 0)
this.insertBefore(document.createElement(html), this.firstChild)
;
});
} : function () { return this; });
// old alias
$.fn.bgIframe = $.fn.bgiframe;
function prop(n) {
return n && n.constructor === Number ? n + 'px' : n;
}
})(jQuery);
/*!
* jScrollPane - v2.0.0beta9 - 2011-02-04
* http://jscrollpane.kelvinluck.com/
*
* Copyright (c) 2010 Kelvin Luck
* Dual licensed under the MIT and GPL licenses.
*/
// Script: jScrollPane - cross browser customisable scrollbars
//
// *Version: 2.0.0beta10, Last updated: 2011-02-04*
//
// Project Home - http://jscrollpane.kelvinluck.com/
// GitHub
- http://github.com/vitch/jScrollPane
// Source
- http://github.com/vitch/jScrollPane/raw/master/script/jquery.j
scrollpane.js
// (Minified) - http://github.com/vitch/jScrollPane/raw/master/script/jquery.j
scrollpane.min.js
//
// About: License
//
// Copyright (c) 2010 Kelvin Luck
// Dual licensed under the MIT or GPL Version 2 licenses.
// http://jscrollpane.kelvinluck.com/MIT-LICENSE.txt
// http://jscrollpane.kelvinluck.com/GPL-LICENSE.txt
//
// About: Examples

//
// All examples and demos are available through the jScrollPane example site at:
// http://jscrollpane.kelvinluck.com/
//
// About: Support and Testing
//
// This plugin is tested on the browsers below and has been found to work reliab
ly on them. If you run
// into a problem on one of the supported browsers then please visit the support
section on the jScrollPane
// website (http://jscrollpane.kelvinluck.com/) for more information on getting
support. You are also
// welcome to fork the project on GitHub if you can contribute a fix for a given
issue.
//
// jQuery Versions - tested in 1.4.2+ - reported to work in 1.3.x
// Browsers Tested - Firefox 3.6.8, Safari 5, Opera 10.6, Chrome 5.0, IE 6, 7, 8
//
// About: Release History
//
// 2.0.0beta10 - (in progress)
// 2.0.0beta9 - (2011-01-31) new API methods, bug fixes and correct keyboard sup
port for FF/OSX
// 2.0.0beta8 - (2011-01-29) touchscreen support, improved keyboard support
// 2.0.0beta7 - (2011-01-23) scroll speed consistent (thanks Aivo Paas)
// 2.0.0beta6 - (2010-12-07) scrollToElement horizontal support
// 2.0.0beta5 - (2010-10-18) jQuery 1.4.3 support, various bug fixes
// 2.0.0beta4 - (2010-09-17) clickOnTrack support, bug fixes
// 2.0.0beta3 - (2010-08-27) Horizontal mousewheel, mwheelIntent, keyboard suppo
rt, bug fixes
// 2.0.0beta2 - (2010-08-21) Bug fixes
// 2.0.0beta1 - (2010-08-17) Rewrite to follow modern best practices and enable
horizontal scrolling, initially hidden
//
elements and dynamicall
y sized elements.
// 1.x - (2006-12-31 - 2010-07-31) Initial version, hosted at googlecode, deprec
ated
(function ($, window, undefined) {
$.fn.jScrollPane = function (settings) {
// JScrollPane "class" - public methods are available through $('selecto
r').data('jsp')
function JScrollPane(elem, s) {
var settings, jsp = this, pane, paneWidth, paneHeight, container, co
ntentWidth, contentHeight,
percentInViewH, percentInViewV, isScrollableV, i
sScrollableH, verticalDrag, dragMaxY,
verticalDragPosition, horizontalDrag, dragMaxX,
horizontalDragPosition,
verticalBar, verticalTrack, scrollbarWidth, vert
icalTrackHeight, verticalDragHeight, arrowUp, arrowDown,
horizontalBar, horizontalTrack, horizontalTrackW
idth, horizontalDragWidth, arrowLeft, arrowRight,
reinitialiseInterval, originalPadding, originalP
addingTotalWidth, previousContentWidth,
wasAtTop = true, wasAtLeft = true, wasAtBottom =
false, wasAtRight = false,
originalElement = elem.clone(false, false).empty
(),

mwEvent = $.fn.mwheelIntent ? 'mwheelIntent.jsp'


: 'mousewheel.jsp';
originalPadding = elem.css('paddingTop') + ' ' +
elem.css('paddin
gRight') + ' ' +
elem.css('paddin
gBottom') + ' ' +
elem.css('paddin
gLeft');
originalPaddingTotalWidth = (parseInt(elem.css('paddingLeft'), 10) |
| 0) +
(parseInt(elem.css('paddingRight'), 10) || 0);
function initialise(s) {
var clonedElem, tempWrapper, /*firstChild, lastChild, */isMainta
iningPositon, lastContentX, lastContentY,
hasContainingSpaceChanged, origi
nalScrollTop, originalScrollLeft;
settings = s;
if (pane === undefined) {
originalScrollTop = elem.scrollTop();
originalScrollLeft = elem.scrollLeft();
elem.css(
{
overflow: 'hidden',
padding: 0
}
);
// TODO: Deal with where width/ height is 0 as it probably m
eans the element is hidden and we should
// come back to it later and check once it is unhidden...
paneWidth = elem.innerWidth() + originalPaddingTotalWidth;
paneHeight = elem.innerHeight();
elem.width(paneWidth);
pane = $('<div class="jspPane" />').css('padding', originalP
adding).append(elem.children());
container = $('<div class="jspContainer" />')
.css({
'width': paneWidth + 'px',
'height': paneHeight + 'px'
}
).append(pane).appendTo(elem);
/*
// Move any margins from the first and last children up to t
he container so they can still
// collapse with neighbouring elements as they would before
jScrollPane
firstChild = pane.find(':first-child');
lastChild = pane.find(':last-child');
elem.css(
{
'margin-top': firstChild.css('margin-top'),

'margin-bottom': lastChild.css('margin-bottom')
}
);
firstChild.css('margin-top', 0);
lastChild.css('margin-bottom', 0);
*/
} else {
elem.css('width', '');
hasContainingSpaceChanged = elem.innerWidth() + originalPadd
ingTotalWidth != paneWidth || elem.outerHeight() != paneHeight;
if (hasContainingSpaceChanged) {
paneWidth = elem.innerWidth() + originalPaddingTotalWidt
h;
paneHeight = elem.innerHeight();
container.css({
width: paneWidth + 'px',
height: paneHeight + 'px'
});
}
// If nothing changed since last check...
if (!hasContainingSpaceChanged && previousContentWidth == co
ntentWidth && pane.outerHeight() == contentHeight) {
elem.width(paneWidth);
return;
}
previousContentWidth = contentWidth;
pane.css('width', '');
elem.width(paneWidth);
container.find('>.jspVerticalBar,>.jspHorizontalBar').remove
().end();
}
// Unfortunately it isn't that easy to find out the width of the
element as it will always report the
// width as allowed by its container, regardless of overflow set
tings.
// A cunning workaround is to clone the element, set its positio
n to absolute and place it in a narrow
// container. Now it will push outwards to its maxium real width
...
clonedElem = pane.clone(false, false).css('position', 'absolute'
);
tempWrapper = $('<div style="width:1px; position: relative;" />'
).append(clonedElem);
$('body').append(tempWrapper);
contentWidth = Math.max(pane.outerWidth(), clonedElem.outerWidth
());
tempWrapper.remove();
contentHeight = pane.outerHeight();
percentInViewH = contentWidth / paneWidth;
percentInViewV = contentHeight / paneHeight;
isScrollableV = percentInViewV > 1;
isScrollableH = percentInViewH > 1;

//console.log(paneWidth, paneHeight, contentWidth, contentHeight


, percentInViewH, percentInViewV, isScrollableH, isScrollableV);
if (!(isScrollableH || isScrollableV)) {
elem.removeClass('jspScrollable');
pane.css({
top: 0,
width: container.width() - originalPaddingTotalWidth
});
removeMousewheel();
removeFocusHandler();
removeKeyboardNav();
removeClickOnTrack();
unhijackInternalLinks();
} else {
elem.addClass('jspScrollable');
isMaintainingPositon = settings.maintainPosition && (vertica
lDragPosition || horizontalDragPosition);
if (isMaintainingPositon) {
lastContentX = contentPositionX();
lastContentY = contentPositionY();
}
initialiseVerticalScroll();
initialiseHorizontalScroll();
resizeScrollbars();
if (isMaintainingPositon) {
scrollToX(lastContentX, false);
scrollToY(lastContentY, false);
}
initFocusHandler();
initMousewheel();
initTouch();
if (settings.enableKeyboardNavigation) {
initKeyboardNav();
}
if (settings.clickOnTrack) {
initClickOnTrack();
}
observeHash();
if (settings.hijackInternalLinks) {
hijackInternalLinks();
}
}
if (settings.autoReinitialise && !reinitialiseInterval) {
reinitialiseInterval = setInterval(
function () {
initialise(settings);
},
settings.autoReinitialiseDelay
);
} else if (!settings.autoReinitialise && reinitialiseInterval) {
clearInterval(reinitialiseInterval);

}
originalScrollTop && elem.scrollTop(0) && scrollToY(originalScro
llTop, false);
originalScrollLeft && elem.scrollLeft(0) && scrollToX(originalSc
rollLeft, false);
elem.trigger('jsp-initialised', [isScrollableH || isScrollableV]
);
}
function initialiseVerticalScroll() {
if (isScrollableV) {
container.append(
$('<div class="jspVerticalBar" /
>').append(
$('<div class="jspCap js
pCapTop" />'),
$('<div class="jspTrack"
/>').append(
$('<div class="j
spDrag" />').append(
$('<div
class="jspDragTop" />'),
$('<div
class="jspDragBottom" />')
)
),
$('<div class="jspCap js
pCapBottom" />')
)
);
verticalBar = container.find('>.jspVerticalBar');
verticalTrack = verticalBar.find('>.jspTrack');
verticalDrag = verticalTrack.find('>.jspDrag');
if (settings.showArrows) {
arrowUp = $('<a class="jspArrow jspArrowUp" />').bind(
'mousedown.jsp', getArro
wScroll(0, -1)
).bind('click.jsp', nil);
arrowDown = $('<a class="jspArrow jspArrowDown" />').bin
d(
'mousedown.jsp', getArro
wScroll(0, 1)
).bind('click.jsp', nil);
if (settings.arrowScrollOnHover) {
arrowUp.bind('mouseover.jsp', getArrowScroll(0, -1,
arrowUp));
arrowDown.bind('mouseover.jsp', getArrowScroll(0, 1,
arrowDown));
}
appendArrows(verticalTrack, settings.verticalArrowPositi
ons, arrowUp, arrowDown);
}
verticalTrackHeight = paneHeight;

container.find('>.jspVerticalBar>.jspCap:visible,>.jspVertic
alBar>.jspArrow').each(
function () {
verticalTrackHeight -= $(thi
s).outerHeight();
}
);
verticalDrag.hover(
function () {
verticalDrag.addClass('jspHo
ver');
},
function () {
verticalDrag.removeClass('js
pHover');
}
).bind(
'mousedown.jsp',
function (e) {
// Stop IE from allowing tex
t selection
$('html').bind('dragstart.js
p selectstart.jsp', nil);
verticalDrag.addClass('jspAc
tive');
var startY = e.pageY - verti
calDrag.position().top;
$('html').bind(
'mousemove.jsp',
function (e) {
positionDrag
Y(e.pageY - startY, false);
}
).bind('mouseup.jsp mous
eleave.jsp', cancelDrag);
return false;
}
);
sizeVerticalScrollbar();
}
}
function sizeVerticalScrollbar() {
verticalTrack.height(verticalTrackHeight + 'px');
verticalDragPosition = 0;
scrollbarWidth = settings.verticalGutter + verticalTrack.outerWi
dth();
// Make the pane thinner to allow for the vertical scrollbar
pane.width(paneWidth - scrollbarWidth - originalPaddingTotalWidt
h);
// Add margin to the left of the pane if scrollbars are on that
side (to position
// the scrollbar on the left or right set it's left or right pro

perty in CSS)
if (verticalBar.position().left === 0) {
pane.css('margin-left', scrollbarWidth + 'px');
}
}
function initialiseHorizontalScroll() {
if (isScrollableH) {
container.append(
$('<div class="jspHorizontalBar"
/>').append(
$('<div class="jspCap js
pCapLeft" />'),
$('<div class="jspTrack"
/>').append(
$('<div class="j
spDrag" />').append(
$('<div
class="jspDragLeft" />'),
$('<div
class="jspDragRight" />')
)
),
$('<div class="jspCap js
pCapRight" />')
)
);
horizontalBar = container.find('>.jspHorizontalBar');
horizontalTrack = horizontalBar.find('>.jspTrack');
horizontalDrag = horizontalTrack.find('>.jspDrag');
if (settings.showArrows) {
arrowLeft = $('<a class="jspArrow jspArrowLeft" />').bin
d(
'mousedown.jsp', getArro
wScroll(-1, 0)
).bind('click.jsp', nil);
arrowRight = $('<a class="jspArrow jspArrowRight" />').b
ind(
'mousedown.jsp', getArro
wScroll(1, 0)
).bind('click.jsp', nil);
if (settings.arrowScrollOnHover) {
arrowLeft.bind('mouseover.jsp', getArrowScroll(-1, 0
, arrowLeft));
arrowRight.bind('mouseover.jsp', getArrowScroll(1, 0
, arrowRight));
}
appendArrows(horizontalTrack, settings.horizontalArrowPo
sitions, arrowLeft, arrowRight);
}
horizontalDrag.hover(
function () {
horizontalDrag.addClass('jsp
Hover');
},
function () {

horizontalDrag.removeClass('
jspHover');
}
).bind(
'mousedown.jsp',
function (e) {
// Stop IE from allowing tex
t selection
$('html').bind('dragstart.js
p selectstart.jsp', nil);
horizontalDrag.addClass('jsp
Active');
var startX = e.pageX - horiz
ontalDrag.position().left;
$('html').bind(
'mousemove.jsp',
function (e) {
positionDrag
X(e.pageX - startX, false);
}
).bind('mouseup.jsp mous
eleave.jsp', cancelDrag);
return false;
}
);
horizontalTrackWidth = container.innerWidth();
sizeHorizontalScrollbar();
}
}
function sizeHorizontalScrollbar() {
container.find('>.jspHorizontalBar>.jspCap:visible,>.jspHorizont
alBar>.jspArrow').each(
function () {
horizontalTrackWidth -= $(this).oute
rWidth();
}
);
horizontalTrack.width(horizontalTrackWidth + 'px');
horizontalDragPosition = 0;
}
function resizeScrollbars() {
if (isScrollableH && isScrollableV) {
var horizontalTrackHeight = horizontalTrack.outerHeight(),
verticalTrackWidth = verticalTra
ck.outerWidth();
verticalTrackHeight -= horizontalTrackHeight;
$(horizontalBar).find('>.jspCap:visible,>.jspArrow').each(
function () {
horizontalTrackWidth += $(th
is).outerWidth();
}
);
horizontalTrackWidth -= verticalTrackWidth;
paneHeight -= verticalTrackWidth;

paneWidth -= horizontalTrackHeight;
horizontalTrack.parent().append(
$('<div class="jspCorner" />').c
ss('width', horizontalTrackHeight + 'px')
);
sizeVerticalScrollbar();
sizeHorizontalScrollbar();
}
// reflow content
if (isScrollableH) {
pane.width((container.outerWidth() - originalPaddingTotalWid
th) + 'px');
}
contentHeight = pane.outerHeight();
percentInViewV = contentHeight / paneHeight;
if (isScrollableH) {
horizontalDragWidth = Math.ceil(1 / percentInViewH * horizon
talTrackWidth);
if (horizontalDragWidth > settings.horizontalDragMaxWidth) {
horizontalDragWidth = settings.horizontalDragMaxWidth;
} else if (horizontalDragWidth < settings.horizontalDragMinW
idth) {
horizontalDragWidth = settings.horizontalDragMinWidth;
}
horizontalDrag.width(horizontalDragWidth + 'px');
dragMaxX = horizontalTrackWidth - horizontalDragWidth;
_positionDragX(horizontalDragPosition); // To update the sta
te for the arrow buttons
}
if (isScrollableV) {
verticalDragHeight = Math.ceil(1 / percentInViewV * vertical
TrackHeight);
if (verticalDragHeight > settings.verticalDragMaxHeight) {
verticalDragHeight = settings.verticalDragMaxHeight;
} else if (verticalDragHeight < settings.verticalDragMinHeig
ht) {
verticalDragHeight = settings.verticalDragMinHeight;
}
verticalDrag.height(verticalDragHeight + 'px');
dragMaxY = verticalTrackHeight - verticalDragHeight;
_positionDragY(verticalDragPosition); // To update the state
for the arrow buttons
}
}
function appendArrows(ele, p, a1, a2) {
var p1 = "before", p2 = "after", aTemp;
// Sniff for mac... Is there a better way to determine whether t
he arrows would naturally appear
// at the top or the bottom of the bar?
if (p == "os") {
p = /Mac/.test(navigator.platform) ? "after" : "split";
}
if (p == p1) {
p2 = p;
} else if (p == p2) {
p1 = p;
aTemp = a1;

a1 = a2;
a2 = aTemp;
}
ele[p1](a1)[p2](a2);
}
function getArrowScroll(dirX, dirY, ele) {
return function () {
arrowScroll(dirX, dirY, this, ele);
this.blur();
return false;
};
}
function arrowScroll(dirX, dirY, arrow, ele) {
arrow = $(arrow).addClass('jspActive');
var eve,
scrollTimeout,
isFirst = true,
doScroll = function () {
if (dirX !== 0) {
jsp.scrollByX(dirX * settings.ar
rowButtonSpeed);
}
if (dirY !== 0) {
jsp.scrollByY(dirY * settings.ar
rowButtonSpeed);
}
scrollTimeout = setTimeout(doScroll,
isFirst ? settings.initialDelay : settings.arrowRepeatFreq);
isFirst = false;
};
doScroll();
eve = ele ? 'mouseout.jsp' : 'mouseup.jsp';
ele = ele || $('html');
ele.bind(
eve,
function () {
arrow.removeClass('jspActive');
scrollTimeout && clearTimeout(scroll
Timeout);
scrollTimeout = null;
ele.unbind(eve);
}
);
}
function initClickOnTrack() {
removeClickOnTrack();
if (isScrollableV) {
verticalTrack.bind(
'mousedown.jsp',
function (e) {
if (e.originalTarget === und
efined || e.originalTarget == e.currentTarget) {
var clickedTrack = $(thi

s),
offset =
clickedTrack.offset(),
directio
n = e.pageY - offset.top - verticalDragPosition,
scrollTi
meout,
isFirst
= true,
doScroll
= function () {
var
offset = clickedTrack.offset(),
pos = e.pageY - offset.top - verticalDragHeight / 2,
contentDragY = paneHeight * settings.scrollPagePercent,
dragY = dragMaxY * contentDragY / (contentHeight - paneHeight);
if (
direction < 0) {
if (verticalDragPosition - dragY > pos) {
jsp.scrollByY(-contentDragY);
} else {
positionDragY(pos);
}
} el
se if (direction > 0) {
if (verticalDragPosition + dragY < pos) {
jsp.scrollByY(contentDragY);
} else {
positionDragY(pos);
}
} el
se {
cancelClick();
return;
}
scro
llTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trac
kClickRepeatFreq);
isFi
rst = false;
},
cancelCl
ick = function () {
scro
llTimeout && clearTimeout(scrollTimeout);

scro
llTimeout = null;
$(do
cument).unbind('mouseup.jsp', cancelClick);
};
doScroll();
$(document).bind('mouseu
p.jsp', cancelClick);
return false;
}
}
);
}
if (isScrollableH) {
horizontalTrack.bind(
'mousedown.jsp',
function (e) {
if (e.originalTarget === und
efined || e.originalTarget == e.currentTarget) {
var clickedTrack = $(thi
s),
offset =
clickedTrack.offset(),
directio
n = e.pageX - offset.left - horizontalDragPosition,
scrollTi
meout,
isFirst
= true,
doScroll
= function () {
var
offset = clickedTrack.offset(),
pos = e.pageX - offset.left - horizontalDragWidth / 2,
contentDragX = paneWidth * settings.scrollPagePercent,
dragX = dragMaxX * contentDragX / (contentWidth - paneWidth);
if (
direction < 0) {
if (horizontalDragPosition - dragX > pos) {
jsp.scrollByX(-contentDragX);
} else {
positionDragX(pos);
}
} el
se if (direction > 0) {
if (horizontalDragPosition + dragX < pos) {
jsp.scrollByX(contentDragX);
} else {

positionDragX(pos);
}
} el
se {
cancelClick();
return;
}
scro
llTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trac
kClickRepeatFreq);
isFi
rst = false;
},
cancelCl
ick = function () {
scro
llTimeout && clearTimeout(scrollTimeout);
scro
llTimeout = null;
$(do
cument).unbind('mouseup.jsp', cancelClick);
};
doScroll();
$(document).bind('mouseu
p.jsp', cancelClick);
return false;
}
}
);
}
}
function removeClickOnTrack() {
if (horizontalTrack) {
horizontalTrack.unbind('mousedown.jsp');
}
if (verticalTrack) {
verticalTrack.unbind('mousedown.jsp');
}
}
function cancelDrag() {
$('html').unbind('dragstart.jsp selectstart.jsp mousemove.jsp mo
useup.jsp mouseleave.jsp');
if (verticalDrag) {
verticalDrag.removeClass('jspActive');
}
if (horizontalDrag) {
horizontalDrag.removeClass('jspActive');
}
}
function positionDragY(destY, animate) {
if (!isScrollableV) {
return;

}
if (destY
destY
} else if
destY
}

< 0) {
= 0;
(destY > dragMaxY) {
= dragMaxY;

// can't just check if(animate) because false is a valid value t


hat could be passed in...
if (animate === undefined) {
animate = settings.animateScroll;
}
if (animate) {
jsp.animate(verticalDrag, 'top', destY, _positionDragY);
} else {
verticalDrag.css('top', destY);
_positionDragY(destY);
}
}
function _positionDragY(destY) {
if (destY === undefined) {
destY = verticalDrag.position().top;
}
container.scrollTop(0);
verticalDragPosition = destY;
var isAtTop = verticalDragPosition === 0,
isAtBottom = verticalDragPosition == dra
gMaxY,
percentScrolled = destY / dragMaxY,
destTop = -percentScrolled * (contentHei
ght - paneHeight);
if (wasAtTop != isAtTop || wasAtBottom != isAtBottom) {
wasAtTop = isAtTop;
wasAtBottom = isAtBottom;
elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, was
AtLeft, wasAtRight]);
}
updateVerticalArrows(isAtTop, isAtBottom);
pane.css('top', destTop);
elem.trigger('jsp-scroll-y', [-destTop, isAtTop, isAtBottom]).tr
igger('scroll');
}
function positionDragX(destX, animate) {
if (!isScrollableH) {
return;
}
if (destX < 0) {
destX = 0;
} else if (destX > dragMaxX) {
destX = dragMaxX;
}
if (animate === undefined) {

animate = settings.animateScroll;
}
if (animate) {
jsp.animate(horizontalDrag, 'left', destX, _positionDragX);
} else {
horizontalDrag.css('left', destX);
_positionDragX(destX);
}
}
function _positionDragX(destX) {
if (destX === undefined) {
destX = horizontalDrag.position().left;
}
container.scrollTop(0);
horizontalDragPosition = destX;
var isAtLeft = horizontalDragPosition === 0,
isAtRight = horizontalDragPosition == dr
agMaxX,
percentScrolled = destX / dragMaxX,
destLeft = -percentScrolled * (contentWi
dth - paneWidth);
if (wasAtLeft != isAtLeft || wasAtRight != isAtRight) {
wasAtLeft = isAtLeft;
wasAtRight = isAtRight;
elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, was
AtLeft, wasAtRight]);
}
updateHorizontalArrows(isAtLeft, isAtRight);
pane.css('left', destLeft);
elem.trigger('jsp-scroll-x', [-destLeft, isAtLeft, isAtRight]).t
rigger('scroll');
}
function updateVerticalArrows(isAtTop, isAtBottom) {
if (settings.showArrows) {
arrowUp[isAtTop ? 'addClass' : 'removeClass']('jspDisabled')
;
arrowDown[isAtBottom ? 'addClass' : 'removeClass']('jspDisab
led');
}
}
function updateHorizontalArrows(isAtLeft, isAtRight) {
if (settings.showArrows) {
arrowLeft[isAtLeft ? 'addClass' : 'removeClass']('jspDisable
d');
arrowRight[isAtRight ? 'addClass' : 'removeClass']('jspDisab
led');
}
}
function scrollToY(destY, animate) {
var percentScrolled = destY / (contentHeight - paneHeight);
positionDragY(percentScrolled * dragMaxY, animate);
}

function scrollToX(destX, animate) {


var percentScrolled = destX / (contentWidth - paneWidth);
positionDragX(percentScrolled * dragMaxX, animate);
}
function scrollToElement(ele, stickToTop, animate) {
var e, eleHeight, eleWidth, eleTop = 0, eleLeft = 0, viewportTop
, maxVisibleEleTop, maxVisibleEleLeft, destY, destX;
// Legal hash values aren't necessarily legal jQuery selectors s
o we need to catch any
// errors from the lookup...
try {
e = $(ele);
} catch (err) {
return;
}
eleHeight = e.outerHeight();
eleWidth = e.outerWidth();
container.scrollTop(0);
container.scrollLeft(0);
// loop through parents adding the offset top of any elements th
at are relatively positioned between
// the focused element and the jspPane so we can get the true di
stance from the top
// of the focused element to the top of the scrollpane...
while (!e.is('.jspPane')) {
eleTop += e.position().top;
eleLeft += e.position().left;
e = e.offsetParent();
if (/^body|html$/i.test(e[0].nodeName)) {
// we ended up too high in the document structure. Quit!
return;
}
}
viewportTop = contentPositionY();
maxVisibleEleTop = viewportTop + paneHeight;
if (eleTop < viewportTop || stickToTop) { // element is above vi
ewport
destY = eleTop - settings.verticalGutter;
} else if (eleTop + eleHeight > maxVisibleEleTop) { // element i
s below viewport
destY = eleTop - paneHeight + eleHeight + settings.verticalG
utter;
}
if (destY) {
scrollToY(destY, animate);
}
viewportLeft = contentPositionX();
maxVisibleEleLeft = viewportLeft + paneWidth;
if (eleLeft < viewportLeft || stickToTop) { // element is to the
left of viewport
destX = eleLeft - settings.horizontalGutter;
} else if (eleLeft + eleWidth > maxVisibleEleLeft) { // element
is to the right viewport

destX = eleLeft - paneWidth + eleWidth + settings.horizontal


Gutter;
}
if (destX) {
scrollToX(destX, animate);
}
}
function contentPositionX() {
return -pane.position().left;
}
function contentPositionY() {
return -pane.position().top;
}
function initMousewheel() {
container.unbind(mwEvent).bind(
mwEvent,
function (event, delta, deltaX, deltaY)
{
var dX = horizontalDragPosition, dY
= verticalDragPosition;
jsp.scrollBy(deltaX * settings.mouse
WheelSpeed, -deltaY * settings.mouseWheelSpeed, false);
// return true if there was no movem
ent so rest of screen can scroll
return dX == horizontalDragPosition
&& dY == verticalDragPosition;
}
);
}
function removeMousewheel() {
container.unbind(mwEvent);
}
function nil() {
return false;
}
function initFocusHandler() {
pane.find(':input,a').unbind('focus.jsp').bind(
'focus.jsp',
function (e) {
scrollToElement(e.target, false);
}
);
}
function removeFocusHandler() {
pane.find(':input,a').unbind('focus.jsp');
}
function initKeyboardNav() {
var keyDown, elementHasScrolled;
// IE also focuses elements that don't have tabindex set.
pane.focus(
function () {

elem.focus();
}
);
elem.attr('tabindex', 0)
.unbind('keydown.jsp keypress.jsp')
.bind(
'keydown.jsp',
function (e) {
if (e.target !== this) {
return;
}
var dX = horizontalDragPosit
ion, dY = verticalDragPosition;
switch (e.keyCode) {
case 40: // down
case 38: // up
case 34: // page down
case 32: // space
case 33: // page up
case 39: // right
case 37: // left
keyDown = e.keyCode;
keyDownHandler();
break;
case 35: // end
scrollToY(contentHei
ght - paneHeight);
keyDown = null;
break;
case 36: // home
scrollToY(0);
keyDown = null;
break;
}
elementHasScrolled = e.keyCo
de == keyDown && dX != horizontalDragPosition || dY != verticalDragPosition;
return !elementHasScrolled;
}
).bind(
'keypress.jsp', // For FF/ OSX s
o that we can cancel the repeat key presses if the JSP scrolls...
function (e) {
if (e.keyCode == keyDown) {
keyDownHandler();
}
return !elementHasScrolled;
}
);
if (settings.hideFocus) {
elem.css('outline', 'none');
if ('hideFocus' in container[0]) {
elem.attr('hideFocus', true);
}
} else {
elem.css('outline', '');
if ('hideFocus' in container[0]) {
elem.attr('hideFocus', false);

}
}
function keyDownHandler() {
var dX = horizontalDragPosition, dY = verticalDragPosition;
switch (keyDown) {
case 40: // down
jsp.scrollByY(settings.keyboardSpeed, false);
break;
case 38: // up
jsp.scrollByY(-settings.keyboardSpeed, false);
break;
case 34: // page down
case 32: // space
jsp.scrollByY(paneHeight * settings.scrollPagePercen
t, false);
break;
case 33: // page up
jsp.scrollByY(-paneHeight * settings.scrollPagePerce
nt, false);
break;
case 39: // right
jsp.scrollByX(settings.keyboardSpeed, false);
break;
case 37: // left
jsp.scrollByX(-settings.keyboardSpeed, false);
break;
}
elementHasScrolled = dX != horizontalDragPosition || dY != v
erticalDragPosition;
return elementHasScrolled;
}
}
function removeKeyboardNav() {
elem.attr('tabindex', '-1')
.removeAttr('tabindex')
.unbind('keydown.jsp keypress.jsp');
}
function observeHash() {
if (location.hash && location.hash.length > 1) {
var e, retryInt;
try {
e = $(location.hash);
} catch (err) {
return;
}
if (e.length && pane.find(location.hash)) {
// nasty workaround but it appears to take a little whil
e before the hash has done its thing
// to the rendered page so we just wait until the contai
ner's scrollTop has been messed up.
if (container.scrollTop() === 0) {
retryInt = setInterval(
function () {
if (containe
r.scrollTop() > 0) {

scrollTo
Element(location.hash, true);
$(docume
nt).scrollTop(container.position().top);
clearInt
erval(retryInt);
}
},
50
);
} else {
scrollToElement(location.hash, true);
$(document).scrollTop(container.position().top);
}
}
}
}
function unhijackInternalLinks() {
$('a.jspHijack').unbind('click.jsp-hijack').removeClass('jspHija
ck');
}
function hijackInternalLinks() {
unhijackInternalLinks();
$('a[href^=#]').addClass('jspHijack').bind(
'click.jsp-hijack',
function () {
var uriParts = this.href.split('#'),
hash;
if (uriParts.length > 1) {
hash = uriParts[1];
if (hash.length > 0 && pane.find
('#' + hash).length > 0) {
scrollToElement('#' + hash,
true);
// Need to return false othe
rwise things mess up... Would be nice to maybe also scroll
// the window to the top of
the scrollpane?
return false;
}
}
}
);
}
// Init touch on iPad, iPhone, iPod, Android
function initTouch() {
var startX,
startY,
touchStartX,
touchStartY,
moved,
moving = false;
container.unbind('touchstart.jsp touchmove.jsp touchend.jsp clic
k.jsp-touchclick').bind(
'touchstart.jsp',
function (e) {

var touch = e.originalEvent.touches[


0];
startX = contentPositionX();
startY = contentPositionY();
touchStartX = touch.pageX;
touchStartY = touch.pageY;
moved = false;
moving = true;
}
).bind(
'touchmove.jsp',
function (ev) {
if (!moving) {
return;
}
var touchPos = ev.originalEvent.touc
hes[0],
dX = horizontalDragPosit
ion, dY = verticalDragPosition;
jsp.scrollTo(startX + touchStartX touchPos.pageX, startY + touchStartY - touchPos.pageY);
moved = moved || Math.abs(touchStart
X - touchPos.pageX) > 5 || Math.abs(touchStartY - touchPos.pageY) > 5;
// return true if there was no movem
ent so rest of screen can scroll
return dX == horizontalDragPosition
&& dY == verticalDragPosition;
}
).bind(
'touchend.jsp',
function (e) {
moving = false;
/*if(moved) {
return false;
}*/
}
).bind(
'click.jsp-touchclick',
function (e) {
if (moved) {
moved = false;
return false;
}
}
);
}
function destroy() {
var currentY = contentPositionY(),
currentX = contentPositionX();
elem.removeClass('jspScrollable').unbind('.jsp');
elem.replaceWith(originalElement.append(pane.children()));
originalElement.scrollTop(currentY);
originalElement.scrollLeft(currentX);
}

// Public API
$.extend(
jsp,
{
// Reinitialises the scroll pane (if it's in
ternal dimensions have changed since the last time it
// was initialised). The settings object whi
ch is passed in will override any settings from the
// previous time it was initialised - if you
don't pass any settings then the ones from the previous
// initialisation will be used.
reinitialise: function (s) {
s = $.extend({}, settings, s);
initialise(s);
},
// Scrolls the specified element (a jQuery o
bject, DOM node or jQuery selector string) into view so
// that it can be seen within the viewport.
If stickToTop is true then the element will appear at
// the top of the viewport, if it is false t
hen the viewport will scroll as little as possible to
// show the element. You can also specify if
you want animation to occur. If you don't provide this
// argument then the animateScroll value fro
m the settings object is used instead.
scrollToElement: function (ele, stickToTop,
animate) {
scrollToElement(ele, stickToTop, animate
);
},
// Scrolls the pane so that the specified co
-ordinates within the content are at the top left
// of the viewport. animate is optional and
if not passed then the value of animateScroll from
// the settings object this jScrollPane was
initialised with is used.
scrollTo: function (destX, destY, animate) {
scrollToX(destX, animate);
scrollToY(destY, animate);
},
// Scrolls the pane so that the specified co
-ordinate within the content is at the left of the
// viewport. animate is optional and if not
passed then the value of animateScroll from the settings
// object this jScrollPane was initialised w
ith is used.
scrollToX: function (destX, animate) {
scrollToX(destX, animate);
},
// Scrolls the pane so that the specified co
-ordinate within the content is at the top of the
// viewport. animate is optional and if not
passed then the value of animateScroll from the settings
// object this jScrollPane was initialised w
ith is used.
scrollToY: function (destY, animate) {
scrollToY(destY, animate);
},
// Scrolls the pane to the specified percent
age of its maximum horizontal scroll position. animate

// is optional and if not passed then the va


lue of animateScroll from the settings object this
// jScrollPane was initialised with is used.
scrollToPercentX: function (destPercentX, an
imate) {
scrollToX(destPercentX * (contentWidth paneWidth), animate);
},
// Scrolls the pane to the specified percent
age of its maximum vertical scroll position. animate
// is optional and if not passed then the va
lue of animateScroll from the settings object this
// jScrollPane was initialised with is used.
scrollToPercentY: function (destPercentY, an
imate) {
scrollToY(destPercentY * (contentHeight
- paneHeight), animate);
},
// Scrolls the pane by the specified amount
of pixels. animate is optional and if not passed then
// the value of animateScroll from the setti
ngs object this jScrollPane was initialised with is used.
scrollBy: function (deltaX, deltaY, animate)
{
jsp.scrollByX(deltaX, animate);
jsp.scrollByY(deltaY, animate);
},
// Scrolls the pane by the specified amount
of pixels. animate is optional and if not passed then
// the value of animateScroll from the setti
ngs object this jScrollPane was initialised with is used.
scrollByX: function (deltaX, animate) {
var destX = contentPositionX() + deltaX,
percentScrolled = destX
/ (contentWidth - paneWidth);
positionDragX(percentScrolled * dragMaxX
, animate);
},
// Scrolls the pane by the specified amount
of pixels. animate is optional and if not passed then
// the value of animateScroll from the setti
ngs object this jScrollPane was initialised with is used.
scrollByY: function (deltaY, animate) {
var destY = contentPositionY() + deltaY,
percentScrolled = destY
/ (contentHeight - paneHeight);
positionDragY(percentScrolled * dragMaxY
, animate);
},
// Positions the horizontal drag at the spec
ified x position (and updates the viewport to reflect
// this). animate is optional and if not pas
sed then the value of animateScroll from the settings
// object this jScrollPane was initialised w
ith is used.
positionDragX: function (x, animate) {
positionDragX(x, animate);
},
// Positions the vertical drag at the specif
ied y position (and updates the viewport to reflect

// this). animate is optional and if not pas


sed then the value of animateScroll from the settings
// object this jScrollPane was initialised w
ith is used.
positionDragY: function (y, animate) {
positionDragX(y, animate);
},
// This method is called when jScrollPane is
trying to animate to a new position. You can override
// it if you want to provide advanced animat
ion functionality. It is passed the following arguments:
// * ele
- the element whose posit
ion is being animated
// * prop
- the property that is be
ing animated
// * value
- the value it's being an
imated to
// * stepCallback - a function that you mus
t execute each time you update the value of the property
// You can use the default implementation (b
elow) as a starting point for your own implementation.
animate: function (ele, prop, value, stepCal
lback) {
var params = {};
params[prop] = value;
ele.animate(
params,
{
'duration': settings
.animateDuration,
'ease': settings.ani
mateEase,
'queue': false,
'step': stepCallback
}
);
},
// Returns the current x position of the vie
wport with regards to the content pane.
getContentPositionX: function () {
return contentPositionX();
},
// Returns the current y position of the vie
wport with regards to the content pane.
getContentPositionY: function () {
return contentPositionY();
},
// Returns the width of the content within t
he scroll pane.
getContentWidth: function () {
return contentWidth();
},
// Returns the height of the content within
the scroll pane.
getContentHeight: function () {
return contentHeight();
},
// Returns the horizontal position of the vi
ewport within the pane content.
getPercentScrolledX: function () {

return contentPositionX() / (contentWidt


h - paneWidth);
},
// Returns the vertical position of the view
port within the pane content.
getPercentScrolledY: function () {
return contentPositionY() / (contentHeig
ht - paneHeight);
},
// Returns whether or not this scrollpane ha
s a horizontal scrollbar.
getIsScrollableH: function () {
return isScrollableH;
},
// Returns whether or not this scrollpane ha
s a vertical scrollbar.
getIsScrollableV: function () {
return isScrollableV;
},
// Gets a reference to the content pane. It
is important that you use this method if you want to
// edit the content of your jScrollPane as i
f you access the element directly then you may have some
// problems (as your original element has ha
d additional elements for the scrollbars etc added into
// it).
getContentPane: function () {
return pane;
},
// Scrolls this jScrollPane down as far as i
t can currently scroll. If animate isn't passed then the
// animateScroll value from settings is used
instead.
scrollToBottom: function (animate) {
positionDragY(dragMaxY, animate);
},
// Hijacks the links on the page which link
to content inside the scrollpane. If you have changed
// the content of your page (e.g. via AJAX)
and want to make sure any new anchor links to the
// contents of your scroll pane will work th
en call this function.
hijackInternalLinks: function () {
hijackInternalLinks();
},
// Removes the jScrollPane and returns the p
age to the state it was in before jScrollPane was
// initialised.
destroy: function () {
destroy();
}
}
);
initialise(s);
}
// Pluginifying code...
settings = $.extend({}, $.fn.jScrollPane.defaults, settings);

// Apply default speed


$.each(['mouseWheelSpeed', 'arrowButtonSpeed', 'trackClickSpeed', 'keybo
ardSpeed'], function () {
settings[this] = settings[this] || settings.speed;
});
var ret;
this.each(
function () {
var elem = $(this), jspApi = elem.data('jsp');
if (jspApi) {
jspApi.reinitialise(settings);
} else {
jspApi = new JScrollPane(elem, settings);
elem.data('jsp', jspApi);
}
ret = ret ? ret.add(elem) : elem;
}
);
return ret;
};
$.fn.jScrollPane.defaults = {
showArrows: false,
maintainPosition: true,
clickOnTrack: true,
autoReinitialise: false,
autoReinitialiseDelay: 500,
verticalDragMinHeight: 0,
verticalDragMaxHeight: 99999,
horizontalDragMinWidth: 0,
horizontalDragMaxWidth: 99999,
animateScroll: false,
animateDuration: 300,
animateEase: 'linear',
hijackInternalLinks: false,
verticalGutter: 4,
horizontalGutter: 4,
mouseWheelSpeed: 0,
arrowButtonSpeed: 0,
arrowRepeatFreq: 50,
arrowScrollOnHover: false,
trackClickSpeed: 0,
trackClickRepeatFreq: 70,
verticalArrowPositions: 'split',
horizontalArrowPositions: 'split',
enableKeyboardNavigation: true,
hideFocus: false,
keyboardSpeed: 0,
initialDelay: 300,
// Delay before starting repeating
speed: 30,
// Default speed when others falsey
scrollPagePercent: .8
// Percent of visible area scrolled when
pageUp/Down or track area pressed
};
})(jQuery, this);
/*
* jQuery Ultimate Carousel 2.0

* Creates a carousel from a set of elements, allowing for pagers.


*
* Based on:
* jQuery Infinite Carousel Plugin (http://code.google.com/p/jquery-infinite-caro
usel)
*/
; (function ($) {
$.fn.carousel = function (options) {
// iterate through each item
this.each(function (i) {
// create instance
var inst = $(this);
// create carousel data object if not set
if (inst.data('carousel') == null) {
inst.data('carousel', {
options: $.fn.carousel.options,
initialized: false,
animating: false
});
}
// create carousel data object minipulation
var carousel = inst.data('carousel');
// merge options for carousel object with that of the supplied optio
ns
carousel.options = $.extend(true, carousel.options, (typeof options
== 'undefined') ? {} : options);
// set easing mode to default if easing mode is not available
carousel.options.easing = $.isFunction($.easing[carousel.options.eas
ing]) ? carousel.options.easing : $.fn.carousel.options.easing;
// initialize carousel for instance
$.fn.carousel.init(inst);
});
return this;
}
// initilize carousel, making any nescessary calculations and adding nescess
ary markup
$.fn.carousel.init = function (inst) {
// ensure inst is a jQuery object
var inst = $(inst);
// get carousel object for instance
var carousel = inst.data('carousel');
var options = carousel.options;
// set the carousel's width and height
carousel.width = (typeof carousel.width == 'number' && carousel.width >
0) ? carousel.width : parseInt(inst.width());
// continue only if carousel's width is greater than 0
if (carousel.width > 0 && !carousel.initialized) {
// get all slides within instance
var slides = inst.children();

// set references for slides


carousel.slides = {
current: 1,
count: slides.length,
width: 0,
height: 0,
outerWidth: 0,
outerHeight: 0,
shown: 1,
template: slides.first().clone().addClass('empty').empty()
};
// iterate through each slide
slides.each(function (i) {
// get the dimensions of the current slide
var width = parseInt($(this).width());
var height = parseInt($(this).height());
var outerWidth = parseInt($(this).outerWidth(true));
var outerHeight = parseInt($(this).outerHeight(true));
// increase the width/height values of slides if the current sli
de's is greater
carousel.slides.width = (width > carousel.slides.width) ? width
: carousel.slides.width;
carousel.slides.height = (height > carousel.slides.height) ? hei
ght : carousel.slides.height;
// increase the outerWidth/outerHeight values of slides if the c
urrent slide's is greater
carousel.slides.outerWidth = (outerWidth > carousel.slides.outer
Width) ? outerWidth : carousel.slides.outerWidth;
carousel.slides.outerHeight = (outerHeight > carousel.slides.out
erHeight) ? outerHeight : carousel.slides.outerHeight;
});
// if more than one slide may be shown, determine slides shown based
on width of carousel and outerWidth of slides
if (inst.width() > carousel.slides.outerWidth) {
carousel.slides.shown = Math.floor(inst.width() / carousel.slide
s.outerWidth);
}
// set the height of the instance
inst.height(carousel.slides.outerHeight);
// set the width of the instance
inst.width(carousel.width);
// continue if the number of slides is greater than the number of sl
ides shown
if (carousel.slides.count > carousel.slides.shown) {
// add the viewport division if it does not exist and set it's w
idth explicitly
if (inst.parent('div.carousel-viewport').length <= 0) {
inst.wrap('<div class="carousel-viewport"></div>').parent('.
carousel-viewport').width((carousel.slides.outerWidth * carousel.slides.shown) (carousel.slides.outerWidth - carousel.slides.width));
}
// set the width and height of all slides

slides.width(carousel.slides.width);
slides.height(carousel.slides.height);
// set the width and height of the slide template
carousel.slides.template.width(carousel.slides.width).height(car
ousel.slides.height);
// calculate the number of empty slides to create
carousel.slides.empty = (carousel.slides.shown - (carousel.slide
s.count % carousel.slides.shown)) % carousel.slides.shown;
// add number of empty slides needed to create
for (i = 0; i < carousel.slides.empty; i++) {
inst.append(carousel.slides.template.clone());
}
// add duplicate slides for purposes of facilitating an infinite
scroll
for (i = 0; i < carousel.slides.shown; i++) {
inst.append($(slides[i]).clone());
}
// calculate the new width of the carousel based on the number o
f slides now present
carousel.width = inst.children().length * carousel.slides.outerW
idth;
// set the width of the instance
inst.width(carousel.width);
// add the carousel pager
$.fn.carousel.pagerAdd(inst);
// set carousel as initialized
carousel.initialized = true;
}
}
};
// add pager for carousel
$.fn.carousel.pagerAdd = function (inst) {
// ensure inst is a jQuery object
var inst = $(inst);
// get carousel object for instance
var carousel = inst.data('carousel');
var options = carousel.options;
// add the pager list if it should be shown and it doesn't already exist
if (options.pager.show && inst.siblings('ul.carousel-pager').length <= 0
) {
// create pager list
var pager = $('<ul class="carousel-pager"></ul>').width((carousel.sl
ides.outerWidth * carousel.slides.shown) - (carousel.slides.outerWidth - carouse
l.slides.width)).bind('click', function (e) {
// set references to target and the target's parent
target = $(e.target);
parentEl = target.parent();
// check if the target is an anchor

if (target.is('a')) {
// prevent the default click behavior
e.preventDefault();
var fromPager = false;
// handle the click based on whether it is a page button or
prev/next button
if (parentEl.hasClass('prev')) {
i = carousel.slides.current - carousel.slides.shown;
}
else if (parentEl.hasClass('next')) {
i = carousel.slides.current + carousel.slides.shown;
}
else {
var page = $('li:not(.prev, .next)', this).index(parentE
l) + 1;
i = (page * carousel.slides.shown) - (carousel.slides.sh
own - 1);
fromPager = true;
}
$.fn.carousel.goTo(inst, i, fromPager);
}
});
// create template for pager button
var pagerTemplate = $('<li><a href="#"></a></li>');
// calculate number of pages
carousel.pages = Math.ceil(carousel.slides.count / carousel.slides.s
hown);
// add page button for each page
for (i = 1; i <= carousel.pages; i++) {
// build the button
var pageButton = pagerTemplate.clone().find('a').parent();
// add active class to first pager button
if (i == 1) {
pageButton.addClass('active');
}
// add the button
pager.append(pageButton);
}
// add previous button to pager
if (options.pager.prevButton.show) {
// build the button
var pagerPrev = pagerTemplate.clone().addClass('prev').find('a')
.html(options.pager.prevButton.text).parent();
// add the button
pager.append(pagerPrev);
}
// add next button to pager

if (options.pager.nextButton.show) {
// build the button
var pagerNext = pagerTemplate.clone().addClass('next').find('a')
.html(options.pager.nextButton.text).parent();
// add the button
pager.append(pagerNext);
}
// add the pager
if (options.pager.position == 'before') {
inst.parent('.carousel-viewport').before(pager);
}
else {
inst.parent('.carousel-viewport').after(pager);
}
// create reference to pager
carousel.pager = inst.addClass('carousel-with-pager').parent('.carou
sel-viewport').siblings('ul.carousel-pager');
}
}
// advance to a specific item within the carousel
$.fn.carousel.goTo = function (inst, i, fromPager) {
// define default fromPager value
var fromPager = (typeof fromPager == 'undefined') ? false : fromPager;
// ensure inst is a jQuery object
var inst = $(inst);
// get carousel object for instance
var carousel = inst.data('carousel');
var options = carousel.options;
// set index to valid slide index
var firstToLast = false;
var lastToFirst = false;
if (i > carousel.slides.count) {
i = i - carousel.slides.count - carousel.slides.empty;
lastToFirst = true;
}
else if (i <= 0) {
i = i + carousel.slides.count + carousel.slides.empty;
firstToLast = true;
}
// only animate if the carousel is not animating and the current slide i
s not the same as requested
if (!(carousel.slides.current == i) && !carousel.animating) {
var distance = {
left: {
slides: carousel.slides.current - i
},
right: {
slides: carousel.slides.count + carousel.slides.empty + i carousel.slides.current
}
}

if (i > carousel.slides.current) {
distance.left.slides = carousel.slides.count + carousel.slides.e
mpty - i + carousel.slides.current;
distance.right.slides = i - carousel.slides.current;
}
distance.left.pages = Math.ceil(distance.left.slides / carousel.slid
es.shown);
distance.right.pages = Math.ceil(distance.right.slides / carousel.sl
ides.shown);
var currentPage = Math.ceil(carousel.slides.current / carousel.slide
s.shown);
var goToPage = Math.ceil(i / carousel.slides.shown);
var animateProperties = {};
// animate right
if (((goToPage > currentPage && distance.right.pages < carousel.page
s) || (distance.right.pages == 1 && currentPage == carousel.pages && !fromPager)
&& !(firstToLast || (!firstToLast && !lastToFirst))) && !(currentPage == 1 && d
istance.left.pages == 1 && !fromPager && !(lastToFirst || (!firstToLast && !last
ToFirst)))) {
if (carousel.slides.current <= carousel.slides.shown) {
var left = -(carousel.slides.outerWidth * (carousel.slides.c
urrent - 1));
}
var rightAnimate = '-=' + (carousel.slides.outerWidth * distance
.right.slides);
animateProperties = { left: rightAnimate }
}
// animate left
else {
if (carousel.slides.current <= carousel.slides.shown) {
var left = -(carousel.slides.outerWidth * (carousel.slides.c
ount + carousel.slides.empty + carousel.slides.current - 1));
}
var leftAnimate = '+=' + (carousel.slides.outerWidth * distance.
left.slides);
animateProperties = { left: leftAnimate }
}
// set initial state if left value is set
if (typeof left != 'undefined') {
inst.css('left', left + 'px');
}
// set the active pager item
if (options.pager.show) {
eq = Math.ceil(i / carousel.slides.shown) - 1;
$('li:not(.prev, .next)', carousel.pager).removeClass('active').
filter(':eq(' + eq + ')').addClass('active');
}
// set slider to animating
carousel.animating = true;

// call slideStart function


carousel.options.slideStart(inst);
// animate slider
inst.animate(animateProperties, options.duration, options.easing, fu
nction () {
// set slider to not animating
carousel.animating = false;
// call slideComplete function
carousel.options.slideComplete(inst);
});
// set first slide reference
carousel.slides.current = i;
}
};
// set default options
$.fn.carousel.options = {
pager: {
show: true,
position: 'before',
prevButton: {
show: true,
// position: 'before',
text: 'Previous'
},
nextButton: {
show: true,
// position: 'after',
text: 'Next'
}
},
slideStart: function (inst) { },
slideComplete: function (inst) { },
easing: 'swing',
duration: 300
};
})(jQuery);
/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
* Licensed under the MIT License (LICENSE.txt).
*
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
* Thanks to: Seamus Leahy for adding deltaX and deltaY
*
* Version: 3.0.4
*
* Requires: 1.2.2+
*/
(function ($) {
var types = ['DOMMouseScroll', 'mousewheel'];
$.event.special.mousewheel = {
setup: function () {
if (this.addEventListener) {
for (var i = types.length; i;) {

this.addEventListener(types[--i], handler, false);


}
} else {
this.onmousewheel = handler;
}
},
teardown: function () {
if (this.removeEventListener) {
for (var i = types.length; i;) {
this.removeEventListener(types[--i], handler, false);
}
} else {
this.onmousewheel = null;
}
}
};
$.fn.extend({
mousewheel: function (fn) {
return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel")
;
},
unmousewheel: function (fn) {
return this.unbind("mousewheel", fn);
}
});
function handler(event) {
var orgEvent = event || window.event, args = [].slice.call(arguments, 1)
, delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
event = $.event.fix(orgEvent);
event.type = "mousewheel";
// Old school scrollwheel delta
if (event.wheelDelta) { delta = event.wheelDelta / 120; }
if (event.detail) { delta = -event.detail / 3; }
// New school multidimensional scroll (touchpads) deltas
deltaY = delta;
// Gecko
if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL
_AXIS) {
deltaY = 0;
deltaX = -1 * delta;
}
// Webkit
if (orgEvent.wheelDeltaY !== undefined) { deltaY = orgEvent.wheelDeltaY
/ 120; }
if (orgEvent.wheelDeltaX !== undefined) { deltaX = -1 * orgEvent.wheelDe
ltaX / 120; }
// Add event and delta to the front of the arguments
args.unshift(event, delta, deltaX, deltaY);
return $.event.handle.apply(this, args);

}
})(jQuery);
/*
* qTip2 - Pretty powerful tooltips - @@vVERSION
* http://qtip2.com
*
* Copyright (c) 2014 Craig Michael Thompson
* Released under the MIT, GPL licenses
* http://jquery.org/license
*
* Date: Fri Jul 25 2014 01:12 EDT-0400
@@BUILDPROPS */
/*global window: false, jQuery: false, console: false, define: false */
/* Cache window, document, undefined */
(function (window, document, undefined) {
// Uses AMD or browser globals to create a jQuery plugin.
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
}
else if (jQuery && !jQuery.fn.qtip) {
factory(jQuery);
}
}
(function ($) {
"use strict"; // Enable ECMAScript "strict" operation for this function.
See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
;// Munge the primitives - Paul Irish tip
var TRUE = true,
FALSE = false,
NULL = null,
// Common variables
X = 'x', Y = 'y',
WIDTH = 'width',
HEIGHT = 'height',
// Positioning sides
TOP = 'top',
LEFT = 'left',
BOTTOM = 'bottom',
RIGHT = 'right',
CENTER = 'center',
// Position adjustment types
FLIP = 'flip',
FLIPINVERT = 'flipinvert',
SHIFT = 'shift',
// Shortcut vars
QTIP, PROTOTYPE, CORNER, CHECKS,
PLUGINS = {},
NAMESPACE = 'qtip',
ATTR_HAS = 'data-hasqtip',
ATTR_ID = 'data-qtip-id',

WIDGET = ['ui-widget', 'ui-tooltip'],


SELECTOR = '.' + NAMESPACE,
INACTIVE_EVENTS = 'click dblclick mousedown mouseup mousemove mouseleave
mouseenter'.split(' '),
CLASS_FIXED = NAMESPACE + '-fixed',
CLASS_DEFAULT = NAMESPACE + '-default',
CLASS_FOCUS = NAMESPACE + '-focus',
CLASS_HOVER = NAMESPACE + '-hover',
CLASS_DISABLED = NAMESPACE + '-disabled',
replaceSuffix = '_replacedByqTip',
oldtitle = 'oldtitle',
trackingBound,
// Browser detection
BROWSER = {
/*
* IE version detection
*
* Adapted from: http://ajaxian.com/archives/attack-of-the-ie-condit
ional-comment
* Credit to James Padolsey for the original implemntation!
*/
ie: (function () {
var v = 3, div = document.createElement('div');
while ((div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![
endif]-->')) {
if (!div.getElementsByTagName('i')[0]) { break; }
}
return v > 4 ? v : NaN;
}()),
/*
* iOS version detection
*/
iOS: parseFloat(
('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.
exec(navigator.userAgent) || [0, ''])[1])
.replace('undefined', '3_2').replace('_', '.').replace('_', '')
) || FALSE
};
; function QTip(target, options, id, attr) {
// Elements and ID
this.id = id;
this.target = target;
this.tooltip = NULL;
this.elements = { target: target };
// Internal constructs
this._id = NAMESPACE + '-' + id;
this.timers = { img: {} };
this.options = options;
this.plugins = {};
// Cache object
this.cache = {
event: {},
target: $(),

disabled: FALSE,
attr: attr,
onTooltip: FALSE,
lastClass: ''
};
// Set the initial flags
this.rendered = this.destroyed = this.disabled = this.waiting =
this.hiddenDuringWait = this.positioning = this.triggering = FAL
SE;
}
PROTOTYPE = QTip.prototype;
PROTOTYPE._when = function (deferreds) {
return $.when.apply($, deferreds);
};
PROTOTYPE.render = function (show) {
if (this.rendered || this.destroyed) { return this; } // If tooltip
has already been rendered, exit
var self = this,
options = this.options,
cache = this.cache,
elements = this.elements,
text = options.content.text,
title = options.content.title,
button = options.content.button,
posOptions = options.position,
namespace = '.' + this._id + ' ',
deferreds = [],
tooltip;
// Add ARIA attributes to target
$.attr(this.target[0], 'aria-describedby', this._id);
// Create tooltip element
this.tooltip = elements.tooltip = tooltip = $('<div/>', {
'id': this._id,
'class': [NAMESPACE, CLASS_DEFAULT, options.style.classes, NAMES
PACE + '-pos-' + options.position.my.abbrev()].join(' '),
'width': options.style.width || '',
'height': options.style.height || '',
'tracking': posOptions.target === 'mouse' && posOptions.adjust.m
ouse,
/* ARIA specific attributes */
'role': 'alert',
'aria-live': 'polite',
'aria-atomic': FALSE,
'aria-describedby': this._id + '-content',
'aria-hidden': TRUE
})
.toggleClass(CLASS_DISABLED, this.disabled)
.attr(ATTR_ID, this.id)
.data(NAMESPACE, this)
.appendTo(posOptions.container)
.append(
// Create content element
elements.content = $('<div />', {

'class': NAMESPACE + '-content',


'id': this._id + '-content',
'aria-atomic': TRUE
})
);
// Set rendered flag and prevent redundant reposition calls for now
this.rendered = -1;
this.positioning = TRUE;
// Create title...
if (title) {
this._createTitle();
// Update title only if its not a callback (called in toggle if
so)
if (!$.isFunction(title)) {
deferreds.push(this._updateTitle(title, FALSE));
}
}
// Create button
if (button) { this._createButton(); }
// Set proper rendered flag and update content if not a callback fun
ction (called in toggle)
if (!$.isFunction(text)) {
deferreds.push(this._updateContent(text, FALSE));
}
this.rendered = TRUE;
// Setup widget classes
this._setWidget();
// Initialize 'render' plugins
$.each(PLUGINS, function (name) {
var instance;
if (this.initialize === 'render' && (instance = this(self))) {
self.plugins[name] = instance;
}
});
// Unassign initial events and assign proper events
this._unassignEvents();
this._assignEvents();
// When deferreds have completed
this._when(deferreds).then(function () {
// tooltiprender event
self._trigger('render');
// Reset flags
self.positioning = FALSE;
// Show tooltip if not hidden during wait period
if (!self.hiddenDuringWait && (options.show.ready || show)) {
self.toggle(TRUE, cache.event, FALSE);
}
self.hiddenDuringWait = FALSE;
});

// Expose API
QTIP.api[this.id] = this;
return this;
};
PROTOTYPE.destroy = function (immediate) {
// Set flag the signify destroy is taking place to plugins
// and ensure it only gets destroyed once!
if (this.destroyed) { return this.target; }
function process() {
if (this.destroyed) { return; }
this.destroyed = TRUE;
var target = this.target,
title = target.attr(oldtitle);
// Destroy tooltip if rendered
if (this.rendered) {
this.tooltip.stop(1, 0).find('*').remove().end().remove();
}
// Destroy all plugins
$.each(this.plugins, function (name) {
this.destroy && this.destroy();
});
// Clear timers and remove bound events
clearTimeout(this.timers.show);
clearTimeout(this.timers.hide);
this._unassignEvents();
// Remove api object and ARIA attributes
target.removeData(NAMESPACE)
.removeAttr(ATTR_ID)
.removeAttr(ATTR_HAS)
.removeAttr('aria-describedby');
// Reset old title attribute if removed
if (this.options.suppress && title) {
target.attr('title', title).removeAttr(oldtitle);
}
// Remove qTip events associated with this API
this._unbind(target);
// Remove ID from used id objects, and delete object references
// for better garbage collection and leak protection
this.options = this.elements = this.cache = this.timers =
this.plugins = this.mouse = NULL;
// Delete epoxsed API object
delete QTIP.api[this.id];
}
// If an immediate destory is needed
if ((immediate !== TRUE || this.triggering === 'hide') && this.rende
red) {

this.tooltip.one('tooltiphidden', $.proxy(process, this));


!this.triggering && this.hide();
}
// If we're not in the process of hiding... process
else { process.call(this); }
return this.target;
};
; function invalidOpt(a) {
return a === NULL || $.type(a) !== 'object';
}
function invalidContent(c) {
return !($.isFunction(c) || (c && c.attr) || c.length || ($.type(c)
=== 'object' && (c.jquery || c.then)));
}
// Option object sanitizer
function sanitizeOptions(opts) {
var content, text, ajax, once;
if (invalidOpt(opts)) { return FALSE; }
if (invalidOpt(opts.metadata)) {
opts.metadata = { type: opts.metadata };
}
if ('content' in opts) {
content = opts.content;
if (invalidOpt(content) || content.jquery || content.done) {
content = opts.content = {
text: (text = invalidContent(content) ? FALSE : content)
};
}
else { text = content.text; }
// DEPRECATED - Old content.ajax plugin functionality
// Converts it into the proper Deferred syntax
if ('ajax' in content) {
ajax = content.ajax;
once = ajax && ajax.once !== FALSE;
delete content.ajax;
content.text = function (event, api) {
var loading = text || $(this).attr(api.options.content.a
ttr) || 'Loading...',
deferred = $.ajax(
$.extend({}, ajax, { context: api })
)
.then(ajax.success, NULL, ajax.error)
.then(function (content) {
if (content && once) { api.set('content.text', conte
nt); }
return content;
},
function (xhr, status, error) {

if (api.destroyed || xhr.status === 0) { return; }


api.set('content.text', status + ': ' + error);
});
return !once ? (api.set('content.text', loading), deferr
ed) : loading;
};
}
if ('title' in content) {
if (!invalidOpt(content.title)) {
content.button = content.title.button;
content.title = content.title.text;
}
if (invalidContent(content.title || FALSE)) {
content.title = FALSE;
}
}
}
if ('position' in opts && invalidOpt(opts.position)) {
opts.position = { my: opts.position, at: opts.position };
}
if ('show' in opts && invalidOpt(opts.show)) {
opts.show = opts.show.jquery ? { target: opts.show } :
opts.show === TRUE ? { ready: TRUE } : { event: opts.show };
}
if ('hide' in opts && invalidOpt(opts.hide)) {
opts.hide = opts.hide.jquery ? { target: opts.hide } : { event:
opts.hide };
}
if ('style' in opts && invalidOpt(opts.style)) {
opts.style = { classes: opts.style };
}
// Sanitize plugin options
$.each(PLUGINS, function () {
this.sanitize && this.sanitize(opts);
});
return opts;
}
// Setup builtin .set() option checks
CHECKS = PROTOTYPE.checks = {
builtin: {
// Core checks
'^id$': function (obj, o, v, prev) {
var id = v === TRUE ? QTIP.nextid : v,
new_id = NAMESPACE + '-' + id;
if (id !== FALSE && id.length > 0 && !$('#' + new_id).length
) {
this._id = new_id;
if (this.rendered) {

this.tooltip[0].id = this._id;
this.elements.content[0].id = this._id + '-content';
this.elements.title[0].id = this._id + '-title';
}
}
else { obj[o] = prev; }
},
'^prerender': function (obj, o, v) {
v && !this.rendered && this.render(this.options.show.ready);
},
// Content checks
'^content.text$': function (obj, o, v) {
this._updateContent(v);
},
'^content.attr$': function (obj, o, v, prev) {
if (this.options.content.text === this.target.attr(prev)) {
this._updateContent(this.target.attr(v));
}
},
'^content.title$': function (obj, o, v) {
// Remove title if content is null
if (!v) { return this._removeTitle(); }
// If title isn't already created, create it now and update
v && !this.elements.title && this._createTitle();
this._updateTitle(v);
},
'^content.button$': function (obj, o, v) {
this._updateButton(v);
},
'^content.title.(text|button)$': function (obj, o, v) {
this.set('content.' + o, v); // Backwards title.text/button
compat
},
// Position checks
'^position.(my|at)$': function (obj, o, v) {
'string' === typeof v && (obj[o] = new CORNER(v, o === 'at')
);
},
'^position.container$': function (obj, o, v) {
this.rendered && this.tooltip.appendTo(v);
},
// Show checks
'^show.ready$': function (obj, o, v) {
v && (!this.rendered && this.render(TRUE) || this.toggle(TRU
E));
},
// Style checks
'^style.classes$': function (obj, o, v, p) {
this.rendered && this.tooltip.removeClass(p).addClass(v);
},
'^style.(width|height)': function (obj, o, v) {
this.rendered && this.tooltip.css(o, v);
},
'^style.widget|content.title': function () {
this.rendered && this._setWidget();

},
'^style.def': function (obj, o, v) {
this.rendered && this.tooltip.toggleClass(CLASS_DEFAULT, !!v
);
},
// Events check
'^events.(render|show|move|hide|focus|blur)$': function (obj, o,
v) {
this.rendered && this.tooltip[($.isFunction(v) ? '' : 'un')
+ 'bind']('tooltip' + o, v);
},
// Properties which require event reassignment
'^(show|hide|position).(event|target|fixed|inactive|leave|distan
ce|viewport|adjust)': function () {
if (!this.rendered) { return; }
// Set tracking flag
var posOptions = this.options.position;
this.tooltip.attr('tracking', posOptions.target === 'mouse'
&& posOptions.adjust.mouse);
// Reassign events
this._unassignEvents();
this._assignEvents();
}
}
};
// Dot notation converter
function convertNotation(options, notation) {
var i = 0, obj, option = options,
// Split notation into array
levels = notation.split('.');
// Loop through
while (option = option[levels[i++]]) {
if (i < levels.length) { obj = option; }
}
return [obj || options, levels.pop()];
}
PROTOTYPE.get = function (notation) {
if (this.destroyed) { return this; }
var o = convertNotation(this.options, notation.toLowerCase()),
result = o[0][o[1]];
return result.precedance ? result.string() : result;
};
function setCallback(notation, args) {
var category, rule, match;
for (category in this.checks) {
for (rule in this.checks[category]) {
if (match = (new RegExp(rule, 'i')).exec(notation)) {

args.push(match);
if (category === 'builtin' || this.plugins[category]) {
this.checks[category][rule].apply(
this.plugins[category] || this, args
);
}
}
}
}
}
var rmove = /^position\.(my|at|adjust|target|container|viewport)|style|c
ontent|show\.ready/i,
rrender = /^prerender|show\.ready/i;
PROTOTYPE.set = function (option, value) {
if (this.destroyed) { return this; }
var rendered = this.rendered,
reposition = FALSE,
options = this.options,
checks = this.checks,
name;
// Convert singular option/value pair into object form
if ('string' === typeof option) {
name = option; option = {}; option[name] = value;
}
else { option = $.extend({}, option); }
// Set all of the defined options to their new values
$.each(option, function (notation, value) {
if (rendered && rrender.test(notation)) {
delete option[notation]; return;
}
// Set new obj value
var obj = convertNotation(options, notation.toLowerCase()), prev
ious;
previous = obj[0][obj[1]];
obj[0][obj[1]] = value && value.nodeType ? $(value) : value;
// Also check if we need to reposition
reposition = rmove.test(notation) || reposition;
// Set the new params for the callback
option[notation] = [obj[0], obj[1], value, previous];
});
// Re-sanitize options
sanitizeOptions(options);
/*
* Execute any valid callbacks for the set options
* Also set positioning flag so we don't get loads of redundant repo
sitioning calls.
*/
this.positioning = TRUE;
$.each(option, $.proxy(setCallback, this));

this.positioning = FALSE;
// Update position if needed
if (this.rendered && this.tooltip[0].offsetWidth > 0 && reposition)
{
this.reposition(options.position.target === 'mouse' ? NULL : thi
s.cache.event);
}
return this;
};
; PROTOTYPE._update = function (content, element, reposition) {
var self = this,
cache = this.cache;
// Make sure tooltip is rendered and content is defined. If not retu
rn
if (!this.rendered || !content) { return FALSE; }
// Use function to parse content
if ($.isFunction(content)) {
content = content.call(this.elements.target, cache.event, this)
|| '';
}
// Handle deferred content
if ($.isFunction(content.then)) {
cache.waiting = TRUE;
return content.then(function (c) {
cache.waiting = FALSE;
return self._update(c, element);
}, NULL, function (e) {
return self._update(e, element);
});
}
// If content is null... return false
if (content === FALSE || (!content && content !== '')) { return FALS
E; }
// Append new content if its a DOM array and show it if hidden
if (content.jquery && content.length > 0) {
element.empty().append(
content.css({ display: 'block', visibility: 'visible' })
);
}
// Content is a regular string, insert the new content
else { element.html(content); }
// Wait for content to be loaded, and reposition
return this._waitForContent(element).then(function (images) {
if (images.images && images.images.length && self.rendered && se
lf.tooltip[0].offsetWidth > 0) {
self.reposition(cache.event, !images.length);
}
});
};

PROTOTYPE._waitForContent = function (element) {


var cache = this.cache;
// Set flag
cache.waiting = TRUE;
// If imagesLoaded is included, ensure images have loaded and return
promise
return ($.fn.imagesLoaded ? element.imagesLoaded() : $.Deferred().re
solve([]))
.done(function () { cache.waiting = FALSE; })
.promise();
};
PROTOTYPE._updateContent = function (content, reposition) {
this._update(content, this.elements.content, reposition);
};
PROTOTYPE._updateTitle = function (content, reposition) {
if (this._update(content, this.elements.title, reposition) === FALSE
) {
this._removeTitle(FALSE);
}
};
PROTOTYPE._createTitle = function () {
var elements = this.elements,
id = this._id + '-title';
// Destroy previous title element, if present
if (elements.titlebar) { this._removeTitle(); }
// Create title bar and title elements
elements.titlebar = $('<div />', {
'class': NAMESPACE + '-titlebar ' + (this.options.style.widget ?
createWidgetClass('header') : '')
})
.append(
elements.title = $('<div />', {
'id': id,
'class': NAMESPACE + '-title',
'aria-atomic': TRUE
})
)
.insertBefore(elements.content)
// Button-specific events
.delegate('.qtip-close', 'mousedown keydown mouseup keyup mouseout',
function (event) {
$(this).toggleClass('ui-state-active ui-state-focus', event.type
.substr(-4) === 'down');
})
.delegate('.qtip-close', 'mouseover mouseout', function (event) {
$(this).toggleClass('ui-state-hover', event.type === 'mouseover'
);
});
// Create button if enabled
if (this.options.content.button) { this._createButton(); }
};

PROTOTYPE._removeTitle = function (reposition) {


var elements = this.elements;
if (elements.title) {
elements.titlebar.remove();
elements.titlebar = elements.title = elements.button = NULL;
// Reposition if enabled
if (reposition !== FALSE) { this.reposition(); }
}
};
; PROTOTYPE.reposition = function (event, effect) {
if (!this.rendered || this.positioning || this.destroyed) { return t
his; }
// Set positioning flag
this.positioning = TRUE;
var cache = this.cache,
tooltip = this.tooltip,
posOptions = this.options.position,
target = posOptions.target,
my = posOptions.my,
at = posOptions.at,
viewport = posOptions.viewport,
container = posOptions.container,
adjust = posOptions.adjust,
method = adjust.method.split(' '),
tooltipWidth = tooltip.outerWidth(FALSE),
tooltipHeight = tooltip.outerHeight(FALSE),
targetWidth = 0,
targetHeight = 0,
type = tooltip.css('position'),
position = { left: 0, top: 0 },
visible = tooltip[0].offsetWidth > 0,
isScroll = event && event.type === 'scroll',
win = $(window),
doc = container[0].ownerDocument,
mouse = this.mouse,
pluginCalculations, offset;
// Check if absolute position was passed
if ($.isArray(target) && target.length === 2) {
// Force left top and set position
at = { x: LEFT, y: TOP };
position = { left: target[0], top: target[1] };
}
// Check if mouse was the target
else if (target === 'mouse') {
// Force left top to allow flipping
at = { x: LEFT, y: TOP };
// Use the cached mouse coordinates if available, or passed even
t has no coordinates
if (mouse && mouse.pageX && (adjust.mouse || !event || !event.pa
geX)) {
event = mouse;

}
// If the passed event has no coordinates (such as a scroll
event)
else if (!event || !event.pageX) {
// Use the mouse origin that caused the show event, if dista
nce hiding is enabled
if ((!adjust.mouse || this.options.show.distance) && cache.o
rigin && cache.origin.pageX) {
event = cache.origin;
}
// Use cached event for resize/scroll events
else if (!event || (event && (event.type === 'resize' || eve
nt.type === 'scroll'))) {
event = cache.event;
}
}
// Calculate body and container offset and take them into accoun
t below
if (type !== 'static') { position = container.offset(); }
if (doc.body.offsetWidth !== (window.innerWidth || doc.documentE
lement.clientWidth)) {
offset = $(document.body).offset();
}
// Use event coordinates for position
position = {
left: event.pageX - position.left + (offset && offset.left |
| 0),
top: event.pageY - position.top + (offset && offset.top || 0
)
};
// Scroll events are a pain, some browsers
if (adjust.mouse && isScroll && mouse) {
position.left -= (mouse.scrollX || 0) - win.scrollLeft();
position.top -= (mouse.scrollY || 0) - win.scrollTop();
}
}
// Target wasn't mouse or absolute...
else {
// Check if event targetting is being used
if (target === 'event') {
if (event && event.target && event.type !== 'scroll' && even
t.type !== 'resize') {
cache.target = $(event.target);
}
else if (!event.target) {
cache.target = this.elements.target;
}
}
else if (target !== 'event') {
cache.target = $(target.jquery ? target : this.elements.targ
et);
}
target = cache.target;

// Parse the target into a jQuery object and make sure there's a
n element present
target = $(target).eq(0);
if (target.length === 0) { return this; }
// Check if window or document is the target
else if (target[0] === document || target[0] === window) {
targetWidth = BROWSER.iOS ? window.innerWidth : target.width
();
targetHeight = BROWSER.iOS ? window.innerHeight : target.hei
ght();
if (target[0] === window) {
position = {
top: (viewport || target).scrollTop(),
left: (viewport || target).scrollLeft()
};
}
}
// Check if the target is an <AREA> element
else if (PLUGINS.imagemap && target.is('area')) {
pluginCalculations = PLUGINS.imagemap(this, target, at, PLUG
INS.viewport ? method : FALSE);
}
// Check if the target is an SVG element
else if (PLUGINS.svg && target && target[0].ownerSVGElement) {
pluginCalculations = PLUGINS.svg(this, target, at, PLUGINS.v
iewport ? method : FALSE);
}
// Otherwise use regular jQuery methods
else {
targetWidth = target.outerWidth(FALSE);
targetHeight = target.outerHeight(FALSE);
position = target.offset();
}
// Parse returned plugin values into proper variables
if (pluginCalculations) {
targetWidth = pluginCalculations.width;
targetHeight = pluginCalculations.height;
offset = pluginCalculations.offset;
position = pluginCalculations.position;
}
// Adjust position to take into account offset parents
position = this.reposition.offset(target, position, container);
// Adjust for position.fixed tooltips (and also iOS scroll bug i
n v3.2-4.0 & v4.3-4.3.2)
if ((BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1) ||
(BROWSER.iOS >= 4.3 && BROWSER.iOS < 4.33) ||
(!BROWSER.iOS && type === 'fixed')
) {
position.left -= win.scrollLeft();
position.top -= win.scrollTop();
}

// Adjust position relative to target


if (!pluginCalculations || (pluginCalculations && pluginCalculat
ions.adjustable !== FALSE)) {
position.left += at.x === RIGHT ? targetWidth : at.x === CEN
TER ? targetWidth / 2 : 0;
position.top += at.y === BOTTOM ? targetHeight : at.y === CE
NTER ? targetHeight / 2 : 0;
}
}
// Adjust position relative to tooltip
position.left += adjust.x + (my.x === RIGHT ? -tooltipWidth : my.x =
== CENTER ? -tooltipWidth / 2 : 0);
position.top += adjust.y + (my.y === BOTTOM ? -tooltipHeight : my.y
=== CENTER ? -tooltipHeight / 2 : 0);
// Use viewport adjustment plugin if enabled
if (PLUGINS.viewport) {
position.adjusted = PLUGINS.viewport(
this, position, posOptions, targetWidth, targetHeight, toolt
ipWidth, tooltipHeight
);
// Apply offsets supplied by positioning plugin (if used)
if (offset && position.adjusted.left) { position.left += offset.
left; }
if (offset && position.adjusted.top) { position.top += offset.to
p; }
}
// Viewport adjustment is disabled, set values to zero
else { position.adjusted = { left: 0, top: 0 }; }
// tooltipmove event
if (!this._trigger('move', [position, viewport.elem || viewport], ev
ent)) { return this; }
delete position.adjusted;
// If effect is disabled, target it mouse, no animation is defined o
r positioning gives NaN out, set CSS directly
if (effect === FALSE || !visible || isNaN(position.left) || isNaN(po
sition.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) {
tooltip.css(position);
}
// Use custom function if provided
else if ($.isFunction(posOptions.effect)) {
posOptions.effect.call(tooltip, this, $.extend({}, position));
tooltip.queue(function (next) {
// Reset attributes to avoid cross-browser rendering bugs
$(this).css({ opacity: '', height: '' });
if (BROWSER.ie) { this.style.removeAttribute('filter'); }
next();
});
}
// Set positioning flag
this.positioning = FALSE;

return this;
};
// Custom (more correct for qTip!) offset calculator
PROTOTYPE.reposition.offset = function (elem, pos, container) {
if (!container[0]) { return pos; }
var ownerDocument = $(elem[0].ownerDocument),
quirks = !!BROWSER.ie && document.compatMode !== 'CSS1Compat',
parent = container[0],
scrolled, position, parentOffset, overflow;
function scroll(e, i) {
pos.left += i * e.scrollLeft();
pos.top += i * e.scrollTop();
}
// Compensate for non-static containers offset
do {
if ((position = $.css(parent, 'position')) !== 'static') {
if (position === 'fixed') {
parentOffset = parent.getBoundingClientRect();
scroll(ownerDocument, -1);
}
else {
parentOffset = $(parent).position();
parentOffset.left += (parseFloat($.css(parent, 'borderLe
ftWidth')) || 0);
parentOffset.top += (parseFloat($.css(parent, 'borderTop
Width')) || 0);
}
pos.left -= parentOffset.left + (parseFloat($.css(parent, 'm
arginLeft')) || 0);
pos.top -= parentOffset.top + (parseFloat($.css(parent, 'mar
ginTop')) || 0);
// If this is the first parent element with an overflow of "
scroll" or "auto", store it
if (!scrolled && (overflow = $.css(parent, 'overflow')) !==
'hidden' && overflow !== 'visible') { scrolled = $(parent); }
}
}
while ((parent = parent.offsetParent));
// Compensate for containers scroll if it also has an offsetParent (
or in IE quirks mode)
if (scrolled && (scrolled[0] !== ownerDocument[0] || quirks)) {
scroll(scrolled, 1);
}
return pos;
};
// Corner class
var C = (CORNER = PROTOTYPE.reposition.Corner = function (corner, forceY
) {
corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi,
CENTER).toLowerCase();
this.x = (corner.match(/left|right/i) || corner.match(/center/) || [

'inherit'])[0].toLowerCase();
this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLo
werCase();
this.forceY = !!forceY;
var f = corner.charAt(0);
this.precedance = (f === 't' || f === 'b' ? Y : X);
}).prototype;
C.invert = function (z, center) {
this[z] = this[z] === LEFT ? RIGHT : this[z] === RIGHT ? LEFT : cent
er || this[z];
};
C.string = function () {
var x = this.x, y = this.y;
return x === y ? x : this.precedance === Y || (this.forceY && y !==
'center') ? y + ' ' + x : x + ' ' + y;
};
C.abbrev = function () {
var result = this.string().split(' ');
return result[0].charAt(0) + (result[1] && result[1].charAt(0) || ''
);
};
C.clone = function () {
return new CORNER(this.string(), this.forceY);
};;
PROTOTYPE.toggle = function (state, event) {
var cache = this.cache,
options = this.options,
tooltip = this.tooltip;
// Try to prevent flickering when tooltip overlaps show element
if (event) {
if ((/over|enter/).test(event.type) && (/out|leave/).test(cache.
event.type) &&
options.show.target.add(event.target).length === options.sho
w.target.length &&
tooltip.has(event.relatedTarget).length) {
return this;
}
// Cache event
cache.event = cloneEvent(event);
}
// If we're currently waiting and we've just hidden... stop it
this.waiting && !state && (this.hiddenDuringWait = TRUE);
// Render the tooltip if showing and it isn't already
if (!this.rendered) { return state ? this.render(1) : this; }
else if (this.destroyed || this.disabled) { return this; }
var type = state ? 'show' : 'hide',
opts = this.options[type],
otherOpts = this.options[!state ? 'show' : 'hide'],
posOptions = this.options.position,
contentOptions = this.options.content,

width = this.tooltip.css('width'),
visible = this.tooltip.is(':visible'),
animate = state || opts.target.length === 1,
sameTarget = !event || opts.target.length < 2 || cache.target[0]
=== event.target,
identicalState, allow, showEvent, delay, after;
// Detect state if valid one isn't provided
if ((typeof state).search('boolean|number')) { state = !visible; }
// Check if the tooltip is in an identical state to the new would-be
state
identicalState = !tooltip.is(':animated') && visible === state && sa
meTarget;
// Fire tooltip(show/hide) event and check if destroyed
allow = !identicalState ? !!this._trigger(type, [90]) : NULL;
// Check to make sure the tooltip wasn't destroyed in the callback
if (this.destroyed) { return this; }
// If the user didn't stop the method prematurely and we're showing
the tooltip, focus it
if (allow !== FALSE && state) { this.focus(event); }
// If the state hasn't changed or the user stopped it, return early
if (!allow || identicalState) { return this; }
// Set ARIA hidden attribute
$.attr(tooltip[0], 'aria-hidden', !!!state);
// Execute state specific properties
if (state) {
// Store show origin coordinates
cache.origin = cloneEvent(this.mouse);
// Update tooltip content & title if it's a dynamic function
if ($.isFunction(contentOptions.text)) { this._updateContent(con
tentOptions.text, FALSE); }
if ($.isFunction(contentOptions.title)) { this._updateTitle(cont
entOptions.title, FALSE); }
// Cache mousemove events for positioning purposes (if not alrea
dy tracking)
if (!trackingBound && posOptions.target === 'mouse' && posOption
s.adjust.mouse) {
$(document).bind('mousemove.' + NAMESPACE, this._storeMouse)
;
trackingBound = TRUE;
}
// Update the tooltip position (set width first to prevent viewp
ort/max-width issues)
if (!width) { tooltip.css('width', tooltip.outerWidth(FALSE)); }
this.reposition(event, arguments[2]);
if (!width) { tooltip.css('width', ''); }
// Hide other tooltips if tooltip is solo
if (!!opts.solo) {
(typeof opts.solo === 'string' ? $(opts.solo) : $(SELECTOR,

opts.solo))
.not(tooltip).not(opts.target).qtip('hide', $.Event('too
ltipsolo'));
}
}
else {
// Clear show timer if we're hiding
clearTimeout(this.timers.show);
// Remove cached origin on hide
delete cache.origin;
// Remove mouse tracking event if not needed (all tracking qTips
are hidden)
if (trackingBound && !$(SELECTOR + '[tracking="true"]:visible',
opts.solo).not(tooltip).length) {
$(document).unbind('mousemove.' + NAMESPACE);
trackingBound = FALSE;
}
// Blur the tooltip
this.blur(event);
}
// Define post-animation, state specific properties
after = $.proxy(function () {
if (state) {
// Prevent antialias from disappearing in IE by removing fil
ter
if (BROWSER.ie) { tooltip[0].style.removeAttribute('filter')
; }
// Remove overflow setting to prevent tip bugs
tooltip.css('overflow', '');
// Autofocus elements if enabled
if ('string' === typeof opts.autofocus) {
$(this.options.show.autofocus, tooltip).focus();
}
// If set, hide tooltip when inactive for delay period
this.options.show.target.trigger('qtip-' + this.id + '-inact
ive');
}
else {
// Reset CSS states
tooltip.css({
display: '',
visibility: '',
opacity: '',
left: '',
top: ''
});
}
// tooltipvisible/tooltiphidden events
this._trigger(state ? 'visible' : 'hidden');
}, this);
// If no effect type is supplied, use a simple toggle

if (opts.effect === FALSE || animate === FALSE) {


tooltip[type]();
after();
}
// Use custom function if provided
else if ($.isFunction(opts.effect)) {
tooltip.stop(1, 1);
opts.effect.call(tooltip, this);
tooltip.queue('fx', function (n) {
after(); n();
});
}
// Use basic fade function by default
else { tooltip.fadeTo(90, state ? 1 : 0, after); }
// If inactive hide method is set, active it
if (state) { opts.target.trigger('qtip-' + this.id + '-inactive'); }
return this;
};
PROTOTYPE.show = function (event) { return this.toggle(TRUE, event); };
PROTOTYPE.hide = function (event) { return this.toggle(FALSE, event); };
; PROTOTYPE.focus = function (event) {
if (!this.rendered || this.destroyed) { return this; }
var qtips = $(SELECTOR),
tooltip = this.tooltip,
curIndex = parseInt(tooltip[0].style.zIndex, 10),
newIndex = QTIP.zindex + qtips.length,
focusedElem;
// Only update the z-index if it has changed and tooltip is not alre
ady focused
if (!tooltip.hasClass(CLASS_FOCUS)) {
// tooltipfocus event
if (this._trigger('focus', [newIndex], event)) {
// Only update z-index's if they've changed
if (curIndex !== newIndex) {
// Reduce our z-index's and keep them properly ordered
qtips.each(function () {
if (this.style.zIndex > curIndex) {
this.style.zIndex = this.style.zIndex - 1;
}
});
// Fire blur event for focused tooltip
qtips.filter('.' + CLASS_FOCUS).qtip('blur', event);
}
// Set the new z-index
tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex;
}
}
return this;

};
PROTOTYPE.blur = function (event) {
if (!this.rendered || this.destroyed) { return this; }
// Set focused status to FALSE
this.tooltip.removeClass(CLASS_FOCUS);
// tooltipblur event
this._trigger('blur', [this.tooltip.css('zIndex')], event);
return this;
};
; PROTOTYPE.disable = function (state) {
if (this.destroyed) { return this; }
// If 'toggle' is passed, toggle the current state
if (state === 'toggle') {
state = !(this.rendered ? this.tooltip.hasClass(CLASS_DISABLED)
: this.disabled);
}
// Disable if no state passed
else if ('boolean' !== typeof state) {
state = TRUE;
}
if (this.rendered) {
this.tooltip.toggleClass(CLASS_DISABLED, state)
.attr('aria-disabled', state);
}
this.disabled = !!state;
return this;
};
PROTOTYPE.enable = function () { return this.disable(FALSE); };
; PROTOTYPE._createButton = function () {
var self = this,
elements = this.elements,
tooltip = elements.tooltip,
button = this.options.content.button,
isString = typeof button === 'string',
close = isString ? button : 'Close tooltip';
if (elements.button) { elements.button.remove(); }
// Use custom button if one was supplied by user, else use default
if (button.jquery) {
elements.button = button;
}
else {
elements.button = $('<a />', {
'class': 'qtip-close ' + (this.options.style.widget ? '' : N
AMESPACE + '-icon'),
'title': close,
'aria-label': close

})
.prepend(
$('<span />', {
'class': 'ui-icon ui-icon-close',
'html': '&times;'
})
);
}
// Create button and setup attributes
elements.button.appendTo(elements.titlebar || tooltip)
.attr('role', 'button')
.click(function (event) {
if (!tooltip.hasClass(CLASS_DISABLED)) { self.hide(event); }
return FALSE;
});
};
PROTOTYPE._updateButton = function (button) {
// Make sure tooltip is rendered and if not, return
if (!this.rendered) { return FALSE; }
var elem = this.elements.button;
if (button) { this._createButton(); }
else { elem.remove(); }
};
;// Widget class creator
function createWidgetClass(cls) {
return WIDGET.concat('').join(cls ? '-' + cls + ' ' : ' ');
}
// Widget class setter method
PROTOTYPE._setWidget = function () {
var on = this.options.style.widget,
elements = this.elements,
tooltip = elements.tooltip,
disabled = tooltip.hasClass(CLASS_DISABLED);
tooltip.removeClass(CLASS_DISABLED);
CLASS_DISABLED = on ? 'ui-state-disabled' : 'qtip-disabled';
tooltip.toggleClass(CLASS_DISABLED, disabled);
tooltip.toggleClass('ui-helper-reset ' + createWidgetClass(), on).to
ggleClass(CLASS_DEFAULT, this.options.style.def && !on);
if (elements.content) {
elements.content.toggleClass(createWidgetClass('content'), on);
}
if (elements.titlebar) {
elements.titlebar.toggleClass(createWidgetClass('header'), on);
}
if (elements.button) {
elements.button.toggleClass(NAMESPACE + '-icon', !on);
}
};; function cloneEvent(event) {
return event && {
type: event.type,
pageX: event.pageX,
pageY: event.pageY,

target: event.target,
relatedTarget: event.relatedTarget,
scrollX: event.scrollX || window.pageXOffset || document.body.sc
rollLeft || document.documentElement.scrollLeft,
scrollY: event.scrollY || window.pageYOffset || document.body.sc
rollTop || document.documentElement.scrollTop
} || {};
}
function delay(callback, duration) {
// If tooltip has displayed, start hide timer
if (duration > 0) {
return setTimeout(
$.proxy(callback, this), duration
);
}
else { callback.call(this); }
}
function showMethod(event) {
if (this.tooltip.hasClass(CLASS_DISABLED)) { return FALSE; }
// Clear hide timers
clearTimeout(this.timers.show);
clearTimeout(this.timers.hide);
// Start show timer
this.timers.show = delay.call(this,
function () { this.toggle(TRUE, event); },
this.options.show.delay
);
}
function hideMethod(event) {
if (this.tooltip.hasClass(CLASS_DISABLED)) { return FALSE; }
// Check if new target was actually the tooltip element
var relatedTarget = $(event.relatedTarget),
ontoTooltip = relatedTarget.closest(SELECTOR)[0] === this.toolti
p[0],
ontoTarget = relatedTarget[0] === this.options.show.target[0];
// Clear timers and stop animation queue
clearTimeout(this.timers.show);
clearTimeout(this.timers.hide);
// Prevent hiding if tooltip is fixed and event target is the toolti
p.
// Or if mouse positioning is enabled and cursor momentarily overlap
s
if (this !== relatedTarget[0] &&
(this.options.position.target === 'mouse' && ontoTooltip) ||
(this.options.hide.fixed && (
(/mouse(out|leave|move)/).test(event.type) && (ontoTooltip |
| ontoTarget))
)) {
try {
event.preventDefault();
event.stopImmediatePropagation();
} catch (e) { }

return;
}
// If tooltip has displayed, start hide timer
this.timers.hide = delay.call(this,
function () { this.toggle(FALSE, event); },
this.options.hide.delay,
this
);
}
function inactiveMethod(event) {
if (this.tooltip.hasClass(CLASS_DISABLED) || !this.options.hide.inac
tive) { return FALSE; }
// Clear timer
clearTimeout(this.timers.inactive);
this.timers.inactive = delay.call(this,
function () { this.hide(event); },
this.options.hide.inactive
);
}
function repositionMethod(event) {
if (this.rendered && this.tooltip[0].offsetWidth > 0) { this.reposit
ion(event); }
}
// Store mouse coordinates
PROTOTYPE._storeMouse = function (event) {
(this.mouse = cloneEvent(event)).type = 'mousemove';
};
// Bind events
PROTOTYPE._bind = function (targets, events, method, suffix, context) {
var ns = '.' + this._id + (suffix ? '-' + suffix : '');
events.length && $(targets).bind(
(events.split ? events : events.join(ns + ' ')) + ns,
$.proxy(method, context || this)
);
};
PROTOTYPE._unbind = function (targets, suffix) {
$(targets).unbind('.' + this._id + (suffix ? '-' + suffix : ''));
};
// Apply common event handlers using delegate (avoids excessive .bind ca
lls!)
var ns = '.' + NAMESPACE;
function delegate(selector, events, method) {
$(document.body).delegate(selector,
(events.split ? events : events.join(ns + ' ')) + ns,
function () {
var api = QTIP.api[$.attr(this, ATTR_ID)];
api && !api.disabled && method.apply(api, arguments);
}
);
}

$(function () {
delegate(SELECTOR, ['mouseenter', 'mouseleave'], function (event) {
var state = event.type === 'mouseenter',
tooltip = $(event.currentTarget),
target = $(event.relatedTarget || event.target),
options = this.options;
// On mouseenter...
if (state) {
// Focus the tooltip on mouseenter (z-index stacking)
this.focus(event);
// Clear hide timer on tooltip hover to prevent it from clos
ing
tooltip.hasClass(CLASS_FIXED) && !tooltip.hasClass(CLASS_DIS
ABLED) && clearTimeout(this.timers.hide);
}
//
else {
//
et (if a hide event is
if
t &&

On mouseleave...
Hide when we leave the tooltip and not onto the show targ
set)
(options.position.target === 'mouse' && options.hide.even
options.show.target && !target.closest(options.show.targ

et[0]).length) {
this.hide(event);
}
}
// Add hover class
tooltip.toggleClass(CLASS_HOVER, state);
});
// Define events which reset the 'inactive' event handler
delegate('[' + ATTR_ID + ']', INACTIVE_EVENTS, inactiveMethod);
});
// Event trigger
PROTOTYPE._trigger = function (type, args, event) {
var callback = $.Event('tooltip' + type);
callback.originalEvent = (event && $.extend({}, event)) || this.cach
e.event || NULL;
this.triggering = type;
this.tooltip.trigger(callback, [this].concat(args || []));
this.triggering = FALSE;
return !callback.isDefaultPrevented();
};
PROTOTYPE._bindEvents = function (showEvents, hideEvents, showTarget, hi
deTarget, showMethod, hideMethod) {
// If hide and show targets are the same...
if (hideTarget.add(showTarget).length === hideTarget.length) {
var toggleEvents = [];
// Filter identical show/hide events
hideEvents = $.map(hideEvents, function (type) {
var showIndex = $.inArray(type, showEvents);

// Both events are identical, remove from both hide and show
events
// and append to toggleEvents
if (showIndex > -1) {
toggleEvents.push(showEvents.splice(showIndex, 1)[0]);
return;
}
return type;
});
// Toggle events are special case of identical show/hide events,
which happen in sequence
toggleEvents.length && this._bind(showTarget, toggleEvents, func
tion (event) {
var state = this.rendered ? this.tooltip[0].offsetWidth > 0
: false;
(state ? hideMethod : showMethod).call(this, event);
});
}
// Apply show/hide/toggle events
this._bind(showTarget, showEvents, showMethod);
this._bind(hideTarget, hideEvents, hideMethod);
};
PROTOTYPE._assignInitialEvents = function (event) {
var options = this.options,
showTarget = options.show.target,
hideTarget = options.hide.target,
showEvents = options.show.event ? $.trim('' + options.show.event
).split(' ') : [],
hideEvents = options.hide.event ? $.trim('' + options.hide.event
).split(' ') : [];
/*
* Make sure hoverIntent functions properly by using mouseleave as a
hide event if
* mouseenter/mouseout is used for show.event, even if it isn't in t
he users options.
*/
if (/mouse(over|enter)/i.test(options.show.event) && !/mouse(out|lea
ve)/i.test(options.hide.event)) {
hideEvents.push('mouseleave');
}
/*
* Also make sure initial mouse targetting works correctly by cachin
g mousemove coords
* on show targets before the tooltip has rendered. Also set onTarge
t when triggered to
* keep mouse tracking working.
*/
this._bind(showTarget, 'mousemove', function (event) {
this._storeMouse(event);
this.cache.onTarget = TRUE;
});
// Define hoverIntent function

function hoverIntent(event) {
// Only continue if tooltip isn't disabled
if (this.disabled || this.destroyed) { return FALSE; }
// Cache the event data
this.cache.event = cloneEvent(event);
this.cache.target = event ? $(event.target) : [undefined];
// Start the event sequence
clearTimeout(this.timers.show);
this.timers.show = delay.call(this,
function () { this.render(typeof event === 'object' || optio
ns.show.ready); },
options.show.delay
);
}
// Filter and bind events
this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, hov
erIntent, function () {
clearTimeout(this.timers.show);
});
// Prerendering is enabled, create tooltip now
if (options.show.ready || options.prerender) { hoverIntent.call(this
, event); }
};
// Event assignment method
PROTOTYPE._assignEvents = function () {
var self = this,
options = this.options,
posOptions = options.position,
tooltip = this.tooltip,
showTarget = options.show.target,
hideTarget = options.hide.target,
containerTarget = posOptions.container,
viewportTarget = posOptions.viewport,
documentTarget = $(document),
bodyTarget = $(document.body),
windowTarget = $(window),
showEvents = options.show.event ? $.trim('' + options.show.event
).split(' ') : [],
hideEvents = options.hide.event ? $.trim('' + options.hide.event
).split(' ') : [];
// Assign passed event callbacks
$.each(options.events, function (name, callback) {
self._bind(tooltip, name === 'toggle' ? ['tooltipshow', 'tooltip
hide'] : ['tooltip' + name], callback, null, tooltip);
});
// Hide tooltips when leaving current window/frame (but not select/o
ption elements)
if (/mouse(out|leave)/i.test(options.hide.event) && options.hide.lea
ve === 'window') {
this._bind(documentTarget, ['mouseout', 'blur'], function (event

) {
if (!/select|option/.test(event.target.nodeName) && !event.r
elatedTarget) {
this.hide(event);
}
});
}
// Enable hide.fixed by adding appropriate class
if (options.hide.fixed) {
hideTarget = hideTarget.add(tooltip.addClass(CLASS_FIXED));
}
/*
* Make sure hoverIntent functions properly by using mouseleave
to clear show timer if
* mouseenter/mouseout is used for show.event, even if it isn't
in the users options.
*/
else if (/mouse(over|enter)/i.test(options.show.event)) {
this._bind(hideTarget, 'mouseleave', function () {
clearTimeout(this.timers.show);
});
}
// Hide tooltip on document mousedown if unfocus events are enabled
if (('' + options.hide.event).indexOf('unfocus') > -1) {
this._bind(containerTarget.closest('html'), ['mousedown', 'touch
start'], function (event) {
var elem = $(event.target),
enabled = this.rendered && !this.tooltip.hasClass(CLASS_
DISABLED) && this.tooltip[0].offsetWidth > 0,
isAncestor = elem.parents(SELECTOR).filter(this.tooltip[
0]).length > 0;
if (elem[0] !== this.target[0] && elem[0] !== this.tooltip[0
] && !isAncestor &&
!this.target.has(elem[0]).length && enabled
) {
this.hide(event);
}
});
}
// Check if the tooltip hides when inactive
if ('number' === typeof options.hide.inactive) {
// Bind inactive method to show target(s) as a custom event
this._bind(showTarget, 'qtip-' + this.id + '-inactive', inactive
Method);
// Define events which reset the 'inactive' event handler
this._bind(hideTarget.add(tooltip), QTIP.inactiveEvents, inactiv
eMethod, '-inactive');
}
// Filter and bind events
this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, sho
wMethod, hideMethod);
// Mouse movement bindings

this._bind(showTarget.add(tooltip), 'mousemove', function (event) {


// Check if the tooltip hides when mouse is moved a certain dist
ance
if ('number' === typeof options.hide.distance) {
var origin = this.cache.origin || {},
limit = this.options.hide.distance,
abs = Math.abs;
// Check if the movement has gone beyond the limit, and hide
it if so
if (abs(event.pageX - origin.pageX) >= limit || abs(event.pa
geY - origin.pageY) >= limit) {
this.hide(event);
}
}
// Cache mousemove coords on show targets
this._storeMouse(event);
});
// Mouse positioning events
if (posOptions.target === 'mouse') {
// If mouse adjustment is on...
if (posOptions.adjust.mouse) {
// Apply a mouseleave event so we don't get problems with ov
erlapping
if (options.hide.event) {
// Track if we're on the target or not
this._bind(showTarget, ['mouseenter', 'mouseleave'], fun
ction (event) {
this.cache.onTarget = event.type === 'mouseenter';
});
}
// Update tooltip position on mousemove
this._bind(documentTarget, 'mousemove', function (event) {
// Update the tooltip position only if the tooltip is vi
sible and adjustment is enabled
if (this.rendered && this.cache.onTarget && !this.toolti
p.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0) {
this.reposition(event);
}
});
}
}
// Adjust positions of the tooltip on window resize if enabled
if (posOptions.adjust.resize || viewportTarget.length) {
this._bind($.event.special.resize ? viewportTarget : windowTarge
t, 'resize', repositionMethod);
}
// Adjust tooltip position on scroll of the window or viewport eleme
nt if present
if (posOptions.adjust.scroll) {
this._bind(windowTarget.add(posOptions.container), 'scroll', rep
ositionMethod);
}
};

// Un-assignment method
PROTOTYPE._unassignEvents = function () {
var targets = [
this.options.show.target[0],
this.options.hide.target[0],
this.rendered && this.tooltip[0],
this.options.position.container[0],
this.options.position.viewport[0],
this.options.position.container.closest('html')[0], // unfocus
window,
document
];
this._unbind($([]).pushStack($.grep(targets, function (i) {
return typeof i === 'object';
})));
};
;// Initialization method
function init(elem, id, opts) {
var obj, posOptions, attr, config, title,
// Setup element references
docBody = $(document.body),
// Use document body instead of document element if needed
newTarget = elem[0] === document ? docBody : elem,
// Grab metadata from element if plugin is present
metadata = (elem.metadata) ? elem.metadata(opts.metadata) : NULL,
// If metadata type if HTML5, grab 'name' from the object instead, o
r use the regular data object otherwise
metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[op
ts.metadata.name] : NULL,
// Grab data from metadata.name (or data-qtipopts as fallback) using
.data() method,
html5 = elem.data(opts.metadata.name || 'qtipopts');
// If we don't get an object returned attempt to parse it manualyl w
ithout parseJSON
try { html5 = typeof html5 === 'string' ? $.parseJSON(html5) : html5
; } catch (e) { }
// Merge in and sanitize metadata
config = $.extend(TRUE, {}, QTIP.defaults, opts,
typeof html5 === 'object' ? sanitizeOptions(html5) : NULL,
sanitizeOptions(metadata5 || metadata));
// Re-grab our positioning options now we've merged our metadata and
set id to passed value
posOptions = config.position;
config.id = id;
// Setup missing content if none is detected
if ('boolean' === typeof config.content.text) {
attr = elem.attr(config.content.attr);
// Grab from supplied attribute if available

if (config.content.attr !== FALSE && attr) { config.content.text


= attr; }
// No valid content was found, abort render
else { return FALSE; }
}
// Setup target options
if (!posOptions.container.length) { posOptions.container = docBody;
}
if (posOptions.target === FALSE) { posOptions.target = newTarget; }
if (config.show.target === FALSE) { config.show.target = newTarget;
}
if (config.show.solo === TRUE) { config.show.solo = posOptions.conta
iner.closest('body'); }
if (config.hide.target === FALSE) { config.hide.target = newTarget;
}
if (config.position.viewport === TRUE) { config.position.viewport =
posOptions.container; }
// Ensure we only use a single container
posOptions.container = posOptions.container.eq(0);
// Convert position corner values into x and y strings
posOptions.at = new CORNER(posOptions.at, TRUE);
posOptions.my = new CORNER(posOptions.my);
// Destroy previous tooltip if overwrite is enabled, or skip element
if not
if (elem.data(NAMESPACE)) {
if (config.overwrite) {
elem.qtip('destroy', true);
}
else if (config.overwrite === FALSE) {
return FALSE;
}
}
// Add has-qtip attribute
elem.attr(ATTR_HAS, id);
// Remove title attribute and store it if present
if (config.suppress && (title = elem.attr('title'))) {
// Final attr call fixes event delegatiom and IE default tooltip
showing problem
elem.removeAttr('title').attr(oldtitle, title).attr('title', '')
;
}
// Initialize the tooltip and add API reference
obj = new QTip(elem, config, id, !!attr);
elem.data(NAMESPACE, obj);
// Catch remove/removeqtip events on target element to destroy redun
dant tooltip
elem.one('remove.qtip-' + id + ' removeqtip.qtip-' + id, function ()
{
var api; if ((api = $(this).data(NAMESPACE))) { api.destroy(true
); }
});

return obj;
}
// jQuery $.fn extension method
QTIP = $.fn.qtip = function (options, notation, newValue) {
var command = ('' + options).toLowerCase(), // Parse command
returned = NULL,
args = $.makeArray(arguments).slice(1),
event = args[args.length - 1],
opts = this[0] ? $.data(this[0], NAMESPACE) : NULL;
// Check for API request
if ((!arguments.length && opts) || command === 'api') {
return opts;
}
// Execute API command if present
else if ('string' === typeof options) {
this.each(function () {
var api = $.data(this, NAMESPACE);
if (!api) { return TRUE; }
// Cache the event if possible
if (event && event.timeStamp) { api.cache.event = event; }
// Check for specific API commands
if (notation && (command === 'option' || command === 'option
s')) {
if (newValue !== undefined || $.isPlainObject(notation))
{
api.set(notation, newValue);
}
else {
returned = api.get(notation);
return FALSE;
}
}
// Execute API command
else if (api[command]) {
api[command].apply(api, args);
}
});
return returned !== NULL ? returned : this;
}
// No API commands. validate provided options and setup qTips
else if ('object' === typeof options || !arguments.length) {
// Sanitize options first
opts = sanitizeOptions($.extend(TRUE, {}, options));
return this.each(function (i) {
var api, id;
// Find next available ID, or use custom ID if provided
id = $.isArray(opts.id) ? opts.id[i] : opts.id;
id = !id || id === FALSE || id.length < 1 || QTIP.api[id] ?
QTIP.nextid++ : id;

// Initialize the qTip and re-grab newly sanitized options


api = init($(this), id, opts);
if (api === FALSE) { return TRUE; }
else { QTIP.api[id] = api; }
// Initialize plugins
$.each(PLUGINS, function () {
if (this.initialize === 'initialize') { this(api); }
});
// Assign initial pre-render events
api._assignInitialEvents(event);
});
}
};
// Expose class
$.qtip = QTip;
// Populated in render method
QTIP.api = {};
; $.each({
/* Allow other plugins to successfully retrieve the title of an elem
ent with a qTip applied */
attr: function (attr, val) {
if (this.length) {
var self = this[0],
title = 'title',
api = $.data(self, 'qtip');
if (attr === title && api && 'object' === typeof api && api.
options.suppress) {
if (arguments.length < 2) {
return $.attr(self, oldtitle);
}
// If qTip is rendered and title was originally used as
content, update it
if (api && api.options.content.attr === title && api.cac
he.attr) {
api.set('content.text', val);
}
// Use the regular attr method to set, then cache the re
sult
return this.attr(oldtitle, val);
}
}
return $.fn['attr' + replaceSuffix].apply(this, arguments);
},
/* Allow clone to correctly retrieve cached title attributes */
clone: function (keepData) {
var titles = $([]), title = 'title',
// Clone our element using the real clone method
elems = $.fn['clone' + replaceSuffix].apply(this, arguments);

// Grab all elements with an oldtitle set, and change it to regu


lar title attribute, if keepData is false
if (!keepData) {
elems.filter('[' + oldtitle + ']').attr('title', function ()
{
return $.attr(this, oldtitle);
})
.removeAttr(oldtitle);
}
return elems;
}
}, function (name, func) {
if (!func || $.fn[name + replaceSuffix]) { return TRUE; }
var old = $.fn[name + replaceSuffix] = $.fn[name];
$.fn[name] = function () {
return func.apply(this, arguments) || old.apply(this, arguments)
;
};
});
/* Fire off 'removeqtip' handler in $.cleanData if jQuery UI not present
(it already does similar).
* This snippet is taken directly from jQuery UI source code found here:
*
http://code.jquery.com/ui/jquery-ui-git.js
*/
if (!$.ui) {
$['cleanData' + replaceSuffix] = $.cleanData;
$.cleanData = function (elems) {
for (var i = 0, elem; (elem = $(elems[i])).length; i++) {
if (elem.attr(ATTR_HAS)) {
try { elem.triggerHandler('removeqtip'); }
catch (e) { }
}
}
$['cleanData' + replaceSuffix].apply(this, arguments);
};
}
;// qTip version
QTIP.version = '@@VERSION';
// Base ID for all qTips
QTIP.nextid = 0;
// Inactive events array
QTIP.inactiveEvents = INACTIVE_EVENTS;
// Base z-index for all qTips
QTIP.zindex = 15000;
// Define configuration defaults
QTIP.defaults = {
prerender: FALSE,
id: FALSE,
overwrite: TRUE,
suppress: TRUE,
content: {
text: TRUE,

attr: 'title',
title: FALSE,
button: FALSE
},
position: {
my: 'top left',
at: 'bottom right',
target: FALSE,
container: FALSE,
viewport: FALSE,
adjust: {
x: 0, y: 0,
mouse: TRUE,
scroll: TRUE,
resize: TRUE,
method: 'flipinvert flipinvert'
},
effect: function (api, pos, viewport) {
$(this).animate(pos, {
duration: 200,
queue: FALSE
});
}
},
show: {
target: FALSE,
event: 'mouseenter',
effect: TRUE,
delay: 90,
solo: FALSE,
ready: FALSE,
autofocus: FALSE
},
hide: {
target: FALSE,
event: 'mouseleave',
effect: TRUE,
delay: 0,
fixed: FALSE,
inactive: FALSE,
leave: 'window',
distance: FALSE
},
style: {
classes: '',
widget: FALSE,
width: FALSE,
height: FALSE,
def: TRUE
},
events: {
render: NULL,
move: NULL,
show: NULL,
hide: NULL,
toggle: NULL,
visible: NULL,
hidden: NULL,
focus: NULL,
blur: NULL

}
};
; var TIP,
// .bind()/.on() namespace
TIPNS = '.qtip-tip',
// Common CSS strings
MARGIN = 'margin',
BORDER = 'border',
COLOR = 'color',
BG_COLOR = 'background-color',
TRANSPARENT = 'transparent',
IMPORTANT = ' !important',
// Check if the browser supports <canvas/> elements
HASCANVAS = !!document.createElement('canvas').getContext,
// Invalid colour values used in parseColours()
INVALID = /rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i;
// Camel-case method, taken from jQuery source
// http://code.jquery.com/jquery-1.8.0.js
function camel(s) { return s.charAt(0).toUpperCase() + s.slice(1); }
/*
* Modified from Modernizr's testPropsAll()
* http://modernizr.com/downloads/modernizr-latest.js
*/
var cssProps = {}, cssPrefixes = ["Webkit", "O", "Moz", "ms"];
function vendorCss(elem, prop) {
var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
props = (prop + ' ' + cssPrefixes.join(ucProp + ' ') + ucProp).s
plit(' '),
cur, val, i = 0;
// If the property has already been mapped...
if (cssProps[prop]) { return elem.css(cssProps[prop]); }
while ((cur = props[i++])) {
if ((val = elem.css(cur)) !== undefined) {
return cssProps[prop] = cur, val;
}
}
}
// Parse a given elements CSS property into an int
function intCss(elem, prop) {
return Math.ceil(parseFloat(vendorCss(elem, prop)));
}
// VML creation (for IE only)
if (!HASCANVAS) {
var createVML = function (tag, props, style) {
return '<qtipvml:' + tag + ' xmlns="urn:schemas-microsoft.com:vm
l" class="qtip-vml" ' + (props || '') +
' style="behavior: url(#default#VML); ' + (style || '') + '"
/>';

};
}
// Canvas only definitions
else {
var PIXEL_RATIO = window.devicePixelRatio || 1,
BACKING_STORE_RATIO = (function () {
var context = document.createElement('canvas').getContext('2
d');
return context.backingStorePixelRatio || context.webkitBacki
ngStorePixelRatio || context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio || context.oBacking
StorePixelRatio || 1;
}()),
SCALE = PIXEL_RATIO / BACKING_STORE_RATIO;
}
function Tip(qtip, options) {
this._ns = 'tip';
this.options = options;
this.offset = options.offset;
this.size = [options.width, options.height];
// Initialize
this.init((this.qtip = qtip));
}
$.extend(Tip.prototype, {
init: function (qtip) {
var context, tip;
// Create tip element and prepend to the tooltip
tip = this.element = qtip.elements.tip = $('<div />', { 'class':
NAMESPACE + '-tip' }).prependTo(qtip.tooltip);
// Create tip drawing element(s)
if (HASCANVAS) {
// save() as soon as we create the canvas element so FF2 doe
sn't bork on our first restore()!
context = $('<canvas />').appendTo(this.element)[0].getConte
xt('2d');
// Setup constant parameters
context.lineJoin = 'miter';
context.miterLimit = 100000;
context.save();
}
else {
context = createVML('shape', 'coordorigin="0,0"', 'position:
absolute;');
this.element.html(context + context);
// Prevent mousing down on the tip since it causes problems
with .live() handling in IE due to VML
qtip._bind($('*', tip).add(tip), ['click', 'mousedown'], fun
ction (event) { event.stopPropagation(); }, this._ns);
}
// Bind update events

qtip._bind(qtip.tooltip, 'tooltipmove', this.reposition, this._n


s, this);
// Create it
this.create();
},
_swapDimensions: function () {
this.size[0] = this.options.height;
this.size[1] = this.options.width;
},
_resetDimensions: function () {
this.size[0] = this.options.width;
this.size[1] = this.options.height;
},
_useTitle: function (corner) {
var titlebar = this.qtip.elements.titlebar;
return titlebar && (
corner.y === TOP || (corner.y === CENTER && this.element.pos
ition().top + (this.size[1] / 2) + this.options.offset < titlebar.outerHeight(TR
UE))
);
},
_parseCorner: function (corner) {
var my = this.qtip.options.position.my;
// Detect corner and mimic properties
if (corner === FALSE || my === FALSE) {
corner = FALSE;
}
else if (corner === TRUE) {
corner = new CORNER(my.string());
}
else if (!corner.string) {
corner = new CORNER(corner);
corner.fixed = TRUE;
}
return corner;
},
_parseWidth: function (corner, side, use) {
var elements = this.qtip.elements,
prop = BORDER + camel(side) + 'Width';
return (use ? intCss(use, prop) : (
intCss(elements.content, prop) ||
intCss(this._useTitle(corner) && elements.titlebar || elemen
ts.content, prop) ||
intCss(elements.tooltip, prop)
)) || 0;
},
_parseRadius: function (corner) {
var elements = this.qtip.elements,
prop = BORDER + camel(corner.y) + camel(corner.x) + 'Radius'
;

return BROWSER.ie < 9 ? 0 :


intCss(this._useTitle(corner) && elements.titlebar || elemen
ts.content, prop) ||
intCss(elements.tooltip, prop) || 0;
},
_invalidColour: function (elem, prop, compare) {
var val = elem.css(prop);
return !val || (compare && val === elem.css(compare)) || INVALID
.test(val) ? FALSE : val;
},
_parseColours: function (corner) {
var elements = this.qtip.elements,
tip = this.element.css('cssText', ''),
borderSide = BORDER + camel(corner[corner.precedance]) + cam
el(COLOR),
colorElem = this._useTitle(corner) && elements.titlebar || e
lements.content,
css = this._invalidColour, color = [];
// Attempt to detect the background colour from various elements
, left-to-right precedance
color[0] = css(tip, BG_COLOR) || css(colorElem, BG_COLOR) || css
(elements.content, BG_COLOR) ||
css(elements.tooltip, BG_COLOR) || tip.css(BG_COLOR);
// Attempt to detect the correct border side colour from various
elements, left-to-right precedance
color[1] = css(tip, borderSide, COLOR) || css(colorElem, borderS
ide, COLOR) ||
css(elements.content, borderSide, COLOR) || css(elements.too
ltip, borderSide, COLOR) || elements.tooltip.css(borderSide);
// Reset background and border colours
$('*', tip).add(tip).css('cssText', BG_COLOR + ':' + TRANSPARENT
+ IMPORTANT + ';' + BORDER + ':0' + IMPORTANT + ';');
return color;
},
_calculateSize: function (corner) {
var y = corner.precedance === Y,
width = this.options['width'],
height = this.options['height'],
isCenter = corner.abbrev() === 'c',
base = (y ? width : height) * (isCenter ? 0.5 : 1),
pow = Math.pow,
round = Math.round,
bigHyp, ratio, result,
smallHyp = Math.sqrt(pow(base, 2) + pow(height, 2)),
hyp = [(this.border / base) * smallHyp, (this.border / height) *
smallHyp];
hyp[2] = Math.sqrt(pow(hyp[0], 2) - pow(this.border, 2));
hyp[3] = Math.sqrt(pow(hyp[1], 2) - pow(this.border, 2));
bigHyp = smallHyp + hyp[2] + hyp[3] + (isCenter ? 0 : hyp[0]);
ratio = bigHyp / smallHyp;

result = [round(ratio * width), round(ratio * height)];


return y ? result : result.reverse();
},
// Tip coordinates calculator
_calculateTip: function (corner, size, scale) {
scale = scale || 1;
size = size || this.size;
var width = size[0] * scale,
height = size[1] * scale,
width2 = Math.ceil(width / 2), height2 = Math.ceil(height /
2),
// Define tip coordinates in terms of height and width values
tips = {
br: [0, 0, width, height, width, 0],
bl: [0, 0, width, 0, 0, height],
tr: [0, height, width, 0, width, height],
tl: [0, 0, 0, height, width, height],
tc: [0, height, width2, 0, width, height],
bc: [0, 0, width, 0, width2, height],
rc: [0, 0, width, height2, 0, height],
lc: [width, 0, width, height, 0, height2]
};
// Set common side shapes
tips.lt = tips.br; tips.rt = tips.bl;
tips.lb = tips.tr; tips.rb = tips.tl;
return tips[corner.abbrev()];
},
// Tip coordinates drawer (canvas)
_drawCoords: function (context, coords) {
context.beginPath();
context.moveTo(coords[0], coords[1]);
context.lineTo(coords[2], coords[3]);
context.lineTo(coords[4], coords[5]);
context.closePath();
},
create: function () {
// Determine tip corner
var c = this.corner = (HASCANVAS || BROWSER.ie) && this._parseCo
rner(this.options.corner);
// If we have a tip corner...
if ((this.enabled = !!this.corner && this.corner.abbrev() !== 'c
')) {
// Cache it
this.qtip.cache.corner = c.clone();
// Create it
this.update();
}
// Toggle tip element
this.element.toggle(this.enabled);

return this.corner;
},
update: function (corner, position) {
if (!this.enabled) { return this; }
var elements = this.qtip.elements,
tip = this.element,
inner = tip.children(),
options = this.options,
curSize = this.size,
mimic = options.mimic,
round = Math.round,
color, precedance, context,
coords, bigCoords, translate, newSize, border, BACKING_STORE
_RATIO;
// Re-determine tip if not already set
if (!corner) { corner = this.qtip.cache.corner || this.corner; }
// Use corner property if we detect an invalid mimic value
if (mimic === FALSE) { mimic = corner; }
// Otherwise inherit mimic properties from the corner object
as necessary
else {
mimic = new CORNER(mimic);
mimic.precedance = corner.precedance;
if (mimic.x === 'inherit') { mimic.x = corner.x; }
else if (mimic.y === 'inherit') { mimic.y = corner.y; }
else if (mimic.x === mimic.y) {
mimic[corner.precedance] = corner[corner.precedance];
}
}
precedance = mimic.precedance;
// Ensure the tip width.height are relative to the tip position
if (corner.precedance === X) { this._swapDimensions(); }
else { this._resetDimensions(); }
// Update our colours
color = this.color = this._parseColours(corner);
// Detect border width, taking into account colours
if (color[1] !== TRANSPARENT) {
// Grab border width
border = this.border = this._parseWidth(corner, corner[corne
r.precedance]);
// If border width isn't zero, use border color as fill if i
t's not invalid (1.0 style tips)
if (options.border && border < 1 && !INVALID.test(color[1]))
{ color[0] = color[1]; }
// Set border width (use detected border width if options.bo
rder is true)
this.border = border = options.border !== TRUE ? options.bor
der : border;

}
// Border colour was invalid, set border to zero
else { this.border = border = 0; }
// Determine tip size
newSize = this.size = this._calculateSize(corner);
tip.css({
width: newSize[0],
height: newSize[1],
lineHeight: newSize[1] + 'px'
});
// Calculate tip translation
if (corner.precedance === Y) {
translate = [
round(mimic.x === LEFT ? border : mimic.x === RIGHT ? ne
wSize[0] - curSize[0] - border : (newSize[0] - curSize[0]) / 2),
round(mimic.y === TOP ? newSize[1] - curSize[1] : 0)
];
}
else {
translate = [
round(mimic.x === LEFT ? newSize[0] - curSize[0] : 0),
round(mimic.y === TOP ? border : mimic.y === BOTTOM ? ne
wSize[1] - curSize[1] - border : (newSize[1] - curSize[1]) / 2)
];
}
// Canvas drawing implementation
if (HASCANVAS) {
// Grab canvas context and clear/save it
context = inner[0].getContext('2d');
context.restore(); context.save();
context.clearRect(0, 0, 6000, 6000);
// Calculate coordinates
coords = this._calculateTip(mimic, curSize, SCALE);
bigCoords = this._calculateTip(mimic, this.size, SCALE);
// Set the canvas size using calculated size
inner.attr(WIDTH, newSize[0] * SCALE).attr(HEIGHT, newSize[1
] * SCALE);
inner.css(WIDTH, newSize[0]).css(HEIGHT, newSize[1]);
// Draw the outer-stroke tip
this._drawCoords(context, bigCoords);
context.fillStyle = color[1];
context.fill();
// Draw the actual tip
context.translate(translate[0] * SCALE, translate[1] * SCALE
);
this._drawCoords(context, coords);
context.fillStyle = color[0];
context.fill();
}
// VML (IE Proprietary implementation)
else {

// Calculate coordinates
coords = this._calculateTip(mimic);
// Setup coordinates string
coords = 'm' + coords[0] + ',' + coords[1] + ' l' + coords[2
] +
',' + coords[3] + ' ' + coords[4] + ',' + coords[5] + '
xe';
// Setup VML-specific offset for pixel-perfection
translate[2] = border && /^(r|b)/i.test(corner.string()) ?
BROWSER.ie === 8 ? 2 : 1 : 0;
// Set initial CSS
inner.css({
coordsize: (newSize[0] + border) + ' ' + (newSize[1] + b
order),
antialias: '' + (mimic.string().indexOf(CENTER) > -1),
left: translate[0] - (translate[2] * Number(precedance =
== X)),
top: translate[1] - (translate[2] * Number(precedance ==
= Y)),
width: newSize[0] + border,
height: newSize[1] + border
})
.each(function (i) {
var $this = $(this);
// Set shape specific attributes
$this[$this.prop ? 'prop' : 'attr']({
coordsize: (newSize[0] + border) + ' ' + (newSize[1]
+ border),
path: coords,
fillcolor: color[0],
filled: !!i,
stroked: !i
})
.toggle(!!(border || i));
// Check if border is enabled and add stroke element
!i && $this.html(createVML(
'stroke', 'weight="' + (border * 2) + 'px" color="'
+ color[1] + '" miterlimit="1000" joinstyle="miter"'
));
});
}
// Opera bug #357 - Incorrect tip position
// https://github.com/Craga89/qTip2/issues/367
window.opera && setTimeout(function () {
elements.tip.css({
display: 'inline-block',
visibility: 'visible'
});
}, 1);
// Position if needed
if (position !== FALSE) { this.calculate(corner, newSize); }
},

calculate: function (corner, size) {


if (!this.enabled) { return FALSE; }
var self = this,
elements = this.qtip.elements,
tip = this.element,
userOffset = this.options.offset,
isWidget = elements.tooltip.hasClass('ui-widget'),
position = {},
precedance, corners;
// Inherit corner if not provided
corner = corner || this.corner;
precedance = corner.precedance;
// Determine which tip dimension to use for adjustment
size = size || this._calculateSize(corner);
// Setup corners and offset array
corners = [corner.x, corner.y];
if (precedance === X) { corners.reverse(); }
// Calculate tip position
$.each(corners, function (i, side) {
var b, bc, br;
if (side === CENTER) {
b = precedance === Y ? LEFT : TOP;
position[b] = '50%';
position[MARGIN + '-' + b] = -Math.round(size[precedance
=== Y ? 0 : 1] / 2) + userOffset;
}
else {
b = self._parseWidth(corner, side, elements.tooltip);
bc = self._parseWidth(corner, side, elements.content);
br = self._parseRadius(corner);
position[side] = Math.max(-self.border, i ? bc : (userOf
fset + (br > b ? br : -b)));
}
});
// Adjust for tip size
position[corner[precedance]] -= size[precedance === X ? 0 : 1];
// Set and return new position
tip.css({ margin: '', top: '', bottom: '', left: '', right: '' }
).css(position);
return position;
},
reposition: function (event, api, pos, viewport) {
if (!this.enabled) { return; }
var cache = api.cache,
newCorner = this.corner.clone(),
adjust = pos.adjusted,
method = api.options.position.adjust.method.split(' '),
horizontal = method[0],
vertical = method[1] || method[0],

shift = { left: FALSE, top: FALSE, x: 0, y: 0 },


offset, css = {}, props;
function shiftflip(direction, precedance, popposite, side, oppos
ite) {
// Horizontal - Shift or flip method
if (direction === SHIFT && newCorner.precedance === precedan
ce && adjust[side] && newCorner[popposite] !== CENTER) {
newCorner.precedance = newCorner.precedance === X ? Y :
X;
}
else if (direction !== SHIFT && adjust[side]) {
newCorner[precedance] = newCorner[precedance] === CENTER
?
(adjust[side] > 0 ? side : opposite) : (newCorner[pr
ecedance] === side ? opposite : side);
}
}
function shiftonly(xy, side, opposite) {
if (newCorner[xy] === CENTER) {
css[MARGIN + '-' + side] = shift[xy] = offset[MARGIN + '
-' + side] - adjust[side];
}
else {
props = offset[opposite] !== undefined ?
[adjust[side], -offset[side]] : [-adjust[side], offs
et[side]];
if ((shift[xy] = Math.max(props[0], props[1])) > props[0
]) {
pos[side] -= adjust[side];
shift[side] = FALSE;
}
css[offset[opposite] !== undefined ? opposite : side] =
shift[xy];
}
}
// If our tip position isn't fixed e.g. doesn't adjust with view
port...
if (this.corner.fixed !== TRUE) {
// Perform shift/flip adjustments
shiftflip(horizontal, X, Y, LEFT, RIGHT);
shiftflip(vertical, Y, X, TOP, BOTTOM);
// Update and redraw the tip if needed (check cached details
of last drawn tip)
if (newCorner.string() !== cache.corner.string() && (cache.c
ornerTop !== adjust.top || cache.cornerLeft !== adjust.left)) {
this.update(newCorner, FALSE);
}
}
// Setup tip offset properties
offset = this.calculate(newCorner);
// Readjust offset object to make it left/top
if (offset.right !== undefined) { offset.left = -offset.right; }

if (offset.bottom !== undefined) { offset.top = -offset.bottom;


}
offset.user = this.offset;
// Perform shift adjustments
if (shift.left = (horizontal === SHIFT && !!adjust.left)) { shif
tonly(X, LEFT, RIGHT); }
if (shift.top = (vertical === SHIFT && !!adjust.top)) { shiftonl
y(Y, TOP, BOTTOM); }
/*
* If the tip is adjusted in both dimensions, or in a
* direction that would cause it to be anywhere but the
* outer border, hide it!
*/
this.element.css(css).toggle(
!((shift.x && shift.y) || (newCorner.x === CENTER && shift.y
) || (newCorner.y === CENTER && shift.x))
);
// Adjust position to accomodate tip dimensions
pos.left -= offset.left.charAt ? offset.user :
horizontal !== SHIFT || shift.top || !shift.left && !shift.t
op ? offset.left + this.border : 0;
pos.top -= offset.top.charAt ? offset.user :
vertical !== SHIFT || shift.left || !shift.left && !shift.to
p ? offset.top + this.border : 0;
// Cache details
cache.cornerLeft = adjust.left; cache.cornerTop = adjust.top;
cache.corner = newCorner.clone();
},
destroy: function () {
// Unbind events
this.qtip._unbind(this.qtip.tooltip, this._ns);
// Remove the tip element(s)
if (this.qtip.elements.tip) {
this.qtip.elements.tip.find('*')
.remove().end().remove();
}
}
});
TIP = PLUGINS.tip = function (api) {
return new Tip(api, api.options.style.tip);
};
// Initialize tip on render
TIP.initialize = 'render';
// Setup plugin sanitization options
TIP.sanitize = function (options) {
if (options.style && 'tip' in options.style) {
var opts = options.style.tip;
if (typeof opts !== 'object') { opts = options.style.tip = { cor
ner: opts }; }
if (!(/string|boolean/i).test(typeof opts.corner)) { opts.corner
= TRUE; }

}
};
// Add new option checks for the plugin
CHECKS.tip = {
'^position.my|style.tip.(corner|mimic|border)$': function () {
// Make sure a tip can be drawn
this.create();
// Reposition the tooltip
this.qtip.reposition();
},
'^style.tip.(height|width)$': function (obj) {
// Re-set dimensions and redraw the tip
this.size = [obj.width, obj.height];
this.update();
// Reposition the tooltip
this.qtip.reposition();
},
'^content.title|style.(classes|widget)$': function () {
this.update();
}
};
// Extend original qTip defaults
$.extend(TRUE, QTIP.defaults, {
style: {
tip: {
corner: TRUE,
mimic: FALSE,
width: 6,
height: 6,
border: TRUE,
offset: 0
}
}
});
; var MODAL, OVERLAY,
MODALCLASS = 'qtip-modal',
MODALSELECTOR = '.' + MODALCLASS;
OVERLAY = function () {
var self = this,
focusableElems = {},
current, onLast,
prevState, elem;
// Modified code from jQuery UI 1.10.0 source
// http://code.jquery.com/ui/1.10.0/jquery-ui.js
function focusable(element) {
// Use the defined focusable checker when possible
if ($.expr[':'].focusable) { return $.expr[':'].focusable; }
var isTabIndexNotNaN = !isNaN($.attr(element, 'tabindex')),
nodeName = element.nodeName && element.nodeName.toLowerCase(
),
map, mapName, img;

if ('area' === nodeName) {


map = element.parentNode;
mapName = map.name;
if (!element.href || !mapName || map.nodeName.toLowerCase()
!== 'map') {
return false;
}
img = $('img[usemap=#' + mapName + ']')[0];
return !!img && img.is(':visible');
}
return (/input|select|textarea|button|object/.test(nodeName) ?
!element.disabled :
'a' === nodeName ?
element.href || isTabIndexNotNaN :
isTabIndexNotNaN
);
}
// Focus inputs using cached focusable elements (see update())
function focusInputs(blurElems) {
// Blurring body element in IE causes window.open windows to unf
ocus!
if (focusableElems.length < 1 && blurElems.length) { blurElems.n
ot('body').blur(); }
// Focus the inputs
else { focusableElems.first().focus(); }
}
// Steal focus from elements outside tooltip
function stealFocus(event) {
if (!elem.is(':visible')) { return; }
var target = $(event.target),
tooltip = current.tooltip,
container = target.closest(SELECTOR),
targetOnTop;
// Determine if input container target is above this
targetOnTop = container.length < 1 ? FALSE :
(parseInt(container[0].style.zIndex, 10) > parseInt(tooltip[
0].style.zIndex, 10));
// If we're showing a modal, but focus has landed on an input be
low
// this modal, divert focus to the first visible input in this m
odal
// or if we can't find one... the tooltip itself
if (!targetOnTop && target.closest(SELECTOR)[0] !== tooltip[0])
{
focusInputs(target);
}
// Detect when we leave the last focusable element...
onLast = event.target === focusableElems[focusableElems.length 1];
}
$.extend(self, {
init: function () {

// Create document overlay


elem = self.elem = $('<div />', {
id: 'qtip-overlay',
html: '<div></div>',
mousedown: function () { return FALSE; }
})
.hide();
// Make sure we can't focus anything outside the tooltip
$(document.body).bind('focusin' + MODALSELECTOR, stealFocus)
;
// Apply keyboard "Escape key" close handler
$(document).bind('keydown' + MODALSELECTOR, function (event)
{
if (current && current.options.show.modal.escape && even
t.keyCode === 27) {
current.hide(event);
}
});
// Apply click handler for blur option
elem.bind('click' + MODALSELECTOR, function (event) {
if (current && current.options.show.modal.blur) {
current.hide(event);
}
});
return self;
},
update: function (api) {
// Update current API reference
current = api;
// Update focusable elements if enabled
if (api.options.show.modal.stealfocus !== FALSE) {
focusableElems = api.tooltip.find('*').filter(function (
) {
return focusable(this);
});
}
else { focusableElems = []; }
},
toggle: function (api, state, duration) {
var docBody = $(document.body),
tooltip = api.tooltip,
options = api.options.show.modal,
effect = options.effect,
type = state ? 'show' : 'hide',
visible = elem.is(':visible'),
visibleModals = $(MODALSELECTOR).filter(':visible:not(:a
nimated)').not(tooltip),
zindex;
// Set active tooltip API reference
self.update(api);
// If the modal can steal the focus...

// Blur the current item and focus anything in the modal we


an
if (state && options.stealfocus !== FALSE) {
focusInputs($(':focus'));
}
// Toggle backdrop cursor style on show
elem.toggleClass('blurs', options.blur);
// Append to body on show
if (state) {
elem.appendTo(document.body);
}
// Prevent modal from conflicting with show.solo, and don't
hide backdrop is other modals are visible
if ((elem.is(':animated') && visible === state && prevState
!== FALSE) || (!state && visibleModals.length)) {
return self;
}
// Stop all animations
elem.stop(TRUE, FALSE);
// Use custom function if provided
if ($.isFunction(effect)) {
effect.call(elem, state);
}
// If no effect type is supplied, use a simple toggle
else if (effect === FALSE) {
elem[type]();
}
// Use basic fade function
else {
elem.fadeTo(parseInt(duration, 10) || 90, state ? 1 : 0,
function () {
if (!state) { elem.hide(); }
});
}
// Reset position and detach from body on hide
if (!state) {
elem.queue(function (next) {
elem.css({ left: '', top: '' });
if (!$(MODALSELECTOR).length) { elem.detach(); }
next();
});
}
// Cache the state
prevState = state;
// If the tooltip is destroyed, set reference to null
if (current.destroyed) { current = NULL; }
return self;
}
});

self.init();
};
OVERLAY = new OVERLAY();
function Modal(api, options) {
this.options = options;
this._ns = '-modal';
this.init((this.qtip = api));
}
$.extend(Modal.prototype, {
init: function (qtip) {
var tooltip = qtip.tooltip;
// If modal is disabled... return
if (!this.options.on) { return this; }
// Set overlay reference
qtip.elements.overlay = OVERLAY.elem;
// Add unique attribute so we can grab modal tooltips easily via
a SELECTOR, and set z-index
tooltip.addClass(MODALCLASS).css('z-index', QTIP.modal_zindex +
$(MODALSELECTOR).length);
// Apply our show/hide/focus modal events
qtip._bind(tooltip, ['tooltipshow', 'tooltiphide'], function (ev
ent, api, duration) {
var oEvent = event.originalEvent;
// Make sure mouseout doesn't trigger a hide when showing th
e modal and mousing onto backdrop
if (event.target === tooltip[0]) {
if (oEvent && event.type === 'tooltiphide' && /mouse(lea
ve|enter)/.test(oEvent.type) && $(oEvent.relatedTarget).closest(OVERLAY.elem[0])
.length) {
try { event.preventDefault(); } catch (e) { }
}
else if (!oEvent || (oEvent && oEvent.type !== 'tooltips
olo')) {
this.toggle(event, event.type === 'tooltipshow', dur
ation);
}
}
}, this._ns, this);
// Adjust modal z-index on tooltip focus
qtip._bind(tooltip, 'tooltipfocus', function (event, api) {
// If focus was cancelled before it reached us, don't do any
thing
if (event.isDefaultPrevented() || event.target !== tooltip[0
]) { return; }
var qtips = $(MODALSELECTOR),
// Keep the modal's lower than other, regular qtips
newIndex = QTIP.modal_zindex + qtips.length,
curIndex = parseInt(tooltip[0].style.zIndex, 10);

// Set overlay z-index


OVERLAY.elem[0].style.zIndex = newIndex - 1;
// Reduce modal z-index's and keep them properly ordered
qtips.each(function () {
if (this.style.zIndex > curIndex) {
this.style.zIndex -= 1;
}
});
// Fire blur event for focused tooltip
qtips.filter('.' + CLASS_FOCUS).qtip('blur', event.originalE
vent);
// Set the new z-index
tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex;
// Set current
OVERLAY.update(api);
// Prevent default handling
try { event.preventDefault(); } catch (e) { }
}, this._ns, this);
// Focus any other visible modals when this one hides
qtip._bind(tooltip, 'tooltiphide', function (event) {
if (event.target === tooltip[0]) {
$(MODALSELECTOR).filter(':visible').not(tooltip).last().
qtip('focus', event);
}
}, this._ns, this);
},
toggle: function (event, state, duration) {
// Make sure default event hasn't been prevented
if (event && event.isDefaultPrevented()) { return this; }
// Toggle it
OVERLAY.toggle(this.qtip, !!state, duration);
},
destroy: function () {
// Remove modal class
this.qtip.tooltip.removeClass(MODALCLASS);
// Remove bound events
this.qtip._unbind(this.qtip.tooltip, this._ns);
// Delete element reference
OVERLAY.toggle(this.qtip, FALSE);
delete this.qtip.elements.overlay;
}
});
MODAL = PLUGINS.modal = function (api) {
return new Modal(api, api.options.show.modal);
};

// Setup sanitiztion rules


MODAL.sanitize = function (opts) {
if (opts.show) {
if (typeof opts.show.modal !== 'object') { opts.show.modal = { o
n: !!opts.show.modal }; }
else if (typeof opts.show.modal.on === 'undefined') { opts.show.
modal.on = TRUE; }
}
};
// Base z-index for all modal tooltips (use qTip core z-index as a base)
QTIP.modal_zindex = QTIP.zindex - 200;
// Plugin needs to be initialized on render
MODAL.initialize = 'render';
// Setup option set checks
CHECKS.modal = {
'^show.modal.(on|blur)$': function () {
// Initialise
this.destroy();
this.init();
// Show the modal if not visible already and tooltip is visible
this.qtip.elems.overlay.toggle(
this.qtip.tooltip[0].offsetWidth > 0
);
}
};
// Extend original api defaults
$.extend(TRUE, QTIP.defaults, {
show: {
modal: {
on: FALSE,
effect: TRUE,
blur: TRUE,
stealfocus: TRUE,
escape: TRUE
}
}
});
; PLUGINS.viewport = function (api, position, posOptions, targetWidth, t
argetHeight, elemWidth, elemHeight) {
var target = posOptions.target,
tooltip = api.elements.tooltip,
my = posOptions.my,
at = posOptions.at,
adjust = posOptions.adjust,
method = adjust.method.split(' '),
methodX = method[0],
methodY = method[1] || method[0],
viewport = posOptions.viewport,
container = posOptions.container,
cache = api.cache,
adjusted = { left: 0, top: 0 },
fixed, newMy, newClass, containerOffset, containerStatic,
viewportWidth, viewportHeight, viewportScroll, viewportOffset;
// If viewport is not a jQuery element, or it's the window/document,

or no adjustment method is used... return


if (!viewport.jquery || target[0] === window || target[0] === docume
nt.body || adjust.method === 'none') {
return adjusted;
}
// Cach container details
containerOffset = container.offset() || adjusted;
containerStatic = container.css('position') === 'static';
// Cache our viewport details
fixed = tooltip.css('position') === 'fixed';
viewportWidth = viewport[0] === window ? viewport.width() : viewport
.outerWidth(FALSE);
viewportHeight = viewport[0] === window ? viewport.height() : viewpo
rt.outerHeight(FALSE);
viewportScroll = { left: fixed ? 0 : viewport.scrollLeft(), top: fix
ed ? 0 : viewport.scrollTop() };
viewportOffset = viewport.offset() || adjusted;
// Generic calculation method
function calculate(side, otherSide, type, adjust, side1, side2, leng
thName, targetLength, elemLength) {
var initialPos = position[side1],
mySide = my[side],
atSide = at[side],
isShift = type === SHIFT,
myLength = mySide === side1 ? elemLength : mySide === side2
? -elemLength : -elemLength / 2,
atLength = atSide === side1 ? targetLength : atSide === side
2 ? -targetLength : -targetLength / 2,
sideOffset = viewportScroll[side1] + viewportOffset[side1] (containerStatic ? 0 : containerOffset[side1]),
overflow1 = sideOffset - initialPos,
overflow2 = initialPos + elemLength - (lengthName === WIDTH
? viewportWidth : viewportHeight) - sideOffset,
offset = myLength - (my.precedance === side || mySide === my
[otherSide] ? atLength : 0) - (atSide === CENTER ? targetLength / 2 : 0);
// shift
if (isShift) {
offset = (mySide === side1 ? 1 : -1) * myLength;
// Adjust position but keep it within viewport dimensions
position[side1] += overflow1 > 0 ? overflow1 : overflow2 > 0
? -overflow2 : 0;
position[side1] = Math.max(
-containerOffset[side1] + viewportOffset[side1],
initialPos - offset,
Math.min(
Math.max(
-containerOffset[side1] + viewportOffset[side1]
+ (lengthName === WIDTH ? viewportWidth : viewportHeight),
initialPos + offset
),
position[side1],
// Make sure we don't adjust complete off the elemen
t when using 'center'
mySide === 'center' ? initialPos - myLength : 1E9

)
);
}
// flip/flipinvert
else {
// Update adjustment amount depending on if using flipinvert
or flip
adjust *= (type === FLIPINVERT ? 2 : 0);
// Check for overflow on the left/top
if (overflow1 > 0 && (mySide !== side1 || overflow2 > 0)) {
position[side1] -= offset + adjust;
newMy.invert(side, side1);
}
// Check for overflow on the bottom/right
else if (overflow2 > 0 && (mySide !== side2 || overflow1 > 0
)) {
position[side1] -= (mySide === CENTER ? -offset : offset
) + adjust;
newMy.invert(side, side2);
}
// Make sure we haven't made things worse with the adjustmen
t and reset if so
if (position[side1] < viewportScroll && -position[side1] > o
verflow2) {
position[side1] = initialPos; newMy = my.clone();
}
}
return position[side1] - initialPos;
}
// Set newMy if using flip or flipinvert methods
if (methodX !== 'shift' || methodY !== 'shift') { newMy = my.clone()
; }
// Adjust position based onviewport and adjustment options
adjusted = {
left: methodX !== 'none' ? calculate(X, Y, methodX, adjust.x, LE
FT, RIGHT, WIDTH, targetWidth, elemWidth) : 0,
top: methodY !== 'none' ? calculate(Y, X, methodY, adjust.y, TOP
, BOTTOM, HEIGHT, targetHeight, elemHeight) : 0
};
// Set tooltip position class if it's changed
if (newMy && cache.lastClass !== (newClass = NAMESPACE + '-pos-' + n
ewMy.abbrev())) {
tooltip.removeClass(api.cache.lastClass).addClass((api.cache.las
tClass = newClass));
}
return adjusted;
};
; PLUGINS.polys = {
// POLY area coordinate calculator
// Special thanks to Ed Cradock for helping out with this.

// Uses a binary search algorithm to find suitable coordinates.


polygon: function (baseCoords, corner) {
var result = {
width: 0, height: 0,
position: {
top: 1e10, right: 0,
bottom: 0, left: 1e10
},
adjustable: FALSE
},
i = 0, next,
coords = [],
compareX = 1, compareY = 1,
realX = 0, realY = 0,
newWidth, newHeight;
// First pass, sanitize coords and determine outer edges
i = baseCoords.length; while (i--) {
next = [parseInt(baseCoords[--i], 10), parseInt(baseCoords[i
+ 1], 10)];
if (next[0] > result.position.right) { result.position.right
= next[0]; }
if (next[0] < result.position.left) { result.position.left =
next[0]; }
if (next[1] > result.position.bottom) { result.position.bott
om = next[1]; }
if (next[1] < result.position.top) { result.position.top = n
ext[1]; }
coords.push(next);
}
// Calculate height and width from outer edges
newWidth = result.width = Math.abs(result.position.right - resul
t.position.left);
newHeight = result.height = Math.abs(result.position.bottom - re
sult.position.top);
// If it's the center corner...
if (corner.abbrev() === 'c') {
result.position = {
left: result.position.left + (result.width / 2),
top: result.position.top + (result.height / 2)
};
}
else {
// Second pass, use a binary search algorithm to locate most
suitable coordinate
while (newWidth > 0 && newHeight > 0 && compareX > 0 && comp
areY > 0) {
newWidth = Math.floor(newWidth / 2);
newHeight = Math.floor(newHeight / 2);
if (corner.x === LEFT) { compareX = newWidth; }
else if (corner.x === RIGHT) { compareX = result.width newWidth; }
else { compareX += Math.floor(newWidth / 2); }
if (corner.y === TOP) { compareY = newHeight; }

else if (corner.y === BOTTOM) { compareY = result.height


- newHeight; }
else { compareY += Math.floor(newHeight / 2); }
i = coords.length; while (i--) {
if (coords.length < 2) { break; }
realX = coords[i][0] - result.position.left;
realY = coords[i][1] - result.position.top;
if ((corner.x === LEFT && realX >= compareX) ||
(corner.x === RIGHT && realX <= compareX) ||
(corner.x === CENTER && (realX < compareX || realX >
(result.width - compareX))) ||
(corner.y === TOP && realY >= compareY) ||
(corner.y === BOTTOM && realY <= compareY) ||
(corner.y === CENTER && (realY < compareY || realY >
(result.height - compareY)))) {
coords.splice(i, 1);
}
}
}
result.position = { left: coords[0][0], top: coords[0][1] };
}
return result;
},
rect: function (ax, ay, bx, by) {
return {
width: Math.abs(bx - ax),
height: Math.abs(by - ay),
position: {
left: Math.min(ax, bx),
top: Math.min(ay, by)
}
};
},
_angles: {
tc: 3 / 2, tr: 7 / 4, tl: 5 / 4,
bc: 1 / 2, br: 1 / 4, bl: 3 / 4,
rc: 2, lc: 1, c: 0
},
ellipse: function (cx, cy, rx, ry, corner) {
var c = PLUGINS.polys._angles[corner.abbrev()],
rxc = c === 0 ? 0 : rx * Math.cos(c * Math.PI),
rys = ry * Math.sin(c * Math.PI);
return {
width: (rx * 2) - Math.abs(rxc),
height: (ry * 2) - Math.abs(rys),
position: {
left: cx + rxc,
top: cy + rys
},
adjustable: FALSE
};
},
circle: function (cx, cy, r, corner) {

return PLUGINS.polys.ellipse(cx, cy, r, r, corner);


}
};; PLUGINS.svg = function (api, svg, corner) {
var doc = $(document),
elem = svg[0],
root = $(elem.ownerSVGElement),
xScale = 1, yScale = 1,
complex = true,
rootWidth, rootHeight,
mtx, transformed, viewBox,
len, next, i, points,
result, position, dimensions;
// Ascend the parentNode chain until we find an element with getBBox
()
while (!elem.getBBox) { elem = elem.parentNode; }
if (!elem.getBBox || !elem.parentNode) { return FALSE; }
// Determine dimensions where possible
rootWidth = root.attr('width') || root.width() || parseInt(root.css(
'width'), 10);
rootHeight = root.attr('height') || root.height() || parseInt(root.c
ss('height'), 10);
// Add stroke characteristics to scaling
var strokeWidth2 = (parseInt(svg.css('stroke-width'), 10) || 0) / 2;
if (strokeWidth2) {
xScale += strokeWidth2 / rootWidth;
yScale += strokeWidth2 / rootHeight;
}
// Determine which shape calculation to use
switch (elem.nodeName) {
case 'ellipse':
case 'circle':
result = PLUGINS.polys.ellipse(
elem.cx.baseVal.value,
elem.cy.baseVal.value,
(elem.rx || elem.r).baseVal.value + strokeWidth2,
(elem.ry || elem.r).baseVal.value + strokeWidth2,
corner
);
break;
case 'line':
case 'polygon':
case 'polyline':
// Determine points object (line has none, so mimic using ar
ray)
points = elem.points || [
{ x: elem.x1.baseVal.value, y: elem.y1.baseVal.value },
{ x: elem.x2.baseVal.value, y: elem.y2.baseVal.value }
];
for (result = [], i = -1, len = points.numberOfItems || poin
ts.length; ++i < len;) {
next = points.getItem ? points.getItem(i) : points[i];
result.push.apply(result, [next.x, next.y]);
}

result = PLUGINS.polys.polygon(result, corner);


break;
// Unknown shape or rectangle? Use bounding box
default:
result = elem.getBoundingClientRect();
result = {
width: result.width, height: result.height,
position: {
left: result.left,
top: result.top
}
};
complex = false;
break;
}
// Shortcut assignments
position = result.position;
root = root[0];
// If the shape was complex (i.e. not using bounding box calculation
s)
if (complex) {
// Convert position into a pixel value
if (root.createSVGPoint) {
mtx = elem.getScreenCTM();
points = root.createSVGPoint();
points.x = position.left;
points.y = position.top;
transformed = points.matrixTransform(mtx);
position.left = transformed.x;
position.top = transformed.y;
}
// Calculate viewBox characteristics
if (root.viewBox && (viewBox = root.viewBox.baseVal) && viewBox.
width && viewBox.height) {
xScale *= rootWidth / viewBox.width;
yScale *= rootHeight / viewBox.height;
}
}
// Adjust by scroll offset
position.left += doc.scrollLeft();
position.top += doc.scrollTop();
return result;
};; PLUGINS.imagemap = function (api, area, corner, adjustMethod) {
if (!area.jquery) { area = $(area); }
var shape = area.attr('shape').toLowerCase().replace('poly', 'polygo
n'),
image = $('img[usemap="#' + area.parent('map').attr('name') + '"
]'),
coordsString = $.trim(area.attr('coords')),
coordsArray = coordsString.replace(/,$/, '').split(','),
imageOffset, coords, i, next, result, len;

// If we can't find the image using the map...


if (!image.length) { return FALSE; }
// Pass coordinates string if polygon
if (shape === 'polygon') {
result = PLUGINS.polys.polygon(coordsArray, corner);
}
// Otherwise parse the coordinates and pass them as arguments
else if (PLUGINS.polys[shape]) {
for (i = -1, len = coordsArray.length, coords = []; ++i < len;)
{
coords.push(parseInt(coordsArray[i], 10));
}
result = PLUGINS.polys[shape].apply(
this, coords.concat(corner)
);
}
// If no shapre calculation method was found, return false
else { return FALSE; }
// Make sure we account for padding and borders on the image
imageOffset = image.offset();
imageOffset.left += Math.ceil((image.outerWidth(FALSE) - image.width
()) / 2);
imageOffset.top += Math.ceil((image.outerHeight(FALSE) - image.heigh
t()) / 2);
// Add image position to offset coordinates
result.position.left += imageOffset.left;
result.position.top += imageOffset.top;
return result;
};; var IE6,
/*
* BGIFrame adaption (http://plugins.jquery.com/project/bgiframe)
* Special thanks to Brandon Aaron
*/
BGIFRAME = '<iframe class="qtip-bgiframe" frameborder="0" tabindex="-1"
src="javascript:\'\';" ' +
' style="display:block; position:absolute; z-index:-1; filter:alpha(
opacity=0); ' +
'-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"
;"></iframe>';
function Ie6(api, qtip) {
this._ns = 'ie6';
this.init((this.qtip = api));
}
$.extend(Ie6.prototype, {
_scroll: function () {
var overlay = this.qtip.elements.overlay;
overlay && (overlay[0].style.top = $(window).scrollTop() + 'px')
;
},

init: function (qtip) {


var tooltip = qtip.tooltip,
scroll;
// Create the BGIFrame element if needed
if ($('select, object').length < 1) {
this.bgiframe = qtip.elements.bgiframe = $(BGIFRAME).appendT
o(tooltip);
// Update BGIFrame on tooltip move
qtip._bind(tooltip, 'tooltipmove', this.adjustBGIFrame, this
._ns, this);
}
// redraw() container for width/height calculations
this.redrawContainer = $('<div/>', { id: NAMESPACE + '-rcontaine
r' })
.appendTo(document.body);
// Fixup modal plugin if present too
if (qtip.elements.overlay && qtip.elements.overlay.addClass('qti
pmodal-ie6fix')) {
qtip._bind(window, ['scroll', 'resize'], this._scroll, this.
_ns, this);
qtip._bind(tooltip, ['tooltipshow'], this._scroll, this._ns,
this);
}
// Set dimensions
this.redraw();
},
adjustBGIFrame: function () {
var tooltip = this.qtip.tooltip,
dimensions = {
height: tooltip.outerHeight(FALSE),
width: tooltip.outerWidth(FALSE)
},
plugin = this.qtip.plugins.tip,
tip = this.qtip.elements.tip,
tipAdjust, offset;
// Adjust border offset
offset = parseInt(tooltip.css('borderLeftWidth'), 10) || 0;
offset = { left: -offset, top: -offset };
// Adjust for tips plugin
if (plugin && tip) {
tipAdjust = (plugin.corner.precedance === 'x') ? [WIDTH, LEF
T] : [HEIGHT, TOP];
offset[tipAdjust[1]] -= tip[tipAdjust[0]]();
}
// Update bgiframe
this.bgiframe.css(offset).css(dimensions);
},
// Max/min width simulator function
redraw: function () {
if (this.qtip.rendered < 1 || this.drawing) { return this; }

var tooltip = this.qtip.tooltip,


style = this.qtip.options.style,
container = this.qtip.options.position.container,
perc, width, max, min;
// Set drawing flag
this.qtip.drawing = 1;
// If tooltip has a set height/width, just set it... like a boss
!
if (style.height) { tooltip.css(HEIGHT, style.height); }
if (style.width) { tooltip.css(WIDTH, style.width); }
// Simulate max/min width if not set width present...
else {
// Reset width and add fluid class
tooltip.css(WIDTH, '').appendTo(this.redrawContainer);
// Grab our tooltip width (add 1 if odd so we don't get wrap
ping problems.. huzzah!)
width = tooltip.width();
if (width % 2 < 1) { width += 1; }
// Grab our max/min properties
max = tooltip.css('maxWidth') || '';
min = tooltip.css('minWidth') || '';
// Parse into proper pixel values
perc = (max + min).indexOf('%') > -1 ? container.width() / 1
00 : 0;
max = ((max.indexOf('%') > -1 ? perc : 1) * parseInt(max, 10
)) || width;
min = ((min.indexOf('%') > -1 ? perc : 1) * parseInt(min, 10
)) || 0;
// Determine new dimension size based on max/min/current val
ues
width = max + min ? Math.min(Math.max(width, min), max) : wi
dth;
// Set the newly calculated width and remvoe fluid class
tooltip.css(WIDTH, Math.round(width)).appendTo(container);
}
// Set drawing flag
this.drawing = 0;
return this;
},
destroy: function () {
// Remove iframe
this.bgiframe && this.bgiframe.remove();
// Remove bound events
this.qtip._unbind([window, this.qtip.tooltip], this._ns);
}
});

IE6 = PLUGINS.ie6 = function (api) {


// Proceed only if the browser is IE6
return BROWSER.ie === 6 ? new Ie6(api) : FALSE;
};
IE6.initialize = 'render';
CHECKS.ie6 = {
'^content|style$': function () {
this.redraw();
}
};;
}));
}(window, document));
/**
@file
jquery.diehard_facebooklike.js
@author
Jake Rutter, William Chang
@version
0.1
@date
- Created: 2010-08-30
- Modified: 2011-02-03
.
@note
Prerequisites:
- jQuery http://www.jquery.com/
- Redirect Page Using CMS (Content Management System).
.
References:
- http://code.google.com/p/jquery-one-fblike/
- http://stackoverflow.com/questions/901115/get-querystring-with-jquery
- http://firequery.binaryage.com/
.
*/
//// Widget: Facebook Like
(function ($) {
// Extend chain library.
$.fn.facebookLike = function (optCustoms) {
// Declare options and set default values.
var optDefaults = {
appId: '',
admins: '',
buttonWidth: 450,
buttonHeight: 80,
showfaces: false,
font: 'lucida grande',
layout: 'normal',
action: 'like',
colorscheme: 'light',
fnLoad: null
};
// Merge two options, modifying the first.
var opt = $.extend(optDefaults, optCustoms);
// Required dependencies using Facebook JavaScript SDK.
$('body').append('<div id=\"fb-root\"></div>');

window.fbAsyncInit = function () {
FB.init({
appId: opt.appId,
status: true,
cookie: true,
xfbml: true
});
// Callback on dependencies load.
if (opt.fnLoad) { opt.fnLoad.call(this); }
};
(function () {
var e = document.createElement('script');
e.async = true;
//commented out due to bug on facebook's end
//forcing https resolves the issue
//e.src = document.location.protocol + '//connect.facebook.net/en_US
/all.js';
e.src = 'https://connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
}());
// Iterate and return each selected element back to library's chain.
return this.each(function (_intIndex) {
/** Create query string parameter. */
function _createParam(strKey, strDataCss) {
if (_eleDataRegion == null) { return ''; }
return strKey + '=' + $('> .' + strDataCss, _eleDataRegion).val(
) + '&';
}
/** Parse markup code. */
function _parseMarkup() {
// Get URL.
var strUrl = $(_eleThis).attr('data-url');
var strDataTokens = [];
// Validate data.
if (strUrl == null || strUrl.length <= 0) {
//throw ('Markup code error, missing value in data-url attri
bute of element.');
} else {
strDataTokens = strUrl.split(';');
if (strDataTokens.length >= 1) {
strUrl = strDataTokens[0];
}
}
// Create and append markup code to document.
if ($(this).hasClass('share')) {
$(_eleThis).html('<a name="fb_share" type="icon_link" share_
url="YOUR_URL"></a><script src="http://static.ak.fbcdn.net/connect.php/js/FB.Sha
re" type="text/javascript"></script>');
} else {
$(_eleThis).html('<fb:like send="false" href=\"' + strUrl +
'" width=\"' + opt.buttonWidth + '\" height=\"' + opt.buttonHeight + '\" show_fa
ces=\"' + opt.showfaces + '\" font=\"' + opt.font + '\" layout=\"' + opt.layout
+ '\" action=\"' + opt.action + '\" colorscheme=\"' + opt.colorscheme + '\"/>');
}
}
/** Init widget. */
this.init = function () {

// Parse markup code.


_parseMarkup();
};
// Fields.
var _eleDataRegion = null;
// Procedural.
var _eleThis = this;
_eleThis.init();
});
};
})(jQuery);
/*
* jQuery starRating 1.0
* Adds star rating functionality
*/
; (function ($) {
$.fn.starRating = function (options) {
var options = $.extend(true, {}, $.fn.starRating.options, (typeof option
s == 'undefined') ? {} : options);
var starsTemplate = $('<div class="stars stars-structured stars-current"
/>').bind('click', function (e) {
if ($(e.target).is('a.star')) {
e.preventDefault();
var url = $(this).data('url');
var rating = $(e.target).data('rating');
var params = new Object();
params.name = rating;
$.fn.starRating.setValue.call(this, rating);
options.onSelected.call(this, url, rating);
}
}).bind('mouseover', function (e) {
if ($(e.target).is('a.star')) {
$(this).removeClass('stars-current');
// create referece object for stars
var stars = $('a.star', this);
// add hover class to the current and preceding stars
stars.removeClass('star-hover').filter(function (i) {
return i <= stars.index(e.target);
}).addClass('star-hover');
}
}).bind('mouseleave', function (e) {
$(this).addClass('stars-current').find('a.star-hover').removeClass('
star-hover');
});
this.not('.stars-structured').each(function (i) {
var url = $(this).attr('data-url');
url = typeof url == 'undefined' ? '' : url;
var rating = parseFloat($(this).attr('data-value'));
var max = parseFloat($(this).attr('data-max'));

var readonly = (typeof $(this).attr('data-readonly') != 'undefined')


? true : false;
var stars = starsTemplate.clone(!readonly).data('url', url);
var starTemplate = readonly ? $('<span class="star" />') : $('<a cla
ss="star" href="#" />');
for (i = 1; i <= max; i++) {
starTemplate.clone().text('Give it a ' + i).data('rating', i).ap
pendTo(stars);
}
if (url == '') {
stars.append('<input type="hidden" name="rating" />');
}
stars = $.fn.starRating.setValue.call($(stars), rating);
$(this).replaceWith(stars);
});
return this;
};
$.fn.starRating.setValue = function (rating) {
$('.star', this).removeClass('star-full star-partial').each(function (i)
{
i++;
var starClass = '';
if (i <= rating) {
starClass = 'star-full';
}
else if (i - rating < 1) {
starClass = 'star-partial';
}
$(this).addClass(starClass);
});
$('input[type=hidden][name=rating]', this).val(rating);
return this;
};
$.fn.starRating.options = {
onSelected: function (url, rating) { }
}
})(jQuery);
/*
Uniform v1.7.3
Copyright 2009 Josh Pyles / Pixelmatrix Design LLC
http://pixelmatrixdesign.com
Requires jQuery 1.4 or newer
Much thanks to Thomas Reynolds and Buck Wilson for their help and advice on this

Disabling text selection is made possible by Mathias Bynens <http://mathiasbynen


s.be/>
and his noSelect plugin. <http://github.com/mathiasbynens/noSelect-jQuery-Plugin
>
Also, thanks to David Kaneda and Eugene Bond for their contributions to the plug
in
License:
MIT License - http://www.opensource.org/licenses/mit-license.php
Enjoy!
*/
; (function ($) {
$.uniform = {
options: {
selectClass: 'selector',
radioClass: 'radio',
checkboxClass: 'checker',
fileClass: 'uploader',
filenameClass: 'filename',
fileBtnClass: 'action',
fileDefaultText: 'No file selected',
fileBtnText: 'Choose File',
checkedClass: 'checked',
focusClass: 'focus',
disabledClass: 'disabled',
buttonClass: 'button',
activeClass: 'active',
hoverClass: 'hover',
useID: true,
idPrefix: 'uniform',
resetSelector: false
},
elements: []
};
if ($.browser.msie && $.browser.version < 7) {
$.support.selectOpacity = false;
} else {
$.support.selectOpacity = true;
}
$.fn.uniform = function (options) {
options = $.extend($.uniform.options, options);
var el = this;
//code for specifying a reset button
if (options.resetSelector != false) {
$(options.resetSelector).mouseup(function () {
function resetThis() {
$.uniform.update(el);
}
setTimeout(resetThis, 10);
});
}

function doInput(elem) {
$el = $(elem);
$el.addClass($el.attr("type"));
storeElement(elem);
}
function doTextarea(elem) {
$(elem).addClass("uniform");
storeElement(elem);
}
function doButton(elem) {
$el = elem;
var divTag = $("<div>"),
spanTag = $("<span>");
divTag.addClass(options.buttonClass);
if (options.useID && $el.attr("id") != "") divTag.attr("id", options
.idPrefix + "-" + $el.attr("id"));
var btnText;
if ($el.is("a")) {
btnText = $el.text();
} else if ($el.is("button")) {
btnText = $el.text();
} else if ($el.is(":submit") || $el.is("input[type=button]")) {
btnText = $el.attr("value");
}
if (btnText == "") btnText = "Submit";
spanTag.html(btnText);
$el.hide();
$el.wrap(divTag);
$el.wrap(spanTag);
//redefine variables
divTag = $el.closest("div");
spanTag = $el.closest("span");
if ($el.is(":disabled")) divTag.addClass(options.disabledClass);
divTag.bind({
"mouseenter.uniform": function () {
divTag.addClass(options.hoverClass);
},
"mouseleave.uniform": function () {
divTag.removeClass(options.hoverClass);
},
"mousedown.uniform touchbegin.uniform": function () {
divTag.addClass(options.activeClass);
},
"mouseup.uniform touchend.uniform": function () {
divTag.removeClass(options.activeClass);
},

"click.uniform touchend.uniform": function (e) {


if ($(e.target).is("span") || $(e.target).is("div")) {
if (elem[0].dispatchEvent) {
var ev = document.createEvent('MouseEvents');
ev.initEvent('click', true, true);
elem[0].dispatchEvent(ev);
} else {
elem[0].click();
}
}
}
});
elem.bind({
"focus.uniform": function () {
divTag.addClass(options.focusClass);
},
"blur.uniform": function () {
divTag.removeClass(options.focusClass);
}
});
$.uniform.noSelect(divTag);
storeElement(elem);
}
function doSelect(elem) {
var divTag = $('<div />'),
spanTag = $('<span />');
divTag.addClass(options.selectClass);
if (options.useID && elem.attr("id") != "") {
divTag.attr("id", options.idPrefix + "-" + elem.attr("id"));
}
var selected = elem.find(":selected:first");
if (selected.length == 0) {
selected = elem.find("option:first");
}
spanTag.html(selected.text());
elem.css('opacity', 0);
elem.wrap(divTag);
elem.before(spanTag);
//redefine variables
divTag = elem.parent("div");
spanTag = elem.siblings("span");
elem.bind({
"change.uniform": function () {
spanTag.text(elem.find(":selected").text());
divTag.removeClass(options.activeClass);
},
"focus.uniform": function () {
divTag.addClass(options.focusClass);
},
"blur.uniform": function () {

divTag.removeClass(options.focusClass);
divTag.removeClass(options.activeClass);
},
"mousedown.uniform touchbegin.uniform": function () {
divTag.addClass(options.activeClass);
},
"mouseup.uniform touchend.uniform": function () {
divTag.removeClass(options.activeClass);
},
"click.uniform touchend.uniform": function () {
divTag.removeClass(options.activeClass);
},
"mouseenter.uniform": function () {
divTag.addClass(options.hoverClass);
},
"mouseleave.uniform": function () {
divTag.removeClass(options.hoverClass);
},
"keyup.uniform": function () {
spanTag.text(elem.find(":selected").text());
}
});
//handle disabled state
if ($(elem).attr("disabled")) {
//box is checked by default, check our box
divTag.addClass(options.disabledClass);
}
$.uniform.noSelect(spanTag);
storeElement(elem);
}
function doCheckbox(elem) {
var divTag = $('<div />'),
spanTag = $('<span />');
divTag.addClass(options.checkboxClass);
//assign the id of the element
if (options.useID && elem.attr("id") != "") {
divTag.attr("id", options.idPrefix + "-" + elem.attr("id"));
}
//wrap with the proper elements
$(elem).wrap(divTag);
$(elem).wrap(spanTag);
//redefine variables
spanTag = elem.parent();
divTag = spanTag.parent();
//hide normal input and add focus classes
$(elem)
.css("opacity", 0)
.bind({
"focus.uniform": function () {
divTag.addClass(options.focusClass);

},
"blur.uniform": function () {
divTag.removeClass(options.focusClass);
},
"click.uniform touchend.uniform": function () {
if (!$(elem).attr("checked")) {
//box was just unchecked, uncheck span
spanTag.removeClass(options.checkedClass);
} else {
//box was just checked, check span.
spanTag.addClass(options.checkedClass);
}
},
"mousedown.uniform touchbegin.uniform": function () {
divTag.addClass(options.activeClass);
},
"mouseup.uniform touchend.uniform": function () {
divTag.removeClass(options.activeClass);
},
"mouseenter.uniform": function () {
divTag.addClass(options.hoverClass);
},
"mouseleave.uniform": function () {
divTag.removeClass(options.hoverClass);
}
});
//handle defaults
if ($(elem).attr("checked")) {
//box is checked by default, check our box
spanTag.addClass(options.checkedClass);
}
//handle disabled state
if ($(elem).attr("disabled")) {
//box is checked by default, check our box
divTag.addClass(options.disabledClass);
}
storeElement(elem);
}
function doRadio(elem) {
var divTag = $('<div />'),
spanTag = $('<span />');
divTag.addClass(options.radioClass);
if (options.useID && elem.attr("id") != "") {
divTag.attr("id", options.idPrefix + "-" + elem.attr("id"));
}
//wrap with the proper elements
$(elem).wrap(divTag);
$(elem).wrap(spanTag);
//redefine variables
spanTag = elem.parent();

divTag = spanTag.parent();
//hide normal input and add focus classes
$(elem)
.css("opacity", 0)
.bind({
"focus.uniform": function () {
divTag.addClass(options.focusClass);
},
"blur.uniform": function () {
divTag.removeClass(options.focusClass);
},
"click.uniform touchend.uniform": function () {
if (!$(elem).attr("checked")) {
//box was just unchecked, uncheck span
spanTag.removeClass(options.checkedClass);
} else {
//box was just checked, check span
$("." + options.radioClass + " span." + options.checkedClass +
":has([name='" + $(elem).attr('name') + "'])").removeClass(options.checkedClass
);
spanTag.addClass(options.checkedClass);
}
},
"mousedown.uniform touchend.uniform": function () {
if (!$(elem).is(":disabled")) {
divTag.addClass(options.activeClass);
}
},
"mouseup.uniform touchbegin.uniform": function () {
divTag.removeClass(options.activeClass);
},
"mouseenter.uniform touchend.uniform": function () {
divTag.addClass(options.hoverClass);
},
"mouseleave.uniform": function () {
divTag.removeClass(options.hoverClass);
}
});
//handle defaults
if ($(elem).attr("checked")) {
//box is checked by default, check span
spanTag.addClass(options.checkedClass);
}
//handle disabled state
if ($(elem).attr("disabled")) {
//box is checked by default, check our box
divTag.addClass(options.disabledClass);
}
storeElement(elem);
}
function doFile(elem) {
//sanitize input
var $el = $(elem);
var divTag = $('<div />'),

filenameTag = $('<span>' + options.fileDefaultText + '</span>'),


btnTag = $('<span>' + options.fileBtnText + '</span>');
divTag.addClass(options.fileClass);
filenameTag.addClass(options.filenameClass);
btnTag.addClass(options.fileBtnClass);
if (options.useID && $el.attr("id") != "") {
divTag.attr("id", options.idPrefix + "-" + $el.attr("id"));
}
//wrap with the proper elements
$el.wrap(divTag);
$el.after(btnTag);
$el.after(filenameTag);
//redefine variables
divTag = $el.closest("div");
filenameTag = $el.siblings("." + options.filenameClass);
btnTag = $el.siblings("." + options.fileBtnClass);
//set the size
if (!$el.attr("size")) {
var divWidth = divTag.width();
//$el.css("width", divWidth);
$el.attr("size", divWidth / 10);
}
//actions
var setFilename = function () {
var filename = $el.val();
if (filename === '') {
filename = options.fileDefaultText;
}
else {
filename = filename.split(/[\/\\]+/);
filename = filename[(filename.length - 1)];
}
filenameTag.text(filename);
};
// Account for input saved across refreshes
setFilename();
$el
.css("opacity", 0)
.bind({
"focus.uniform": function () {
divTag.addClass(options.focusClass);
},
"blur.uniform": function () {
divTag.removeClass(options.focusClass);
},
"mousedown.uniform": function () {
if (!$(elem).is(":disabled")) {
divTag.addClass(options.activeClass);
}
},
"mouseup.uniform": function () {
divTag.removeClass(options.activeClass);

},
"mouseenter.uniform": function () {
divTag.addClass(options.hoverClass);
},
"mouseleave.uniform": function () {
divTag.removeClass(options.hoverClass);
}
});
// IE7 doesn't fire onChange until blur or second fire.
if ($.browser.msie) {
// IE considers browser chrome blocking I/O, so it
// suspends tiemouts until after the file has been selected.
$el.bind('click.uniform.ie7', function () {
setTimeout(setFilename, 0);
});
} else {
// All other browsers behave properly
$el.bind('change.uniform', setFilename);
}
//handle defaults
if ($el.attr("disabled")) {
//box is checked by default, check our box
divTag.addClass(options.disabledClass);
}
$.uniform.noSelect(filenameTag);
$.uniform.noSelect(btnTag);
storeElement(elem);
}
$.uniform.restore = function (elem) {
if (elem == undefined) {
elem = $($.uniform.elements);
}
$(elem).each(function () {
if ($(this).is(":checkbox")) {
//unwrap from span and div
$(this).unwrap().unwrap();
} else if ($(this).is("select")) {
//remove sibling span
$(this).siblings("span").remove();
//unwrap parent div
$(this).unwrap();
} else if ($(this).is(":radio")) {
//unwrap from span and div
$(this).unwrap().unwrap();
} else if ($(this).is(":file")) {
//remove sibling spans
$(this).siblings("span").remove();
//unwrap parent div
$(this).unwrap();
} else if ($(this).is("button, :submit, a, input[type='button']"
)) {
//unwrap from span and div
$(this).unwrap().unwrap();
}

//unbind events
$(this).unbind(".uniform");
//reset inline style
$(this).css("opacity", "1");
//remove item from list of uniformed elements
var index = $.inArray($(elem), $.uniform.elements);
$.uniform.elements.splice(index, 1);
});
};
function storeElement(elem) {
//store this element in our global array
elem = $(elem).get();
if (elem.length > 1) {
$.each(elem, function (i, val) {
$.uniform.elements.push(val);
});
} else {
$.uniform.elements.push(elem);
}
}
//noSelect v1.0
$.uniform.noSelect = function (elem) {
function f() {
return false;
};
$(elem).each(function () {
this.onselectstart = this.ondragstart = f; // Webkit & IE
$(this)
.mousedown(f) // Webkit & Opera
.css({ MozUserSelect: 'none' }); // Firefox
});
};
$.uniform.update = function (elem) {
if (elem == undefined) {
elem = $($.uniform.elements);
}
//sanitize input
elem = $(elem);
elem.each(function () {
//do to each item in the selector
//function to reset all classes
var $e = $(this);
if ($e.is("select")) {
//element is a select
var spanTag = $e.siblings("span");
var divTag = $e.parent("div");
divTag.removeClass(options.hoverClass + " " + options.focusC
lass + " " + options.activeClass);
//reset current selected text
spanTag.html($e.find(":selected").text());

if ($e.is(":disabled")) {
divTag.addClass(options.disabledClass);
} else {
divTag.removeClass(options.disabledClass);
}
} else if ($e.is(":checkbox")) {
//element is a checkbox
var spanTag = $e.closest("span");
var divTag = $e.closest("div");
divTag.removeClass(options.hoverClass + " " + options.focusC
lass + " " + options.activeClass);
spanTag.removeClass(options.checkedClass);
if ($e.is(":checked")) {
spanTag.addClass(options.checkedClass);
}
if ($e.is(":disabled")) {
divTag.addClass(options.disabledClass);
} else {
divTag.removeClass(options.disabledClass);
}
} else if ($e.is(":radio")) {
//element is a radio
var spanTag = $e.closest("span");
var divTag = $e.closest("div");
divTag.removeClass(options.hoverClass + " " + options.focusC
lass + " " + options.activeClass);
spanTag.removeClass(options.checkedClass);
if ($e.is(":checked")) {
spanTag.addClass(options.checkedClass);
}
if ($e.is(":disabled")) {
divTag.addClass(options.disabledClass);
} else {
divTag.removeClass(options.disabledClass);
}
} else if ($e.is(":file")) {
var divTag = $e.parent("div");
var filenameTag = $e.siblings(options.filenameClass);
btnTag = $e.siblings(options.fileBtnClass);
divTag.removeClass(options.hoverClass + " " + options.focusC
lass + " " + options.activeClass);
filenameTag.text($e.val());
if ($e.is(":disabled")) {
divTag.addClass(options.disabledClass);
} else {
divTag.removeClass(options.disabledClass);
}
} else if ($e.is(":submit") || $e.is("button") || $e.is("a") ||
elem.is("input[type=button]")) {

var divTag = $e.closest("div");


divTag.removeClass(options.hoverClass + " " + options.focusC
lass + " " + options.activeClass);
if ($e.is(":disabled")) {
divTag.addClass(options.disabledClass);
} else {
divTag.removeClass(options.disabledClass);
}
}
});
};
return this.each(function () {
if ($.support.selectOpacity) {
var elem = $(this);
if (elem.is("select")) {
//element is a select
if (elem.attr("multiple") != true) {
//element is not a multi-select
if (elem.attr("size") == undefined || elem.attr("size")
<= 1) {
doSelect(elem);
}
}
} else if (elem.is(":checkbox")) {
//element is a checkbox
doCheckbox(elem);
} else if (elem.is(":radio")) {
//element is a radio
doRadio(elem);
} else if (elem.is(":file")) {
//element is a file upload
doFile(elem);
} else if (elem.is(":text, :password, input[type='email']")) {
doInput(elem);
} else if (elem.is("textarea")) {
doTextarea(elem);
} else if (elem.is("a") || elem.is(":submit") || elem.is("button
") || elem.is("input[type=button]")) {
doButton(elem);
}
}
});
};
})(jQuery);
; (function ($) {
$.fn.toggleFormGroup = function (disable) {
disable = (typeof disable == 'boolean') ? disable : null;
if (disable == null) {
disable = (this.hasClass('disabled')) ? true : false;
}
if (disable) {
this.addClass('disabled').find(':input').attr('disabled', 'disabled'
);

}
else {
this.removeClass('disabled').find(':input').removeAttr('disabled').f
ilter('.uniformed').removeClass('disabled').parents('.disabled').filter('.select
or, .radio, .checker, .uploader').removeClass('disabled');
}
// fix uniform select boxes in IE
$('div.selector').css('position', 'static').css('position', 'relative');
return this;
}
})(jQuery);
// Declare global variables.
var strFacebookApplicationId = $('body > .data_facebook_application_id').val();
var strUserProfileId = $('body > .data_user_profile_id').val();
if (typeof (window.cms) != "undefined") {
//
/** Init Facebook Like button for Favorite CMS module. */
window.cms.initFacebookLike = function (strSelector) {
if (typeof strSelector === 'undefined' || strSelector == null || strSele
ctor.length <= 0) {
strSelector = '.btn_facebook_like';
}
if (typeof ($(strSelector).facebookLike) != "undefined") {
// Create Facebook like widget.
$(strSelector).facebookLike({
appId: strFacebookApplicationId,
buttonWidth: 100,
buttonHeight: 23,
font: 'arial',
layout: 'button_count',
fnLoad: function () {
FB.Event.subscribe('edge.create', function (strUrl, objEvent
) {
// Get AJAX URL.
var strAjaxUrl = $(objEvent.dom.parentNode).attr('data-u
rl');
var cmsID = $(objEvent.dom.parentNode).attr('cmsid');
AddFavorite(cmsID, strAjaxUrl);
//
if (strAjaxUrl != null) {
//
strTokens = strAjaxUrl.spl
it(';');
//
if (strTokens.length >= 2)
{
//
strAjaxUrl = strTokens
[1];
//
} else {
//
throw ('Markup code er
ror, missing second string token in data-url attribute.');
//
}
//
} else {
//
throw ('Markup code error,
missing value in data-url attribute of element.');
//
}
//
// Get id from URL.
//
var strId = '';
//
var strParams = new RegExp('[\

\?&]' + 'id' + '=([^&#]*)').exec(strUrl);


//
if (strParams != null && strPa
rams.length == 2) {
//
strId = strParams[1];
//
} else { return; }
//
// Set data parameters.
//
var objDataParameters = {
//
userProfileId: strUserProf
ileId,
//
cmsItemId: strId,
//
sourceUrl: window.location
.href,
//
configurationFavorite: win
dow.cms.strConfigurationFavorite
//
};
// Perform AJAX.
//
$.post(strAjaxUrl, objDataPara
meters, function (data, status) {
//
if (status == 'success' &&
data == '0') {
//
} else if (status == 'succ
ess') {
//
// Append markup code.
//
$('#myfavorites_contai
ner').empty().append(data).addWidgets();
//
// Set count view.
//
window.cms.countFavori
tes();
//
} else { throw (status); }
//
});
});
FB.Event.subscribe('edge.remove', function (strUrl, objEvent
) {
// Do something. Reference: http://developers.facebook.c
om/blog/post/446/
});
}
});
}
}
/** Count favorites for gutter region of document. */
window.cms.countFavorites = function () {
// Init.
var eleSource = $('#btn_myfavorites').get(0);
var eleTargets = $('.favorites_count').get();
if (eleSource == null || eleTargets == null || eleTargets.length <= 0) {
return; }
// Get AJAX URL.
var strAjaxUrl = $(eleSource).attr('data-url');
if (strAjaxUrl == null || strAjaxUrl.length <= 0) {
throw ('Markup code error, missing value in data-url attribute of el
ement.');
}
// Set data parameters.
var objDataParameters = {
userProfileId: strUserProfileId

};
// Perform AJAX.
$.post(strAjaxUrl, objDataParameters, function (data, status) {
if (status == 'success' && data == '0') {
} else if (status == 'success') {
$(eleTargets).text(data);
} else { throw (status); }
});
}
/** Reload favorites for gutter region of document. */
window.cms.reloadFavorites = function () {
// Get AJAX URL.
var strAjaxUrl = $('#myfavorites_container').attr('data-reloadurl');
if (strAjaxUrl == null || strAjaxUrl.length <= 0) {
throw ('Markup code error, missing value in data-reloadurl attribute
of element.');
}
// Set data parameters.
var objDataParameters = {
userProfileId: strUserProfileId,
configurationFavorite: window.cms.strConfigurationFavorite
};
// Perform AJAX.
$.post(strAjaxUrl, objDataParameters, function (data, status) {
if (status == 'success' && data == '0') {
} else if (status == 'success') {
// Append markup code.
$('#myfavorites_container').empty().append(data).addWidgets();
// Set count view.
window.cms.countFavorites();
} else { throw (status); }
});
}
/** Reload cart to gutter region of document. */
window.cms.reloadCart = function () {
// Init.
var eleCount = $('#btn_mycart .count').get(0);
var eleBody = $('#mycart_container').empty().get(0);
if (eleCount == null || eleBody == null) { return; }
// Get AJAX URL.
var strAjaxUrl = $(eleBody).attr('data-url');
if (strAjaxUrl == null || strAjaxUrl.length <= 0) {
throw ('Markup code error, missing value in data-url attribute of el
ement.');
}
// Set data parameters.
var objDataParameters = {
configurationCart: window.cms.strConfigurationCart
};
// Perform AJAX.
$.post(strAjaxUrl, objDataParameters, function (data, status) {
if (status == 'success' && data == '0') {
} else if (status == 'success') {
// Append markup code.
var eleList = $(data).appendTo(eleBody);
// Set count view.
$(eleCount).text(data.split("<h3>").length - 1); //count number
of h3 headers instead *

} else { throw (status); }


});
// Continue default action.
return true;
}
// Procedural.
window.cms.initFacebookLike();
}
/**
* Equal Heights Plugin
* Equalize the heights of elements. Great for columns or any elements
* that need to be the same size (floats, etc).
*
* Version 1.0
* Updated 12/10/2008
*
* Copyright (c) 2008 Rob Glazebrook (cssnewbie.com)
*
* Usage: $(object).equalHeights([minHeight], [maxHeight]);
*
* Example 1: $(".cols").equalHeights(); Sets all columns to the same height.
* Example 2: $(".cols").equalHeights(400); Sets all cols to at least 400px tall.
* Example 3: $(".cols").equalHeights(100,300); Cols are at least 100 but no more
* than 300 pixels tall. Elements with too much content will gain a scrollbar.
*
*/
; (function ($) {
$.fn.equalHeights = function (minHeight, maxHeight) {
tallest = (minHeight) ? minHeight : 0;
this.each(function () {
if ($(this).outerHeight(true) > tallest) {
tallest = $(this).outerHeight(true);
}
});
if ((maxHeight) && tallest > maxHeight) {
tallest = maxHeight;
}
return this.each(function () {
var verticalPadding = parseInt($(this).css('padding-top')) + parseIn
t($(this).css('padding-bottom'));
$(this).height(tallest - verticalPadding);
});
}
})(jQuery);
/**
@file
jquery.diehard_aspnetvalidationhighlighter.js
@author
William Chang
@version
0.1
@date
- Created: 2011-02-03
- Modified: 2011-02-08

.
@note
Prerequisites:
- Microsoft ASP.NET Web Forms
- jQuery http://www.jquery.com/
.
References:
- https://developer.mozilla.org/en/DOM/window
- http://codinglifestyle.wordpress.com/2009/09/16/change-background-color-of-inv
alid-controls-asp-net-validator/
.
*/
// Widget: Aspnet Validation Highlighter
(function ($) {
var memberPublic = null;
var _extensionName = 'aspnetValidationHighlighter';
// Declare options and set default values.
var _opt, _optCustoms = null;
var _optDefaults = {
strFieldErrorCss: 'error_field'
};
/* Private Fields
//-------------------------------------------------------------------*/
var _fnAspnetValidatorUpdateDisplay = null;
/* Public Methods
//-------------------------------------------------------------------*/
/** Extend core library. */
memberPublic = $[_extensionName] = function (optCustoms) {
// Merge two options, modifying the first.
_opt = $.extend({}, _optDefaults, optCustoms);
// Init.
memberPublic.init();
// Return library's object.
return this;
};
/** Init widget. */
memberPublic.init = function () {
// Validate Aspnet function exist in window and document of browser.
if (typeof window !== 'object' || typeof window.document !== 'object' ||
typeof window.ValidatorUpdateDisplay !== 'function') {
return;
}
// Declare reference variable to Aspnet function.
_fnAspnetValidatorUpdateDisplay = window.ValidatorUpdateDisplay;
// Override Aspnet function.
window.ValidatorUpdateDisplay = memberPublic.runValidatorUpdateDisplay;
// Validate Aspnet variable exist.
if (typeof Page_IsValid === 'boolean') {
if (Page_IsValid == false && Page_Validators !== 'undefined') {
for (var i = 0; i < Page_Validators.length; i += 1) {
// Validate Aspnet form fields on page load.
memberPublic.validateFormField(document.getElementById(Page_
Validators[i].controltovalidate));
}

}
}
};
/** Get options. */
memberPublic.getOptions = function () {
return _opt;
};
/** Run alternative of Aspnet function. */
memberPublic.runValidatorUpdateDisplay = function (eleValidator) {
if (typeof _fnAspnetValidatorUpdateDisplay === 'function') {
_fnAspnetValidatorUpdateDisplay(eleValidator);
}
memberPublic.validateFormField(document.getElementById(eleValidator.cont
roltovalidate));
};
/** Validate form field. */
memberPublic.validateFormField = function (eleField) {
var boolIsAllValid = true;
for (var i = 0; i < eleField.Validators.length; i += 1) {
if (!eleField.Validators[i].isvalid) {
boolIsAllValid = false;
break;
}
}
$(eleField).toggleClass(_optDefaults.strFieldErrorCss, !boolIsAllValid);
};
/* Chainability
//-------------------------------------------------------------------*/
/** Extend chain library. */
$.fn[_extensionName] = function (optCustoms) {
// Merge two options, modifying the first.
_opt = $.extend({}, _optDefaults, optCustoms);
// Iterate and return each selected element back to library's chain.
return this.each(function (_intIndex) {
/** Init widget. */
this.init = function () {
// Do something.
};
// Procedural.
var _eleThis = this;
_eleThis.init();
});
};
})(jQuery);
/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
* Dual licensed under the MIT (MIT_LICENSE.txt)
* and GPL Version 2 (GPL_LICENSE.txt) licenses.
*
* Version: 1.1.1
* Requires jQuery 1.3+
* Docs: http://docs.jquery.com/Plugins/livequery
*/
(function ($) {
$.extend($.fn, {

livequery: function (type, fn, fn2) {


var self = this, q;
// Handle different call patterns
if ($.isFunction(type))
fn2 = fn, fn = type, type = undefined;
// See if Live Query already exists
$.each($.livequery.queries, function (i, query) {
if (self.selector == query.selector && self.context == query.con
text &&
type == query.type && (!fn || fn.$lqguid == quer
y.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid))
// Found the query, exit the each loop
return (q = query) && false;
});
// Create new Live Query if it wasn't found
q = q || new $.livequery(this.selector, this.context, type, fn, fn2)
;
// Make sure it is running
q.stopped = false;
// Run it immediately for the first time
q.run();
// Contnue the chain
return this;
},
expire: function (type, fn, fn2) {
var self = this;
// Handle different call patterns
if ($.isFunction(type))
fn2 = fn, fn = type, type = undefined;
// Find the Live Query based on arguments and stop it
$.each($.livequery.queries, function (i, query) {
if (self.selector == query.selector && self.context == query.con
text &&
(!type || type == query.type) && (!fn || fn.$lqg
uid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) && !this.
stopped)
$.livequery.stop(query.id);
});
// Continue the chain
return this;
}
});
$.livequery = function (selector, context, type, fn, fn2) {
this.selector = selector;
this.context = context;
this.type = type;
this.fn = fn;
this.fn2 = fn2;
this.elements = [];

this.stopped = false;
// The id is the index of the Live Query in $.livequery.queries
this.id = $.livequery.queries.push(this) - 1;
// Mark the functions for matching later on
fn.$lqguid = fn.$lqguid || $.livequery.guid++;
if (fn2) fn2.$lqguid = fn2.$lqguid || $.livequery.guid++;
// Return the Live Query
return this;
};
$.livequery.prototype = {
stop: function () {
var query = this;
if (this.type)
// Unbind all bound events
this.elements.unbind(this.type, this.fn);
else if (this.fn2)
// Call the second function for all matched elements
this.elements.each(function (i, el) {
query.fn2.apply(el);
});
// Clear out matched elements
this.elements = [];
// Stop the Live Query from running until restarted
this.stopped = true;
},
run: function () {
// Short-circuit if stopped
if (this.stopped) return;
var query = this;
var oEls = this.elements,
els = $(this.selector, this.context),
nEls = els.not(oEls);
// Set elements to the latest set of matched elements
this.elements = els;
if (this.type) {
// Bind events to newly matched elements
nEls.bind(this.type, this.fn);
// Unbind events to elements no longer matched
if (oEls.length > 0)
$.each(oEls, function (i, el) {
if ($.inArray(el, els) < 0)
$.event.remove(el, query.type, query.fn);
});
}
else {
// Call the first function for newly matched elements
nEls.each(function () {
query.fn.apply(this);

});
// Call the second function for elements no longer matched
if (this.fn2 && oEls.length > 0)
$.each(oEls, function (i, el) {
if ($.inArray(el, els) < 0)
query.fn2.apply(el);
});
}
}
};
$.extend($.livequery, {
guid: 0,
queries: [],
queue: [],
running: false,
timeout: null,
checkQueue: function () {
if ($.livequery.running && $.livequery.queue.length) {
var length = $.livequery.queue.length;
// Run each Live Query currently in the queue
while (length--)
$.livequery.queries[$.livequery.queue.shift()].run();
}
},
pause: function () {
// Don't run anymore Live Queries until restarted
$.livequery.running = false;
},
play: function () {
// Restart Live Queries
$.livequery.running = true;
// Request a run of the Live Queries
$.livequery.run();
},
registerPlugin: function () {
$.each(arguments, function (i, n) {
// Short-circuit if the method doesn't exist
if (!$.fn[n]) return;
// Save a reference to the original method
var old = $.fn[n];
// Create a new method
$.fn[n] = function () {
// Call the original method
var r = old.apply(this, arguments);
// Request a run of the Live Queries
$.livequery.run();
// Return the original methods result
return r;
}
});

},
run: function (id) {
if (id != undefined) {
// Put the particular Live Query in the queue if it doesn't alre
ady exist
if ($.inArray(id, $.livequery.queue) < 0)
$.livequery.queue.push(id);
}
else
// Put each Live Query in the queue if it doesn't already exist
$.each($.livequery.queries, function (id) {
if ($.inArray(id, $.livequery.queue) < 0)
$.livequery.queue.push(id);
});
// Clear timeout if it already exists
if ($.livequery.timeout) clearTimeout($.livequery.timeout);
// Create a timeout to check the queue and actually run the Live Que
ries
$.livequery.timeout = setTimeout($.livequery.checkQueue, 20);
},
stop: function (id) {
if (id != undefined)
// Stop are particular Live Query
$.livequery.queries[id].stop();
else
// Stop all Live Queries
$.each($.livequery.queries, function (id) {
$.livequery.queries[id].stop();
});
}
});
// Register core DOM manipulation methods
$.livequery.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', '
attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove'
, 'html');
// Run Live Queries when the Document is ready
$(function () { $.livequery.play(); });
})(jQuery);
; (function ($) {
// set behavior for external links
$.fn.externalLink = function () {
this.addClass('external').live('click', function (e) {
if ($(this).attr('target') != '_self' && window.location.toString().
indexOf('secure.seaworldparks.com') == -1) {
//Send tracking info to Google Analytics if an external link is
clicked.
var linkHref = $(this).attr('href');
var newUrl = _trackLinkClick(['External Links', linkHref]);
return !window.open(newUrl);
} else {
window.location = this.href;

}
});
return this;
}
})(jQuery);
/*
* jPlayer Plugin for jQuery JavaScript Library
* http://www.happyworm.com/jquery/jplayer
*
* Copyright (c) 2009 - 2010 Happyworm Ltd
* Dual licensed under the MIT and GPL licenses.
* - http://www.opensource.org/licenses/mit-license.php
* - http://www.gnu.org/copyleft/gpl.html
*
* Author: Mark J Panaghiston
* Version: 2.0.0
* Date: 20th December 2010
*/
(function ($, undefined) {
// Adapted from jquery.ui.widget.js (1.8.7): $.widget.bridge
$.fn.jPlayer = function (options) {
var name = "jPlayer";
var isMethodCall = typeof options === "string",
args = Array.prototype.slice.call(arguments, 1),
returnValue = this;
// allow multiple hashes to be passed on init
options = !isMethodCall && args.length ?
$.extend.apply(null, [true, options].concat(args)) :
options;
// prevent calls to internal methods
if (isMethodCall && options.charAt(0) === "_") {
return returnValue;
}
if (isMethodCall) {
this.each(function () {
var instance = $.data(this, name),
methodValue = instance && $.isFunction(i
nstance[options]) ?
instance[options].apply(instance
, args) :
instance;
if (methodValue !== instance && methodValue !== undefined) {
returnValue = methodValue;
return false;
}
});
} else {
this.each(function () {
var instance = $.data(this, name);
if (instance) {
instance.option(options || {})._init(); // Orig jquery.ui.wi
dget.js code: Not recommend for jPlayer. ie., Applying new options to an existin
g instance (via the jPlayer constructor) and performing the _init(). The _init()

is what concerns me. It would leave a lot of event handlers acting on jPlayer i
nstance and the interface.
instance.option(options || {}); // The new constructor only
changes the options. Changing options only has basic support atm.
} else {
$.data(this, name, new $.jPlayer(options, this));
}
});
}
return returnValue;
};
$.jPlayer = function (options, element) {
// allow instantiation without initializing for simple inheritance
if (arguments.length) {
this.element = $(element);
this.options = $.extend(true, {},
this.options,
options
);
var self = this;
this.element.bind("remove.jPlayer", function () {
self.destroy();
});
this._init();
}
};
// End of: (Adapted from jquery.ui.widget.js (1.8.7))
$.jPlayer.event = {
ready: "jPlayer_ready",
resize: "jPlayer_resize", // Not implemented.
error: "jPlayer_error", // Event error code in event.jPlayer.error.type.
See $.jPlayer.error
warning: "jPlayer_warning", // Event warning code in event.jPlayer.warni
ng.type. See $.jPlayer.warning
// Other events match HTML5 spec.
loadstart: "jPlayer_loadstart",
progress: "jPlayer_progress",
suspend: "jPlayer_suspend",
abort: "jPlayer_abort",
emptied: "jPlayer_emptied",
stalled: "jPlayer_stalled",
play: "jPlayer_play",
pause: "jPlayer_pause",
loadedmetadata: "jPlayer_loadedmetadata",
loadeddata: "jPlayer_loadeddata",
waiting: "jPlayer_waiting",
playing: "jPlayer_playing",
canplay: "jPlayer_canplay",
canplaythrough: "jPlayer_canplaythrough",
seeking: "jPlayer_seeking",
seeked: "jPlayer_seeked",
timeupdate: "jPlayer_timeupdate",
ended: "jPlayer_ended",
ratechange: "jPlayer_ratechange",
durationchange: "jPlayer_durationchange",
volumechange: "jPlayer_volumechange"

};
$.jPlayer.htmlEvent = [ // These HTML events are bubbled through to the jPla
yer event, without any internal action.
"loadstart",
// "progress", // jPlayer uses internally before bubbling.
// "suspend", // jPlayer uses internally before bubbling.
"abort",
// "error", // jPlayer uses internally before bubbling.
"emptied",
"stalled",
// "play", // jPlayer uses internally before bubbling.
// "pause", // jPlayer uses internally before bubbling.
"loadedmetadata",
"loadeddata",
// "waiting", // jPlayer uses internally before bubbling.
// "playing", // jPlayer uses internally before bubbling.
// "canplay", // jPlayer fixes the volume (for Chrome) before bubbling.
"canplaythrough",
// "seeking", // jPlayer uses internally before bubbling.
// "seeked", // jPlayer uses internally before bubbling.
// "timeupdate", // jPlayer uses internally before bubbling.
// "ended", // jPlayer uses internally before bubbling.
"ratechange"
// "durationchange" // jPlayer uses internally before bubbling.
// "volumechange" // Handled by jPlayer in volume() method, primarily due to
the volume fix (for Chrome) in the canplay event. [*] Need to review whether th
e latest Chrome still needs the fix sometime.
];
$.jPlayer.pause = function () {
// $.each($.jPlayer.instances, function(i, element) {
$.each($.jPlayer.prototype.instances, function (i, element) {
if (element.data("jPlayer").status.srcSet) { // Check that media is
set otherwise would cause error event.
element.jPlayer("pause");
}
});
};
$.jPlayer.timeFormat = {
showHour: false,
showMin: true,
showSec: true,
padHour: false,
padMin: true,
padSec: true,
sepHour: ":",
sepMin: ":",
sepSec: ""
};
$.jPlayer.convertTime = function (sec) {
var myTime = new Date(sec * 1000);
var hour = myTime.getUTCHours();
var min = myTime.getUTCMinutes();
var sec = myTime.getUTCSeconds();
var strHour = ($.jPlayer.timeFormat.padHour && hour < 10) ? "0" + hour :
hour;
var strMin = ($.jPlayer.timeFormat.padMin && min < 10) ? "0" + min : min

;
var strSec = ($.jPlayer.timeFormat.padSec && sec < 10) ? "0" + sec : sec
;
return (($.jPlayer.timeFormat.showHour) ? strHour + $.jPlayer.timeFormat
.sepHour : "") + (($.jPlayer.timeFormat.showMin) ? strMin + $.jPlayer.timeFormat
.sepMin : "") + (($.jPlayer.timeFormat.showSec) ? strSec + $.jPlayer.timeFormat.
sepSec : "");
};
// Adapting jQuery 1.4.4 code for jQuery.browser. Required since jQuery 1.3.
2 does not detect Chrome as webkit.
$.jPlayer.uaMatch = function (ua) {
var ua = ua.toLowerCase();
// Useragent RegExp
var rwebkit = /(webkit)[ \/]([\w.]+)/;
var ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/;
var rmsie = /(msie) ([\w.]+)/;
var rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/;
var match = rwebkit.exec(ua) ||
ropera.exec(ua) ||
rmsie.exec(ua) ||
ua.indexOf("compatible") < 0 && rmozilla.exec(ua) ||
[];
return { browser: match[1] || "", version: match[2] || "0" };
};
$.jPlayer.browser = {
};
var browserMatch = $.jPlayer.uaMatch(navigator.userAgent);
if (browserMatch.browser) {
$.jPlayer.browser[browserMatch.browser] = true;
$.jPlayer.browser.version = browserMatch.version;
}
$.jPlayer.prototype = {
count: 0, // Static Variable: Change it via prototype.
version: { // Static Object
script: "2.0.0",
needFlash: "2.0.0",
flash: "unknown"
},
options: { // Instanced in $.jPlayer() constructor
swfPath: "js", // Path to Jplayer.swf. Can be relative, absolute or
server root relative.
solution: "html, flash", // Valid solutions: html, flash. Order defi
nes priority. 1st is highest,
supplied: "mp3", // Defines which formats jPlayer will try and suppo
rt and the priority by the order. 1st is highest,
preload: 'metadata', // HTML5 Spec values: none, metadata, auto.
volume: 0.8, // The volume. Number 0 to 1.
muted: false,
backgroundColor: "#000000", // To define the jPlayer div and Flash b
ackground color.
cssSelectorAncestor: "#jp_interface_1",
cssSelector: {
videoPlay: ".jp-video-play",

play: ".jp-play",
pause: ".jp-pause",
stop: ".jp-stop",
seekBar: ".jp-seek-bar",
playBar: ".jp-play-bar",
mute: ".jp-mute",
unmute: ".jp-unmute",
volumeBar: ".jp-volume-bar",
volumeBarValue: ".jp-volume-bar-value",
currentTime: ".jp-current-time",
duration: ".jp-duration"
},
// globalVolume: false, // Not implemented: Set to make volume chang
es affect all jPlayer instances
// globalMute: false, // Not implemented: Set to make mute changes a
ffect all jPlayer instances
idPrefix: "jp", // Prefix for the ids of html elements created by jP
layer. For flash, this must not include characters: . - + * / \
errorAlerts: false,
warningAlerts: false
},
instances: {}, // Static Object
status: { // Instanced in _init()
src: "",
media: {},
paused: true,
format: {},
formatType: "",
waitForPlay: true, // Same as waitForLoad except in case where prelo
ading.
waitForLoad: true,
srcSet: false,
video: false, // True if playing a video
seekPercent: 0,
currentPercentRelative: 0,
currentPercentAbsolute: 0,
currentTime: 0,
duration: 0
},
_status: { // Instanced in _init(): These status values are persistent.
ie., Are not affected by a status reset.
volume: undefined, // Set by constructor option/default.
muted: false, // Set by constructor option/default.
width: 0, // Read from CSS
height: 0 // Read from CSS
},
internal: { // Instanced in _init()
ready: false,
instance: undefined,
htmlDlyCmdId: undefined
},
solution: { // Static Object: Defines the solutions built in jPlayer.
html: true,
flash: true
},
// 'MPEG-4 support' : canPlayType('video/mp4; codecs="mp4v.20.8"')
format: { // Static Object
mp3: {
codec: 'audio/mpeg; codecs="mp3"',
flashCanPlay: true,

media: 'audio'
},
m4a: { // AAC / MP4
codec: 'audio/mp4; codecs="mp4a.40.2"',
flashCanPlay: true,
media: 'audio'
},
oga: { // OGG
codec: 'audio/ogg; codecs="vorbis"',
flashCanPlay: false,
media: 'audio'
},
wav: { // PCM
codec: 'audio/wav; codecs="1"',
flashCanPlay: false,
media: 'audio'
},
webma: { // WEBM
codec: 'audio/webm; codecs="vorbis"',
flashCanPlay: false,
media: 'audio'
},
m4v: { // H.264 / MP4
codec: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
flashCanPlay: true,
media: 'video'
},
ogv: { // OGG
codec: 'video/ogg; codecs="theora, vorbis"',
flashCanPlay: false,
media: 'video'
},
webmv: { // WEBM
codec: 'video/webm; codecs="vorbis, vp8"',
flashCanPlay: false,
media: 'video'
}
},
_init: function () {
var self = this;
this.element.empty();
this.status = $.extend({}, this.status, this._status); // Copy stati
c to unique instance. Adds the status propeties that persist through a reset. NB
: Might want to use $.jPlayer.prototype.status instead once options completely i
mplmented and _init() returned to $.fn.jPlayer plugin.
this.internal = $.extend({}, this.internal); // Copy static to uniqu
e instance.
this.formats = []; // Array based on supplied string option. Order d
efines priority.
this.solutions = []; // Array based on solution string option. Order
defines priority.
this.require = {}; // Which media types are required: video, audio.
this.htmlElement = {}; // DOM elements created by jPlayer
this.html = {}; // In _init()'s this.desired code and setmedia(): Ac
cessed via this[solution], where solution from this.solutions array.
this.html.audio = {};

this.html.video = {};
this.flash = {}; // In _init()'s this.desired code and setmedia(): A
ccessed via this[solution], where solution from this.solutions array.
this.css = {};
this.css.cs = {}; // Holds the css selector strings
this.css.jq = {}; // Holds jQuery selectors. ie., $(css.cs.method)
this.status.volume = this._limitValue(this.options.volume, 0, 1); //
Set volume status from constructor option.
this.status.muted = this.options.muted; // Set muted status from con
structor option.
this.status.width = this.element.css('width'); // Sets from CSS.
this.status.height = this.element.css('height'); // Sets from CSS.
this.element.css({ 'background-color': this.options.backgroundColor
});
// Create the formats array, with prority based on the order of the
supplied formats string
$.each(this.options.supplied.toLowerCase().split(","), function (ind
ex1, value1) {
var format = value1.replace(/^\s+|\s+$/g, ""); //trim
if (self.format[format]) { // Check format is valid.
var dupFound = false;
$.each(self.formats, function (index2, value2) { // Check fo
r duplicates
if (format === value2) {
dupFound = true;
return false;
}
});
if (!dupFound) {
self.formats.push(format);
}
}
});
// Create the solutions array, with prority based on the order of th
e solution string
$.each(this.options.solution.toLowerCase().split(","), function (ind
ex1, value1) {
var solution = value1.replace(/^\s+|\s+$/g, ""); //trim
if (self.solution[solution]) { // Check solution is valid.
var dupFound = false;
$.each(self.solutions, function (index2, value2) { // Check
for duplicates
if (solution === value2) {
dupFound = true;
return false;
}
});
if (!dupFound) {
self.solutions.push(solution);
}
}
});
this.internal.instance = "jp_" + this.count;
this.instances[this.internal.instance] = this.element;

// Check the jPlayer div has an id and create one if required. Impor
tant for Flash to know the unique id for comms.
if (this.element.attr("id") === "") {
this.element.attr("id", this.options.idPrefix + "_jplayer_" + th
is.count);
}
this.internal.self = $.extend({}, {
id: this.element.attr("id"),
jq: this.element
});
this.internal.audio = $.extend({}, {
id: this.options.idPrefix + "_audio_" + this.count,
jq: undefined
});
this.internal.video = $.extend({}, {
id: this.options.idPrefix + "_video_" + this.count,
jq: undefined
});
this.internal.flash = $.extend({}, {
id: this.options.idPrefix + "_flash_" + this.count,
jq: undefined,
swf: this.options.swfPath + ((this.options.swfPath !== "" && thi
s.options.swfPath.slice(-1) !== "/") ? "/" : "") + "Jplayer.swf"
});
this.internal.poster = $.extend({}, {
id: this.options.idPrefix + "_poster_" + this.count,
jq: undefined
});
// Register listeners defined in the constructor
$.each($.jPlayer.event, function (eventName, eventType) {
if (self.options[eventName] !== undefined) {
self.element.bind(eventType + ".jPlayer", self.options[event
Name]); // With .jPlayer namespace.
self.options[eventName] = undefined; // Destroy the handler
pointer copy on the options. Reason, events can be added/removed in other ways s
o this could be obsolete and misleading.
}
});
// Create the poster image.
this.htmlElement.poster = document.createElement('img');
this.htmlElement.poster.id = this.internal.poster.id;
this.htmlElement.poster.onload = function () { // Note that this did
not work on Firefox 3.6: poster.addEventListener("onload", function() {}, false
); Did not investigate x-browser.
if (!self.status.video || self.status.waitForPlay) {
self.internal.poster.jq.show();
}
};
this.element.append(this.htmlElement.poster);
this.internal.poster.jq = $("#" + this.internal.poster.id);
this.internal.poster.jq.css({ 'width': this.status.width, 'height':
this.status.height });
this.internal.poster.jq.hide();
// Determine if we require solutions for audio, video or both media
types.

this.require.audio = false;
this.require.video = false;
$.each(this.formats, function (priority, format) {
self.require[self.format[format].media] = true;
});
this.html.audio.available = false;
if (this.require.audio) { // If a supplied format is audio
this.htmlElement.audio = document.createElement('audio');
this.htmlElement.audio.id = this.internal.audio.id;
this.html.audio.available = !!this.htmlElement.audio.canPlayType
;
}
this.html.video.available = false;
if (this.require.video) { // If a supplied format is video
this.htmlElement.video = document.createElement('video');
this.htmlElement.video.id = this.internal.video.id;
this.html.video.available = !!this.htmlElement.video.canPlayType
;
}
this.flash.available = this._checkForFlash(10); // IE9 forced to fal
se due to ExternalInterface problem.
this.html.canPlay = {};
this.flash.canPlay = {};
$.each(this.formats, function (priority, format) {
self.html.canPlay[format] = self.html[self.format[format].media]
.available && "" !== self.htmlElement[self.format[format].media].canPlayType(sel
f.format[format].codec);
self.flash.canPlay[format] = self.format[format].flashCanPlay &&
self.flash.available;
});
this.html.desired = false;
this.flash.desired = false;
$.each(this.solutions, function (solutionPriority, solution) {
if (solutionPriority === 0) {
self[solution].desired = true;
} else {
var audioCanPlay = false;
var videoCanPlay = false;
$.each(self.formats, function (formatPriority, format) {
if (self[self.solutions[0]].canPlay[format]) { // The ot
her solution can play
if (self.format[format].media === 'video') {
videoCanPlay = true;
} else {
audioCanPlay = true;
}
}
});
self[solution].desired = (self.require.audio && !audioCanPla
y) || (self.require.video && !videoCanPlay);
}
});
// This is what jPlayer will support, based on solution and supplied
.
this.html.support = {};
this.flash.support = {};
$.each(this.formats, function (priority, format) {

self.html.support[format] = self.html.canPlay[format] && self.ht


ml.desired;
self.flash.support[format] = self.flash.canPlay[format] && self.
flash.desired;
});
// If jPlayer is supporting any format in a solution, then the solut
ion is used.
this.html.used = false;
this.flash.used = false;
$.each(this.solutions, function (solutionPriority, solution) {
$.each(self.formats, function (formatPriority, format) {
if (self[solution].support[format]) {
self[solution].used = true;
return false;
}
});
});
// If neither html nor flash are being used by this browser, then me
dia playback is not possible. Trigger an error event.
if (!(this.html.used || this.flash.used)) {
this._error({
type: $.jPlayer.error.NO_SOLUTION,
context: "{solution:'" + this.options.solution + "', supplie
d:'" + this.options.supplied + "'}",
message: $.jPlayer.errorMsg.NO_SOLUTION,
hint: $.jPlayer.errorHint.NO_SOLUTION
});
}
// Init solution active state and the event gates to false.
this.html.active = false;
this.html.audio.gate = false;
this.html.video.gate = false;
this.flash.active = false;
this.flash.gate = false;
// Add the flash solution if it is being used.
if (this.flash.used) {
var flashVars = 'id=' + escape(this.internal.self.id) + '&vol='
+ this.status.volume + '&muted=' + this.status.muted;
if ($.browser.msie && Number($.browser.version) <= 8) {
var html_obj = '<object id="' + this.internal.flash.id + '"'
;
html_obj += ' classid="clsid:d27cdb6e-ae6d-11cf-96b8-4445535
40000"';
html_obj += ' codebase="' + document.URL.substring(0, docume
nt.URL.indexOf(':')) + '://fpdownload.macromedia.com/pub/shockwave/cabs/flash/sw
flash.cab"'; // Fixed IE non secured element warning.
html_obj += ' type="application/x-shockwave-flash"';
html_obj += ' width="0" height="0">';
html_obj += '</object>';
var obj_param = [];
obj_param[0] = '<param name="movie" value="' + this.internal
.flash.swf + '" />';
obj_param[1] = '<param name="quality" value="high" />';
obj_param[2] = '<param name="FlashVars" value="' + flashVars
+ '" />';

obj_param[3] = '<param name="allowScriptAccess" value="alway


s" />';
obj_param[4] = '<param name="bgcolor" value="' + this.option
s.backgroundColor + '" />';
var ie_dom = document.createElement(html_obj);
for (var i = 0; i < obj_param.length; i++) {
ie_dom.appendChild(document.createElement(obj_param[i]))
;
}
this.element.append(ie_dom);
} else {
var html_embed = '<embed name="' + this.internal.flash.id +
'" id="' + this.internal.flash.id + '" src="' + this.internal.flash.swf + '"';
html_embed += ' width="0" height="0" bgcolor="' + this.optio
ns.backgroundColor + '"';
html_embed += ' quality="high" FlashVars="' + flashVars + '"
';
html_embed += ' allowScriptAccess="always"';
html_embed += ' type="application/x-shockwave-flash" plugins
page="http://www.macromedia.com/go/getflashplayer" />';
this.element.append(html_embed);
}
this.internal.flash.jq = $("#" + this.internal.flash.id);
this.internal.flash.jq.css({ 'width': '0px', 'height': '0px' });
// Must do via CSS as setting attr() to zero causes a jQuery error in IE.
}
// Add the HTML solution if being used.
if (this.html.used) {
// The HTML Audio handlers
if (this.html.audio.available) {
this._addHtmlEventListeners(this.htmlElement.audio, this.htm
l.audio);
this.element.append(this.htmlElement.audio);
this.internal.audio.jq = $("#" + this.internal.audio.id);
}
// The HTML Video handlers
if (this.html.video.available) {
this._addHtmlEventListeners(this.htmlElement.video, this.htm
l.video);
this.element.append(this.htmlElement.video);
this.internal.video.jq = $("#" + this.internal.video.id);
this.internal.video.jq.css({ 'width': '0px', 'height': '0px'
}); // Using size 0x0 since a .hide() causes issues in iOS
}
}
if (this.html.used && !this.flash.used) { // If only HTML, then emul
ate flash ready() call after 100ms.
window.setTimeout(function () {
self.internal.ready = true;
self.version.flash = "n/a";
self._trigger($.jPlayer.event.ready);
}, 100);
}
// Set up the css selectors for the control and feedback entities.

$.each(this.options.cssSelector, function (fn, cssSel) {


self._cssSelector(fn, cssSel);
});
this._updateInterface();
this._updateButtons(false);
this._updateVolume(this.status.volume);
this._updateMute(this.status.muted);
if (this.css.jq.videoPlay.length) {
this.css.jq.videoPlay.hide();
}
$.jPlayer.prototype.count++; // Change static variable via prototype
.
},
destroy: function () {
// MJP: The background change remains. Review later.
// Reset the interface, remove seeking effect and times.
this._resetStatus();
this._updateInterface();
this._seeked();
if (this.css.jq.currentTime.length) {
this.css.jq.currentTime.text("");
}
if (this.css.jq.duration.length) {
this.css.jq.duration.text("");
}
if (this.status.srcSet) { // Or you get a bogus error event
this.pause(); // Pauses the media and clears any delayed command
s used in the HTML solution.
}
$.each(this.css.jq, function (fn, jq) { // Remove any bindings from
the interface controls.
jq.unbind(".jPlayer");
});
this.element.removeData("jPlayer"); // Remove jPlayer data
this.element.unbind(".jPlayer"); // Remove all event handlers create
d by the jPlayer constructor
this.element.empty(); // Remove the inserted child elements
this.instances[this.internal.instance] = undefined; // Clear the ins
tance on the static instance object
},
enable: function () { // Plan to implement
// options.disabled = false
},
disable: function () { // Plan to implement
// options.disabled = true
},
_addHtmlEventListeners: function (mediaElement, entity) {
var self = this;
mediaElement.preload = this.options.preload;
mediaElement.muted = this.options.muted;
// Create the event listeners
// Only want the active entity to affect jPlayer and bubble events.
// Using entity.gate so that object is referenced and gate property
always current

mediaElement.addEventListener("progress", function () {
if (entity.gate && !self.status.waitForLoad) {
self._getHtmlStatus(mediaElement);
self._updateInterface();
self._trigger($.jPlayer.event.progress);
}
}, false);
mediaElement.addEventListener("timeupdate", function () {
if (entity.gate && !self.status.waitForLoad) {
self._getHtmlStatus(mediaElement);
self._updateInterface();
self._trigger($.jPlayer.event.timeupdate);
}
}, false);
mediaElement.addEventListener("durationchange", function () {
if (entity.gate && !self.status.waitForLoad) {
self.status.duration = this.duration;
self._getHtmlStatus(mediaElement);
self._updateInterface();
self._trigger($.jPlayer.event.durationchange);
}
}, false);
mediaElement.addEventListener("play", function () {
if (entity.gate && !self.status.waitForLoad) {
self._updateButtons(true);
self._trigger($.jPlayer.event.play);
}
}, false);
mediaElement.addEventListener("playing", function () {
if (entity.gate && !self.status.waitForLoad) {
self._updateButtons(true);
self._seeked();
self._trigger($.jPlayer.event.playing);
}
}, false);
mediaElement.addEventListener("pause", function () {
if (entity.gate && !self.status.waitForLoad) {
self._updateButtons(false);
self._trigger($.jPlayer.event.pause);
}
}, false);
mediaElement.addEventListener("waiting", function () {
if (entity.gate && !self.status.waitForLoad) {
self._seeking();
self._trigger($.jPlayer.event.waiting);
}
}, false);
mediaElement.addEventListener("canplay", function () {
if (entity.gate && !self.status.waitForLoad) {
mediaElement.volume = self._volumeFix(self.status.volume);
self._trigger($.jPlayer.event.canplay);
}
}, false);
mediaElement.addEventListener("seeking", function () {
if (entity.gate && !self.status.waitForLoad) {
self._seeking();
self._trigger($.jPlayer.event.seeking);
}
}, false);
mediaElement.addEventListener("seeked", function () {

if (entity.gate && !self.status.waitForLoad) {


self._seeked();
self._trigger($.jPlayer.event.seeked);
}
}, false);
mediaElement.addEventListener("suspend", function () { // Seems to b
e the only way of capturing that the iOS4 browser did not actually play the medi
a from the page code. ie., It needs a user gesture.
if (entity.gate && !self.status.waitForLoad) {
self._seeked();
self._trigger($.jPlayer.event.suspend);
}
}, false);
mediaElement.addEventListener("ended", function () {
if (entity.gate && !self.status.waitForLoad) {
// Order of the next few commands are important. Change the
time and then pause.
// Solves a bug in Firefox, where issuing pause 1st causes t
he media to play from the start. ie., The pause is ignored.
if (!$.jPlayer.browser.webkit) { // Chrome crashes if you do
this in conjunction with a setMedia command in an ended event handler. ie., The
playlist demo.
self.htmlElement.media.currentTime = 0; // Safari does n
ot care about this command. ie., It works with or without this line. (Both Safar
i and Chrome are Webkit.)
}
self.htmlElement.media.pause(); // Pause otherwise a click o
n the progress bar will play from that point, when it shouldn't, since it stoppe
d playback.
self._updateButtons(false);
self._getHtmlStatus(mediaElement, true); // With override tr
ue. Otherwise Chrome leaves progress at full.
self._updateInterface();
self._trigger($.jPlayer.event.ended);
}
}, false);
mediaElement.addEventListener("error", function () {
if (entity.gate && !self.status.waitForLoad) {
self._updateButtons(false);
self._seeked();
if (self.status.srcSet) { // Deals with case of clearMedia()
causing an error event.
self.status.waitForLoad = true; // Allows the load opera
tion to try again.
self.status.waitForPlay = true; // Reset since a play wa
s captured.
if (self.status.video) {
self.internal.video.jq.css({ 'width': '0px', 'height
': '0px' });
}
if (self._validString(self.status.media.poster)) {
self.internal.poster.jq.show();
}
if (self.css.jq.videoPlay.length) {
self.css.jq.videoPlay.show();
}
self._error({
type: $.jPlayer.error.URL,
context: self.status.src, // this.src shows absolute
urls. Want context to show the url given.

message: $.jPlayer.errorMsg.URL,
hint: $.jPlayer.errorHint.URL
});
}
}
}, false);
// Create all the other event listeners that bubble up to a jPlayer
event from html, without being used by jPlayer.
$.each($.jPlayer.htmlEvent, function (i, eventType) {
mediaElement.addEventListener(this, function () {
if (entity.gate && !self.status.waitForLoad) {
self._trigger($.jPlayer.event[eventType]);
}
}, false);
});
},
_getHtmlStatus: function (media, override) {
var ct = 0, d = 0, cpa = 0, sp = 0, cpr = 0;
ct = media.currentTime;
cpa = (this.status.duration > 0) ? 100 * ct / this.status.duration :
0;
if ((typeof media.seekable === "object") && (media.seekable.length >
0)) {
sp = (this.status.duration > 0) ? 100 * media.seekable.end(media
.seekable.length - 1) / this.status.duration : 100;
cpr = 100 * media.currentTime / media.seekable.end(media.seekabl
e.length - 1);
} else {
sp = 100;
cpr = cpa;
}
if (override) {
ct = 0;
cpr = 0;
cpa = 0;
}
this.status.seekPercent = sp;
this.status.currentPercentRelative = cpr;
this.status.currentPercentAbsolute = cpa;
this.status.currentTime = ct;
},
_resetStatus: function () {
var self = this;
this.status = $.extend({}, this.status, $.jPlayer.prototype.status);
// Maintains the status properties that persist through a reset. ie., The prope
rties of this._status, contained in the current this.status.
},
_trigger: function (eventType, error, warning) { // eventType always val
id as called using $.jPlayer.event.eventType
var event = $.Event(eventType);
event.jPlayer = {};
event.jPlayer.version = $.extend({}, this.version);
event.jPlayer.status = $.extend(true, {}, this.status); // Deep copy
event.jPlayer.html = $.extend(true, {}, this.html); // Deep copy
event.jPlayer.flash = $.extend(true, {}, this.flash); // Deep copy
if (error) event.jPlayer.error = $.extend({}, error);

if (warning) event.jPlayer.warning = $.extend({}, warning);


this.element.trigger(event);
},
jPlayerFlashEvent: function (eventType, status) { // Called from Flash
if (eventType === $.jPlayer.event.ready && !this.internal.ready) {
this.internal.ready = true;
this.version.flash = status.version;
if (this.version.needFlash !== this.version.flash) {
this._error({
type: $.jPlayer.error.VERSION,
context: this.version.flash,
message: $.jPlayer.errorMsg.VERSION + this.version.flash
,
hint: $.jPlayer.errorHint.VERSION
});
}
this._trigger(eventType);
}
if (this.flash.gate) {
switch (eventType) {
case $.jPlayer.event.progress:
this._getFlashStatus(status);
this._updateInterface();
this._trigger(eventType);
break;
case $.jPlayer.event.timeupdate:
this._getFlashStatus(status);
this._updateInterface();
this._trigger(eventType);
break;
case $.jPlayer.event.play:
this._seeked();
this._updateButtons(true);
this._trigger(eventType);
break;
case $.jPlayer.event.pause:
this._updateButtons(false);
this._trigger(eventType);
break;
case $.jPlayer.event.ended:
this._updateButtons(false);
this._trigger(eventType);
break;
case $.jPlayer.event.error:
this.status.waitForLoad = true; // Allows the load opera
tion to try again.
this.status.waitForPlay = true; // Reset since a play wa
s captured.
if (this.status.video) {
this.internal.flash.jq.css({ 'width': '0px', 'height
': '0px' });
}
if (this._validString(this.status.media.poster)) {
this.internal.poster.jq.show();
}
if (this.css.jq.videoPlay.length) {
this.css.jq.videoPlay.show();
}
if (this.status.video) { // Set up for another try. Exec
ute before error event.

this._flash_setVideo(this.status.media);
} else {
this._flash_setAudio(this.status.media);
}
this._error({
type: $.jPlayer.error.URL,
context: status.src,
message: $.jPlayer.errorMsg.URL,
hint: $.jPlayer.errorHint.URL
});
break;
case $.jPlayer.event.seeking:
this._seeking();
this._trigger(eventType);
break;
case $.jPlayer.event.seeked:
this._seeked();
this._trigger(eventType);
break;
default:
this._trigger(eventType);
}
}
return false;
},
_getFlashStatus: function (status) {
this.status.seekPercent = status.seekPercent;
this.status.currentPercentRelative = status.currentPercentRelative;
this.status.currentPercentAbsolute = status.currentPercentAbsolute;
this.status.currentTime = status.currentTime;
this.status.duration = status.duration;
},
_updateButtons: function (playing) {
this.status.paused = !playing;
if (this.css.jq.play.length && this.css.jq.pause.length) {
if (playing) {
this.css.jq.play.hide();
this.css.jq.pause.show();
} else {
this.css.jq.play.show();
this.css.jq.pause.hide();
}
}
},
_updateInterface: function () {
if (this.css.jq.seekBar.length) {
this.css.jq.seekBar.width(this.status.seekPercent + "%");
}
if (this.css.jq.playBar.length) {
this.css.jq.playBar.width(this.status.currentPercentRelative + "
%");
}
if (this.css.jq.currentTime.length) {
this.css.jq.currentTime.text($.jPlayer.convertTime(this.status.c
urrentTime));
}
if (this.css.jq.duration.length) {
this.css.jq.duration.text($.jPlayer.convertTime(this.status.dura
tion));
}

},
_seeking: function () {
if (this.css.jq.seekBar.length) {
this.css.jq.seekBar.addClass("jp-seeking-bg");
}
},
_seeked: function () {
if (this.css.jq.seekBar.length) {
this.css.jq.seekBar.removeClass("jp-seeking-bg");
}
},
setMedia: function (media) {
/* media[format] = String: URL of format. Must contain all of the s
upplied option's video or audio formats.
* media.poster = String: Video poster URL.
* media.subtitles = String: * NOT IMPLEMENTED * URL of subtitles S
RT file
* media.chapters = String: * NOT IMPLEMENTED * URL of chapters SRT
file
* media.stream = Boolean: * NOT IMPLEMENTED * Designating actual m
edia streams. ie., "false/undefined" for files. Plan to refresh the flash every
so often.
*/
var self = this;
this._seeked();
clearTimeout(this.internal.htmlDlyCmdId); // Clears any delayed comm
ands used in the HTML solution.
// Store the current html gates, since we need for clearMedia() cond
itions.
var audioGate = this.html.audio.gate;
var videoGate = this.html.video.gate;
var supported = false;
$.each(this.formats, function (formatPriority, format) {
var isVideo = self.format[format].media === 'video';
$.each(self.solutions, function (solutionPriority, solution) {
if (self[solution].support[format] && self._validString(medi
a[format])) { // Format supported in solution and url given for format.
var isHtml = solution === 'html';
if (isVideo) {
if (isHtml) {
self.html.audio.gate = false;
self.html.video.gate = true;
self.flash.gate = false;
} else {
self.html.audio.gate = false;
self.html.video.gate = false;
self.flash.gate = true;
}
} else {
if (isHtml) {
self.html.audio.gate = true;
self.html.video.gate = false;
self.flash.gate = false;
} else {

self.html.audio.gate = false;
self.html.video.gate = false;
self.flash.gate = true;
}
}
//
//
//
//

Clear media of the previous solution if:


- it was Flash
- changing from HTML to Flash
- the HTML solution media type (audio or video) rema

ined the same.


// Note that, we must be careful with clearMedia() on iP
hone, otherwise clearing the video when changing to audio corrupts the built in
video player.
if (self.flash.active || (self.html.active && self.flash
.gate) || (audioGate === self.html.audio.gate && videoGate === self.html.video.g
ate)) {
self.clearMedia();
} else if (audioGate !== self.html.audio.gate && videoGa
te !== self.html.video.gate) { // If switching between html elements
self._html_pause();
// Hide the video if it was being used.
if (self.status.video) {
self.internal.video.jq.css({ 'width': '0px', 'he
ight': '0px' });
}
self._resetStatus(); // Since clearMedia usually doe
s this. Execute after status.video useage.
}
if (isVideo) {
if (isHtml) {
self._html_setVideo(media);
self.html.active = true;
self.flash.active = false;
} else {
self._flash_setVideo(media);
self.html.active = false;
self.flash.active = true;
}
if (self.css.jq.videoPlay.length) {
self.css.jq.videoPlay.show();
}
self.status.video = true;
} else {
if (isHtml) {
self._html_setAudio(media);
self.html.active = true;
self.flash.active = false;
} else {
self._flash_setAudio(media);
self.html.active = false;
self.flash.active = true;
}
if (self.css.jq.videoPlay.length) {
self.css.jq.videoPlay.hide();
}
self.status.video = false;
}

supported = true;
return false; // Exit $.each
}
});
if (supported) {
return false; // Exit $.each
}
});
if (supported) {
// Set poster after the possible clearMedia() command above. IE
had issues since the IMG onload event occurred immediately when cached. ie., The
clearMedia() hide the poster.
if (this._validString(media.poster)) {
if (this.htmlElement.poster.src !== media.poster) { // Since
some browsers do not generate img onload event.
this.htmlElement.poster.src = media.poster;
} else {
this.internal.poster.jq.show();
}
} else {
this.internal.poster.jq.hide(); // Hide if not used, since c
learMedia() does not always occur above. ie., HTML audio <-> video switching.
}
this.status.srcSet = true;
this.status.media = $.extend({}, media);
this._updateButtons(false);
this._updateInterface();
} else { // jPlayer cannot support any formats provided in this brow
ser
// Pause here if old media could be playing. Otherwise, playing
media being changed to bad media would leave the old media playing.
if (this.status.srcSet && !this.status.waitForPlay) {
this.pause();
}
// Reset all the control flags
this.html.audio.gate = false;
this.html.video.gate = false;
this.flash.gate = false;
this.html.active = false;
this.flash.active = false;
// Reset status and interface.
this._resetStatus();
this._updateInterface();
this._updateButtons(false);
// Hide the any old media
this.internal.poster.jq.hide();
if (this.html.used && this.require.video) {
this.internal.video.jq.css({ 'width': '0px', 'height': '0px'
});
}
if (this.flash.used) {
this.internal.flash.jq.css({ 'width': '0px', 'height': '0px'
});
}
// Send an error event
this._error({
type: $.jPlayer.error.NO_SUPPORT,
context: "{supplied:'" + this.options.supplied + "'}",
message: $.jPlayer.errorMsg.NO_SUPPORT,

hint: $.jPlayer.errorHint.NO_SUPPORT
});
}
},
clearMedia: function () {
this._resetStatus();
this._updateButtons(false);
this.internal.poster.jq.hide();
clearTimeout(this.internal.htmlDlyCmdId);
if (this.html.active) {
this._html_clearMedia();
} else if (this.flash.active) {
this._flash_clearMedia();
}
},
load: function () {
if (this.status.srcSet) {
if (this.html.active) {
this._html_load();
} else if (this.flash.active) {
this._flash_load();
}
} else {
this._urlNotSetError("load");
}
},
play: function (time) {
time = (typeof time === "number") ? time : NaN; // Remove jQuery eve
nt from click handler
if (this.status.srcSet) {
if (this.html.active) {
this._html_play(time);
} else if (this.flash.active) {
this._flash_play(time);
}
} else {
this._urlNotSetError("play");
}
},
videoPlay: function (e) { // Handles clicks on the play button over the
video poster
this.play();
},
pause: function (time) {
time = (typeof time === "number") ? time : NaN; // Remove jQuery eve
nt from click handler
if (this.status.srcSet) {
if (this.html.active) {
this._html_pause(time);
} else if (this.flash.active) {
this._flash_pause(time);
}
} else {
this._urlNotSetError("pause");
}
},
pauseOthers: function () {

var self = this;


$.each(this.instances, function (i, element) {
if (self.element !== element) { // Do not this instance.
if (element.data("jPlayer").status.srcSet) { // Check that m
edia is set otherwise would cause error event.
element.jPlayer("pause");
}
}
});
},
stop: function () {
if (this.status.srcSet) {
if (this.html.active) {
this._html_pause(0);
} else if (this.flash.active) {
this._flash_pause(0);
}
} else {
this._urlNotSetError("stop");
}
},
playHead: function (p) {
p = this._limitValue(p, 0, 100);
if (this.status.srcSet) {
if (this.html.active) {
this._html_playHead(p);
} else if (this.flash.active) {
this._flash_playHead(p);
}
} else {
this._urlNotSetError("playHead");
}
},
mute: function () {
this.status.muted = true;
if (this.html.used) {
this._html_mute(true);
}
if (this.flash.used) {
this._flash_mute(true);
}
this._updateMute(true);
this._updateVolume(0);
this._trigger($.jPlayer.event.volumechange);
},
unmute: function () {
this.status.muted = false;
if (this.html.used) {
this._html_mute(false);
}
if (this.flash.used) {
this._flash_mute(false);
}
this._updateMute(false);
this._updateVolume(this.status.volume);
this._trigger($.jPlayer.event.volumechange);
},
_updateMute: function (mute) {
if (this.css.jq.mute.length && this.css.jq.unmute.length) {
if (mute) {

this.css.jq.mute.hide();
this.css.jq.unmute.show();
} else {
this.css.jq.mute.show();
this.css.jq.unmute.hide();
}
}
},
volume: function (v) {
v = this._limitValue(v, 0, 1);
this.status.volume = v;
if (this.html.used) {
this._html_volume(v);
}
if (this.flash.used) {
this._flash_volume(v);
}
if (!this.status.muted) {
this._updateVolume(v);
}
this._trigger($.jPlayer.event.volumechange);
},
volumeBar: function (e) { // Handles clicks on the volumeBar
if (!this.status.muted && this.css.jq.volumeBar) { // Ignore clicks
when muted
var offset = this.css.jq.volumeBar.offset();
var x = e.pageX - offset.left;
var w = this.css.jq.volumeBar.width();
var v = x / w;
this.volume(v);
}
},
volumeBarValue: function (e) { // Handles clicks on the volumeBarValue
this.volumeBar(e);
},
_updateVolume: function (v) {
if (this.css.jq.volumeBarValue.length) {
this.css.jq.volumeBarValue.width((v * 100) + "%");
}
},
_volumeFix: function (v) { // Need to review if this is still necessary
on latest Chrome
var rnd = 0.001 * Math.random(); // Fix for Chrome 4: Fix volume bei
ng set multiple times before playing bug.
var fix = (v < 0.5) ? rnd : -rnd; // Fix for Chrome 4: Solves volume
change before play bug. (When new vol == old vol Chrome 4 does nothing!)
return (v + fix); // Fix for Chrome 4: Event solves initial volume n
ot being set correctly.
},
_cssSelectorAncestor: function (ancestor, refresh) {
this.options.cssSelectorAncestor = ancestor;
if (refresh) {
$.each(this.options.cssSelector, function (fn, cssSel) {
self._cssSelector(fn, cssSel);
});
}
},
_cssSelector: function (fn, cssSel) {
var self = this;

if (typeof cssSel === 'string') {


if ($.jPlayer.prototype.options.cssSelector[fn]) {
if (this.css.jq[fn] && this.css.jq[fn].length) {
this.css.jq[fn].unbind(".jPlayer");
}
this.options.cssSelector[fn] = cssSel;
this.css.cs[fn] = this.options.cssSelectorAncestor + " " + c
ssSel;
if (cssSel) { // Checks for empty string
this.css.jq[fn] = $(this.css.cs[fn]);
} else {
this.css.jq[fn] = []; // To comply with the css.jq[fn].l
ength check before its use. As of jQuery 1.4 could have used $() for an empty se
t.
}
if (this.css.jq[fn].length) {
var handler = function (e) {
self[fn](e);
$(this).blur();
return false;
}
this.css.jq[fn].bind("click.jPlayer", handler); // Using
jPlayer namespace
}
if (cssSel && this.css.jq[fn].length !== 1) { // So empty st
rings do not generate the warning. ie., they just remove the old one.
this._warning({
type: $.jPlayer.warning.CSS_SELECTOR_COUNT,
context: this.css.cs[fn],
message: $.jPlayer.warningMsg.CSS_SELECTOR_COUNT + t
his.css.jq[fn].length + " found for " + fn + " method.",
hint: $.jPlayer.warningHint.CSS_SELECTOR_COUNT
});
}
} else {
this._warning({
type: $.jPlayer.warning.CSS_SELECTOR_METHOD,
context: fn,
message: $.jPlayer.warningMsg.CSS_SELECTOR_METHOD,
hint: $.jPlayer.warningHint.CSS_SELECTOR_METHOD
});
}
} else {
this._warning({
type: $.jPlayer.warning.CSS_SELECTOR_STRING,
context: cssSel,
message: $.jPlayer.warningMsg.CSS_SELECTOR_STRING,
hint: $.jPlayer.warningHint.CSS_SELECTOR_STRING
});
}
},
seekBar: function (e) { // Handles clicks on the seekBar
if (this.css.jq.seekBar) {
var offset = this.css.jq.seekBar.offset();
var x = e.pageX - offset.left;
var w = this.css.jq.seekBar.width();
var p = 100 * x / w;

this.playHead(p);
}
},
playBar: function (e) { // Handles clicks on the playBar
this.seekBar(e);
},
currentTime: function (e) { // Handles clicks on the text
// Added to avoid errors using cssSelector system for the text
},
duration: function (e) { // Handles clicks on the text
// Added to avoid errors using cssSelector system for the text
},
// Options code adapted from ui.widget.js (1.8.7). Made changes so the
key can use dot notation. To match previous getData solution in jPlayer 1.
option: function (key, value) {
var options = key;
// Enables use: options(). Returns a copy of options object
if (arguments.length === 0) {
return $.extend(true, {}, this.options);
}
if (typeof key === "string") {
var keys = key.split(".");
// Enables use: options("someOption") Returns a copy of the opt
ion. Supports dot notation.
if (value === undefined) {
var opt = $.extend(true, {}, this.options);
for (var i = 0; i < keys.length; i++) {
if (opt[keys[i]] !== undefined) {
opt = opt[keys[i]];
} else {
this._warning({
type: $.jPlayer.warning.OPTION_KEY,
context: key,
message: $.jPlayer.warningMsg.OPTION_KEY,
hint: $.jPlayer.warningHint.OPTION_KEY
});
return undefined;
}
}
return opt;
}
// Enables use: options("someOptionObject", someObject}). Creat
es: {someOptionObject:someObject}
// Enables use: options("someOption", someValue). Creates: {som
eOption:someValue}
// Enables use: options("someOptionObject.someOption", someValue
). Creates: {someOptionObject:{someOption:someValue}}
options = {};
var opt = options;
for (var i = 0; i < keys.length; i++) {
if (i < keys.length - 1) {
opt[keys[i]] = {};
opt = opt[keys[i]];

} else {
opt[keys[i]] = value;
}
}
}
// Otherwise enables use: options(optionObject). Uses original obje
ct (the key)
this._setOptions(options);
return this;
},
_setOptions: function (options) {
var self = this;
$.each(options, function (key, value) { // This supports the 2 level
depth that the options of jPlayer has. Would review if we ever need more depth.
self._setOption(key, value);
});
return this;
},
_setOption: function (key, value) {
var self = this;
// The ability to set options is limited at this time.
switch (key) {
case "cssSelectorAncestor":
this.options[key] = value;
$.each(self.options.cssSelector, function (fn, cssSel) { //
Refresh all associations for new ancestor.
self._cssSelector(fn, cssSel);
});
break;
case "cssSelector":
$.each(value, function (fn, cssSel) {
self._cssSelector(fn, cssSel);
});
break;
}
return this;
},
// End of: (Options code adapted from ui.widget.js)
// The resize() set of functions are not implemented yet.
// Basically are currently used to allow Flash debugging without too muc
h hassle.
resize: function (css) {
// MJP: Want to run some checks on dim {} first.
if (this.html.active) {
this._resizeHtml(css);
}
if (this.flash.active) {
this._resizeFlash(css);
}
this._trigger($.jPlayer.event.resize);
},
_resizePoster: function (css) {

// Not implemented yet


},
_resizeHtml: function (css) {
// Not implemented yet
},
_resizeFlash: function (css) {
this.internal.flash.jq.css({ 'width': css.width, 'height': css.heigh
t });
},
_html_initMedia: function () {
if (this.status.srcSet && !this.status.waitForPlay) {
this.htmlElement.media.pause();
}
if (this.options.preload !== 'none') {
this._html_load();
}
this._trigger($.jPlayer.event.timeupdate); // The flash generates th
is event for its solution.
},
_html_setAudio: function (media) {
var self = this;
// Always finds a format due to checks in setMedia()
$.each(this.formats, function (priority, format) {
if (self.html.support[format] && media[format]) {
self.status.src = media[format];
self.status.format[format] = true;
self.status.formatType = format;
return false;
}
});
this.htmlElement.media = this.htmlElement.audio;
this._html_initMedia();
},
_html_setVideo: function (media) {
var self = this;
// Always finds a format due to checks in setMedia()
$.each(this.formats, function (priority, format) {
if (self.html.support[format] && media[format]) {
self.status.src = media[format];
self.status.format[format] = true;
self.status.formatType = format;
return false;
}
});
this.htmlElement.media = this.htmlElement.video;
this._html_initMedia();
},
_html_clearMedia: function () {
if (this.htmlElement.media) {
if (this.htmlElement.media.id === this.internal.video.id) {
this.internal.video.jq.css({ 'width': '0px', 'height': '0px'
});
}
this.htmlElement.media.pause();
this.htmlElement.media.src = "";
if (!($.browser.msie && Number($.browser.version) >= 9)) { // IE
9 Bug: media.load() on broken src causes an exception. In try/catch IE9 generate
s the error event too, but it is delayed and corrupts jPlayer's event masking.

this.htmlElement.media.load(); // Stops an old, "in progress


" download from continuing the download. Triggers the loadstart, error and empti
ed events, due to the empty src. Also an abort event if a download was in progre
ss.
}
}
},
_html_load: function () {
if (this.status.waitForLoad) {
this.status.waitForLoad = false;
this.htmlElement.media.src = this.status.src;
try {
this.htmlElement.media.load(); // IE9 Beta throws an excepti
on here on broken links. Review again later as IE9 Beta matures
} catch (err) { }
}
clearTimeout(this.internal.htmlDlyCmdId);
},
_html_play: function (time) {
var self = this;
this._html_load(); // Loads if required and clears any delayed comma
nds.
this.htmlElement.media.play(); // Before currentTime attempt otherwi
se Firefox 4 Beta never loads.
if (!isNaN(time)) {
try {
this.htmlElement.media.currentTime = time;
} catch (err) {
this.internal.htmlDlyCmdId = setTimeout(function () {
self.play(time);
}, 100);
return; // Cancel execution and wait for the delayed command
.
}
}
this._html_checkWaitForPlay();
},
_html_pause: function (time) {
var self = this;
if (time > 0) { // We do not want the stop() command, which does pau
se(0), causing a load operation.
this._html_load(); // Loads if required and clears any delayed c
ommands.
} else {
clearTimeout(this.internal.htmlDlyCmdId);
}
// Order of these commands is important for Safari (Win) and IE9. Pa
use then change currentTime.
this.htmlElement.media.pause();
if (!isNaN(time)) {
try {
this.htmlElement.media.currentTime = time;
} catch (err) {
this.internal.htmlDlyCmdId = setTimeout(function () {
self.pause(time);

}, 100);
return; // Cancel execution and wait for the delayed command
.
}
}
if (time > 0) { // Avoids a setMedia() followed by stop() or pause(0
) hiding the video play button.
this._html_checkWaitForPlay();
}
},
_html_playHead: function (percent) {
var self = this;
this._html_load(); // Loads if required and clears any delayed comma
nds.
try {
if ((typeof this.htmlElement.media.seekable === "object") && (th
is.htmlElement.media.seekable.length > 0)) {
this.htmlElement.media.currentTime = percent * this.htmlElem
ent.media.seekable.end(this.htmlElement.media.seekable.length - 1) / 100;
} else if (this.htmlElement.media.duration > 0 && !isNaN(this.ht
mlElement.media.duration)) {
this.htmlElement.media.currentTime = percent * this.htmlElem
ent.media.duration / 100;
} else {
throw "e";
}
} catch (err) {
this.internal.htmlDlyCmdId = setTimeout(function () {
self.playHead(percent);
}, 100);
return; // Cancel execution and wait for the delayed command.
}
if (!this.status.waitForLoad) {
this._html_checkWaitForPlay();
}
},
_html_checkWaitForPlay: function () {
if (this.status.waitForPlay) {
this.status.waitForPlay = false;
if (this.css.jq.videoPlay.length) {
this.css.jq.videoPlay.hide();
}
if (this.status.video) {
this.internal.poster.jq.hide();
this.internal.video.jq.css({ 'width': this.status.width, 'he
ight': this.status.height });
}
}
},
_html_volume: function (v) {
if (this.html.audio.available) {
this.htmlElement.audio.volume = v;
}
if (this.html.video.available) {
this.htmlElement.video.volume = v;
}
},
_html_mute: function (m) {
if (this.html.audio.available) {
this.htmlElement.audio.muted = m;

}
if (this.html.video.available) {
this.htmlElement.video.muted = m;
}
},
_flash_setAudio: function (media) {
var self = this;
try {
// Always finds a format due to checks in setMedia()
$.each(this.formats, function (priority, format) {
if (self.flash.support[format] && media[format]) {
switch (format) {
case "m4a":
self._getMovie().fl_setAudio_m4a(media[format]);
break;
case "mp3":
self._getMovie().fl_setAudio_mp3(media[format]);
break;
}
self.status.src = media[format];
self.status.format[format] = true;
self.status.formatType = format;
return false;
}
});
if (this.options.preload === 'auto') {
this._flash_load();
this.status.waitForLoad = false;
}
} catch (err) { this._flashError(err); }
},
_flash_setVideo: function (media) {
var self = this;
try {
// Always finds a format due to checks in setMedia()
$.each(this.formats, function (priority, format) {
if (self.flash.support[format] && media[format]) {
switch (format) {
case "m4v":
self._getMovie().fl_setVideo_m4v(media[format]);
break;
}
self.status.src = media[format];
self.status.format[format] = true;
self.status.formatType = format;
return false;
}
});
if (this.options.preload === 'auto') {
this._flash_load();
this.status.waitForLoad = false;
}
} catch (err) { this._flashError(err); }
},
_flash_clearMedia: function () {
this.internal.flash.jq.css({ 'width': '0px', 'height': '0px' }); //
Must do via CSS as setting attr() to zero causes a jQuery error in IE.
try {

this._getMovie().fl_clearMedia();
} catch (err) { this._flashError(err); }
},
_flash_load: function () {
try {
this._getMovie().fl_load();
} catch (err) { this._flashError(err); }
this.status.waitForLoad = false;
},
_flash_play: function (time) {
try {
this._getMovie().fl_play(time);
} catch (err) { this._flashError(err); }
this.status.waitForLoad = false;
this._flash_checkWaitForPlay();
},
_flash_pause: function (time) {
try {
this._getMovie().fl_pause(time);
} catch (err) { this._flashError(err); }
if (time > 0) { // Avoids a setMedia() followed by stop() or pause(0
) hiding the video play button.
this.status.waitForLoad = false;
this._flash_checkWaitForPlay();
}
},
_flash_playHead: function (p) {
try {
this._getMovie().fl_play_head(p)
} catch (err) { this._flashError(err); }
if (!this.status.waitForLoad) {
this._flash_checkWaitForPlay();
}
},
_flash_checkWaitForPlay: function () {
if (this.status.waitForPlay) {
this.status.waitForPlay = false;
if (this.css.jq.videoPlay.length) {
this.css.jq.videoPlay.hide();
}
if (this.status.video) {
this.internal.poster.jq.hide();
this.internal.flash.jq.css({ 'width': this.status.width, 'he
ight': this.status.height });
}
}
},
_flash_volume: function (v) {
try {
this._getMovie().fl_volume(v);
} catch (err) { this._flashError(err); }
},
_flash_mute: function (m) {
try {
this._getMovie().fl_mute(m);
} catch (err) { this._flashError(err); }
},
_getMovie: function () {
return document[this.internal.flash.id];
},

_checkForFlash: function (version) {


// Function checkForFlash adapted from FlashReplace by Robert Nyman
// http://code.google.com/p/flashreplace/
var flashIsInstalled = false;
var flash;
if (window.ActiveXObject) {
try {
flash = new ActiveXObject(("ShockwaveFlash.ShockwaveFlash."
+ version));
flashIsInstalled = true;
}
catch (e) {
// Throws an error if the version isn't available
}
}
else if (navigator.plugins && navigator.mimeTypes.length > 0) {
flash = navigator.plugins["Shockwave Flash"];
if (flash) {
var flashVersion = navigator.plugins["Shockwave Flash"].desc
ription.replace(/.*\s(\d+\.\d+).*/, "$1");
if (flashVersion >= version) {
flashIsInstalled = true;
}
}
}
if ($.browser.msie && Number($.browser.version) >= 9) { // IE9 does
not work with external interface. With dynamic Flash insertion like jPlayer uses
.
return false;
} else {
return flashIsInstalled;
}
},
_validString: function (url) {
return (url && typeof url === "string"); // Empty strings return fal
se
},
_limitValue: function (value, min, max) {
return (value < min) ? min : ((value > max) ? max : value);
},
_urlNotSetError: function (context) {
this._error({
type: $.jPlayer.error.URL_NOT_SET,
context: context,
message: $.jPlayer.errorMsg.URL_NOT_SET,
hint: $.jPlayer.errorHint.URL_NOT_SET
});
},
_flashError: function (error) {
this._error({
type: $.jPlayer.error.FLASH,
context: this.internal.flash.swf,
message: $.jPlayer.errorMsg.FLASH + error.message,
hint: $.jPlayer.errorHint.FLASH
});
},
_error: function (error) {
this._trigger($.jPlayer.event.error, error);
if (this.options.errorAlerts) {
this._alert("Error!" + (error.message ? "\n\n" + error.message :

"") + (error.hint ? "\n\n" + error.hint : "") + "\n\nContext: " + error.context


);
}
},
_warning: function (warning) {
this._trigger($.jPlayer.event.warning, undefined, warning);
if (this.options.errorAlerts) {
this._alert("Warning!" + (warning.message ? "\n\n" + warning.mes
sage : "") + (warning.hint ? "\n\n" + warning.hint : "") + "\n\nContext: " + war
ning.context);
}
},
_alert: function (message) {
alert("jPlayer " + this.version.script + " : id='" + this.internal.s
elf.id + "' : " + message);
}
};
$.jPlayer.error = {
FLASH: "e_flash",
NO_SOLUTION: "e_no_solution",
NO_SUPPORT: "e_no_support",
URL: "e_url",
URL_NOT_SET: "e_url_not_set",
VERSION: "e_version"
};
$.jPlayer.errorMsg = {
FLASH: "jPlayer's Flash fallback is not configured correctly, or a comma
nd was issued before the jPlayer Ready event. Details: ", // Used in: _flashErro
r()
NO_SOLUTION: "No solution can be found by jPlayer in this browser. Neith
er HTML nor Flash can be used.", // Used in: _init()
NO_SUPPORT: "It is not possible to play any media format provided in set
Media() on this browser using your current options.", // Used in: setMedia()
URL: "Media URL could not be loaded.", // Used in: jPlayerFlashEvent() a
nd _addHtmlEventListeners()
URL_NOT_SET: "Attempt to issue media playback commands, while no media u
rl is set.", // Used in: load(), play(), pause(), stop() and playHead()
VERSION: "jPlayer " + $.jPlayer.prototype.version.script + " needs Jplay
er.swf version " + $.jPlayer.prototype.version.needFlash + " but found " // Used
in: jPlayerReady()
};
$.jPlayer.errorHint = {
FLASH: "Check your swfPath option and that Jplayer.swf is there.",
NO_SOLUTION: "Review the jPlayer options: support and supplied.",
NO_SUPPORT: "Video or audio formats defined in the supplied option are m
issing.",
URL: "Check media URL is valid.",
URL_NOT_SET: "Use setMedia() to set the media URL.",
VERSION: "Update jPlayer files."
};
$.jPlayer.warning = {
CSS_SELECTOR_COUNT: "e_css_selector_count",
CSS_SELECTOR_METHOD: "e_css_selector_method",
CSS_SELECTOR_STRING: "e_css_selector_string",
OPTION_KEY: "e_option_key"
};

$.jPlayer.warningMsg = {
CSS_SELECTOR_COUNT: "The number of methodCssSelectors found did not equa
l one: ",
CSS_SELECTOR_METHOD: "The methodName given in jPlayer('cssSelector') is
not a valid jPlayer method.",
CSS_SELECTOR_STRING: "The methodCssSelector given in jPlayer('cssSelecto
r') is not a String or is empty.",
OPTION_KEY: "The option requested in jPlayer('option') is undefined."
};
$.jPlayer.warningHint = {
CSS_SELECTOR_COUNT: "Check your css selector and the ancestor.",
CSS_SELECTOR_METHOD: "Check your method name.",
CSS_SELECTOR_STRING: "Check your css selector is a string.",
OPTION_KEY: "Check your option name."
};
})(jQuery);
/*
* jQuery Cycle Plugin (core engine only)
* Examples and documentation at: http://jquery.malsup.com/cycle/
* Copyright (c) 2007-2010 M. Alsup
* Version: 2.99 (12-MAR-2011)
* Dual licensed under the MIT and GPL licenses.
* http://jquery.malsup.com/license.html
* Requires: jQuery v1.3.2 or later
*/
(function ($) { var ver = "2.99"; if ($.support == undefined) { $.support = { op
acity: !($.browser.msie) }; } function debug(s) { $.fn.cycle.debug && log(s); }
function log() { window.console && console.log && console.log("[cycle] " + Array
.prototype.join.call(arguments, " ")); } $.expr[":"].paused = function (el) { re
turn el.cyclePause; }; $.fn.cycle = function (options, arg2) { var o = { s: this
.selector, c: this.context }; if (this.length === 0 && options != "stop") { if (
!$.isReady && o.s) { log("DOM not ready, queuing slideshow"); $(function () { $(
o.s, o.c).cycle(options, arg2); }); return this; } log("terminating; zero elemen
ts found by selector" + ($.isReady ? "" : " (DOM not ready)")); return this; } r
eturn this.each(function () { var opts = handleArguments(this, options, arg2); i
f (opts === false) { return; } opts.updateActivePagerLink = opts.updateActivePag
erLink || $.fn.cycle.updateActivePagerLink; if (this.cycleTimeout) { clearTimeou
t(this.cycleTimeout); } this.cycleTimeout = this.cyclePause = 0; var $cont = $(t
his); var $slides = opts.slideExpr ? $(opts.slideExpr, this) : $cont.children();
var els = $slides.get(); if (els.length < 2) { log("terminating; too few slides
: " + els.length); return; } var opts2 = buildOptions($cont, $slides, els, opts,
o); if (opts2 === false) { return; } var startTime = opts2.continuous ? 10 : ge
tTimeout(els[opts2.currSlide], els[opts2.nextSlide], opts2, !opts2.backwards); i
f (startTime) { startTime += (opts2.delay || 0); if (startTime < 10) { startTime
= 10; } debug("first timeout: " + startTime); this.cycleTimeout = setTimeout(fu
nction () { go(els, opts2, 0, !opts.backwards); }, startTime); } }); }; function
handleArguments(cont, options, arg2) { if (cont.cycleStop == undefined) { cont.
cycleStop = 0; } if (options === undefined || options === null) { options = {};
} if (options.constructor == String) { switch (options) { case "destroy": case "
stop": var opts = $(cont).data("cycle.opts"); if (!opts) { return false; } cont.
cycleStop++; if (cont.cycleTimeout) { clearTimeout(cont.cycleTimeout); } cont.cy
cleTimeout = 0; $(cont).removeData("cycle.opts"); if (options == "destroy") { de
stroy(opts); } return false; case "toggle": cont.cyclePause = (cont.cyclePause =
== 1) ? 0 : 1; checkInstantResume(cont.cyclePause, arg2, cont); return false; ca
se "pause": cont.cyclePause = 1; return false; case "resume": cont.cyclePause =
0; checkInstantResume(false, arg2, cont); return false; case "prev": case "next"
: var opts = $(cont).data("cycle.opts"); if (!opts) { log('options not found, "p

rev/next" ignored'); return false; } $.fn.cycle[options](opts); return false; de


fault: options = { fx: options }; } return options; } else { if (options.constru
ctor == Number) { var num = options; options = $(cont).data("cycle.opts"); if (!
options) { log("options not found, can not advance slide"); return false; } if (
num < 0 || num >= options.elements.length) { log("invalid slide index: " + num);
return false; } options.nextSlide = num; if (cont.cycleTimeout) { clearTimeout(
cont.cycleTimeout); cont.cycleTimeout = 0; } if (typeof arg2 == "string") { opti
ons.oneTimeFx = arg2; } go(options.elements, options, 1, num >= options.currSlid
e); return false; } } return options; function checkInstantResume(isPaused, arg2
, cont) { if (!isPaused && arg2 === true) { var options = $(cont).data("cycle.op
ts"); if (!options) { log("options not found, can not resume"); return false; }
if (cont.cycleTimeout) { clearTimeout(cont.cycleTimeout); cont.cycleTimeout = 0;
} go(options.elements, options, 1, !options.backwards); } } } function removeFi
lter(el, opts) { if (!$.support.opacity && opts.cleartype && el.style.filter) {
try { el.style.removeAttribute("filter"); } catch (smother) { } } } function des
troy(opts) { if (opts.next) { $(opts.next).unbind(opts.prevNextEvent); } if (opt
s.prev) { $(opts.prev).unbind(opts.prevNextEvent); } if (opts.pager || opts.page
rAnchorBuilder) { $.each(opts.pagerAnchors || [], function () { this.unbind().re
move(); }); } opts.pagerAnchors = null; if (opts.destroy) { opts.destroy(opts);
} } function buildOptions($cont, $slides, els, options, o) { var opts = $.extend
({}, $.fn.cycle.defaults, options || {}, $.metadata ? $cont.metadata() : $.meta
? $cont.data() : {}); if (opts.autostop) { opts.countdown = opts.autostopCount |
| els.length; } var cont = $cont[0]; $cont.data("cycle.opts", opts); opts.$cont
= $cont; opts.stopCount = cont.cycleStop; opts.elements = els; opts.before = opt
s.before ? [opts.before] : []; opts.after = opts.after ? [opts.after] : []; if (
!$.support.opacity && opts.cleartype) { opts.after.push(function () { removeFilt
er(this, opts); }); } if (opts.continuous) { opts.after.push(function () { go(el
s, opts, 0, !opts.backwards); }); } saveOriginalOpts(opts); if (!$.support.opaci
ty && opts.cleartype && !opts.cleartypeNoBg) { clearTypeFix($slides); } if ($con
t.css("position") == "static") { $cont.css("position", "relative"); } if (opts.w
idth) { $cont.width(opts.width); } if (opts.height && opts.height != "auto") { $
cont.height(opts.height); } if (opts.startingSlide) { opts.startingSlide = parse
Int(opts.startingSlide); } else { if (opts.backwards) { opts.startingSlide = els
.length - 1; } } if (opts.random) { opts.randomMap = []; for (var i = 0; i < els
.length; i++) { opts.randomMap.push(i); } opts.randomMap.sort(function (a, b) {
return Math.random() - 0.5; }); opts.randomIndex = 1; opts.startingSlide = opts.
randomMap[1]; } else { if (opts.startingSlide >= els.length) { opts.startingSlid
e = 0; } } opts.currSlide = opts.startingSlide || 0; var first = opts.startingSl
ide; $slides.css({ position: "absolute", top: 0, left: 0 }).hide().each(function
(i) { var z; if (opts.backwards) { z = first ? i <= first ? els.length + (i - f
irst) : first - i : els.length - i; } else { z = first ? i >= first ? els.length
- (i - first) : first - i : els.length - i; } $(this).css("z-index", z); }); $(
els[first]).css("opacity", 1).show(); removeFilter(els[first], opts); if (opts.f
it && opts.width) { $slides.width(opts.width); } if (opts.fit && opts.height &&
opts.height != "auto") { $slides.height(opts.height); } var reshape = opts.conta
inerResize && !$cont.innerHeight(); if (reshape) { var maxw = 0, maxh = 0; for (
var j = 0; j < els.length; j++) { var $e = $(els[j]), e = $e[0], w = $e.outerWid
th(), h = $e.outerHeight(); if (!w) { w = e.offsetWidth || e.width || $e.attr("w
idth"); } if (!h) { h = e.offsetHeight || e.height || $e.attr("height"); } maxw
= w > maxw ? w : maxw; maxh = h > maxh ? h : maxh; } if (maxw > 0 && maxh > 0) {
$cont.css({ width: maxw + "px", height: maxh + "px" }); } } if (opts.pause) { $
cont.hover(function () { this.cyclePause++; }, function () { this.cyclePause--;
}); } if (supportMultiTransitions(opts) === false) { return false; } var requeue
= false; options.requeueAttempts = options.requeueAttempts || 0; $slides.each(f
unction () { var $el = $(this); this.cycleH = (opts.fit && opts.height) ? opts.h
eight : ($el.height() || this.offsetHeight || this.height || $el.attr("height")
|| 0); this.cycleW = (opts.fit && opts.width) ? opts.width : ($el.width() || thi
s.offsetWidth || this.width || $el.attr("width") || 0); if ($el.is("img")) { var
loadingIE = ($.browser.msie && this.cycleW == 28 && this.cycleH == 30 && !this.
complete); var loadingFF = ($.browser.mozilla && this.cycleW == 34 && this.cycle

H == 19 && !this.complete); var loadingOp = ($.browser.opera && ((this.cycleW ==


42 && this.cycleH == 19) || (this.cycleW == 37 && this.cycleH == 17)) && !this.
complete); var loadingOther = (this.cycleH == 0 && this.cycleW == 0 && !this.com
plete); if (loadingIE || loadingFF || loadingOp || loadingOther) { if (o.s && op
ts.requeueOnImageNotLoaded && ++options.requeueAttempts < 100) { log(options.req
ueueAttempts, " - img slide not loaded, requeuing slideshow: ", this.src, this.c
ycleW, this.cycleH); setTimeout(function () { $(o.s, o.c).cycle(options); }, opt
s.requeueTimeout); requeue = true; return false; } else { log("could not determi
ne size of image: " + this.src, this.cycleW, this.cycleH); } } } return true; })
; if (requeue) { return false; } opts.cssBefore = opts.cssBefore || {}; opts.css
After = opts.cssAfter || {}; opts.cssFirst = opts.cssFirst || {}; opts.animIn =
opts.animIn || {}; opts.animOut = opts.animOut || {}; $slides.not(":eq(" + first
+ ")").css(opts.cssBefore); $($slides[first]).css(opts.cssFirst); if (opts.time
out) { opts.timeout = parseInt(opts.timeout); if (opts.speed.constructor == Stri
ng) { opts.speed = $.fx.speeds[opts.speed] || parseInt(opts.speed); } if (!opts.
sync) { opts.speed = opts.speed / 2; } var buffer = opts.fx == "none" ? 0 : opts
.fx == "shuffle" ? 500 : 250; while ((opts.timeout - opts.speed) < buffer) { opt
s.timeout += opts.speed; } } if (opts.easing) { opts.easeIn = opts.easeOut = opt
s.easing; } if (!opts.speedIn) { opts.speedIn = opts.speed; } if (!opts.speedOut
) { opts.speedOut = opts.speed; } opts.slideCount = els.length; opts.currSlide =
opts.lastSlide = first; if (opts.random) { if (++opts.randomIndex == els.length
) { opts.randomIndex = 0; } opts.nextSlide = opts.randomMap[opts.randomIndex]; }
else { if (opts.backwards) { opts.nextSlide = opts.startingSlide == 0 ? (els.le
ngth - 1) : opts.startingSlide - 1; } else { opts.nextSlide = opts.startingSlide
>= (els.length - 1) ? 0 : opts.startingSlide + 1; } } if (!opts.multiFx) { var
init = $.fn.cycle.transitions[opts.fx]; if ($.isFunction(init)) { init($cont, $s
lides, opts); } else { if (opts.fx != "custom" && !opts.multiFx) { log("unknown
transition: " + opts.fx, "; slideshow terminating"); return false; } } } var e0
= $slides[first]; if (opts.before.length) { opts.before[0].apply(e0, [e0, e0, op
ts, true]); } if (opts.after.length) { opts.after[0].apply(e0, [e0, e0, opts, tr
ue]); } if (opts.next) { $(opts.next).bind(opts.prevNextEvent, function () { ret
urn advance(opts, 1); }); } if (opts.prev) { $(opts.prev).bind(opts.prevNextEven
t, function () { return advance(opts, 0); }); } if (opts.pager || opts.pagerAnch
orBuilder) { buildPager(els, opts); } exposeAddSlide(opts, els); return opts; }
function saveOriginalOpts(opts) { opts.original = { before: [], after: [] }; opt
s.original.cssBefore = $.extend({}, opts.cssBefore); opts.original.cssAfter = $.
extend({}, opts.cssAfter); opts.original.animIn = $.extend({}, opts.animIn); opt
s.original.animOut = $.extend({}, opts.animOut); $.each(opts.before, function ()
{ opts.original.before.push(this); }); $.each(opts.after, function () { opts.or
iginal.after.push(this); }); } function supportMultiTransitions(opts) { var i, t
x, txs = $.fn.cycle.transitions; if (opts.fx.indexOf(",") > 0) { opts.multiFx =
true; opts.fxs = opts.fx.replace(/\s*/g, "").split(","); for (i = 0; i < opts.fx
s.length; i++) { var fx = opts.fxs[i]; tx = txs[fx]; if (!tx || !txs.hasOwnPrope
rty(fx) || !$.isFunction(tx)) { log("discarding unknown transition: ", fx); opts
.fxs.splice(i, 1); i--; } } if (!opts.fxs.length) { log("No valid transitions na
med; slideshow terminating."); return false; } } else { if (opts.fx == "all") {
opts.multiFx = true; opts.fxs = []; for (p in txs) { tx = txs[p]; if (txs.hasOwn
Property(p) && $.isFunction(tx)) { opts.fxs.push(p); } } } } if (opts.multiFx &&
opts.randomizeEffects) { var r1 = Math.floor(Math.random() * 20) + 30; for (i =
0; i < r1; i++) { var r2 = Math.floor(Math.random() * opts.fxs.length); opts.fx
s.push(opts.fxs.splice(r2, 1)[0]); } debug("randomized fx sequence: ", opts.fxs)
; } return true; } function exposeAddSlide(opts, els) { opts.addSlide = function
(newSlide, prepend) { var $s = $(newSlide), s = $s[0]; if (!opts.autostopCount)
{ opts.countdown++; } els[prepend ? "unshift" : "push"](s); if (opts.els) { opt
s.els[prepend ? "unshift" : "push"](s); } opts.slideCount = els.length; $s.css("
position", "absolute"); $s[prepend ? "prependTo" : "appendTo"](opts.$cont); if (
prepend) { opts.currSlide++; opts.nextSlide++; } if (!$.support.opacity && opts.
cleartype && !opts.cleartypeNoBg) { clearTypeFix($s); } if (opts.fit && opts.wid
th) { $s.width(opts.width); } if (opts.fit && opts.height && opts.height != "aut
o") { $s.height(opts.height); } s.cycleH = (opts.fit && opts.height) ? opts.heig

ht : $s.height(); s.cycleW = (opts.fit && opts.width) ? opts.width : $s.width();


$s.css(opts.cssBefore); if (opts.pager || opts.pagerAnchorBuilder) { $.fn.cycle
.createPagerAnchor(els.length - 1, s, $(opts.pager), els, opts); } if ($.isFunct
ion(opts.onAddSlide)) { opts.onAddSlide($s); } else { $s.hide(); } }; } $.fn.cyc
le.resetState = function (opts, fx) { fx = fx || opts.fx; opts.before = []; opts
.after = []; opts.cssBefore = $.extend({}, opts.original.cssBefore); opts.cssAft
er = $.extend({}, opts.original.cssAfter); opts.animIn = $.extend({}, opts.origi
nal.animIn); opts.animOut = $.extend({}, opts.original.animOut); opts.fxFn = nul
l; $.each(opts.original.before, function () { opts.before.push(this); }); $.each
(opts.original.after, function () { opts.after.push(this); }); var init = $.fn.c
ycle.transitions[fx]; if ($.isFunction(init)) { init(opts.$cont, $(opts.elements
), opts); } }; function go(els, opts, manual, fwd) { if (manual && opts.busy &&
opts.manualTrump) { debug("manualTrump in go(), stopping active transition"); $(
els).stop(true, true); opts.busy = 0; } if (opts.busy) { debug("transition activ
e, ignoring new tx request"); return; } var p = opts.$cont[0], curr = els[opts.c
urrSlide], next = els[opts.nextSlide]; if (p.cycleStop != opts.stopCount || p.cy
cleTimeout === 0 && !manual) { return; } if (!manual && !p.cyclePause && !opts.b
ounce && ((opts.autostop && (--opts.countdown <= 0)) || (opts.nowrap && !opts.ra
ndom && opts.nextSlide < opts.currSlide))) { if (opts.end) { opts.end(opts); } r
eturn; } var changed = false; if ((manual || !p.cyclePause) && (opts.nextSlide !
= opts.currSlide)) { changed = true; var fx = opts.fx; curr.cycleH = curr.cycleH
|| $(curr).height(); curr.cycleW = curr.cycleW || $(curr).width(); next.cycleH
= next.cycleH || $(next).height(); next.cycleW = next.cycleW || $(next).width();
if (opts.multiFx) { if (opts.lastFx == undefined || ++opts.lastFx >= opts.fxs.l
ength) { opts.lastFx = 0; } fx = opts.fxs[opts.lastFx]; opts.currFx = fx; } if (
opts.oneTimeFx) { fx = opts.oneTimeFx; opts.oneTimeFx = null; } $.fn.cycle.reset
State(opts, fx); if (opts.before.length) { $.each(opts.before, function (i, o) {
if (p.cycleStop != opts.stopCount) { return; } o.apply(next, [curr, next, opts,
fwd]); }); } var after = function () { opts.busy = 0; $.each(opts.after, functi
on (i, o) { if (p.cycleStop != opts.stopCount) { return; } o.apply(next, [curr,
next, opts, fwd]); }); }; debug("tx firing(" + fx + "); currSlide: " + opts.curr
Slide + "; nextSlide: " + opts.nextSlide); opts.busy = 1; if (opts.fxFn) { opts.
fxFn(curr, next, opts, after, fwd, manual && opts.fastOnEvent); } else { if ($.i
sFunction($.fn.cycle[opts.fx])) { $.fn.cycle[opts.fx](curr, next, opts, after, f
wd, manual && opts.fastOnEvent); } else { $.fn.cycle.custom(curr, next, opts, af
ter, fwd, manual && opts.fastOnEvent); } } } if (changed || opts.nextSlide == op
ts.currSlide) { opts.lastSlide = opts.currSlide; if (opts.random) { opts.currSli
de = opts.nextSlide; if (++opts.randomIndex == els.length) { opts.randomIndex =
0; } opts.nextSlide = opts.randomMap[opts.randomIndex]; if (opts.nextSlide == op
ts.currSlide) { opts.nextSlide = (opts.currSlide == opts.slideCount - 1) ? 0 : o
pts.currSlide + 1; } } else { if (opts.backwards) { var roll = (opts.nextSlide 1) < 0; if (roll && opts.bounce) { opts.backwards = !opts.backwards; opts.nextS
lide = 1; opts.currSlide = 0; } else { opts.nextSlide = roll ? (els.length - 1)
: opts.nextSlide - 1; opts.currSlide = roll ? 0 : opts.nextSlide + 1; } } else {
var roll = (opts.nextSlide + 1) == els.length; if (roll && opts.bounce) { opts.
backwards = !opts.backwards; opts.nextSlide = els.length - 2; opts.currSlide = e
ls.length - 1; } else { opts.nextSlide = roll ? 0 : opts.nextSlide + 1; opts.cur
rSlide = roll ? els.length - 1 : opts.nextSlide - 1; } } } } if (changed && opts
.pager) { opts.updateActivePagerLink(opts.pager, opts.currSlide, opts.activePage
rClass); } var ms = 0; if (opts.timeout && !opts.continuous) { ms = getTimeout(e
ls[opts.currSlide], els[opts.nextSlide], opts, fwd); } else { if (opts.continuou
s && p.cyclePause) { ms = 10; } } if (ms > 0) { p.cycleTimeout = setTimeout(func
tion () { go(els, opts, 0, !opts.backwards); }, ms); } } $.fn.cycle.updateActive
PagerLink = function (pager, currSlide, clsName) { $(pager).each(function () { $
(this).children().removeClass(clsName).eq(currSlide).addClass(clsName); }); }; f
unction getTimeout(curr, next, opts, fwd) { if (opts.timeoutFn) { var t = opts.t
imeoutFn.call(curr, curr, next, opts, fwd); while (opts.fx != "none" && (t - opt
s.speed) < 250) { t += opts.speed; } debug("calculated timeout: " + t + "; speed
: " + opts.speed); if (t !== false) { return t; } } return opts.timeout; } $.fn.
cycle.next = function (opts) { advance(opts, 1); }; $.fn.cycle.prev = function (

opts) { advance(opts, 0); }; function advance(opts, moveForward) { var val = mov


eForward ? 1 : -1; var els = opts.elements; var p = opts.$cont[0], timeout = p.c
ycleTimeout; if (timeout) { clearTimeout(timeout); p.cycleTimeout = 0; } if (opt
s.random && val < 0) { opts.randomIndex--; if (--opts.randomIndex == -2) { opts.
randomIndex = els.length - 2; } else { if (opts.randomIndex == -1) { opts.random
Index = els.length - 1; } } opts.nextSlide = opts.randomMap[opts.randomIndex]; }
else { if (opts.random) { opts.nextSlide = opts.randomMap[opts.randomIndex]; }
else { opts.nextSlide = opts.currSlide + val; if (opts.nextSlide < 0) { if (opts
.nowrap) { return false; } opts.nextSlide = els.length - 1; } else { if (opts.ne
xtSlide >= els.length) { if (opts.nowrap) { return false; } opts.nextSlide = 0;
} } } } var cb = opts.onPrevNextEvent || opts.prevNextClick; if ($.isFunction(cb
)) { cb(val > 0, opts.nextSlide, els[opts.nextSlide]); } go(els, opts, 1, moveFo
rward); return false; } function buildPager(els, opts) { var $p = $(opts.pager);
$.each(els, function (i, o) { $.fn.cycle.createPagerAnchor(i, o, $p, els, opts)
; }); opts.updateActivePagerLink(opts.pager, opts.startingSlide, opts.activePage
rClass); } $.fn.cycle.createPagerAnchor = function (i, el, $p, els, opts) { var
a; if ($.isFunction(opts.pagerAnchorBuilder)) { a = opts.pagerAnchorBuilder(i, e
l); debug("pagerAnchorBuilder(" + i + ", el) returned: " + a); } else { a = '<a
href="#">' + (i + 1) + "</a>"; } if (!a) { return; } var $a = $(a); if ($a.paren
ts("body").length === 0) { var arr = []; if ($p.length > 1) { $p.each(function (
) { var $clone = $a.clone(true); $(this).append($clone); arr.push($clone[0]); })
; $a = $(arr); } else { $a.appendTo($p); } } opts.pagerAnchors = opts.pagerAncho
rs || []; opts.pagerAnchors.push($a); $a.bind(opts.pagerEvent, function (e) { e.
preventDefault(); opts.nextSlide = i; var p = opts.$cont[0], timeout = p.cycleTi
meout; if (timeout) { clearTimeout(timeout); p.cycleTimeout = 0; } var cb = opts
.onPagerEvent || opts.pagerClick; if ($.isFunction(cb)) { cb(opts.nextSlide, els
[opts.nextSlide]); } go(els, opts, 1, opts.currSlide < i); }); if (!/^click/.tes
t(opts.pagerEvent) && !opts.allowPagerClickBubble) { $a.bind("click.cycle", func
tion () { return false; }); } if (opts.pauseOnPagerHover) { $a.hover(function ()
{ opts.$cont[0].cyclePause++; }, function () { opts.$cont[0].cyclePause--; });
} }; $.fn.cycle.hopsFromLast = function (opts, fwd) { var hops, l = opts.lastSli
de, c = opts.currSlide; if (fwd) { hops = c > l ? c - l : opts.slideCount - l; }
else { hops = c < l ? l - c : l + opts.slideCount - c; } return hops; }; functi
on clearTypeFix($slides) { debug("applying clearType background-color hack"); fu
nction hex(s) { s = parseInt(s).toString(16); return s.length < 2 ? "0" + s : s;
} function getBg(e) { for (; e && e.nodeName.toLowerCase() != "html"; e = e.par
entNode) { var v = $.css(e, "background-color"); if (v && v.indexOf("rgb") >= 0)
{ var rgb = v.match(/\d+/g); return "#" + hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2
]); } if (v && v != "transparent") { return v; } } return "#ffffff"; } $slides.e
ach(function () { $(this).css("background-color", getBg(this)); }); } $.fn.cycle
.commonReset = function (curr, next, opts, w, h, rev) { $(opts.elements).not(cur
r).hide(); if (typeof opts.cssBefore.opacity == "undefined") { opts.cssBefore.op
acity = 1; } opts.cssBefore.display = "block"; if (opts.slideResize && w !== fal
se && next.cycleW > 0) { opts.cssBefore.width = next.cycleW; } if (opts.slideRes
ize && h !== false && next.cycleH > 0) { opts.cssBefore.height = next.cycleH; }
opts.cssAfter = opts.cssAfter || {}; opts.cssAfter.display = "none"; $(curr).css
("zIndex", opts.slideCount + (rev === true ? 1 : 0)); $(next).css("zIndex", opts
.slideCount + (rev === true ? 0 : 1)); }; $.fn.cycle.custom = function (curr, ne
xt, opts, cb, fwd, speedOverride) { var $l = $(curr), $n = $(next); var speedIn
= opts.speedIn, speedOut = opts.speedOut, easeIn = opts.easeIn, easeOut = opts.e
aseOut; $n.css(opts.cssBefore); if (speedOverride) { if (typeof speedOverride ==
"number") { speedIn = speedOut = speedOverride; } else { speedIn = speedOut = 1
; } easeIn = easeOut = null; } var fn = function () { $n.animate(opts.animIn, sp
eedIn, easeIn, function () { cb(); }); }; $l.animate(opts.animOut, speedOut, eas
eOut, function () { $l.css(opts.cssAfter); if (!opts.sync) { fn(); } }); if (opt
s.sync) { fn(); } }; $.fn.cycle.transitions = { fade: function ($cont, $slides,
opts) { $slides.not(":eq(" + opts.currSlide + ")").css("opacity", 0); opts.befor
e.push(function (curr, next, opts) { $.fn.cycle.commonReset(curr, next, opts); o
pts.cssBefore.opacity = 0; }); opts.animIn = { opacity: 1 }; opts.animOut = { op
acity: 0 }; opts.cssBefore = { top: 0, left: 0 }; } }; $.fn.cycle.ver = function

() { return ver; }; $.fn.cycle.defaults = { activePagerClass: "activeSlide", af


ter: null, allowPagerClickBubble: false, animIn: null, animOut: null, autostop:
0, autostopCount: 0, backwards: false, before: null, cleartype: !$.support.opaci
ty, cleartypeNoBg: false, containerResize: 1, continuous: 0, cssAfter: null, css
Before: null, delay: 0, easeIn: null, easeOut: null, easing: null, end: null, fa
stOnEvent: 0, fit: 0, fx: "fade", fxFn: null, height: "auto", manualTrump: true,
next: null, nowrap: 0, onPagerEvent: null, onPrevNextEvent: null, pager: null,
pagerAnchorBuilder: null, pagerEvent: "click.cycle", pause: 0, pauseOnPagerHover
: 0, prev: null, prevNextEvent: "click.cycle", random: 0, randomizeEffects: 1, r
equeueOnImageNotLoaded: true, requeueTimeout: 250, rev: 0, shuffle: null, slideE
xpr: null, slideResize: 1, speed: 1000, speedIn: null, speedOut: null, startingS
lide: 0, sync: 1, timeout: 4000, timeoutFn: null, updateActivePagerLink: null };
})(jQuery);
// addThis function for use with Flash
var addThis = function () {
addthis_open(document.body, ('more'), '[URL]', '[TITLE]');
};
// add configuration option for GA tracker object
if (typeof (window.cms) != "undefined") {
var addThisConfigure = function () {
if (typeof (window.cms.lang) != "undefined") {
window.addthis_config = {
ui_language: window.cms.lang
}
};
window.addthis_config = {
services_expanded: 'twitter, facebook, googlebuzz, delicious, digg,
more',
//ui_language: window.cms.lang,
ui_use_addressbook: true,
ui_508_compliant: true,
data_track_clickback: false,
data_ga_tracker: typeof window.pageTracker != 'undefined' ? window.p
ageTracker : null
};
window.addthis_share = {
email_template: window.cms.emailTemplate,
templates: {
twitter: '{{title}}: {{url}}'
}
};
};
// add configuration options for addThis on load
var addthis_onload = addThisConfigure();
}
// create jQuery enclosure for compatiblity with other frameworks
; (function ($) {
// set options for menus
var menuOptions = {
sensitivity: 3,
interval: 25
};
// indicate that an overlay is being shown
var showOverlay = function () {

$('body').addClass('overlay');
if (typeof $.overlays == 'undefined') {
$.overlays = 1;
}
else {
$.overlays++;
}
};
// indicate that an overlay is not being shown
var hideOverlay = function () {
$.overlays--;
if ($.overlays <= 0) {
$('body').removeClass('overlay');
$.overlays = 0;
}
};
// set default colorBox options
var colorBoxOptions = {
initialHeight: 20,
initialHeight: 60,
overlayClose: false,
escKey: false,
scrolling: false,
opacity: 0.7,
rel: 'nofollow',
onOpen: function () {
// hide any qTips on opening of colorBox
$('.qtip').qtip('hide');
}
}
// set default open/close functionality for modals
$(document).bind('cbox_open', showOverlay)
.bind('cbox_complete', function (e) {
$('#cboxLoadedContent').addWidgets();
}).bind('cbox_closed', hideOverlay);
// set default colorBox options
$.colorBoxOptions = function (options) {
return $.extend(true, {}, colorBoxOptions, options || {});
};
// apply widgets to grid-popdown content
$('.grid-popdown article:visible.hover').livequery(function () {
$(this).not('.widgeted').addClass('widgeted').addWidgets();
});
// adds widgets within given element
$.fn.addWidgets = function () {
if (this.length > 0) {
// create carousels
$('.carousel .carousel-filmstrip:visible', this).not('.widgeted').ad
dClass('widgeted').carousel({
easing: 'easeInOutExpo'
}).find('li .frame').carouselFrame();

// create tabs
$('.ui-tabs:visible', this).structureTabs().not('.ui-tabs-static').e
ach(function (i) {
// set default tabs options
var options = {
show: function (event, ui) {
$(ui.tab).addClass('ui-state-active').parents('li').sibl
ings('li').find('a.ui-state-active').removeClass('ui-state-active');
$(ui.panel).toggleFormGroup(false).siblings('.ui-tabs-pa
nel').toggleFormGroup(true);
$(ui.panel).not('.widgeted').addClass('widgeted').addWid
gets(true);
}
}
// use cookie persistant in tabs contain forms
if ($(this).hasClass('ui-tabs-form')) {
options.cookie = {
expires: 1
}
}
// create tabs
$(this).tabs(options);
});
// open specific tab on anchor
$('a.ui-tab-select', this).bind('click', function (e) {
e.preventDefault();
var tabPanelId = $(this).url().attr('hash');
var tabPanel = $('[id=' + tabPanelId + ']');
var tabs = tabPanel.parents('.ui-tabs');
var tabIndex = $('.ui-tabs-panel', tabs).index(tabPanel);
tabs.tabs('select', tabIndex);
});
// add custom scrollbars
$('.scrollable:visible', this).jScrollPane({
showArrows: true,
verticalGutter: 0,
horizontalGutter: 0
});
// add truncation to truncated results lists
$('.truncated-results:visible', this).click(function (e) {
var target = $(e.target);
if (target.is('.reveal')) {
var hidden = target.parent('section').find('> ul').data('hid
den') || {};
if (hidden.length) {
var textToggle = target.data('textToggle');

target.data('textToggle', target.text()).text(textToggle
);
hidden.toggleClass('hide');
}
e.preventDefault();
}
}).find('section > ul').each(function (i) {
var limit = 15;
var lis = $('> li', this);
if (lis.length > limit) {
var reveal = $('<a />', {
'href': '#',
'class': 'reveal',
'text': '(View All)'
}).data('textToggle', '(View Less)');
var hidden = lis.filter(':nth-child(n+' + (limit + 1) + ')')
.addClass('hide');
$(this).data('hidden', hidden).parent('section').append(reve
al);
}
});
// add rating widgets
$('.stars:visible', this).starRating({
onSelected: function (url, rating) {
// open modal if url is not empty
if (url != '') {
// create url object
var url = $.url(url);
// add value paramater to url object
url.param('rating', rating);
options = $.colorBoxOptions({
href: url.toString()
});
// open modal
$.colorbox(options);
}
}
});
// add HTML5 audio player with Flash fallback
$('.audio-player:visible', this).each(function (i) {
var file = $(this).attr('data-file');
var options = {
ready: function () {
$(this).jPlayer('setMedia', {
mp3: file
});
},
supplied: 'mp3',
swfPath: '/swf',

solution: 'html, flash',


backgroundColor: '#FFFFFF'
};
$(this).jPlayer(options);
});
// add button hover classes
$('.button, .ui-tabs-nav li a:visible', this).hoverClass();
// position articles within popdown grids
$('.grid-popdown article:visible', this).positionAbsolute().hoverCla
ss(menuOptions);
// add social button to posts
$('.social:visible', this).each(function (i) {
// get title and URL
var title = $(this).attr('data-title');
var url = $(this).attr('data-url');
var offsetTop = $.browser.safari ? 0 : -15;
// configure addThis
var addthisButtonConfig = window.addthis_config;
// configure addThis sharing
var addthisButtonShare = $.extend(true, {}, window.addthis_share
, {
url: url,
title: title
});
// add addThis button
if (typeof (addthis) != "undefined")
addthis.toolbox(this, addthisButtonConfig, addthisButtonShar
e);
});
// attach jQuery UI datepicker to date fields
$('input.form-date', this).datepicker({
firstDay: 0,
dateFormat: 'mm/dd/yy',
monthNames: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'A
ug', 'Sep', 'Oct', 'Nov', 'Dec'],
dayNamesMin: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
nextText: '&#x25B6;',
prevText: '&#x25C0;',
showOn: 'focus',
showAnim: 'fadeIn',
buttonText: '',
showButtonPanel: false,
beforeShowDay: function (date) {
var $this = $(this);
var dates = $(this).data('dates');
var selectable = [
true,
''

];
if (typeof dates == 'object') {
var date = $.datepicker.formatDate('yy-mm-dd', date);
if ($.inArray(date, dates) < 0) {
selectable[0] = false;
}
}
else if ($this.hasClass('form-date-future') && $.datepicker.
formatDate('yymmdd', date) < $.datepicker.formatDate('yymmdd', new Date())) {
selectable[0] = false;
}
return selectable;
}
}).filter('[data-dates]').each(function (i) {
var $this = $(this);
var datesAttr = $this.attr('data-dates');
var dates = jQuery.parseJSON(datesAttr);
var datesArr = new Array();
var numDates = dates.length;
$.each(dates, function (i) {
var date = new Date(dates[i].date);
var dateStr = $.datepicker.formatDate('yy-mm-dd', date);
datesArr.push(dateStr);
});
$this.data('dates', datesArr);
$(this).datepicker('refresh');
//
//
//
//

$.ajax({
url: url,
type: 'GET',
dataType: 'json'

,
//

// data: $.param

//

success: functio

(monthYear),
n(dates){
//
sArr = new Array();
//
ates = dates.length;

var date

//
ates, function(i){
//
var date = new Date(dates[i].date);
//
var dateStr = $.datepicker.formatDate('yy-mm-dd', date);

$.each(d

//
datesArr.push(dateStr);
//
//
ta('dates', datesArr);

var numD

});
$this.da

//
$(this).
datepicker('refresh');
//
}
//
});
}).end().filter(function () {
if ($(this).parents('.shopping-cart').length > 0) {
return true;
}
}).datepicker('option', 'dateFormat', 'mm/dd/yy').end().filter(funct
ion () {
if (!$(this).is('.form-date-empty') && $(this).datepicker('getDa
te') == null) {
return true;
}
}).datepicker('setDate', '+0');
// add modal box functionality
$('a.widget-modal', this).colorbox(colorBoxOptions);
// add tooltip functionality
$('a.widget-tooltip:visible', this).not('.tooltip').addClass('toolti
p').each(function (i) {
// set the URL for the tooltip to load
var url = $(this).attr('href');
// do not add tooltips inside tooltips
if ($(this).parents('.qtip').length == 0) {
// set options for tooltip
var qTipOptions = {
content: {
url: url
},
style: {
width: {
min: 260,
max: 260
},
color: false,
textAlign: 'left',
border: {
width: 3,
color: '#AADEEB'
},
tip: {
corner: 'leftMiddle'
}
},
position: {
adjust: {
screen: true
},
corner: {
target: 'rightMiddle',
tooltip: 'leftMiddle'
},
container: $('.content-container')
},
show: {
solo: true

},
hide: {
fixed: true,
effect: {
type: 'hide'
}
},
api: {
beforeShow: showOverlay,
beforeHide: hideOverlay,
onFocus: function () {
this.elements.contentWrapper.addWidgets();
}
}
};
// change to click event on buttons
if ($(this).hasClass('button')) {
qTipOptions.show.when.event = 'click';
qTipOptions.hide.when.event = 'unfocus';
}
// create tooltip
$(this).click(function (e) {
e.preventDefault();
}).qtip(qTipOptions);
}
});
// create structure for stylization of tables
$('table:visible', this).structureTable();
// create dateCalendar
$('.date-calendar:visible', this).each(function (i) {
var url = $(this).attr('data-url');
//alert(url);
// create url object from URL
var url = $.url(url);
// add data paramaters to url object
url.param({
languageCode: window.cms.lang
});
$(this).dateCalendar({
url: url.toString()
});
}).unbind('click').click(function (e) {
//alert("hey");
if ($(e.target).parents('tbody').length > 0 && $(e.target).is('a
')) {
e.preventDefault();
$('tbody tr td a').removeClass('selected').filter(e.target).
addClass('selected');
var href = $(e.target).attr('href');

if (typeof href == 'string') {


var rel = $(this).attr('id');
var datePickerInst = $(this).data('datepicker');
var date = {
languageCode: window.cms.lang,
year: $.fn.dateCalendar.zeroFill(datePickerInst.draw
Year, 2),
month: $.fn.dateCalendar.zeroFill(datePickerInst.dra
wMonth + 1, 2),
day: $.fn.dateCalendar.zeroFill($(e.target).text(),
2)
};
//alert("hey");
$.ajax({
url: href,
type: 'GET',
dataType: 'html',
data: $.param(date),
success: function (html) {
$('.' + rel + '.park-hours-detail').html(html).a
ddWidgets();
}
});
}
}
});
// open package-calendar links in a modal
$('#package-calendar:visible', this).unbind('click').click(function
(e) {
var target = $(e.target);
if (target.parents('tbody').length > 0 && (target.is('a') || (ta
rget.parents('a').length && (target = $(e.target).parents('a'))))) {
e.preventDefault();
var href = target.attr('href');
if (typeof href == 'string') {
var datePickerInst = $(this).data('datepicker');
var date = {
languageCode: window.cms.lang,
year: $.fn.dateCalendar.zeroFill(datePickerInst.draw
Year, 2),
month: $.fn.dateCalendar.zeroFill(datePickerInst.dra
wMonth + 1, 2),
day: $.fn.dateCalendar.zeroFill($(e.target).text(),
2)
};
$.colorbox({ href: href });
}
}
});
// Associate date select elements with their related calendars
$('.date-calendar-select select:visible', this).change(function () {

var parent = $(this).parents('.date-calendar-select');


var dateCalendar = $('[id=' + parent.attr('rel') + ']');
var month = $('select.month', parent).val();
var year = $('select.year', parent).val();
var date = new Date(month + '1 , ' + year);
dateCalendar.datepicker('setDate', date);
});
// fill status bar to proper amount
$('.content-container .progress progress .complete:visible', this).s
tatusFill();
// fill status bar to proper amount
$('.content-container .payment-progress:visible', this).each(functio
n (i) {
var max = parseInt($(this).attr('data-max')) - 1;
var val = parseInt($(this).attr('data-value')) - 1;
var fill = (val / max) * 100;
$('.fill:visible', this).statusFill(fill);
$('ol li:eq(' + val + '):visible', this).addClass('active');
$('ol li:lt(' + val + '):visible', this).addClass('completed');
});
// structure form elements
$('select, input:checkbox, input:radio, input:file:visible', this).n
ot('.uniformed').addClass('uniformed').uniform().end().filter('select').each(fun
ction (i) {
// create reference for uniform wrapper
var selector = $(this).parent('.selector');
// don't continue if element has not been structured with unifor
m
if (selector.length) {
// wrap text within span with another
$('> span', selector).wrap('<div />');
// get dimensions for select element
var selectWidth = $(this).outerWidth();
// check if a width for the select element was returned
if (selectWidth > 0 && !$(this).hasClass('dimensioned')) {
// get dimensions for selector
var selectorWidth = selector.outerWidth();
var selectorPadding = selectorWidth - selector.width();
// set the width of both the wrapper and the select elem
ent
selectorWidth = selector.width(selectWidth + selectorPad
ding).outerWidth();
$(this).width(selectorWidth).addClass('dimensioned');
}
}
});
// create example text for text fields
$('input[type=text][title]:visible', this).example(function () {
return $(this).attr('title');

});
// replace input submit buttons with formatted button elements
$('input[type=submit]', this).each(function (i) {
var attributes = $(this).get(0).attributes;
var button = $('<button type="submit" />');
$.each(attributes, function (i) {
var name = attributes[i].nodeName;
var val = attributes[i].nodeValue;
if (name == 'value') {
button.html(val)
}
else if (name != 'type') {
button.attr(name, val)
}
});
button.addClass('button action').wrapInner('<span><span><span></
span></span></span>');
$(this).replaceWith(button);
});
}
return this;
};
// define ie-specific plugins if not loaded
$.fn.bgiframe = !$.fn.bgiframe ? function () { return this } : $.fn.bgiframe
;
// remove white space from inline-block elements
// $('nav ul, footer section.nav-internal ul').trimWhiteSpace();
// fix nav drop-downs in IE6
$('header nav > ul > li > .articles, header nav ul.nav-primary > li > ul, he
ader nav#nav-portal ul > li > ul, .content-container .grid-popdown article').bgi
frame();
// structure primary navigation and handle hover
$('header nav ul.nav-primary > li').bind('mouseover', function () {
var menu = $('> ul', this),
menuItems = menu.find('> li'),
menuWidth = menu.width(),
menuItemsWidth = 0;
menuItems.equalHeights().each(function (i) {
menuItemsWidth += $(this).outerWidth(true);
}).not('.ctas').width(function () {
return $(this).width() + Math.floor((menuWidth - menuItemsWidth) / m
enuItems.not('.ctas').length);
});
}).find('> a').structureMenuItem();
//Send tracking info to Google Analytics if a top nav link is clicked.
$('.nav-primary').delegate('a', 'click', function (e) {

//Get text for the link that was clicked.


var linkClickedTitle = $(this).text();
//Get the current link's parent link.
var parentLink = $(this).parents('li:last').find('> a').get(0);
var parentLinkTitle = $(parentLink).text();
try {
//Send tracking info.
if (parentLinkTitle == linkClickedTitle) {
//Current link is top-level so only send info for this link.
_trackLinkClick([this.href, 'Primary Nav Clicks', linkClickedTit
le]);
}
else {
//Current link is sub-level so send info for it and its parent l
ink.
_trackLinkClick([this.href, 'Primary Nav Clicks', parentLinkTitl
e, linkClickedTitle]);
}
}
catch (err) {
if (typeof (console) != "undefined")
console.log(err);
}
});
//Send tracking info to Google Analytics if a footer nav link is clicked.
$('footer').delegate('a', 'click', function (e) {
//Get text for the link that was clicked.
var linkClickedTitle = $(this).text();
//Send tracking info.
_trackLinkClick([this.href, 'Footer Nav Clicks', linkClickedTitle]);
});
// structure breadcrumb
$('.breadcrumb').structureBreadcrumb();
// create equal-height footer sections
$('footer section').equalHeights();
// fix hover support for expanded nav actions
$('header nav.nav-actions > ul li.expanded, header nav.nav-site > ul.nav-pri
mary > li, header nav#nav-portal ul > li, .navbar nav > ul > li').hoverClass(men
uOptions);
// add widgets to all elements within container
$('#aspnetForm').addWidgets();
// structure blocks
$('aside.sidebar-right .block:last-child').addClass('block-last');
// show/hide search box filter
$('.search-box').bind('mouseleave', function (e) {
$('.search-filter', this).removeClass('search-filter-active');
}).find('.search-filter > a').click(function () {
$(this).parents('.search-filter').toggleClass('search-filter-active');
}).end().find('input[type=text]').focus(function () {

$(this).siblings('.search-filter').removeClass('search-filter-active');
});
// disable search submit on
$(document).ready(function () {
$('.search-box button.search').attr('disabled', 'disabled');
$('.search-box input.form-text').keyup(function () {
if ($(this).val() != '') {
$('.search-box button.search').removeAttr('disabled');
} else {
$('.search-box button.search').attr('disabled', 'disabled');
}
});
});
// show/hide language switcher
$('.language-switcher').bind('mouseleave', function (e) {
$(this).removeClass('language-switcher-active');
}).click(function (e) {
e.preventDefault();
$(e.target).parents('.language-switcher').toggleClass('language-switcher
-active');
});
// highlight Web Forms modules on error
$('.scfSingleLineTextBox, .scfEmailTextBox').change(function () {
if ($(this).siblings('.scfValidator').css('display') == 'block') {
$(this).addClass('error');
} else {
$(this).removeClass('error');
}
});
// add reveal link for sub-menu items which contain children
$('aside.sidebar_left ul.nav-sub').click(function (e) {
var target = $(e.target);
if (target.is('a.reveal') && target.siblings('ul').length) {
target.siblings('ul').toggleClass('hide').parent('li').siblings('li'
).find('a.reveal').siblings('ul').addClass('hide');
e.preventDefault();
}
}).find(' > li').each(function (i) {
var $this = $(this);
var ul = $('> ul', this);
if (ul.length && !$('a.active', ul).length) {
var reveal = $('<a />', {
'href': '#',
'class': 'reveal',
'text': '(View All)'
});
var anchor = $('>
var anchorWidth =
var anchorPadding
anchor.css('paddingLeft'));
var revealWidth =

a', $this);
anchor.outerWidth(true);
= parseInt(anchor.css('paddingRight')) + parseInt(
parseInt(ul.addClass('hide').before(reveal).parent

('li').addClass('expanded').find('a.reveal').outerWidth(true));
anchor.width(anchorWidth - anchorPadding - revealWidth - 5);
}
});
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//

toggle the state/province fields in shopping cart payment page


$.fn.toggleStateProvince = function(){
this.each(function(i){
var state = $(this).parents('.country').siblings('.state');
var stateSelect = state.find('.state');
var provinceInput = state.find('.province');
var zip = $(this).parents('.country').siblings('.zip');
var zipLabel = zip.find('.zip')
var postalLabel = zip.find('.postal-code');
var country = $(this).val();
if (country == 'USA')
{
stateSelect.toggleFormGroup(false);
provinceInput.toggleFormGroup(true);
zipLabel.toggleFormGroup(false);
postalLabel.toggleFormGroup(true);
}
else
{
stateSelect.toggleFormGroup(true);
provinceInput.toggleFormGroup(false);
zipLabel.toggleFormGroup(true);
postalLabel.toggleFormGroup(false);
}
});
return this;
};

// toggle the shipping fields in shopping cart payment page


// $.fn.toggleShipping = function(){
// if (this.length > 0)
// {
//
var shippingAddress = $('.content-container .payment #shipping-a
ddress');
//
var shippingOptions = $('.content-container .payment #shipping-o
ptions');
//
//
var shippingType = this.filter(':checked').val();
//
//
if (shippingType == 'custom' || shippingType == 'billing')
//
{
//
shippingOptions.toggleFormGroup(false);
//
}
//
else
//
{
//
shippingOptions.toggleFormGroup(true);
//
}
//

//
//
//
//
//
//
//
//
// }
//
// return
// };

if (shippingType == 'custom')
{
shippingAddress.toggleFormGroup(false);
}
else
{
shippingAddress.toggleFormGroup(true);
}
this;

// toggle the password/postal code fields on user sign in page


//$.fn.togglePasswordPostalCode = function (focus) {
//
if (this.length > 0) {
//
var passwordContainer = this.parents('.user').siblings('.password'
);
//
//
//
//
//
//
//
//
//
//
//

var password = $('.password', passwordContainer);


var postalCode = $('.postal-code', passwordContainer);
if (password.length > 0 && postalCode.length > 0) {
if (this.val().match('@') || this.val() == '') {
password.toggleFormGroup(false);
postalCode.toggleFormGroup(true);
}
else {
password.toggleFormGroup(true);
postalCode.toggleFormGroup(false);
}

//
//

if (focus) {
$('label:not(.disabled) input', passwordContainer).focus()

;
//
//
//

}
}
}

//
return this;
//};
//
//
//
//
//
//
//
//

show/hide shipping address and shipping options on payment page


$('.content-container .payment')
.find('.shipping-type input:radio').toggleShipping().change(function(e){
$(this).toggleShipping();
}).end()
.find('.country select').toggleStateProvince().change(function(){
$(this).toggleStateProvince();
});

// toggle the password/postal code fields on user sign in page


//$('#user-returning .user input[type=text]').togglePasswordPostalCode().blu
r(function () {
//
$(this).togglePasswordPostalCode(true);
//});
// handle Modal AJAX forms
$('#aspnetForm').submit(function (e) {
var contentModal = $('#content-modal[data-action]:visible');
if (contentModal.length > 0) {

// Confirm user.
if ($(this).attr('disabled') == 'disabled') { return false; }
// Declare action.
var eleAction = $(this).attr('disabled', 'disabled').get(0);
e.preventDefault();
var
var
var
var

eleLabel = null;
strLabel = '';
url = contentModal.attr('data-action');
data = $(':input', contentModal).bind('focus', function (evt) {
eleLabel = $(this).parents('label');
strLabel = $(eleLabel).data('label_text');
if (strLabel) { $('strong', eleLabel).text(strLabel); }
}).serialize();
$.ajax({
url: url,
type: 'GET',
dataType: 'json',
data: data,
success: function (data) {
var message = $('.message', contentModal);
if (data.GeneralMessage.length > 0) {
message.text(data.GeneralMessage).show();
}
else {
message.hide();
}
if (data.Success == true) {
message.show().addClass('success');
contentModal.html(message);
}
else {
var eleLabel = null;
var eleLabelInner = null;
$.each(data.Errors, function (i) {
eleLabel = $('[name=' + data.Errors[i].ElementName +
']').parents('label').addClass('error').get(0);
eleLabelInner = $('strong', eleLabel).get(0);
$(eleLabel).data('label_text', $(eleLabelInner).text
());
$(eleLabelInner).text(data.Errors[i].Message);
});
}
$.colorbox.resize();
$(eleAction).removeAttr('disabled');
}
});
}
});
// pause flash video when modal window opens
$(document).ready(function () {
$('a.widget-modal', this).bind('click', function (e) {
e.preventDefault();

try {
window.document["video-player-object"].jsPause();
} catch (err) {
//alert("err : " + err);
}
});
$('.aAddCartSubmitButton', this).bind('click', function (e) {
// e.preventDefault();
try {
//Send click to GA
var product = e.currentTarget;
_trackLinkClick([product.href, 'Select Product Clicks', product.
id, product.title]);
} catch (err) {
console.log("err : " + err);
}
});
});
// set behavior for external links using urlToolbox
var externalLinkSelector = 'a:external, a[href$=".pdf"], a[href$=".mp3"]';
if ($.browser.msie && $.browser.version < 9) {
externalLinkSelector = 'a:external';
}
$(externalLinkSelector).externalLink();
})(jQuery);
$('input.compare').live('click', function () {
var ids = '';
$('input.compare:checked').each(function (index, element) {
ids += $(element).val() + ",";
});
$('.widget-modal.compare').attr('href', '/ajax/TicketCompare.aspx?ids=' + id
s.substr(0, ids.length - 1));
});
// add placeholder add-to-cart modal windows
//$('a.button-alt, a.button-small-alt', '.book-online .content-container').addCl
ass('widget-modal').attr('href', '/_ajaxplaceholder/select-product.html').parent
s('.content-container').addWidgets();
//sorted content tabs
$('.sorted-content-nav').click(function (e) {
if ($(e.target).is('a')) {
e.preventDefault();
var anchor = $(e.target);
anchor.parents('li').addClass('active').siblings('li').removeClass('acti
ve');
if ($(this).hasClass('tabs')) {
$(anchor.attr('href')).show().siblings('.sorted-content-tab').hide()
;
$('.sorted-content-tab').addWidgets();
//Send click to GA
var sortedContentNavTitle = anchor[0].rel;

var sortedContentNavTab = anchor[0].innerText;


_trackLinkClick([anchor.attr("href"), 'Tab Clicks', sortedContentNav
Title, sortedContentNavTab]);
}
else {
var sortedContentId = anchor.parents('li').children('span.cmsItemId'
).first().text();
var all = anchor.hasClass('all') ? '1' : '';
var data = new Object();
switch (anchor.attr('rel')) {
case 'attractions':
url = '/ajax/EventSorterAjaxLayout.ashx';
data.m = 'all';
data.homeItemId = $('#homeItemId').text();
break;
case 'events':
url = '/ajax/EventSorterAjaxLayout.ashx';
data.m = 'byMonth';
data.date = sortedContentId;
data.homeItemId = $('#homeItemId').text();
break;
default:
url = '/ajax/SortedContentAjaxLayout.ashx';
data.cmsItemId = sortedContentId;
data.all = all;
}
//
//
//
//
//
//
//
//
//

$.ajax({
url: url,
type: 'GET',
dataType: 'json',
data: $.param(data),
success: function (json) {
WriteSortedContent(json);
}
});

}
}
});
function WriteSortedContent(content) {
$('#attractions, #dining, #events').empty();
for (var i = 0; i < content.length; i++) {
$('#attractions').append(CreateAttraction(content[i]));
}
if ($('#dining').length > 0) {
for (var i = 0; i < content.length; i++) {
$('#dining').append(CreateDining(content[i]));
}
}
if ($('#events').length > 0) {
for (var i = 0; i < content.length; i++) {

$('#events').append(CreateEvent(content[i]));
}
}
$('.content-box-inner').addWidgets();
window.cms.initFacebookLike('.btn_facebook_like');
}
function CreateAttraction(item) {
if (item == null) { return ''; }
var article = $('<article />').append('<a href="' + item.Link + '"><img src=
"' + item.Image + '" alt="' + item.Title + '" /></a><h1>' + item.Title + '</h1><
div class="content-popdown">' + item.Body + '<p class="actions"><a class="button
button-alt" href="' + item.Link + '"><span><span><span>Learn More</span></span>
</span></a></p><p class="social"><div class="rating"><div class="total"><span><s
pan>0</span></span></div><div class="stars" data-value="' + item.AverageRating +
'" data-max="5" data-url="/ajax/RatingAjaxLayout.ashx?cmsHomeId=' + window.cms.
homeId + '&cmsItemId=' + item.Id + '&m=CreateRatingWithLink" ></div><div class="
avg"></div></div><div class="btn_facebook_like " data-url="http://' + window.loc
ation.hostname + '/ajax/FacebookLike.aspx?id=' + item.Id + ';http://' + window.l
ocation.hostname + '/ajax/FavoriteAjaxLayout.ashx?m=CreateFavorite"></div></p></
div>');
var strRatingAndReviewUrl = getRatingAndReviewUrl(item);
var article = $('<article />').append('<a href="' + item.Link + '"><img src=
"' + item.Image + '" alt="' + item.Title + '" /></a><h1>' + item.Title + '</h1><
div class="content-popdown">' + item.Body + '<p class="actions"><a class="button
button-alt" href="' + item.Link + '"><span><span><span>Learn More</span></span>
</span></a></p><p class="social"><div class="rating"><div class="total"><span><s
pan>0</span></span></div><div class="stars" data-value="' + item.AverageRating +
'" data-max="5" data-url="' + strRatingAndReviewUrl + '"></div><div class="avg"
></div></div><div class="btn_facebook_like " data-url="http://' + window.locatio
n.hostname + '/ajax/FacebookLike.aspx?id=' + item.Id + ';http://' + window.locat
ion.hostname + '/ajax/FavoriteAjaxLayout.ashx?m=CreateFavorite"></div></p></div>
');
return article;
}
function CreateDining(item) {
if (item == null) { return ''; }
var strRatingAndReviewUrl = getRatingAndReviewUrl(item);
var article = $('<article />').append('<img src="' + item.Image + '" alt="'
+ item.Title + '" /><div class="content"><h1>' + item.Title + '</h1><p>' + item.
Body + '</p><div class="actions-info clearfix"><p class="actions"><a href="' + i
tem.Link + '" class="button button"><span><span><span>Learn More</span></span></
span></a></p><ul class="info-icons info-icons-dining"></ul></div><p class="socia
l"><div class="rating"><div class="total"><span><span>0</span></span></div><div
class="stars" role="rating" data-value="' + item.AvergeRating + '" data-max="5"
data-url="' + strRatingAndReviewUrl + '"></div><div class="avg"></div></div></p>
<ul class="social" data-url="' + item.Link + '" data-title="' + item.Title + '">
<li class="share first"><a href="#" class="addthis_button_expanded">Share</a></l
i></ul></div>');
return article;
}
function CreateEvent(item) {
if (item == null) { return ''; }
var article = $('<article />').append('<img src="' + item.Image + '" alt="'

+ item.Title + '" /><h1>' + item.Title + '</h1><p class="date">' + item.StartDat


e + ' - ' + item.EndDate + '</p><div class="content-popdown">' + item.Body + '<p
class="actions"><a class="button button-alt" href="' + item.Link + '"><span><sp
an><span>Learn More</span></span></span></a></p><div class="social"><div class="
total"><span><span>' + item.CommentCount + '</span></span></div><div class="star
s" data-url="/ajax/SortedContentAjaxLayout.ashx?m=CreateRating&cmsItemId=' + ite
m.Id + '" data-value="' + item.AverageRating + '" data-max="5"></div><div class=
"avg">' + item.AverageRating + '</div><ul class="social" data-url="' + item.Link
+ '" data-title="' + item.Title + '"><li class="share last"><a href="#" class="
addthis_button_expanded">Share</a></li></ul></div>');
return article;
}
function getRatingAndReviewUrl(item) {
// Validate user has profile.
if (typeof window.cms === 'object' && window.cms.userProfileId.length > 0) {
return '/ajax/RatingsReviews.aspx?cmsHomeId=' + window.cms.homeId + '&am
p;cmsItemId=' + item.Id + '&amp;rating=0';
} else {
return '/ajax/RatingAjaxLayout.ashx?cmsHomeId=' + window.cms.homeId + '&
amp;cmsItemId=' + item.Id + '&amp;m=CreateRatingWithLink';
}
}
//allergen filter
$('#main').delegate('#allergen-filter', 'change', function (e) {
if ($('#negative-filter').val() != 'All') {
var value = $(this).val();
$('#negative-filter').val('All').change();
$(this).val(value);
}
$('#negative-filter option').removeAttr('selected');
$('#negative-filter option').first().attr('selected', 'selected');
$('#allergen-table .filter').removeClass('filter');
$('#allergen-table tbody tr').has('td.' + $(this).val()).addClass('filter');
});
$('#main').delegate('#negative-filter', 'change', function (e) {
if ($('#allergen-filter').val() != 'All') {
var value = $(this).val();
$('#allergen-filter').val('All').change();
$(this).val(value);
}
if ($(this).val() != 'All') {
$('#allergen-table tbody tr').addClass('filter');
$('#allergen-table tbody tr').has('td.' + $(this).val()).removeClass('fi
lter');
} else {
$('#allergen-table tbody tr.filter').removeClass('filter');
}
});
$('#main').delegate('#restaurant-filter', 'change', function () {
$('#allergen-table tbody tr').show();
if ($(this).val() != 'All') {
$('#allergen-table tbody tr:not(.' + $(this).val() + ')').hide();
}
});
$('.park-hours select.month, .park-hours select.year').change(function () {
$('.park-hours-detail.park-hours-calendar').html('');
});

//ratings widget
$('#rate-1, #rate-2, #rate-3, #rate-4, #rate-5').click(function () {
sendRequest($(this).attr('id').substr($(this).attr('id').length - 1, 1));
return false;
});
function sendRequest(rating) {
var eleTarget = $('#response');
var objDataParameters = {
input: '<%=Sitecore.Context.Item.ID.ToString() %>'
};
$.post('/ajax/RatingAjaxLayout.ashx?m=CreateRating&cmsItemId=' + objDataPara
meters.input + '&cmsItemParentId=' + objDataParameters.input + '&value=' + ratin
g, objDataParameters, function (data, status) {
if (status == 'success') {
$(eleTarget).text(data);
//$(eleButton).removeAttr('disabled');
} else {
throw (status);
}
});
}
$('.btn_review').bind('click', function (e) {
if ($(this).attr('disabled') == 'disabled') { return false; }
// Init.
var eleButton = $(this).attr('disabled', 'disabled').get(0);
var eleTarget = $('.reviews').get(0);
//
// Set data parameters.
//
var objDataParameters = {
//
input:'{3A1FB0FC-07C4-4733-9E84-E94145065BBE}'
//
};
//
// Perform AJAX.
//
$.post('ajax/RatingAjaxLayout.ashx?m=Debug', objDataParameters,
function(data, status) {
//
if(status == 'success') {
//
$(eleTarget).text(data);
//
$(eleButton).removeAttr('disabled');
//
} else {
//
throw(status);
//
}
//
});
// Prevent default action.
return false;
});
var sendButtons = $('.fb-send');
if (sendButtons != 'undefined') {
(function (d) {
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) { return; }
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js"; // #xfbml=1"; -> removed
per http://stackoverflow.com/questions/10415884/fb-init-has-already-been-called
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
//$('body').prepend('<div id="fb-root"></div>'); //Page Editor Breaks;
}
function updateSend(share_url) {
$('.fb-send').attr('data-href', share_url);
}

function moveSend(x, y) {
$('.fb-send-wrapper').css({ 'top': y, 'left': x });
}
function moveSendHome(position) {
var x = 0;
var y = 0;
if (position == 1) {
x = 878;
y = 413;
}
if (position == 2) {
x = 861;
y = 403;
}
moveSend(x, y);
}
function moveSendVideo(position) {
var x = 0;
var y = 0;
if (position == 1) {
x = 725;
y = 408;
}
if (position == 2) {
x = 725;
y = 408;
}
moveSend(x, y);
}
function hideSend() {
$('.fb-send-wrapper').hide();
}
function showSend() {
$('.fb-send-wrapper').show();
}

/********** JavaScript functions for BookOnline ********************************


******************/
var maLinkData = new Array();
function tabLink(pipeData) {
// Accepts a pipe-delimited string of control IDs that relate to a single
// tab and returns the actual controls as they exist on the page.
var saIDs = pipeData.split("|");
var tab = document.getElementById(saIDs[0]); // Div containing the Tab's Lin
k and Label controls.
var lnk = document.getElementById(saIDs[1]); // The Tab's Link control (disp
layed when not active).
var lbl = document.getElementById(saIDs[2]); // The Tab's Label control (dis

played when active).


var pnl = document.getElementById(saIDs[3]); // The related Div containing t
he Pass Types.
return { tab: tab, link: lnk, label: lbl, panel: pnl };
}
$(document).ready(function () {
var sLoc = location.href.toLowerCase();
if (sLoc.indexOf("/tickets") > 0) {
initTicketsPage();
} else if (sLoc.indexOf("/basic-info") > 0) {
initBasicInfoPage();
}
});
function initTicketsPage() {
maLinkData = new Array();
var lnkData = null;
// maTabLinks[] is an Array of control IDs that are written to the page from
the code behind.
if ((typeof (maTabLinks) != "undefined") && (maTabLinks.length > 0)) {
// Create an Array of tabLink objects that reference the related control
s for each tab.
for (var i = 0; i < maTabLinks.length; i++) {
lnkData = new tabLink(maTabLinks[i]);
// Bind each Link to the setActiveTab() function.
//lnkData.link.onclick = function (index) { return setActiveTab(inde
x) } (i);
$("#" + lnkData.link.id).bind('click', function (event) {
return tabClick(event, this);
});
maLinkData[i] = lnkData;
}
// If the users hits this page from the back button or a Page refresh,
// this will restore the Active Tab to its previous index.
var sIdx = (window.location.hash + "").replace("#", "");
var iIdx = (isNaN(parseInt(sIdx))) ? 0 : parseInt(sIdx);
if (iIdx >= maTabLinks.length) iIdx = 0;
setActiveTab(iIdx);
}
}
function initBasicInfoPage() {
$("#" + txtAdultCountID).bind('blur', saveBasicInfoData);
$("#" + txtChildCountID).bind('blur', saveBasicInfoData);
$("#" + txtInfantCountID).bind('blur', saveBasicInfoData);
// $("#" + optTravelDatesKnownID).bind('click', function (event) { optionCh
ange(event, this); });
// $("#" + optTravelDatesUnknownID).bind('click', function (event) { option
Change(event, this); });
// $("#" + txtDateFromID).bind('change', validateDateChange);
// $("#" + txtDateToID).bind('change', validateDateChange);
$("#" + optYesID).bind('click', function (event) { optionChange(event, this)
; });
$("#" + optNoID).bind('click', function (event) { optionChange(event, this);
});
$("#" + txtZipCodeID).bind('blur', saveBasicInfoData);
$("#" + selCountryID).bind('change', saveBasicInfoData);
}

function validateDateChange() {
ele = $(".crevDateFieldsTo").get(0);
ValidatorValidate(ele);
}
function validateFromDatesConfiguration(source, arguments) {
arguments.IsValid = validateDateConfiguration();
ele = $(".crevDateFieldsTo").get(0);
if (this.eleState == null) {
this.eleState = 'true';
}
//determine if other date field was already checked
if (eleState != 'false') {
this.eleState = 'false';
ValidatorValidate(ele);
}
this.eleState = null;
eleValidator = $(".crevDateFieldsTo");
eleValidator1 = $(".crevDateFieldsFrom");
if (arguments.IsValid) {
$(eleValidator).hide();
$(eleValidator1).hide();
} else {
$(eleValidator).show();
$(eleValidator1).show();
}
}
function validateToDatesConfiguration(source, arguments) {
arguments.IsValid = validateDateConfiguration();
el = $(".crevDateFieldsFrom").get(0);
if (this.eleState == null) {
this.eleState = 'true';
}
//determine if other date field was already checked
if (eleState != 'false') {
this.eleState = 'false';
ValidatorValidate(ele);
}
this.eleState = null;
eleValidator = $(".crevDateFieldsTo");
eleValidator1 = $(".crevDateFieldsFrom");
if (arguments.IsValid) {
$(eleValidator).hide();
$(eleValidator1).hide();
} else {
$(eleValidator).show();
$(eleValidator1).show();
}
}

function validateDateConfiguration() {
var dateFrom = new Date($("#" + txtDateFromID).val());
var dateTo = new Date($("#" + txtDateToID).val());
if (dateFrom > dateTo) { //invalid: end date before start date
return false;
} else {
return true;
}
}
function saveBasicInfoData() {
var sQueryStr = "AdultCount=" + escape($("#" + txtAdultCountID).val()) +
"&ChildCount=" + escape($("#" + txtChildCountID).val()) +
"&InfantCount=" + escape($("#" + txtInfantCountID).val()) +
//
"&TravelDatesKnown=" + (($("#" + optTravelDatesKnownID).attr("ch
ecked")) ? "true" : "false") +
//
"&DateFrom=" + escape($("#" + txtDateFromID).val()) +
//
"&DateTo=" + escape($("#" + txtDateToID).val()) +
"&IsUSResident=" + (($("#" + optYesID).attr("checked")) ? "true"
: "false") +
"&Country=" + escape($("#" + selCountryID).val()) +
"&ZipCode=" + escape($("#" + txtZipCodeID).val());
CallbackToServer(sQueryStr);
}
function optionChange(event, srcElem) {
var sPnlID = null;
var bDisabled = false;
switch (srcElem.id) {
//
case optTravelDatesKnownID:
//
sPnlID = pnlTravelDatesDatesID;
//
bDisabled = false;
//
break;
//
case optTravelDatesUnknownID:
//
sPnlID = pnlTravelDatesDatesID;
//
bDisabled = true;
//
break;
case optYesID:
sPnlID = pnlEnterZipCodeID;
bDisabled = false;
break;
case optNoID:
sPnlID = pnlEnterZipCodeID;
bDisabled = true;
break;
}
//
if (srcElem.id == optTravelDatesKnownID || srcElem.id == optTravelDate
sUnknownID){
//
if (bDisabled) {
//
$("#" + sPnlID + " :input").attr("disabled", "disabled");
//
$("#" + sPnlID).attr("disabled", "disabled");
//
} else {
//
$("#" + sPnlID + " :input").removeAttr("disabled");
//
$("#" + sPnlID).removeAttr("disabled");
//
}
//
}

if (srcElem.id == optYesID || srcElem.id == optNoID) {


var sPnlID1 = pnlSelectCountryID;
if (bDisabled) {
$("#" + sPnlID + " :input").val("")
$("#" + sPnlID).css("display", "none");
$("#" + sPnlID1).css("display", "block");
} else {
$("#" + sPnlID).css("display", "block");
$("#" + sPnlID1).css("display", "none");
}
}
saveBasicInfoData();
}
function showAddToCartPopup(event, srcElem) {
var sData = $(srcElem).next().text();
var saData = sData.split("|");
if (saData.length > 1) {
var sCatalogGuid = saData[0];
var sSellGroupGuid = saData[1];
var sURL = "/ajax/BookOnlineCartInput.ashx?CatalogGuid="
+ sCatalogGuid + "&SellingGroupGuid=" + sSellGroupGuid;
$.post(sURL, function (data, status) {
if ((status == "success") && (data.length > 0)) {
var divPopup = $("#divAddToCartPopup");
if (divPopup != null) {
divPopup.html(data);
displayPopupAtButton(srcElem);
}
}
});
}
}
function updateShoppingCart(event, srcElem) {
var sData = $(srcElem).next().text();
var saData = sData.split("|");
if (saData.length > 1) {
var sCatalogGuid = saData[0];
var sSellGroupGuid = saData[1];
var sURL = "/ajax/BookOnlineCartInput.ashx?CatalogGuid=" +
sCatalogGuid + "&SellingGroupGuid=" + sSellGroupGuid +
"&Values=" + getCartPopupValues();
$.post(sURL, function (data, status) {
if ((status == "success") && (data.length > 0)) {
if (data.toLowerCase().indexOf("success:") == 0) {
hideAddToCartPopup();
saTotals = data.substr("success:".length).split("|");
if (saTotals.length > 1) showCartTotals(saTotals[0], saTotal
s[1]);
data = "";
} else if (data.length > 0) {
divPopup = $("#divAddToCartPopup");
if (divPopup != null) {
divPopup.html(data);
displayPopupAtButton(srcElem);

}
} else {
hideAddToCartPopup();
}
}
});
}
}
function displayPopupAtButton(button) {
var divPopup = $("#divAddToCartPopup");
var tblPopup = $("#divAddToCartPopup table:first");
var rcBtn = getElemPageRect(button);
if ((divPopup != null) && (tblPopup != null)) {
divPopup.css("visibility", "visible");
var iWidth = tblPopup.outerWidth();
if (!rcBtn.isEmpty) {
divPopup.css("left", (rcBtn.left - iWidth).toString() + "px");
divPopup.css("top", rcBtn.top.toString() + "px");
}
if (iWidth > 0) {
divPopup.css("width", iWidth.toString() + "px");
}
}
var firstInput = $("#divAddToCartPopup input:first");
if ((firstInput == null) || (firstInput.width() == null)) {
firstInput = $("#divAddToCartPopup button:first");
}
if ((firstInput != null) && (firstInput.width() != null)) {
firstInput.focus();
}
}
function getCartPopupValues() {
var sValues = "";
var divPopup = $("#divAddToCartPopup");
$("#divAddToCartPopup input[type=text]").each(function () {
if (sValues.length > 0) sValues += "|";
sValues += $(this).context.id + "~" + $(this).val();
});
return sValues;
}
function hideAddToCartPopup(values) {
var divPopup = $("#divAddToCartPopup");
if (divPopup != null) {
divPopup.css("visibility", "hidden");
divPopup.css("left", "0px");
divPopup.css("top", "0px");
divPopup.css("width", "10px");
}
}
function showCartTotals(totalAmount, totalItems) {
$(".clsShoppingCartTotalAmount").each(function (e) {
e.text(totalAmount);
});
//$(".clsShoppingCartTotalItems").each(function (e) {
//e.text(totalItems);
//});

}
function fillAddToCartPopup(cartData) {
if ((typeof (cartData) != "undefined") && (cartData != null)) {
if ((typeof (cartData.SelectedPlus) != "undefined") && (cartData.Selecte
dPlus.length > 0)) {
var divPopup = document.getElementById("divAddToCartPopup");
if (divPopup != null) {
var sTR = "\t<tr valign=\"middle\">\n";
var sTD = "\t\t<td align=\"left\" style=\"white-space:nowrap;\">
\n";
var sLbl = "\t\t\t<label>[LABEL]</label>";
var sInp = "<input type=\"text\" size=\"4\" value=\"\" />\n";
var sHTML = "<table cellpadding=\"5\" cellspacing=\"0\" style=\"
width:50px;\">\n";
for (var i = 0; i < cartData.SelectedPlus.length; i++) {
sHTML += (sTR + sTD + sLbl.replace("[LABEL]", cartData.Selec
tedPlus[i].LabelText) + "\t\t</td>\n" + sTD);
switch (aryData[i].DataType.toLowerCase()) {
case "input":
sHTML += sInp;
break;
case "date":
sHTML += sInp;
break;
}
sHTML += "\t\t</td>\n\t</tr>\n";
}
var sText = (typeof (msAddToCartText) != "undefined") ? msAddToC
artText : "";
sTD = "\t\t<td align=\"center\" colspan=\"2\" style=\"white-spac
e:nowrap;\">\n"
var sBtn = "\t\t\t<button class=\"button\" onclick=\"alert('Add
call to the cart " +
"function here.'); hideAddToCartPopup(); return
false;\"><span><span><span>" +
sText + "</span></span></span></button>\n";
sHTML += (sTR + sTD + sBtn + "\t\t</td>\n\t</tr>\n</table>\n");
divPopup.innerHTML = sHTML;
return true;
}
}
}
return false;
}
function getElemPageRect(elem) {
var iLeft = 0, iTop = 0, iWidth = 0, iHeight = 0;
try {
iWidth = elem.offsetWidth;
iHeight = elem.offsetHeight;
if ((iWidth > 0) && (iHeight > 0)) {
with ($("#" + elem.id).offset()) {
iLeft = left; iTop = top;
}
}
} catch (e) {
iWidth = 0; // Triggers the IsEmpty switch below.
}
var bIsEmpty = ((iWidth == 0) || (iHeight == 0)) ? true : false;

if (bIsEmpty) { iLeft = 0; iTop = 0; iWidth = 0; iHeight = 0; }


return { left: iLeft, top: iTop, width: iWidth, height: iHeight, isEmpty: bI
sEmpty };
}
function getElemRect(elem) {
// Returns the coordinate rectangle (left, top, width, height, right, bottom
) of any element.
if ((elem == null) || (elem.offsetLeft == null)) return null;
var iLeft = toInt(elem.offsetLeft), iTop = toInt(elem.offsetTop);
var iWidth = toInt(elem.offsetWidth), iHeight = toInt(elem.offsetHeight);
var nxtParent = elem.parentNode;
var offParent = elem.offsetParent;
while (nxtParent != null) {
if (((nxtParent.tagName) && (nxtParent.tagName.toUpperCase() == "DIV"))
|| (nxtParent == offParent)) {
iLeft += toInt(nxtParent.offsetLeft); iTop += toInt(nxtParent.offset
Top);
if (nxtParent.scrollLeft) iLeft -= toInt(nxtParent.scrollLeft);
if (nxtParent.scrollTop) iTop -= toInt(nxtParent.scrollTop);
iBrdrWd = 0; iBrdrHt = 0;
try {
iBrdrWd = toInt(getElemCurrentStyle(nxtParent, "border-width"));
iBrdrHt = toInt(getElemCurrentStyle(nxtParent, "border-Height"))
;
} catch (e) { iBrdrWd = 0; iBrdrHt = 0; }
iLeft += iBrdrWd; iTop += iBrdrHt;
}
if ((nxtParent.tagName) && (nxtParent.tagName.toUpperCase() == "BODY"))
break;
if (nxtParent == offParent) offParent = nxtParent.offsetParent;
nxtParent = nxtParent.parentNode;
}
function toInt(x) {
var sNbr = trim(x + ""), iNbr = 0;
try { iNbr = (isNaN(parseInt(sNbr, 10))) ? 0 : parseInt(sNbr, 10); } cat
ch (e) { iNbr = 0; }
return iNbr;
}
function trim(s) {
return s.replace(/^\s*/, "").replace(/\s*$/, "");
}
return { left: iLeft, top: iTop, width: iWidth, height: iHeight };
}
function getElemCurrentStyle(elem, cssRule) {
var sReturn = "";
if (isObject(elem)) {
if (typeof (elem) == "string") elem = document.getElementById(elem);
} else {
return sReturn;
}
if (isObject(cssRule)) {
var rule = getStyleRuleName(cssRule);
if (document.defaultView && document.defaultView.getComputedStyle) {
sReturn = document.defaultView.getComputedStyle(elem, null).getPrope
rtyValue(rule.cssName);
} else if (elem.currentStyle) {
sReturn = elem.currentStyle[rule.propName];
}

}
function isObject(obj) {
return ((obj) && (obj != null) && (typeof (obj) != "undefined")) ? true
: false;
}
return sReturn;
}
function getStyleRuleName(cssRule) {
var sProp = cssRule, sCss = cssRule, sChar = "", bUpper = false, i = 0;
if (cssRule.indexOf("-") >= 0) {
sProp = "";
for (i = 0; i < cssRule.length; i++) {
sChar = cssRule.substr(i, 1);
if (sChar == "-") {
bUpper = true;
} else {
sProp += ((bUpper) ? sChar.toUpperCase() : sChar.toLowerCase());
bUpper = false;
}
}
} else if (cssRule.toLowerCase() != cssRule) {
sCss = "";
for (i = 0; i < cssRule.length; i++) {
sChar = cssRule.substr(i, 1);
if (sChar.toLowerCase() != sChar) sCss += "-";
sCss += sChar.toLowerCase();
}
}
return { propName: sProp, cssName: sCss };
}
function tabClick(event, srcElem) {
// Show/Hide the controls pertaing to each Tab based on the Active Tab (pass
ed by the index parameter).
// var bActive = false;
// var srcElement = (event.target) ? event.target : event.srcElement;
for (var i = 0; i < maLinkData.length; i++) {
if (maLinkData[i].link == srcElem) return setActiveTab(i);
}
}
function setActiveTab(index) {
// Show/Hide the controls pertaing to each Tab based on the Active Tab (pass
ed by the index parameter).
var bActive = false;
for (var i = 0; i < maLinkData.length; i++) {
bActive = (i == index) ? true : false;
if (maLinkData[i].tab != null) maLinkData[i].tab.className = (bActive) ?
"clsActiveTab" : "clsNormalTab";
if (maLinkData[i].link != null) maLinkData[i].link.style.display = (bAct
ive) ? "none" : "";
if (maLinkData[i].label != null) maLinkData[i].label.style.display = (bA
ctive) ? "" : "none";
if (maLinkData[i].panel != null) maLinkData[i].panel.style.display = (bA
ctive) ? "" : "none";
}
// Store the last Active Tab index for page refreshes and/or returns.
window.location.hash = index.toString();
return false; // Stop the hyperlink from submitting the page.

}
function showMessage(message, title, buttons, callback, defaultIndex, cancelInde
x) {
$('#messageSEA').remove();
$('body').append('<div id="messageSEA"></div>');
var wrapper = $('#messageSEA');
wrapper.append("<div></div>");
var msg = $('div', wrapper);
if (typeof (title) != 'undefined') {
title = $("<h1>" + title + "</h1><br />");
if (title.text().length > 0)
msg.append(title);
}
if (typeof (message) != 'undefined') {
message = $("<p>" + message + "</p><br />");
if (message.text().length > 0)
msg.append(message);
}
msg.append("<div></div>");
if (msg.text().length > 0) {
var box = $('div', msg);
$('input', box).remove();
if (typeof (buttons) == 'string') {
buttons = new Array(buttons);
}
if (typeof (buttons) == 'undefined' || buttons.length == 0) {
buttons = new Array('OK');
}
if (buttons.length == 1) {
cancelIndex = 0;
defaultIndex = 0;
}
if (cancelIndex >= buttons.length)
cancelIndex = -1;
if (defaultIndex >= buttons.length)
defaultIndex = -1;
for (var i = 0; i < buttons.length; i++) {
box.append('<span class="button action" data-value="' + buttons[i] +
'"><span><span><span>' + buttons[i] + '</span></span></span></span>');
}
var btns = $('span.button', box);
btns.click(function () {
if (typeof (callback) == 'function')
callback($(this).data('value'));
$('#messageSEA').remove();
});
wrapper.keypress(function (e) {
if ((e.which == 13) && defaultIndex >= 0 && defaultIndex < btns.leng
th) {
e.preventDefault();
$(btns[defaultIndex]).trigger('click');
}
else if (e.which == 27 && cancelIndex >= 0 && cancelIndex < btns.len
gth) {
e.preventDefault();
$(btns[cancelIndex]).trigger('click');

}
});
var height = msg.outerHeight();
var width = Math.max(Math.min(Math.max($('h1', msg).outerWidth(), $('p',
msg).outerWidth(), $('div', msg).outerWidth()), window.innerWidth), 200);
msg.css('margin-top', height / -2 + 'px');
msg.css('width', width + 'px');
msg.css('margin-left', width / -2 + 'px');
if (cancelIndex >= 0 && cancelIndex < btns.length && btns.length > 1) {
$($('input', box)[cancelIndex]).addClass('cancel');
}
if (defaultIndex >= 0 && defaultIndex < btns.length) {
$($('input', box)[defaultIndex]).addClass('default');
}
wrapper.focus();
}
else
$('#messageSEA').remove();
}

S-ar putea să vă placă și