snaplet-fay 0.3.1.0 → 0.3.1.1
raw patch · 22 files changed
+11187/−16 lines, 22 filesdep ~aesondep ~bytestringdep ~data-defaultPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: aeson, bytestring, data-default, directory, fay, filepath, mtl, transformers
API changes (from Hackage documentation)
Files
- README.md +125/−0
- example/example.cabal +56/−0
- example/log/.gitignore +4/−0
- example/snaplets/fay/devel.cfg +25/−0
- example/snaplets/fay/js/.gitignore +4/−0
- example/snaplets/fay/src/Application/SharedTypes.hs +28/−0
- example/snaplets/fay/src/BrokenFile.hs +2/−0
- example/snaplets/fay/src/Dom.hs +20/−0
- example/snaplets/fay/src/Index.hs +117/−0
- example/snaplets/heist/templates/index.tpl +39/−0
- example/snaplets/heist/templates/login-form.tpl +10/−0
- example/snaplets/heist/templates/register-form.tpl +11/−0
- example/src/Application.hs +25/−0
- example/src/Main.hs +102/−0
- example/src/Site.hs +74/−0
- example/static/broken.html +10/−0
- example/static/index.js +21/−0
- example/static/jquery.js +9404/−0
- example/static/screen.css +42/−0
- example/static/underscore.js +1059/−0
- snaplet-fay.cabal +9/−9
- src/Snap/Snaplet/Fay/Internal.hs +0/−7
+ README.md view
@@ -0,0 +1,125 @@+Snaplet Fay+===========++Snaplet Fay integrates [Snap](http://www.snapframework.com) with+[Fay](http://www.fay-lang.org). Snap is a+[Haskell](http://www.haskell.org) web framework and Fay is a compiler+from a proper subset of Haskell to JavaScript. Snaplet Fay integrates+them nicely with each other allowing automatic (re)compilation of Fay+source files. Snap provides this for both static content and haskell+sources preventing web server restarts and here we add Fay to this+list as well. This lets us write both front and back-end code in Haskell.+++Features+--------++* Compile and serve fay files on request, no need to restart the+ snap server.+* Production mode to pre-compile all fay files.+* Uses Fay's pretty print option (js-beautify) to create JS files that+ are easier to debug.+* Writes JS to disk to allow reading the generated source.+* Share Fay source files between Haskell and Fay.+* Automatically encode/decode records shared between Snap and Fay by+ using the fayax functions.+++Changelog+---------++0.3.1.1.:++* Hackage version now includes the example application+* Updated repository location++0.3.1.0:++* Add `packages` flag in the config which lets you use other fay packages without using includeDirs+* On errors in development mode a js file is produced that prints the error to the console (Thanks Daniel Bruegmann)++0.3.0.1:++* Bump to support snap 0.10 and fay 0.11++Installation+------------++You will need Haskell. The simplest way to get up and running with is+to install+[The Haskell Platform](http://hackage.haskell.org/platform/).++Everything else is available on hackage:+```+cabal install snaplet-fay+```+++Example Usage+-------------++Site.hs:+```+import Snap.Snaplet.Fay++routes = [..., ("/fay", with fay fayServe)]++app :: SnapletInit App App+app = makeSnaplet "app" "A snaplet example application." Nothing $ do+ fay' <- nestSnaplet "fay" fay initFay+ return $ App { _fay = fay' }+```++Application.hs:+```+import Snap.Snaplet.Fay++data App = App { _fay :: Snaplet Fay }++makeLens ''App+```++Run your application now.++A snaplet config file will be generated at snaplets/fay/devel.cfg the+first time your application initializes the snaplet. The defaults are+the recommended ones for development.++Place your Fay .hs files in snaplets/fay/src. Note that a default+devel.cfg will not be created if you have already created the fay+directory. If this happens to you, move snaplets/fay, start your+application, and then move the files back into snaplets/fay.++Any requests to the specified directory (in this case /fay/) will+compile the appropriate Fay file and serve it.+++Example Application+-------------------++There is an example available in the `example` directory. It requires+fay-jquery [hackage](http://hackage.haskell.org/package/fay-jquery) [github](http://www.github.com/faylang/fay-jquery).+++Development Status+------------------++Snaplet Fay is functioning and will be updated to keep up with both+Snap and Fay.+++Contributions+-----------++Fork on!++Any enhancements are welcome.++The github master may require the latest fay master, available at+[faylang/fay](https://github.com/faylang/fay/).+++Contact+-------++File an issue, e-mail or visit `#fay @ irc.freenode.net`.
+ example/example.cabal view
@@ -0,0 +1,56 @@+Name: example+Version: 0.1+Synopsis: Project Synopsis Here+Description: Project Description Here+License: AllRightsReserved+Author: Author+Maintainer: maintainer@example.com+Stability: Experimental+Category: Web+Build-type: Simple+Cabal-version: >=1.2++Flag development+ Description: Whether to build the server in development (interpreted) mode+ Default: False++Executable example+ hs-source-dirs: src, snaplets/fay/src+ main-is: Main.hs++ Build-depends:+ base >= 4+ , MonadCatchIO-transformers >= 0.2.1+ , aeson >= 0.6+ , bytestring >= 0.9+ , fay+ , fay-jquery+ , heist >= 0.8+ , lens >= 3.7+ , mtl >= 2+ , snap >= 0.9+ , snap-core >= 0.9+ , snap-loader-static >= 0.9+ , snap-server >= 0.9+ , snaplet-fay >= 0.3.1.1+ , text >= 0.11+ , time >= 1.1 && < 1.5+ , xmlhtml >= 0.1++ if flag(development)+ build-depends:+ snap-loader-dynamic >= 0.9 && < 0.11+ cpp-options: -DDEVELOPMENT+ -- In development mode, speed is already going to suffer, so skip+ -- the fancy optimization flags. Additionally, disable all+ -- warnings. The hint library doesn't give an option to execute+ -- compiled code when there were also warnings, so disabling+ -- warnings allows quicker workflow.+ ghc-options: -threaded -w -Wall+ else+ if impl(ghc >= 6.12.0)+ ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2+ -fno-warn-orphans -fno-warn-unused-do-bind+ else+ ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2+ -fno-warn-orphans
+ example/log/.gitignore view
@@ -0,0 +1,4 @@+# Ignore everything in this directory+*+# Except this file+!.gitignore
+ example/snaplets/fay/devel.cfg view
@@ -0,0 +1,25 @@+# "Development": Compile files on every request.+#+# "Production": Compile all files i snaplets/src/fay when the application is started and then serve them statically.+#+# Both methods will write files to disk for debugging purposes.+# Default is "Development".+compileMode = "Development"+# Print more or less information about what the snaplet is doing.+# Default is on.+verbose = on+# Run js-beautify on the results if it is available in the PATH.+# If it isn't available the compiled file will be used as is.+# Default is on.+prettyPrint = on+# A comma-separated list of directories to look for fay imports in.+# This is useful if you want to share modules between Fay and Snap.+# Paths are relative to the root of the snap application.+# snaplets/fay/src will always be checked for imports.+# Default is "" meaning no additional directories will be checked.+includeDirs = ""+# A comma separated list of Fay package names.+# This gives the same result as using includeDirs,+# except Fay figures out the paths for you.+# Default is "" meaning no other Fay packages will be used.+packages = "fay-jquery"
+ example/snaplets/fay/js/.gitignore view
@@ -0,0 +1,4 @@+# Ignore everything in this directory+*+# Except this file+!.gitignore
@@ -0,0 +1,28 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE CPP #-}++module Application.SharedTypes where++import Prelude+import Data.Data+#ifdef FAY+import FFI+#endif+++data Time = Time { time :: String }+ deriving (Read,Data,Typeable,Show)++data UserRegister = UserRegister { user :: String, password :: String, passwordConfirmation :: String }+ deriving (Read,Data,Typeable,Show)++data UserLogin = UserLogin { ul_user :: String, ul_password :: String, remember :: Bool }+ deriving (Read,Data,Typeable,Show)++data UserRegisterResponse = Fail | OK+ deriving (Read,Data,Typeable,Show)++data UserLoginResponse = LoggedIn | BadLogin+ deriving (Read,Data,Typeable,Show)
+ example/snaplets/fay/src/BrokenFile.hs view
@@ -0,0 +1,2 @@++broken:(
+ example/snaplets/fay/src/Dom.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE EmptyDataDecls #-}++module Dom where++import FFI+import Prelude+++data Element+data Global+data Document++addOnload :: Fay f -> Fay ()+addOnload = ffi "window.addEventListener(\"load\", %1)"++createElement :: String -> Fay Element+createElement = ffi "document.createElement(%1)"++setInterval :: Double -> Fay () -> Fay Double+setInterval = ffi "setInterval(%2, %1)"
+ example/snaplets/fay/src/Index.hs view
@@ -0,0 +1,117 @@+{-# LANGUAGE EmptyDataDecls #-}+{-# OPTIONS -Wall -fno-warn-name-shadowing -fno-warn-unused-do-bind #-}++module Index where++import FFI+import Prelude++-- | Time is shared between Snap and Fay+-- | Location: snaplets/fay/src/Application/SharedTypes.hs+import Application.SharedTypes+-- | Dom is a Fay only module+-- | Location: snaplets/fay/src+import Dom+-- | The fay-jquery package+import JQuery++void :: Fay f -> Fay ()+void f = f >> return ()++main :: Fay ()+main = mapM_ addOnload [onload, registrationOnload, loginOnload, void (select "#logout" >>= click (const submitLogout))]++(=<<) :: (a -> Fay b) -> Fay a -> Fay b+(=<<) = flip (>>=)++onload :: Fay ()+onload = void $ do+ contents <- select "#content"+ div <- select "<div></div>"+ setHtml "This element was created by Fay through an onload handler!" div+ appendTo contents div++ currentTime+ setInterval 2000 currentTime++currentTime :: Fay ()+currentTime =+ ajaxJson "/ajax/current-time" (\(Time time) -> void $ select "#current-time" >>= setHtml time)++formOnload :: String -> Fay () -> Fay ()+formOnload buttonSel getForm = void $ select buttonSel >>= click (const getForm)++registrationOnload :: Fay ()+registrationOnload = formOnload "#viewRegisterForm" requestRegisterHtml++loginOnload :: Fay ()+loginOnload = formOnload "#viewLoginForm" requestLoginHtml++requestHtml :: String -> Fay () -> Fay ()+requestHtml url submitAction = do+ formContainer <- select "#formContainer"+ hide Slow formContainer+ ajaxHtml url (\h -> do+ setHtml h formContainer+ findSelector "form" formContainer >>= submit (\e -> preventDefault e >> submitAction)+ jshow Slow formContainer+ return ())++typeof :: f -> String+typeof = ffi "typeof %1"++requestRegisterHtml :: Fay ()+requestRegisterHtml = requestHtml "/ajax/register-form" submitRegister++requestLoginHtml :: Fay ()+requestLoginHtml = requestHtml "/ajax/login-form" submitLogin++submitRegister :: Fay ()+submitRegister = do+ json <- select "#formContainer form" >>= formJson :: Fay UserRegister+ jPost "/ajax/register" json (\c -> case c of+ Fail -> select "#loginStatus" >>= showStatus Error "Oops! Username taken or fields have length < 4"+ OK -> do+ select "#loginStatus" >>= showStatus Notice "Account created!"+ select "#formContainer" >>= hide Fast >> requestLoginHtml)++submitLogin :: Fay ()+submitLogin = do+ form <- select "#formContainer form"+ json <- formJson form :: Fay UserLogin+ jPost "/ajax/login" json (\c -> case c of+ BadLogin -> select "#loginStatus" >>= showStatus Error "Oops! Bad login information!"+ LoggedIn -> void $ do+ select "#loginStatus" >>= showStatus Notice "Logged in! Too bad there is no additional functionality for you now."+ select "#formContainer" >>= hide Fast)++submitLogout :: Fay ()+submitLogout = ajaxJson "/ajax/logout" (\_ -> void $ select "#loginStatus" >>= showStatus Notice "You have been logged out.")++data Status = Error | Notice++statusClass :: Status -> String+statusClass Error = "error"+statusClass Notice = "notice"++showStatus :: Status -> String -> JQuery -> Fay ()+showStatus status msg el = void $+ return el >>= hide Fast >>=+ removeClass (statusClass Error) >>= removeClass (statusClass Notice) >>=+ setHtml msg >>=+ addClass (statusClass status) >>=+ jshow Fast >> return ()++formJson :: JQuery -> Fay f+formJson = ffi "Helpers.formJson(%1)"++-- jQuery additions++jPost :: String -> Automatic f -> (Automatic g -> Fay ()) -> Fay ()+jPost = ffi "jQuery.ajax(%1, { data: JSON.stringify(%2), type: 'POST', processData: false, contentType: 'text/json', success: %3 })"++ajaxHtml :: String -> (String -> Fay()) -> Fay ()+ajaxHtml = ffi "jQuery.ajax(%1, { success : %2 })"++ajaxJson :: String -> (Automatic f -> Fay ()) -> Fay ()+ajaxJson = ffi "jQuery.ajax(%1, { success : %2 })"
+ example/snaplets/heist/templates/index.tpl view
@@ -0,0 +1,39 @@+<html>+ <head>+ <title>Snaplet Fay Example Application</title>+ <link rel="stylesheet" type="text/css" href="/static/screen.css"/>+ <script src="/static/jquery.js"></script>+ <script src="/static/underscore.js"></script>+ <script src="/static/index.js"></script>+ <script src="/fay/Index.js"></script>+ </head>+ <body>+ <div id="content">+ <h1>Snaplet Fay Example Application</h1>++ <div>Current time:</div>+ <div id="current-time"><current-time/></div>++ <br>+ <div id="loginStatus" class="status">+ <ifLoggedIn>+ You're logged in.+ </ifLoggedIn>+ <ifLoggedOut>+ You're not logged in.+ </ifLoggedOut>+ </div>+ <input id="viewLoginForm" type="button" value="Log in">+ <input id="viewRegisterForm" type="button" value="Register">+ <input id="logout" type="button" value="Log out">++ <div id="formContainer">+ </div>++ <br>+ <div><a href="/static/broken.html">See what happens when you try to load a html file referencing a Fay file containing Syntax errors.</a></div>++ <br>+ </div>+ </body>+</html>
+ example/snaplets/heist/templates/login-form.tpl view
@@ -0,0 +1,10 @@+<form class="login-form" action="/login">+ <input type="hidden" name="instance" value="UserLogin">+ <label for="ul_user">Username</label>+ <input type="text" name="ul_user">+ <label for="ul_password">Password</label>+ <input type="password" name="ul_password">+ <input type="checkbox" name="remember"> Remember me+ <input class="submit" type="submit" value="Log In">+ <div class="status"></div>+</form>
+ example/snaplets/heist/templates/register-form.tpl view
@@ -0,0 +1,11 @@+<form class="register-form" action="/register">+ <input type="hidden" name="instance" value="UserRegister">+ <label for="user">Username</label>+ <input type="text" name="user">+ <label for="password">Password</label>+ <input type="password" name="password">+ <label for="user">Repeat Password</label>+ <input type="password" name="passwordConfirmation">+ <input class="submit" type="submit" value="Register">+ <div class="status"></div>+</form>
+ example/src/Application.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE TemplateHaskell #-}++module Application where+------------------------------------------------------------------------------+import Control.Lens+import Snap.Snaplet+import Snap.Snaplet.Auth+import Snap.Snaplet.Fay+import Snap.Snaplet.Heist+import Snap.Snaplet.Session+------------------------------------------------------------------------------+data App = App+ { _heist :: Snaplet (Heist App)+ , _fay :: Snaplet Fay+ , _session :: Snaplet SessionManager+ , _auth :: Snaplet (AuthManager App)+ }++makeLenses ''App++instance HasHeist App where+ heistLens = subSnaplet heist++------------------------------------------------------------------------------+type AppHandler = Handler App App
+ example/src/Main.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE TemplateHaskell #-}++module Main where++------------------------------------------------------------------------------+import Control.Exception (SomeException, try)+import qualified Data.Text as T+import Snap.Http.Server+import Snap.Snaplet+import Snap.Snaplet.Config+import Snap.Core+import System.IO+import Site++#ifdef DEVELOPMENT+import Snap.Loader.Dynamic+#else+import Snap.Loader.Static+#endif+++------------------------------------------------------------------------------+-- | This is the entry point for this web server application. It supports+-- easily switching between interpreting source and running statically compiled+-- code.+--+-- In either mode, the generated program should be run from the root of the+-- project tree. When it is run, it locates its templates, static content, and+-- source files in development mode, relative to the current working directory.+--+-- When compiled with the development flag, only changes to the libraries, your+-- cabal file, or this file should require a recompile to be picked up.+-- Everything else is interpreted at runtime. There are a few consequences of+-- this.+--+-- First, this is much slower. Running the interpreter takes a significant+-- chunk of time (a couple tenths of a second on the author's machine, at this+-- time), regardless of the simplicity of the loaded code. In order to+-- recompile and re-load server state as infrequently as possible, the source+-- directories are watched for updates, as are any extra directories specified+-- below.+--+-- Second, the generated server binary is MUCH larger, since it links in the+-- GHC API (via the hint library).+--+-- Third, and the reason you would ever want to actually compile with+-- development mode, is that it enables a faster development cycle. You can+-- simply edit a file, save your changes, and hit reload to see your changes+-- reflected immediately.+--+-- When this is compiled without the development flag, all the actions are+-- statically compiled in. This results in faster execution, a smaller binary+-- size, and having to recompile the server for any code change.+--+main :: IO ()+main = do+ -- Depending on the version of loadSnapTH in scope, this either enables+ -- dynamic reloading, or compiles it without. The last argument to+ -- loadSnapTH is a list of additional directories to watch for changes to+ -- trigger reloads in development mode. It doesn't need to include source+ -- directories, those are picked up automatically by the splice.+ (conf, site, cleanup) <- $(loadSnapTH [| getConf |]+ 'getActions+ ["snaplets/heist/templates"])++ _ <- try $ httpServe conf site :: IO (Either SomeException ())+ cleanup+++------------------------------------------------------------------------------+-- | This action loads the config used by this application. The loaded config+-- is returned as the first element of the tuple produced by the loadSnapTH+-- Splice. The type is not solidly fixed, though it must be an IO action that+-- produces the same type as 'getActions' takes. It also must be an instance of+-- Typeable. If the type of this is changed, a full recompile will be needed to+-- pick up the change, even in development mode.+--+-- This action is only run once, regardless of whether development or+-- production mode is in use.+getConf :: IO (Config Snap AppConfig)+getConf = commandLineAppConfig defaultConfig+++------------------------------------------------------------------------------+-- | This function generates the the site handler and cleanup action from the+-- configuration. In production mode, this action is only run once. In+-- development mode, this action is run whenever the application is reloaded.+--+-- Development mode also makes sure that the cleanup actions are run+-- appropriately before shutdown. The cleanup action returned from loadSnapTH+-- should still be used after the server has stopped handling requests, as the+-- cleanup actions are only automatically run when a reload is triggered.+--+-- This sample doesn't actually use the config passed in, but more+-- sophisticated code might.+getActions :: Config Snap AppConfig -> IO (Snap (), IO ())+getActions conf = do+ (msgs, site, cleanup) <- runSnaplet+ (appEnvironment =<< getOther conf) app+ hPutStrLn stderr $ T.unpack msgs+ return (site, cleanup)
+ example/src/Site.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE OverloadedStrings #-}++module Site+ ( app+ ) where++------------------------------------------------------------------------------+import Control.Applicative+import Control.Monad.Trans+import Data.ByteString (ByteString)+import qualified Data.ByteString.Char8 as BS+import qualified Data.Text as T+import Data.Time.Clock+import Snap.Snaplet+import Snap.Snaplet.Auth hiding (session)+import Snap.Snaplet.Auth.Backends.JsonFile+import Snap.Snaplet.Fay+import Snap.Snaplet.Heist+import Snap.Snaplet.Session.Backends.CookieSession+import Snap.Util.FileServe+------------------------------------------------------------------------------+import Application+import Application.SharedTypes+++currentTimeAjax :: AppHandler Time+currentTimeAjax = Time . show <$> liftIO getCurrentTime++-- TODO this can be handled automatically by heistServe+registerForm :: AppHandler ()+registerForm = render "register-form"+loginForm :: AppHandler ()+loginForm = render "login-form"++register :: UserRegister -> Handler App (AuthManager App) UserRegisterResponse+register (UserRegister u p pc)+ | length u < 4 || length p < 4 || p /= pc = return Fail+ | otherwise = do+ let u' = T.pack u+ exists <- usernameExists u'+ if exists then return Fail else (createUser u' (BS.pack p) >> return OK)++login :: UserLogin -> Handler App (AuthManager App) UserLoginResponse+login (UserLogin u p r) =+ either (return BadLogin) (return LoggedIn) <$>+ loginByUsername (BS.pack u) (ClearText $ BS.pack p) r++------------------------------------------------------------------------------+-- | The application's routes.+routes :: [(ByteString, Handler App App ())]+routes = [+ ("/ajax/current-time", toFayax currentTimeAjax)+ , ("/ajax/login", with auth $ fayax login)+ , ("/ajax/login-form", loginForm)+ , ("/ajax/logout", with auth logout)+ , ("/ajax/register", with auth $ fayax register)+ , ("/ajax/register-form", registerForm)+ , ("/fay", with fay fayServe)+ , ("/static", serveDirectory "static")+ ]+++------------------------------------------------------------------------------+-- | The application initializer.+app :: SnapletInit App App+app = makeSnaplet "app" "An snaplet example application." Nothing $ do+ s <- nestSnaplet "sess" session $+ initCookieSessionManager "site_key.txt" "sess" (Just 3600)+ h <- nestSnaplet "" heist $ heistInit "templates"+ f <- nestSnaplet "fay" fay $ initFay+ a <- nestSnaplet "auth" auth $ initJsonFileAuthManager defAuthSettings session "users.json"+ addAuthSplices auth+ addRoutes routes+ return $ App h f s a
+ example/static/broken.html view
@@ -0,0 +1,10 @@+<html>+ <head>+ <title>Page with broken Fay code (development mode).</title>+ <script src="/fay/BrokenFile.js"></script>+ </head>+ <body>+ <h1>Page with broken Fay code (development mode).</h1>+ <p>Check the JS console for the error message.</p>+ </body>+</html>
+ example/static/index.js view
@@ -0,0 +1,21 @@+window.Helpers = {+ formJson : function (form) {+ var o = {};+ $("input, select", form).each(function (_,e) {+ e = $(e);+ var t = e.attr("type");+ var p = e.attr("name");+ if (!p) return;+ var v = e.val();+ v = t === "checkbox" ? v === "on" : v;+ if (p in o && o[p] instanceof Array) {+ o[p].push(v);+ } else if (p in o) {+ o[p] = [o[p], v];+ } else {+ o[p] = v;+ }+ });+ return o;+ }+};
+ example/static/jquery.js view
@@ -0,0 +1,9404 @@+/*!+ * jQuery JavaScript Library v1.7.2+ * http://jquery.com/+ *+ * Copyright 2011, John Resig+ * Dual licensed under the MIT or GPL Version 2 licenses.+ * http://jquery.org/license+ *+ * Includes Sizzle.js+ * http://sizzlejs.com/+ * Copyright 2011, The Dojo Foundation+ * Released under the MIT, BSD, and GPL Licenses.+ *+ * Date: Wed Mar 21 12:46:34 2012 -0700+ */+(function( window, undefined ) {++// Use the correct document accordingly with window argument (sandbox)+var document = window.document,+ navigator = window.navigator,+ location = window.location;+var jQuery = (function() {++// Define a local copy of jQuery+var jQuery = function( selector, context ) {+ // The jQuery object is actually just the init constructor 'enhanced'+ return new jQuery.fn.init( selector, context, rootjQuery );+ },++ // Map over jQuery in case of overwrite+ _jQuery = window.jQuery,++ // Map over the $ in case of overwrite+ _$ = window.$,++ // A central reference to the root jQuery(document)+ rootjQuery,++ // A simple way to check for HTML strings or ID strings+ // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)+ quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,++ // Check if a string has a non-whitespace character in it+ rnotwhite = /\S/,++ // Used for trimming whitespace+ trimLeft = /^\s+/,+ trimRight = /\s+$/,++ // Match a standalone tag+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,++ // JSON RegExp+ rvalidchars = /^[\],:{}\s]*$/,+ rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,+ rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,+ rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,++ // Useragent RegExp+ rwebkit = /(webkit)[ \/]([\w.]+)/,+ ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,+ rmsie = /(msie) ([\w.]+)/,+ rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,++ // Matches dashed string for camelizing+ rdashAlpha = /-([a-z]|[0-9])/ig,+ rmsPrefix = /^-ms-/,++ // Used by jQuery.camelCase as callback to replace()+ fcamelCase = function( all, letter ) {+ return ( letter + "" ).toUpperCase();+ },++ // Keep a UserAgent string for use with jQuery.browser+ userAgent = navigator.userAgent,++ // For matching the engine and version of the browser+ browserMatch,++ // The deferred used on DOM ready+ readyList,++ // The ready event handler+ DOMContentLoaded,++ // Save a reference to some core methods+ toString = Object.prototype.toString,+ hasOwn = Object.prototype.hasOwnProperty,+ push = Array.prototype.push,+ slice = Array.prototype.slice,+ trim = String.prototype.trim,+ indexOf = Array.prototype.indexOf,++ // [[Class]] -> type pairs+ class2type = {};++jQuery.fn = jQuery.prototype = {+ constructor: jQuery,+ init: function( selector, context, rootjQuery ) {+ var match, elem, ret, doc;++ // Handle $(""), $(null), or $(undefined)+ if ( !selector ) {+ return this;+ }++ // Handle $(DOMElement)+ if ( selector.nodeType ) {+ this.context = this[0] = selector;+ this.length = 1;+ return this;+ }++ // The body element only exists once, optimize finding it+ if ( selector === "body" && !context && document.body ) {+ this.context = document;+ this[0] = document.body;+ this.selector = selector;+ this.length = 1;+ return this;+ }++ // Handle HTML strings+ if ( typeof selector === "string" ) {+ // Are we dealing with HTML string or an ID?+ if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {+ // Assume that strings that start and end with <> are HTML and skip the regex check+ match = [ null, selector, null ];++ } else {+ match = quickExpr.exec( selector );+ }++ // Verify a match, and that no context was specified for #id+ if ( match && (match[1] || !context) ) {++ // HANDLE: $(html) -> $(array)+ if ( match[1] ) {+ context = context instanceof jQuery ? context[0] : context;+ doc = ( context ? context.ownerDocument || context : document );++ // If a single string is passed in and it's a single tag+ // just do a createElement and skip the rest+ ret = rsingleTag.exec( selector );++ if ( ret ) {+ if ( jQuery.isPlainObject( context ) ) {+ selector = [ document.createElement( ret[1] ) ];+ jQuery.fn.attr.call( selector, context, true );++ } else {+ selector = [ doc.createElement( ret[1] ) ];+ }++ } else {+ ret = jQuery.buildFragment( [ match[1] ], [ doc ] );+ selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;+ }++ return jQuery.merge( this, selector );++ // HANDLE: $("#id")+ } else {+ elem = document.getElementById( match[2] );++ // Check parentNode to catch when Blackberry 4.6 returns+ // nodes that are no longer in the document #6963+ if ( elem && elem.parentNode ) {+ // Handle the case where IE and Opera return items+ // by name instead of ID+ if ( elem.id !== match[2] ) {+ return rootjQuery.find( selector );+ }++ // Otherwise, we inject the element directly into the jQuery object+ this.length = 1;+ this[0] = elem;+ }++ this.context = document;+ this.selector = selector;+ return this;+ }++ // HANDLE: $(expr, $(...))+ } else if ( !context || context.jquery ) {+ return ( context || rootjQuery ).find( selector );++ // HANDLE: $(expr, context)+ // (which is just equivalent to: $(context).find(expr)+ } else {+ return this.constructor( context ).find( selector );+ }++ // HANDLE: $(function)+ // Shortcut for document ready+ } else if ( jQuery.isFunction( selector ) ) {+ return rootjQuery.ready( selector );+ }++ if ( selector.selector !== undefined ) {+ this.selector = selector.selector;+ this.context = selector.context;+ }++ return jQuery.makeArray( selector, this );+ },++ // Start with an empty selector+ selector: "",++ // The current version of jQuery being used+ jquery: "1.7.2",++ // The default length of a jQuery object is 0+ length: 0,++ // The number of elements contained in the matched element set+ size: function() {+ return this.length;+ },++ toArray: function() {+ return slice.call( this, 0 );+ },++ // Get the Nth element in the matched element set OR+ // Get the whole matched element set as a clean array+ get: function( num ) {+ return num == null ?++ // Return a 'clean' array+ this.toArray() :++ // Return just the object+ ( num < 0 ? this[ this.length + num ] : this[ num ] );+ },++ // Take an array of elements and push it onto the stack+ // (returning the new matched element set)+ pushStack: function( elems, name, selector ) {+ // Build a new jQuery matched element set+ var ret = this.constructor();++ if ( jQuery.isArray( elems ) ) {+ push.apply( ret, elems );++ } else {+ jQuery.merge( ret, elems );+ }++ // Add the old object onto the stack (as a reference)+ ret.prevObject = this;++ ret.context = this.context;++ if ( name === "find" ) {+ ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;+ } else if ( name ) {+ ret.selector = this.selector + "." + name + "(" + selector + ")";+ }++ // Return the newly-formed element set+ return ret;+ },++ // Execute a callback for every element in the matched set.+ // (You can seed the arguments with an array of args, but this is+ // only used internally.)+ each: function( callback, args ) {+ return jQuery.each( this, callback, args );+ },++ ready: function( fn ) {+ // Attach the listeners+ jQuery.bindReady();++ // Add the callback+ readyList.add( fn );++ return this;+ },++ eq: function( i ) {+ i = +i;+ return i === -1 ?+ this.slice( i ) :+ this.slice( i, i + 1 );+ },++ first: function() {+ return this.eq( 0 );+ },++ last: function() {+ return this.eq( -1 );+ },++ slice: function() {+ return this.pushStack( slice.apply( this, arguments ),+ "slice", slice.call(arguments).join(",") );+ },++ map: function( callback ) {+ return this.pushStack( jQuery.map(this, function( elem, i ) {+ return callback.call( elem, i, elem );+ }));+ },++ end: function() {+ return this.prevObject || this.constructor(null);+ },++ // For internal use only.+ // Behaves like an Array's method, not like a jQuery method.+ push: push,+ sort: [].sort,+ splice: [].splice+};++// Give the init function the jQuery prototype for later instantiation+jQuery.fn.init.prototype = jQuery.fn;++jQuery.extend = jQuery.fn.extend = function() {+ var options, name, src, copy, copyIsArray, clone,+ target = arguments[0] || {},+ i = 1,+ length = arguments.length,+ deep = false;++ // Handle a deep copy situation+ if ( typeof target === "boolean" ) {+ deep = target;+ target = arguments[1] || {};+ // skip the boolean and the target+ i = 2;+ }++ // Handle case when target is a string or something (possible in deep copy)+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {+ target = {};+ }++ // extend jQuery itself if only one argument is passed+ if ( length === i ) {+ target = this;+ --i;+ }++ for ( ; i < length; i++ ) {+ // Only deal with non-null/undefined values+ if ( (options = arguments[ i ]) != null ) {+ // Extend the base object+ for ( name in options ) {+ src = target[ name ];+ copy = options[ name ];++ // Prevent never-ending loop+ if ( target === copy ) {+ continue;+ }++ // Recurse if we're merging plain objects or arrays+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {+ if ( copyIsArray ) {+ copyIsArray = false;+ clone = src && jQuery.isArray(src) ? src : [];++ } else {+ clone = src && jQuery.isPlainObject(src) ? src : {};+ }++ // Never move original objects, clone them+ target[ name ] = jQuery.extend( deep, clone, copy );++ // Don't bring in undefined values+ } else if ( copy !== undefined ) {+ target[ name ] = copy;+ }+ }+ }+ }++ // Return the modified object+ return target;+};++jQuery.extend({+ noConflict: function( deep ) {+ if ( window.$ === jQuery ) {+ window.$ = _$;+ }++ if ( deep && window.jQuery === jQuery ) {+ window.jQuery = _jQuery;+ }++ return jQuery;+ },++ // Is the DOM ready to be used? Set to true once it occurs.+ isReady: false,++ // A counter to track how many items to wait for before+ // the ready event fires. See #6781+ readyWait: 1,++ // Hold (or release) the ready event+ holdReady: function( hold ) {+ if ( hold ) {+ jQuery.readyWait++;+ } else {+ jQuery.ready( true );+ }+ },++ // Handle when the DOM is ready+ ready: function( wait ) {+ // Either a released hold or an DOMready/load event and not yet ready+ if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).+ if ( !document.body ) {+ return setTimeout( jQuery.ready, 1 );+ }++ // Remember that the DOM is ready+ jQuery.isReady = true;++ // If a normal DOM Ready event fired, decrement, and wait if need be+ if ( wait !== true && --jQuery.readyWait > 0 ) {+ return;+ }++ // If there are functions bound, to execute+ readyList.fireWith( document, [ jQuery ] );++ // Trigger any bound ready events+ if ( jQuery.fn.trigger ) {+ jQuery( document ).trigger( "ready" ).off( "ready" );+ }+ }+ },++ bindReady: function() {+ if ( readyList ) {+ return;+ }++ readyList = jQuery.Callbacks( "once memory" );++ // Catch cases where $(document).ready() is called after the+ // browser event has already occurred.+ if ( document.readyState === "complete" ) {+ // Handle it asynchronously to allow scripts the opportunity to delay ready+ return setTimeout( jQuery.ready, 1 );+ }++ // Mozilla, Opera and webkit nightlies currently support this event+ if ( document.addEventListener ) {+ // Use the handy event callback+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );++ // A fallback to window.onload, that will always work+ window.addEventListener( "load", jQuery.ready, false );++ // If IE event model is used+ } else if ( document.attachEvent ) {+ // ensure firing before onload,+ // maybe late but safe also for iframes+ document.attachEvent( "onreadystatechange", DOMContentLoaded );++ // A fallback to window.onload, that will always work+ window.attachEvent( "onload", jQuery.ready );++ // If IE and not a frame+ // continually check to see if the document is ready+ var toplevel = false;++ try {+ toplevel = window.frameElement == null;+ } catch(e) {}++ if ( document.documentElement.doScroll && toplevel ) {+ doScrollCheck();+ }+ }+ },++ // See test/unit/core.js for details concerning isFunction.+ // Since version 1.3, DOM methods and functions like alert+ // aren't supported. They return false on IE (#2968).+ isFunction: function( obj ) {+ return jQuery.type(obj) === "function";+ },++ isArray: Array.isArray || function( obj ) {+ return jQuery.type(obj) === "array";+ },++ isWindow: function( obj ) {+ return obj != null && obj == obj.window;+ },++ isNumeric: function( obj ) {+ return !isNaN( parseFloat(obj) ) && isFinite( obj );+ },++ type: function( obj ) {+ return obj == null ?+ String( obj ) :+ class2type[ toString.call(obj) ] || "object";+ },++ isPlainObject: function( obj ) {+ // Must be an Object.+ // Because of IE, we also have to check the presence of the constructor property.+ // Make sure that DOM nodes and window objects don't pass through, as well+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {+ return false;+ }++ try {+ // Not own constructor property must be Object+ if ( obj.constructor &&+ !hasOwn.call(obj, "constructor") &&+ !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {+ return false;+ }+ } catch ( e ) {+ // IE8,9 Will throw exceptions on certain host objects #9897+ return false;+ }++ // Own properties are enumerated firstly, so to speed up,+ // if last one is own, then all properties are own.++ var key;+ for ( key in obj ) {}++ return key === undefined || hasOwn.call( obj, key );+ },++ isEmptyObject: function( obj ) {+ for ( var name in obj ) {+ return false;+ }+ return true;+ },++ error: function( msg ) {+ throw new Error( msg );+ },++ parseJSON: function( data ) {+ if ( typeof data !== "string" || !data ) {+ return null;+ }++ // Make sure leading/trailing whitespace is removed (IE can't handle it)+ data = jQuery.trim( data );++ // Attempt to parse using the native JSON parser first+ if ( window.JSON && window.JSON.parse ) {+ return window.JSON.parse( data );+ }++ // Make sure the incoming data is actual JSON+ // Logic borrowed from http://json.org/json2.js+ if ( rvalidchars.test( data.replace( rvalidescape, "@" )+ .replace( rvalidtokens, "]" )+ .replace( rvalidbraces, "")) ) {++ return ( new Function( "return " + data ) )();++ }+ jQuery.error( "Invalid JSON: " + data );+ },++ // Cross-browser xml parsing+ parseXML: function( data ) {+ if ( typeof data !== "string" || !data ) {+ return null;+ }+ var xml, tmp;+ try {+ if ( window.DOMParser ) { // Standard+ tmp = new DOMParser();+ xml = tmp.parseFromString( data , "text/xml" );+ } else { // IE+ xml = new ActiveXObject( "Microsoft.XMLDOM" );+ xml.async = "false";+ xml.loadXML( data );+ }+ } catch( e ) {+ xml = undefined;+ }+ if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {+ jQuery.error( "Invalid XML: " + data );+ }+ return xml;+ },++ noop: function() {},++ // Evaluates a script in a global context+ // Workarounds based on findings by Jim Driscoll+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context+ globalEval: function( data ) {+ if ( data && rnotwhite.test( data ) ) {+ // We use execScript on Internet Explorer+ // We use an anonymous function so that context is window+ // rather than jQuery in Firefox+ ( window.execScript || function( data ) {+ window[ "eval" ].call( window, data );+ } )( data );+ }+ },++ // Convert dashed to camelCase; used by the css and data modules+ // Microsoft forgot to hump their vendor prefix (#9572)+ camelCase: function( string ) {+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );+ },++ nodeName: function( elem, name ) {+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();+ },++ // args is for internal usage only+ each: function( object, callback, args ) {+ var name, i = 0,+ length = object.length,+ isObj = length === undefined || jQuery.isFunction( object );++ if ( args ) {+ if ( isObj ) {+ for ( name in object ) {+ if ( callback.apply( object[ name ], args ) === false ) {+ break;+ }+ }+ } else {+ for ( ; i < length; ) {+ if ( callback.apply( object[ i++ ], args ) === false ) {+ break;+ }+ }+ }++ // A special, fast, case for the most common use of each+ } else {+ if ( isObj ) {+ for ( name in object ) {+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {+ break;+ }+ }+ } else {+ for ( ; i < length; ) {+ if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {+ break;+ }+ }+ }+ }++ return object;+ },++ // Use native String.trim function wherever possible+ trim: trim ?+ function( text ) {+ return text == null ?+ "" :+ trim.call( text );+ } :++ // Otherwise use our own trimming functionality+ function( text ) {+ return text == null ?+ "" :+ text.toString().replace( trimLeft, "" ).replace( trimRight, "" );+ },++ // results is for internal usage only+ makeArray: function( array, results ) {+ var ret = results || [];++ if ( array != null ) {+ // The window, strings (and functions) also have 'length'+ // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930+ var type = jQuery.type( array );++ if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {+ push.call( ret, array );+ } else {+ jQuery.merge( ret, array );+ }+ }++ return ret;+ },++ inArray: function( elem, array, i ) {+ var len;++ if ( array ) {+ if ( indexOf ) {+ return indexOf.call( array, elem, i );+ }++ len = array.length;+ i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;++ for ( ; i < len; i++ ) {+ // Skip accessing in sparse arrays+ if ( i in array && array[ i ] === elem ) {+ return i;+ }+ }+ }++ return -1;+ },++ merge: function( first, second ) {+ var i = first.length,+ j = 0;++ if ( typeof second.length === "number" ) {+ for ( var l = second.length; j < l; j++ ) {+ first[ i++ ] = second[ j ];+ }++ } else {+ while ( second[j] !== undefined ) {+ first[ i++ ] = second[ j++ ];+ }+ }++ first.length = i;++ return first;+ },++ grep: function( elems, callback, inv ) {+ var ret = [], retVal;+ inv = !!inv;++ // Go through the array, only saving the items+ // that pass the validator function+ for ( var i = 0, length = elems.length; i < length; i++ ) {+ retVal = !!callback( elems[ i ], i );+ if ( inv !== retVal ) {+ ret.push( elems[ i ] );+ }+ }++ return ret;+ },++ // arg is for internal usage only+ map: function( elems, callback, arg ) {+ var value, key, ret = [],+ i = 0,+ length = elems.length,+ // jquery objects are treated as arrays+ isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;++ // Go through the array, translating each of the items to their+ if ( isArray ) {+ for ( ; i < length; i++ ) {+ value = callback( elems[ i ], i, arg );++ if ( value != null ) {+ ret[ ret.length ] = value;+ }+ }++ // Go through every key on the object,+ } else {+ for ( key in elems ) {+ value = callback( elems[ key ], key, arg );++ if ( value != null ) {+ ret[ ret.length ] = value;+ }+ }+ }++ // Flatten any nested arrays+ return ret.concat.apply( [], ret );+ },++ // A global GUID counter for objects+ guid: 1,++ // Bind a function to a context, optionally partially applying any+ // arguments.+ proxy: function( fn, context ) {+ if ( typeof context === "string" ) {+ var tmp = fn[ context ];+ context = fn;+ fn = tmp;+ }++ // Quick check to determine if target is callable, in the spec+ // this throws a TypeError, but we will just return undefined.+ if ( !jQuery.isFunction( fn ) ) {+ return undefined;+ }++ // Simulated bind+ var args = slice.call( arguments, 2 ),+ proxy = function() {+ return fn.apply( context, args.concat( slice.call( arguments ) ) );+ };++ // Set the guid of unique handler to the same of original handler, so it can be removed+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;++ return proxy;+ },++ // Mutifunctional method to get and set values to a collection+ // The value/s can optionally be executed if it's a function+ access: function( elems, fn, key, value, chainable, emptyGet, pass ) {+ var exec,+ bulk = key == null,+ i = 0,+ length = elems.length;++ // Sets many values+ if ( key && typeof key === "object" ) {+ for ( i in key ) {+ jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );+ }+ chainable = 1;++ // Sets one value+ } else if ( value !== undefined ) {+ // Optionally, function values get executed if exec is true+ exec = pass === undefined && jQuery.isFunction( value );++ if ( bulk ) {+ // Bulk operations only iterate when executing function values+ if ( exec ) {+ exec = fn;+ fn = function( elem, key, value ) {+ return exec.call( jQuery( elem ), value );+ };++ // Otherwise they run against the entire set+ } else {+ fn.call( elems, value );+ fn = null;+ }+ }++ if ( fn ) {+ for (; i < length; i++ ) {+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );+ }+ }++ chainable = 1;+ }++ return chainable ?+ elems :++ // Gets+ bulk ?+ fn.call( elems ) :+ length ? fn( elems[0], key ) : emptyGet;+ },++ now: function() {+ return ( new Date() ).getTime();+ },++ // Use of jQuery.browser is frowned upon.+ // More details: http://docs.jquery.com/Utilities/jQuery.browser+ uaMatch: function( ua ) {+ ua = ua.toLowerCase();++ 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" };+ },++ sub: function() {+ function jQuerySub( selector, context ) {+ return new jQuerySub.fn.init( selector, context );+ }+ jQuery.extend( true, jQuerySub, this );+ jQuerySub.superclass = this;+ jQuerySub.fn = jQuerySub.prototype = this();+ jQuerySub.fn.constructor = jQuerySub;+ jQuerySub.sub = this.sub;+ jQuerySub.fn.init = function init( selector, context ) {+ if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {+ context = jQuerySub( context );+ }++ return jQuery.fn.init.call( this, selector, context, rootjQuerySub );+ };+ jQuerySub.fn.init.prototype = jQuerySub.fn;+ var rootjQuerySub = jQuerySub(document);+ return jQuerySub;+ },++ browser: {}+});++// Populate the class2type map+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {+ class2type[ "[object " + name + "]" ] = name.toLowerCase();+});++browserMatch = jQuery.uaMatch( userAgent );+if ( browserMatch.browser ) {+ jQuery.browser[ browserMatch.browser ] = true;+ jQuery.browser.version = browserMatch.version;+}++// Deprecated, use jQuery.browser.webkit instead+if ( jQuery.browser.webkit ) {+ jQuery.browser.safari = true;+}++// IE doesn't match non-breaking spaces with \s+if ( rnotwhite.test( "\xA0" ) ) {+ trimLeft = /^[\s\xA0]+/;+ trimRight = /[\s\xA0]+$/;+}++// All jQuery objects should point back to these+rootjQuery = jQuery(document);++// Cleanup functions for the document ready method+if ( document.addEventListener ) {+ DOMContentLoaded = function() {+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );+ jQuery.ready();+ };++} else if ( document.attachEvent ) {+ DOMContentLoaded = function() {+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).+ if ( document.readyState === "complete" ) {+ document.detachEvent( "onreadystatechange", DOMContentLoaded );+ jQuery.ready();+ }+ };+}++// The DOM ready check for Internet Explorer+function doScrollCheck() {+ if ( jQuery.isReady ) {+ return;+ }++ try {+ // If IE is used, use the trick by Diego Perini+ // http://javascript.nwbox.com/IEContentLoaded/+ document.documentElement.doScroll("left");+ } catch(e) {+ setTimeout( doScrollCheck, 1 );+ return;+ }++ // and execute any waiting functions+ jQuery.ready();+}++return jQuery;++})();+++// String to Object flags format cache+var flagsCache = {};++// Convert String-formatted flags into Object-formatted ones and store in cache+function createFlags( flags ) {+ var object = flagsCache[ flags ] = {},+ i, length;+ flags = flags.split( /\s+/ );+ for ( i = 0, length = flags.length; i < length; i++ ) {+ object[ flags[i] ] = true;+ }+ return object;+}++/*+ * Create a callback list using the following parameters:+ *+ * flags: an optional list of space-separated flags that will change how+ * the callback list behaves+ *+ * By default a callback list will act like an event callback list and can be+ * "fired" multiple times.+ *+ * Possible flags:+ *+ * once: will ensure the callback list can only be fired once (like a Deferred)+ *+ * memory: will keep track of previous values and will call any callback added+ * after the list has been fired right away with the latest "memorized"+ * values (like a Deferred)+ *+ * unique: will ensure a callback can only be added once (no duplicate in the list)+ *+ * stopOnFalse: interrupt callings when a callback returns false+ *+ */+jQuery.Callbacks = function( flags ) {++ // Convert flags from String-formatted to Object-formatted+ // (we check in cache first)+ flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {};++ var // Actual callback list+ list = [],+ // Stack of fire calls for repeatable lists+ stack = [],+ // Last fire value (for non-forgettable lists)+ memory,+ // Flag to know if list was already fired+ fired,+ // Flag to know if list is currently firing+ firing,+ // First callback to fire (used internally by add and fireWith)+ firingStart,+ // End of the loop when firing+ firingLength,+ // Index of currently firing callback (modified by remove if needed)+ firingIndex,+ // Add one or several callbacks to the list+ add = function( args ) {+ var i,+ length,+ elem,+ type,+ actual;+ for ( i = 0, length = args.length; i < length; i++ ) {+ elem = args[ i ];+ type = jQuery.type( elem );+ if ( type === "array" ) {+ // Inspect recursively+ add( elem );+ } else if ( type === "function" ) {+ // Add if not in unique mode and callback is not in+ if ( !flags.unique || !self.has( elem ) ) {+ list.push( elem );+ }+ }+ }+ },+ // Fire callbacks+ fire = function( context, args ) {+ args = args || [];+ memory = !flags.memory || [ context, args ];+ fired = true;+ firing = true;+ firingIndex = firingStart || 0;+ firingStart = 0;+ firingLength = list.length;+ for ( ; list && firingIndex < firingLength; firingIndex++ ) {+ if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) {+ memory = true; // Mark as halted+ break;+ }+ }+ firing = false;+ if ( list ) {+ if ( !flags.once ) {+ if ( stack && stack.length ) {+ memory = stack.shift();+ self.fireWith( memory[ 0 ], memory[ 1 ] );+ }+ } else if ( memory === true ) {+ self.disable();+ } else {+ list = [];+ }+ }+ },+ // Actual Callbacks object+ self = {+ // Add a callback or a collection of callbacks to the list+ add: function() {+ if ( list ) {+ var length = list.length;+ add( arguments );+ // Do we need to add the callbacks to the+ // current firing batch?+ if ( firing ) {+ firingLength = list.length;+ // With memory, if we're not firing then+ // we should call right away, unless previous+ // firing was halted (stopOnFalse)+ } else if ( memory && memory !== true ) {+ firingStart = length;+ fire( memory[ 0 ], memory[ 1 ] );+ }+ }+ return this;+ },+ // Remove a callback from the list+ remove: function() {+ if ( list ) {+ var args = arguments,+ argIndex = 0,+ argLength = args.length;+ for ( ; argIndex < argLength ; argIndex++ ) {+ for ( var i = 0; i < list.length; i++ ) {+ if ( args[ argIndex ] === list[ i ] ) {+ // Handle firingIndex and firingLength+ if ( firing ) {+ if ( i <= firingLength ) {+ firingLength--;+ if ( i <= firingIndex ) {+ firingIndex--;+ }+ }+ }+ // Remove the element+ list.splice( i--, 1 );+ // If we have some unicity property then+ // we only need to do this once+ if ( flags.unique ) {+ break;+ }+ }+ }+ }+ }+ return this;+ },+ // Control if a given callback is in the list+ has: function( fn ) {+ if ( list ) {+ var i = 0,+ length = list.length;+ for ( ; i < length; i++ ) {+ if ( fn === list[ i ] ) {+ return true;+ }+ }+ }+ return false;+ },+ // Remove all callbacks from the list+ empty: function() {+ list = [];+ return this;+ },+ // Have the list do nothing anymore+ disable: function() {+ list = stack = memory = undefined;+ return this;+ },+ // Is it disabled?+ disabled: function() {+ return !list;+ },+ // Lock the list in its current state+ lock: function() {+ stack = undefined;+ if ( !memory || memory === true ) {+ self.disable();+ }+ return this;+ },+ // Is it locked?+ locked: function() {+ return !stack;+ },+ // Call all callbacks with the given context and arguments+ fireWith: function( context, args ) {+ if ( stack ) {+ if ( firing ) {+ if ( !flags.once ) {+ stack.push( [ context, args ] );+ }+ } else if ( !( flags.once && memory ) ) {+ fire( context, args );+ }+ }+ return this;+ },+ // Call all the callbacks with the given arguments+ fire: function() {+ self.fireWith( this, arguments );+ return this;+ },+ // To know if the callbacks have already been called at least once+ fired: function() {+ return !!fired;+ }+ };++ return self;+};+++++var // Static reference to slice+ sliceDeferred = [].slice;++jQuery.extend({++ Deferred: function( func ) {+ var doneList = jQuery.Callbacks( "once memory" ),+ failList = jQuery.Callbacks( "once memory" ),+ progressList = jQuery.Callbacks( "memory" ),+ state = "pending",+ lists = {+ resolve: doneList,+ reject: failList,+ notify: progressList+ },+ promise = {+ done: doneList.add,+ fail: failList.add,+ progress: progressList.add,++ state: function() {+ return state;+ },++ // Deprecated+ isResolved: doneList.fired,+ isRejected: failList.fired,++ then: function( doneCallbacks, failCallbacks, progressCallbacks ) {+ deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks );+ return this;+ },+ always: function() {+ deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );+ return this;+ },+ pipe: function( fnDone, fnFail, fnProgress ) {+ return jQuery.Deferred(function( newDefer ) {+ jQuery.each( {+ done: [ fnDone, "resolve" ],+ fail: [ fnFail, "reject" ],+ progress: [ fnProgress, "notify" ]+ }, function( handler, data ) {+ var fn = data[ 0 ],+ action = data[ 1 ],+ returned;+ if ( jQuery.isFunction( fn ) ) {+ deferred[ handler ](function() {+ returned = fn.apply( this, arguments );+ if ( returned && jQuery.isFunction( returned.promise ) ) {+ returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify );+ } else {+ newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );+ }+ });+ } else {+ deferred[ handler ]( newDefer[ action ] );+ }+ });+ }).promise();+ },+ // Get a promise for this deferred+ // If obj is provided, the promise aspect is added to the object+ promise: function( obj ) {+ if ( obj == null ) {+ obj = promise;+ } else {+ for ( var key in promise ) {+ obj[ key ] = promise[ key ];+ }+ }+ return obj;+ }+ },+ deferred = promise.promise({}),+ key;++ for ( key in lists ) {+ deferred[ key ] = lists[ key ].fire;+ deferred[ key + "With" ] = lists[ key ].fireWith;+ }++ // Handle state+ deferred.done( function() {+ state = "resolved";+ }, failList.disable, progressList.lock ).fail( function() {+ state = "rejected";+ }, doneList.disable, progressList.lock );++ // Call given func if any+ if ( func ) {+ func.call( deferred, deferred );+ }++ // All done!+ return deferred;+ },++ // Deferred helper+ when: function( firstParam ) {+ var args = sliceDeferred.call( arguments, 0 ),+ i = 0,+ length = args.length,+ pValues = new Array( length ),+ count = length,+ pCount = length,+ deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?+ firstParam :+ jQuery.Deferred(),+ promise = deferred.promise();+ function resolveFunc( i ) {+ return function( value ) {+ args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;+ if ( !( --count ) ) {+ deferred.resolveWith( deferred, args );+ }+ };+ }+ function progressFunc( i ) {+ return function( value ) {+ pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;+ deferred.notifyWith( promise, pValues );+ };+ }+ if ( length > 1 ) {+ for ( ; i < length; i++ ) {+ if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) {+ args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) );+ } else {+ --count;+ }+ }+ if ( !count ) {+ deferred.resolveWith( deferred, args );+ }+ } else if ( deferred !== firstParam ) {+ deferred.resolveWith( deferred, length ? [ firstParam ] : [] );+ }+ return promise;+ }+});+++++jQuery.support = (function() {++ var support,+ all,+ a,+ select,+ opt,+ input,+ fragment,+ tds,+ events,+ eventName,+ i,+ isSupported,+ div = document.createElement( "div" ),+ documentElement = document.documentElement;++ // Preliminary tests+ div.setAttribute("className", "t");+ div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";++ all = div.getElementsByTagName( "*" );+ a = div.getElementsByTagName( "a" )[ 0 ];++ // Can't get basic test support+ if ( !all || !all.length || !a ) {+ return {};+ }++ // First batch of supports tests+ select = document.createElement( "select" );+ opt = select.appendChild( document.createElement("option") );+ input = div.getElementsByTagName( "input" )[ 0 ];++ support = {+ // IE strips leading whitespace when .innerHTML is used+ leadingWhitespace: ( div.firstChild.nodeType === 3 ),++ // Make sure that tbody elements aren't automatically inserted+ // IE will insert them into empty tables+ tbody: !div.getElementsByTagName("tbody").length,++ // Make sure that link elements get serialized correctly by innerHTML+ // This requires a wrapper element in IE+ htmlSerialize: !!div.getElementsByTagName("link").length,++ // Get the style information from getAttribute+ // (IE uses .cssText instead)+ style: /top/.test( a.getAttribute("style") ),++ // Make sure that URLs aren't manipulated+ // (IE normalizes it by default)+ hrefNormalized: ( a.getAttribute("href") === "/a" ),++ // Make sure that element opacity exists+ // (IE uses filter instead)+ // Use a regex to work around a WebKit issue. See #5145+ opacity: /^0.55/.test( a.style.opacity ),++ // Verify style float existence+ // (IE uses styleFloat instead of cssFloat)+ cssFloat: !!a.style.cssFloat,++ // Make sure that if no value is specified for a checkbox+ // that it defaults to "on".+ // (WebKit defaults to "" instead)+ checkOn: ( input.value === "on" ),++ // Make sure that a selected-by-default option has a working selected property.+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)+ optSelected: opt.selected,++ // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)+ getSetAttribute: div.className !== "t",++ // Tests for enctype support on a form(#6743)+ enctype: !!document.createElement("form").enctype,++ // Makes sure cloning an html5 element does not cause problems+ // Where outerHTML is undefined, this still works+ html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",++ // Will be defined later+ submitBubbles: true,+ changeBubbles: true,+ focusinBubbles: false,+ deleteExpando: true,+ noCloneEvent: true,+ inlineBlockNeedsLayout: false,+ shrinkWrapBlocks: false,+ reliableMarginRight: true,+ pixelMargin: true+ };++ // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead+ jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat");++ // Make sure checked status is properly cloned+ input.checked = true;+ support.noCloneChecked = input.cloneNode( true ).checked;++ // Make sure that the options inside disabled selects aren't marked as disabled+ // (WebKit marks them as disabled)+ select.disabled = true;+ support.optDisabled = !opt.disabled;++ // Test to see if it's possible to delete an expando from an element+ // Fails in Internet Explorer+ try {+ delete div.test;+ } catch( e ) {+ support.deleteExpando = false;+ }++ if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {+ div.attachEvent( "onclick", function() {+ // Cloning a node shouldn't copy over any+ // bound event handlers (IE does this)+ support.noCloneEvent = false;+ });+ div.cloneNode( true ).fireEvent( "onclick" );+ }++ // Check if a radio maintains its value+ // after being appended to the DOM+ input = document.createElement("input");+ input.value = "t";+ input.setAttribute("type", "radio");+ support.radioValue = input.value === "t";++ input.setAttribute("checked", "checked");++ // #11217 - WebKit loses check when the name is after the checked attribute+ input.setAttribute( "name", "t" );++ div.appendChild( input );+ fragment = document.createDocumentFragment();+ fragment.appendChild( div.lastChild );++ // WebKit doesn't clone checked state correctly in fragments+ support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;++ // Check if a disconnected checkbox will retain its checked+ // value of true after appended to the DOM (IE6/7)+ support.appendChecked = input.checked;++ fragment.removeChild( input );+ fragment.appendChild( div );++ // Technique from Juriy Zaytsev+ // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/+ // We only care about the case where non-standard event systems+ // are used, namely in IE. Short-circuiting here helps us to+ // avoid an eval call (in setAttribute) which can cause CSP+ // to go haywire. See: https://developer.mozilla.org/en/Security/CSP+ if ( div.attachEvent ) {+ for ( i in {+ submit: 1,+ change: 1,+ focusin: 1+ }) {+ eventName = "on" + i;+ isSupported = ( eventName in div );+ if ( !isSupported ) {+ div.setAttribute( eventName, "return;" );+ isSupported = ( typeof div[ eventName ] === "function" );+ }+ support[ i + "Bubbles" ] = isSupported;+ }+ }++ fragment.removeChild( div );++ // Null elements to avoid leaks in IE+ fragment = select = opt = div = input = null;++ // Run tests that need a body at doc ready+ jQuery(function() {+ var container, outer, inner, table, td, offsetSupport,+ marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight,+ paddingMarginBorderVisibility, paddingMarginBorder,+ body = document.getElementsByTagName("body")[0];++ if ( !body ) {+ // Return for frameset docs that don't have a body+ return;+ }++ conMarginTop = 1;+ paddingMarginBorder = "padding:0;margin:0;border:";+ positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;";+ paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;";+ style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;";+ html = "<div " + style + "display:block;'><div style='" + paddingMarginBorder + "0;display:block;overflow:hidden;'></div></div>" ++ "<table " + style + "' cellpadding='0' cellspacing='0'>" ++ "<tr><td></td></tr></table>";++ container = document.createElement("div");+ container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px";+ body.insertBefore( container, body.firstChild );++ // Construct the test element+ div = document.createElement("div");+ container.appendChild( div );++ // Check if table cells still have offsetWidth/Height when they are set+ // to display:none and there are still other visible table cells in a+ // table row; if so, offsetWidth/Height are not reliable for use when+ // determining if an element has been hidden directly using+ // display:none (it is still safe to use offsets if a parent element is+ // hidden; don safety goggles and see bug #4512 for more information).+ // (only IE 8 fails this test)+ div.innerHTML = "<table><tr><td style='" + paddingMarginBorder + "0;display:none'></td><td>t</td></tr></table>";+ tds = div.getElementsByTagName( "td" );+ isSupported = ( tds[ 0 ].offsetHeight === 0 );++ tds[ 0 ].style.display = "";+ tds[ 1 ].style.display = "none";++ // Check if empty table cells still have offsetWidth/Height+ // (IE <= 8 fail this test)+ support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );++ // Check if div with explicit width and no margin-right incorrectly+ // gets computed margin-right based on width of container. For more+ // info see bug #3333+ // Fails in WebKit before Feb 2011 nightlies+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right+ if ( window.getComputedStyle ) {+ div.innerHTML = "";+ marginDiv = document.createElement( "div" );+ marginDiv.style.width = "0";+ marginDiv.style.marginRight = "0";+ div.style.width = "2px";+ div.appendChild( marginDiv );+ support.reliableMarginRight =+ ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;+ }++ if ( typeof div.style.zoom !== "undefined" ) {+ // Check if natively block-level elements act like inline-block+ // elements when setting their display to 'inline' and giving+ // them layout+ // (IE < 8 does this)+ div.innerHTML = "";+ div.style.width = div.style.padding = "1px";+ div.style.border = 0;+ div.style.overflow = "hidden";+ div.style.display = "inline";+ div.style.zoom = 1;+ support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );++ // Check if elements with layout shrink-wrap their children+ // (IE 6 does this)+ div.style.display = "block";+ div.style.overflow = "visible";+ div.innerHTML = "<div style='width:5px;'></div>";+ support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );+ }++ div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility;+ div.innerHTML = html;++ outer = div.firstChild;+ inner = outer.firstChild;+ td = outer.nextSibling.firstChild.firstChild;++ offsetSupport = {+ doesNotAddBorder: ( inner.offsetTop !== 5 ),+ doesAddBorderForTableAndCells: ( td.offsetTop === 5 )+ };++ inner.style.position = "fixed";+ inner.style.top = "20px";++ // safari subtracts parent border width here which is 5px+ offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 );+ inner.style.position = inner.style.top = "";++ outer.style.overflow = "hidden";+ outer.style.position = "relative";++ offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 );+ offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );++ if ( window.getComputedStyle ) {+ div.style.marginTop = "1%";+ support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%";+ }++ if ( typeof container.style.zoom !== "undefined" ) {+ container.style.zoom = 1;+ }++ body.removeChild( container );+ marginDiv = div = container = null;++ jQuery.extend( support, offsetSupport );+ });++ return support;+})();+++++var rbrace = /^(?:\{.*\}|\[.*\])$/,+ rmultiDash = /([A-Z])/g;++jQuery.extend({+ cache: {},++ // Please use with caution+ uuid: 0,++ // Unique for each copy of jQuery on the page+ // Non-digits removed to match rinlinejQuery+ expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),++ // The following elements throw uncatchable exceptions if you+ // attempt to add expando properties to them.+ noData: {+ "embed": true,+ // Ban all objects except for Flash (which handle expandos)+ "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",+ "applet": true+ },++ hasData: function( elem ) {+ elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];+ return !!elem && !isEmptyDataObject( elem );+ },++ data: function( elem, name, data, pvt /* Internal Use Only */ ) {+ if ( !jQuery.acceptData( elem ) ) {+ return;+ }++ var privateCache, thisCache, ret,+ internalKey = jQuery.expando,+ getByName = typeof name === "string",++ // We have to handle DOM nodes and JS objects differently because IE6-7+ // can't GC object references properly across the DOM-JS boundary+ isNode = elem.nodeType,++ // Only DOM nodes need the global jQuery cache; JS object data is+ // attached directly to the object so GC can occur automatically+ cache = isNode ? jQuery.cache : elem,++ // Only defining an ID for JS objects if its cache already exists allows+ // the code to shortcut on the same path as a DOM node with no cache+ id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey,+ isEvents = name === "events";++ // Avoid doing any more work than we need to when trying to get data on an+ // object that has no data at all+ if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) {+ return;+ }++ if ( !id ) {+ // Only DOM nodes need a new unique ID for each element since their data+ // ends up in the global cache+ if ( isNode ) {+ elem[ internalKey ] = id = ++jQuery.uuid;+ } else {+ id = internalKey;+ }+ }++ if ( !cache[ id ] ) {+ cache[ id ] = {};++ // Avoids exposing jQuery metadata on plain JS objects when the object+ // is serialized using JSON.stringify+ if ( !isNode ) {+ cache[ id ].toJSON = jQuery.noop;+ }+ }++ // An object can be passed to jQuery.data instead of a key/value pair; this gets+ // shallow copied over onto the existing cache+ if ( typeof name === "object" || typeof name === "function" ) {+ if ( pvt ) {+ cache[ id ] = jQuery.extend( cache[ id ], name );+ } else {+ cache[ id ].data = jQuery.extend( cache[ id ].data, name );+ }+ }++ privateCache = thisCache = cache[ id ];++ // jQuery data() is stored in a separate object inside the object's internal data+ // cache in order to avoid key collisions between internal data and user-defined+ // data.+ if ( !pvt ) {+ if ( !thisCache.data ) {+ thisCache.data = {};+ }++ thisCache = thisCache.data;+ }++ if ( data !== undefined ) {+ thisCache[ jQuery.camelCase( name ) ] = data;+ }++ // Users should not attempt to inspect the internal events object using jQuery.data,+ // it is undocumented and subject to change. But does anyone listen? No.+ if ( isEvents && !thisCache[ name ] ) {+ return privateCache.events;+ }++ // Check for both converted-to-camel and non-converted data property names+ // If a data property was specified+ if ( getByName ) {++ // First Try to find as-is property data+ ret = thisCache[ name ];++ // Test for null|undefined property data+ if ( ret == null ) {++ // Try to find the camelCased property+ ret = thisCache[ jQuery.camelCase( name ) ];+ }+ } else {+ ret = thisCache;+ }++ return ret;+ },++ removeData: function( elem, name, pvt /* Internal Use Only */ ) {+ if ( !jQuery.acceptData( elem ) ) {+ return;+ }++ var thisCache, i, l,++ // Reference to internal data cache key+ internalKey = jQuery.expando,++ isNode = elem.nodeType,++ // See jQuery.data for more information+ cache = isNode ? jQuery.cache : elem,++ // See jQuery.data for more information+ id = isNode ? elem[ internalKey ] : internalKey;++ // If there is already no cache entry for this object, there is no+ // purpose in continuing+ if ( !cache[ id ] ) {+ return;+ }++ if ( name ) {++ thisCache = pvt ? cache[ id ] : cache[ id ].data;++ if ( thisCache ) {++ // Support array or space separated string names for data keys+ if ( !jQuery.isArray( name ) ) {++ // try the string as a key before any manipulation+ if ( name in thisCache ) {+ name = [ name ];+ } else {++ // split the camel cased version by spaces unless a key with the spaces exists+ name = jQuery.camelCase( name );+ if ( name in thisCache ) {+ name = [ name ];+ } else {+ name = name.split( " " );+ }+ }+ }++ for ( i = 0, l = name.length; i < l; i++ ) {+ delete thisCache[ name[i] ];+ }++ // If there is no data left in the cache, we want to continue+ // and let the cache object itself get destroyed+ if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {+ return;+ }+ }+ }++ // See jQuery.data for more information+ if ( !pvt ) {+ delete cache[ id ].data;++ // Don't destroy the parent cache unless the internal data object+ // had been the only thing left in it+ if ( !isEmptyDataObject(cache[ id ]) ) {+ return;+ }+ }++ // Browsers that fail expando deletion also refuse to delete expandos on+ // the window, but it will allow it on all other JS objects; other browsers+ // don't care+ // Ensure that `cache` is not a window object #10080+ if ( jQuery.support.deleteExpando || !cache.setInterval ) {+ delete cache[ id ];+ } else {+ cache[ id ] = null;+ }++ // We destroyed the cache and need to eliminate the expando on the node to avoid+ // false lookups in the cache for entries that no longer exist+ if ( isNode ) {+ // IE does not allow us to delete expando properties from nodes,+ // nor does it have a removeAttribute function on Document nodes;+ // we must handle all of these cases+ if ( jQuery.support.deleteExpando ) {+ delete elem[ internalKey ];+ } else if ( elem.removeAttribute ) {+ elem.removeAttribute( internalKey );+ } else {+ elem[ internalKey ] = null;+ }+ }+ },++ // For internal use only.+ _data: function( elem, name, data ) {+ return jQuery.data( elem, name, data, true );+ },++ // A method for determining if a DOM node can handle the data expando+ acceptData: function( elem ) {+ if ( elem.nodeName ) {+ var match = jQuery.noData[ elem.nodeName.toLowerCase() ];++ if ( match ) {+ return !(match === true || elem.getAttribute("classid") !== match);+ }+ }++ return true;+ }+});++jQuery.fn.extend({+ data: function( key, value ) {+ var parts, part, attr, name, l,+ elem = this[0],+ i = 0,+ data = null;++ // Gets all values+ if ( key === undefined ) {+ if ( this.length ) {+ data = jQuery.data( elem );++ if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {+ attr = elem.attributes;+ for ( l = attr.length; i < l; i++ ) {+ name = attr[i].name;++ if ( name.indexOf( "data-" ) === 0 ) {+ name = jQuery.camelCase( name.substring(5) );++ dataAttr( elem, name, data[ name ] );+ }+ }+ jQuery._data( elem, "parsedAttrs", true );+ }+ }++ return data;+ }++ // Sets multiple values+ if ( typeof key === "object" ) {+ return this.each(function() {+ jQuery.data( this, key );+ });+ }++ parts = key.split( ".", 2 );+ parts[1] = parts[1] ? "." + parts[1] : "";+ part = parts[1] + "!";++ return jQuery.access( this, function( value ) {++ if ( value === undefined ) {+ data = this.triggerHandler( "getData" + part, [ parts[0] ] );++ // Try to fetch any internally stored data first+ if ( data === undefined && elem ) {+ data = jQuery.data( elem, key );+ data = dataAttr( elem, key, data );+ }++ return data === undefined && parts[1] ?+ this.data( parts[0] ) :+ data;+ }++ parts[1] = value;+ this.each(function() {+ var self = jQuery( this );++ self.triggerHandler( "setData" + part, parts );+ jQuery.data( this, key, value );+ self.triggerHandler( "changeData" + part, parts );+ });+ }, null, value, arguments.length > 1, null, false );+ },++ removeData: function( key ) {+ return this.each(function() {+ jQuery.removeData( this, key );+ });+ }+});++function dataAttr( elem, key, data ) {+ // If nothing was found internally, try to fetch any+ // data from the HTML5 data-* attribute+ if ( data === undefined && elem.nodeType === 1 ) {++ var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();++ data = elem.getAttribute( name );++ if ( typeof data === "string" ) {+ try {+ data = data === "true" ? true :+ data === "false" ? false :+ data === "null" ? null :+ jQuery.isNumeric( data ) ? +data :+ rbrace.test( data ) ? jQuery.parseJSON( data ) :+ data;+ } catch( e ) {}++ // Make sure we set the data so it isn't changed later+ jQuery.data( elem, key, data );++ } else {+ data = undefined;+ }+ }++ return data;+}++// checks a cache object for emptiness+function isEmptyDataObject( obj ) {+ for ( var name in obj ) {++ // if the public data object is empty, the private is still empty+ if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {+ continue;+ }+ if ( name !== "toJSON" ) {+ return false;+ }+ }++ return true;+}+++++function handleQueueMarkDefer( elem, type, src ) {+ var deferDataKey = type + "defer",+ queueDataKey = type + "queue",+ markDataKey = type + "mark",+ defer = jQuery._data( elem, deferDataKey );+ if ( defer &&+ ( src === "queue" || !jQuery._data(elem, queueDataKey) ) &&+ ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) {+ // Give room for hard-coded callbacks to fire first+ // and eventually mark/queue something else on the element+ setTimeout( function() {+ if ( !jQuery._data( elem, queueDataKey ) &&+ !jQuery._data( elem, markDataKey ) ) {+ jQuery.removeData( elem, deferDataKey, true );+ defer.fire();+ }+ }, 0 );+ }+}++jQuery.extend({++ _mark: function( elem, type ) {+ if ( elem ) {+ type = ( type || "fx" ) + "mark";+ jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 );+ }+ },++ _unmark: function( force, elem, type ) {+ if ( force !== true ) {+ type = elem;+ elem = force;+ force = false;+ }+ if ( elem ) {+ type = type || "fx";+ var key = type + "mark",+ count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 );+ if ( count ) {+ jQuery._data( elem, key, count );+ } else {+ jQuery.removeData( elem, key, true );+ handleQueueMarkDefer( elem, type, "mark" );+ }+ }+ },++ queue: function( elem, type, data ) {+ var q;+ if ( elem ) {+ type = ( type || "fx" ) + "queue";+ q = jQuery._data( elem, type );++ // Speed up dequeue by getting out quickly if this is just a lookup+ if ( data ) {+ if ( !q || jQuery.isArray(data) ) {+ q = jQuery._data( elem, type, jQuery.makeArray(data) );+ } else {+ q.push( data );+ }+ }+ return q || [];+ }+ },++ dequeue: function( elem, type ) {+ type = type || "fx";++ var queue = jQuery.queue( elem, type ),+ fn = queue.shift(),+ hooks = {};++ // If the fx queue is dequeued, always remove the progress sentinel+ if ( fn === "inprogress" ) {+ fn = queue.shift();+ }++ if ( fn ) {+ // Add a progress sentinel to prevent the fx queue from being+ // automatically dequeued+ if ( type === "fx" ) {+ queue.unshift( "inprogress" );+ }++ jQuery._data( elem, type + ".run", hooks );+ fn.call( elem, function() {+ jQuery.dequeue( elem, type );+ }, hooks );+ }++ if ( !queue.length ) {+ jQuery.removeData( elem, type + "queue " + type + ".run", true );+ handleQueueMarkDefer( elem, type, "queue" );+ }+ }+});++jQuery.fn.extend({+ queue: function( type, data ) {+ var setter = 2;++ if ( typeof type !== "string" ) {+ data = type;+ type = "fx";+ setter--;+ }++ if ( arguments.length < setter ) {+ return jQuery.queue( this[0], type );+ }++ return data === undefined ?+ this :+ this.each(function() {+ var queue = jQuery.queue( this, type, data );++ if ( type === "fx" && queue[0] !== "inprogress" ) {+ jQuery.dequeue( this, type );+ }+ });+ },+ dequeue: function( type ) {+ return this.each(function() {+ jQuery.dequeue( this, type );+ });+ },+ // Based off of the plugin by Clint Helfers, with permission.+ // http://blindsignals.com/index.php/2009/07/jquery-delay/+ delay: function( time, type ) {+ time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;+ type = type || "fx";++ return this.queue( type, function( next, hooks ) {+ var timeout = setTimeout( next, time );+ hooks.stop = function() {+ clearTimeout( timeout );+ };+ });+ },+ clearQueue: function( type ) {+ return this.queue( type || "fx", [] );+ },+ // Get a promise resolved when queues of a certain type+ // are emptied (fx is the type by default)+ promise: function( type, object ) {+ if ( typeof type !== "string" ) {+ object = type;+ type = undefined;+ }+ type = type || "fx";+ var defer = jQuery.Deferred(),+ elements = this,+ i = elements.length,+ count = 1,+ deferDataKey = type + "defer",+ queueDataKey = type + "queue",+ markDataKey = type + "mark",+ tmp;+ function resolve() {+ if ( !( --count ) ) {+ defer.resolveWith( elements, [ elements ] );+ }+ }+ while( i-- ) {+ if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||+ ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||+ jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&+ jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) {+ count++;+ tmp.add( resolve );+ }+ }+ resolve();+ return defer.promise( object );+ }+});+++++var rclass = /[\n\t\r]/g,+ rspace = /\s+/,+ rreturn = /\r/g,+ rtype = /^(?:button|input)$/i,+ rfocusable = /^(?:button|input|object|select|textarea)$/i,+ rclickable = /^a(?:rea)?$/i,+ rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,+ getSetAttribute = jQuery.support.getSetAttribute,+ nodeHook, boolHook, fixSpecified;++jQuery.fn.extend({+ attr: function( name, value ) {+ return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );+ },++ removeAttr: function( name ) {+ return this.each(function() {+ jQuery.removeAttr( this, name );+ });+ },++ prop: function( name, value ) {+ return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );+ },++ removeProp: function( name ) {+ name = jQuery.propFix[ name ] || name;+ return this.each(function() {+ // try/catch handles cases where IE balks (such as removing a property on window)+ try {+ this[ name ] = undefined;+ delete this[ name ];+ } catch( e ) {}+ });+ },++ addClass: function( value ) {+ var classNames, i, l, elem,+ setClass, c, cl;++ if ( jQuery.isFunction( value ) ) {+ return this.each(function( j ) {+ jQuery( this ).addClass( value.call(this, j, this.className) );+ });+ }++ if ( value && typeof value === "string" ) {+ classNames = value.split( rspace );++ for ( i = 0, l = this.length; i < l; i++ ) {+ elem = this[ i ];++ if ( elem.nodeType === 1 ) {+ if ( !elem.className && classNames.length === 1 ) {+ elem.className = value;++ } else {+ setClass = " " + elem.className + " ";++ for ( c = 0, cl = classNames.length; c < cl; c++ ) {+ if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {+ setClass += classNames[ c ] + " ";+ }+ }+ elem.className = jQuery.trim( setClass );+ }+ }+ }+ }++ return this;+ },++ removeClass: function( value ) {+ var classNames, i, l, elem, className, c, cl;++ if ( jQuery.isFunction( value ) ) {+ return this.each(function( j ) {+ jQuery( this ).removeClass( value.call(this, j, this.className) );+ });+ }++ if ( (value && typeof value === "string") || value === undefined ) {+ classNames = ( value || "" ).split( rspace );++ for ( i = 0, l = this.length; i < l; i++ ) {+ elem = this[ i ];++ if ( elem.nodeType === 1 && elem.className ) {+ if ( value ) {+ className = (" " + elem.className + " ").replace( rclass, " " );+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {+ className = className.replace(" " + classNames[ c ] + " ", " ");+ }+ elem.className = jQuery.trim( className );++ } else {+ elem.className = "";+ }+ }+ }+ }++ return this;+ },++ toggleClass: function( value, stateVal ) {+ var type = typeof value,+ isBool = typeof stateVal === "boolean";++ if ( jQuery.isFunction( value ) ) {+ return this.each(function( i ) {+ jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );+ });+ }++ return this.each(function() {+ if ( type === "string" ) {+ // toggle individual class names+ var className,+ i = 0,+ self = jQuery( this ),+ state = stateVal,+ classNames = value.split( rspace );++ while ( (className = classNames[ i++ ]) ) {+ // check each className given, space seperated list+ state = isBool ? state : !self.hasClass( className );+ self[ state ? "addClass" : "removeClass" ]( className );+ }++ } else if ( type === "undefined" || type === "boolean" ) {+ if ( this.className ) {+ // store className if set+ jQuery._data( this, "__className__", this.className );+ }++ // toggle whole className+ this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";+ }+ });+ },++ hasClass: function( selector ) {+ var className = " " + selector + " ",+ i = 0,+ l = this.length;+ for ( ; i < l; i++ ) {+ if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {+ return true;+ }+ }++ return false;+ },++ val: function( value ) {+ var hooks, ret, isFunction,+ elem = this[0];++ if ( !arguments.length ) {+ if ( elem ) {+ hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];++ if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {+ return ret;+ }++ ret = elem.value;++ return typeof ret === "string" ?+ // handle most common string cases+ ret.replace(rreturn, "") :+ // handle cases where value is null/undef or number+ ret == null ? "" : ret;+ }++ return;+ }++ isFunction = jQuery.isFunction( value );++ return this.each(function( i ) {+ var self = jQuery(this), val;++ if ( this.nodeType !== 1 ) {+ return;+ }++ if ( isFunction ) {+ val = value.call( this, i, self.val() );+ } else {+ val = value;+ }++ // Treat null/undefined as ""; convert numbers to string+ if ( val == null ) {+ val = "";+ } else if ( typeof val === "number" ) {+ val += "";+ } else if ( jQuery.isArray( val ) ) {+ val = jQuery.map(val, function ( value ) {+ return value == null ? "" : value + "";+ });+ }++ hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];++ // If set returns undefined, fall back to normal setting+ if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {+ this.value = val;+ }+ });+ }+});++jQuery.extend({+ valHooks: {+ option: {+ get: function( elem ) {+ // attributes.value is undefined in Blackberry 4.7 but+ // uses .value. See #6932+ var val = elem.attributes.value;+ return !val || val.specified ? elem.value : elem.text;+ }+ },+ select: {+ get: function( elem ) {+ var value, i, max, option,+ index = elem.selectedIndex,+ values = [],+ options = elem.options,+ one = elem.type === "select-one";++ // Nothing was selected+ if ( index < 0 ) {+ return null;+ }++ // Loop through all the selected options+ i = one ? index : 0;+ max = one ? index + 1 : options.length;+ for ( ; i < max; i++ ) {+ option = options[ i ];++ // Don't return options that are disabled or in a disabled optgroup+ if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&+ (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {++ // Get the specific value for the option+ value = jQuery( option ).val();++ // We don't need an array for one selects+ if ( one ) {+ return value;+ }++ // Multi-Selects return an array+ values.push( value );+ }+ }++ // Fixes Bug #2551 -- select.val() broken in IE after form.reset()+ if ( one && !values.length && options.length ) {+ return jQuery( options[ index ] ).val();+ }++ return values;+ },++ set: function( elem, value ) {+ var values = jQuery.makeArray( value );++ jQuery(elem).find("option").each(function() {+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;+ });++ if ( !values.length ) {+ elem.selectedIndex = -1;+ }+ return values;+ }+ }+ },++ attrFn: {+ val: true,+ css: true,+ html: true,+ text: true,+ data: true,+ width: true,+ height: true,+ offset: true+ },++ attr: function( elem, name, value, pass ) {+ var ret, hooks, notxml,+ nType = elem.nodeType;++ // don't get/set attributes on text, comment and attribute nodes+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {+ return;+ }++ if ( pass && name in jQuery.attrFn ) {+ return jQuery( elem )[ name ]( value );+ }++ // Fallback to prop when attributes are not supported+ if ( typeof elem.getAttribute === "undefined" ) {+ return jQuery.prop( elem, name, value );+ }++ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );++ // All attributes are lowercase+ // Grab necessary hook if one is defined+ if ( notxml ) {+ name = name.toLowerCase();+ hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );+ }++ if ( value !== undefined ) {++ if ( value === null ) {+ jQuery.removeAttr( elem, name );+ return;++ } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {+ return ret;++ } else {+ elem.setAttribute( name, "" + value );+ return value;+ }++ } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {+ return ret;++ } else {++ ret = elem.getAttribute( name );++ // Non-existent attributes return null, we normalize to undefined+ return ret === null ?+ undefined :+ ret;+ }+ },++ removeAttr: function( elem, value ) {+ var propName, attrNames, name, l, isBool,+ i = 0;++ if ( value && elem.nodeType === 1 ) {+ attrNames = value.toLowerCase().split( rspace );+ l = attrNames.length;++ for ( ; i < l; i++ ) {+ name = attrNames[ i ];++ if ( name ) {+ propName = jQuery.propFix[ name ] || name;+ isBool = rboolean.test( name );++ // See #9699 for explanation of this approach (setting first, then removal)+ // Do not do this for boolean attributes (see #10870)+ if ( !isBool ) {+ jQuery.attr( elem, name, "" );+ }+ elem.removeAttribute( getSetAttribute ? name : propName );++ // Set corresponding property to false for boolean attributes+ if ( isBool && propName in elem ) {+ elem[ propName ] = false;+ }+ }+ }+ }+ },++ attrHooks: {+ type: {+ set: function( elem, value ) {+ // We can't allow the type property to be changed (since it causes problems in IE)+ if ( rtype.test( elem.nodeName ) && elem.parentNode ) {+ jQuery.error( "type property can't be changed" );+ } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {+ // Setting the type on a radio button after the value resets the value in IE6-9+ // Reset value to it's default in case type is set after value+ // This is for element creation+ var val = elem.value;+ elem.setAttribute( "type", value );+ if ( val ) {+ elem.value = val;+ }+ return value;+ }+ }+ },+ // Use the value property for back compat+ // Use the nodeHook for button elements in IE6/7 (#1954)+ value: {+ get: function( elem, name ) {+ if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {+ return nodeHook.get( elem, name );+ }+ return name in elem ?+ elem.value :+ null;+ },+ set: function( elem, value, name ) {+ if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {+ return nodeHook.set( elem, value, name );+ }+ // Does not return so that setAttribute is also used+ elem.value = value;+ }+ }+ },++ propFix: {+ tabindex: "tabIndex",+ readonly: "readOnly",+ "for": "htmlFor",+ "class": "className",+ maxlength: "maxLength",+ cellspacing: "cellSpacing",+ cellpadding: "cellPadding",+ rowspan: "rowSpan",+ colspan: "colSpan",+ usemap: "useMap",+ frameborder: "frameBorder",+ contenteditable: "contentEditable"+ },++ prop: function( elem, name, value ) {+ var ret, hooks, notxml,+ nType = elem.nodeType;++ // don't get/set properties on text, comment and attribute nodes+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {+ return;+ }++ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );++ if ( notxml ) {+ // Fix name and attach hooks+ name = jQuery.propFix[ name ] || name;+ hooks = jQuery.propHooks[ name ];+ }++ if ( value !== undefined ) {+ if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {+ return ret;++ } else {+ return ( elem[ name ] = value );+ }++ } else {+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {+ return ret;++ } else {+ return elem[ name ];+ }+ }+ },++ propHooks: {+ tabIndex: {+ get: function( elem ) {+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/+ var attributeNode = elem.getAttributeNode("tabindex");++ return attributeNode && attributeNode.specified ?+ parseInt( attributeNode.value, 10 ) :+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?+ 0 :+ undefined;+ }+ }+ }+});++// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional)+jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex;++// Hook for boolean attributes+boolHook = {+ get: function( elem, name ) {+ // Align boolean attributes with corresponding properties+ // Fall back to attribute presence where some booleans are not supported+ var attrNode,+ property = jQuery.prop( elem, name );+ return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?+ name.toLowerCase() :+ undefined;+ },+ set: function( elem, value, name ) {+ var propName;+ if ( value === false ) {+ // Remove boolean attributes when set to false+ jQuery.removeAttr( elem, name );+ } else {+ // value is true since we know at this point it's type boolean and not false+ // Set boolean attributes to the same name and set the DOM property+ propName = jQuery.propFix[ name ] || name;+ if ( propName in elem ) {+ // Only set the IDL specifically if it already exists on the element+ elem[ propName ] = true;+ }++ elem.setAttribute( name, name.toLowerCase() );+ }+ return name;+ }+};++// IE6/7 do not support getting/setting some attributes with get/setAttribute+if ( !getSetAttribute ) {++ fixSpecified = {+ name: true,+ id: true,+ coords: true+ };++ // Use this for any attribute in IE6/7+ // This fixes almost every IE6/7 issue+ nodeHook = jQuery.valHooks.button = {+ get: function( elem, name ) {+ var ret;+ ret = elem.getAttributeNode( name );+ return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ?+ ret.nodeValue :+ undefined;+ },+ set: function( elem, value, name ) {+ // Set the existing or create a new attribute node+ var ret = elem.getAttributeNode( name );+ if ( !ret ) {+ ret = document.createAttribute( name );+ elem.setAttributeNode( ret );+ }+ return ( ret.nodeValue = value + "" );+ }+ };++ // Apply the nodeHook to tabindex+ jQuery.attrHooks.tabindex.set = nodeHook.set;++ // Set width and height to auto instead of 0 on empty string( Bug #8150 )+ // This is for removals+ jQuery.each([ "width", "height" ], function( i, name ) {+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {+ set: function( elem, value ) {+ if ( value === "" ) {+ elem.setAttribute( name, "auto" );+ return value;+ }+ }+ });+ });++ // Set contenteditable to false on removals(#10429)+ // Setting to empty string throws an error as an invalid value+ jQuery.attrHooks.contenteditable = {+ get: nodeHook.get,+ set: function( elem, value, name ) {+ if ( value === "" ) {+ value = "false";+ }+ nodeHook.set( elem, value, name );+ }+ };+}+++// Some attributes require a special call on IE+if ( !jQuery.support.hrefNormalized ) {+ jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {+ get: function( elem ) {+ var ret = elem.getAttribute( name, 2 );+ return ret === null ? undefined : ret;+ }+ });+ });+}++if ( !jQuery.support.style ) {+ jQuery.attrHooks.style = {+ get: function( elem ) {+ // Return undefined in the case of empty string+ // Normalize to lowercase since IE uppercases css property names+ return elem.style.cssText.toLowerCase() || undefined;+ },+ set: function( elem, value ) {+ return ( elem.style.cssText = "" + value );+ }+ };+}++// Safari mis-reports the default selected property of an option+// Accessing the parent's selectedIndex property fixes it+if ( !jQuery.support.optSelected ) {+ jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {+ get: function( elem ) {+ var parent = elem.parentNode;++ if ( parent ) {+ parent.selectedIndex;++ // Make sure that it also works with optgroups, see #5701+ if ( parent.parentNode ) {+ parent.parentNode.selectedIndex;+ }+ }+ return null;+ }+ });+}++// IE6/7 call enctype encoding+if ( !jQuery.support.enctype ) {+ jQuery.propFix.enctype = "encoding";+}++// Radios and checkboxes getter/setter+if ( !jQuery.support.checkOn ) {+ jQuery.each([ "radio", "checkbox" ], function() {+ jQuery.valHooks[ this ] = {+ get: function( elem ) {+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified+ return elem.getAttribute("value") === null ? "on" : elem.value;+ }+ };+ });+}+jQuery.each([ "radio", "checkbox" ], function() {+ jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {+ set: function( elem, value ) {+ if ( jQuery.isArray( value ) ) {+ return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );+ }+ }+ });+});+++++var rformElems = /^(?:textarea|input|select)$/i,+ rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/,+ rhoverHack = /(?:^|\s)hover(\.\S+)?\b/,+ rkeyEvent = /^key/,+ rmouseEvent = /^(?:mouse|contextmenu)|click/,+ rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,+ rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,+ quickParse = function( selector ) {+ var quick = rquickIs.exec( selector );+ if ( quick ) {+ // 0 1 2 3+ // [ _, tag, id, class ]+ quick[1] = ( quick[1] || "" ).toLowerCase();+ quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" );+ }+ return quick;+ },+ quickIs = function( elem, m ) {+ var attrs = elem.attributes || {};+ return (+ (!m[1] || elem.nodeName.toLowerCase() === m[1]) &&+ (!m[2] || (attrs.id || {}).value === m[2]) &&+ (!m[3] || m[3].test( (attrs[ "class" ] || {}).value ))+ );+ },+ hoverHack = function( events ) {+ return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );+ };++/*+ * Helper functions for managing events -- not part of the public interface.+ * Props to Dean Edwards' addEvent library for many of the ideas.+ */+jQuery.event = {++ add: function( elem, types, handler, data, selector ) {++ var elemData, eventHandle, events,+ t, tns, type, namespaces, handleObj,+ handleObjIn, quick, handlers, special;++ // Don't attach events to noData or text/comment nodes (allow plain objects tho)+ if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {+ return;+ }++ // Caller can pass in an object of custom data in lieu of the handler+ if ( handler.handler ) {+ handleObjIn = handler;+ handler = handleObjIn.handler;+ selector = handleObjIn.selector;+ }++ // Make sure that the handler has a unique ID, used to find/remove it later+ if ( !handler.guid ) {+ handler.guid = jQuery.guid++;+ }++ // Init the element's event structure and main handler, if this is the first+ events = elemData.events;+ if ( !events ) {+ elemData.events = events = {};+ }+ eventHandle = elemData.handle;+ if ( !eventHandle ) {+ elemData.handle = eventHandle = function( e ) {+ // Discard the second event of a jQuery.event.trigger() and+ // when an event is called after a page has unloaded+ return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?+ jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :+ undefined;+ };+ // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events+ eventHandle.elem = elem;+ }++ // Handle multiple events separated by a space+ // jQuery(...).bind("mouseover mouseout", fn);+ types = jQuery.trim( hoverHack(types) ).split( " " );+ for ( t = 0; t < types.length; t++ ) {++ tns = rtypenamespace.exec( types[t] ) || [];+ type = tns[1];+ namespaces = ( tns[2] || "" ).split( "." ).sort();++ // If event changes its type, use the special event handlers for the changed type+ special = jQuery.event.special[ type ] || {};++ // If selector defined, determine special event api type, otherwise given type+ type = ( selector ? special.delegateType : special.bindType ) || type;++ // Update special based on newly reset type+ special = jQuery.event.special[ type ] || {};++ // handleObj is passed to all event handlers+ handleObj = jQuery.extend({+ type: type,+ origType: tns[1],+ data: data,+ handler: handler,+ guid: handler.guid,+ selector: selector,+ quick: selector && quickParse( selector ),+ namespace: namespaces.join(".")+ }, handleObjIn );++ // Init the event handler queue if we're the first+ handlers = events[ type ];+ if ( !handlers ) {+ handlers = events[ type ] = [];+ handlers.delegateCount = 0;++ // Only use addEventListener/attachEvent if the special events handler returns false+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {+ // Bind the global event handler to the element+ if ( elem.addEventListener ) {+ elem.addEventListener( type, eventHandle, false );++ } else if ( elem.attachEvent ) {+ elem.attachEvent( "on" + type, eventHandle );+ }+ }+ }++ if ( special.add ) {+ special.add.call( elem, handleObj );++ if ( !handleObj.handler.guid ) {+ handleObj.handler.guid = handler.guid;+ }+ }++ // Add to the element's handler list, delegates in front+ if ( selector ) {+ handlers.splice( handlers.delegateCount++, 0, handleObj );+ } else {+ handlers.push( handleObj );+ }++ // Keep track of which events have ever been used, for event optimization+ jQuery.event.global[ type ] = true;+ }++ // Nullify elem to prevent memory leaks in IE+ elem = null;+ },++ global: {},++ // Detach an event or set of events from an element+ remove: function( elem, types, handler, selector, mappedTypes ) {++ var elemData = jQuery.hasData( elem ) && jQuery._data( elem ),+ t, tns, type, origType, namespaces, origCount,+ j, events, special, handle, eventType, handleObj;++ if ( !elemData || !(events = elemData.events) ) {+ return;+ }++ // Once for each type.namespace in types; type may be omitted+ types = jQuery.trim( hoverHack( types || "" ) ).split(" ");+ for ( t = 0; t < types.length; t++ ) {+ tns = rtypenamespace.exec( types[t] ) || [];+ type = origType = tns[1];+ namespaces = tns[2];++ // Unbind all events (on this namespace, if provided) for the element+ if ( !type ) {+ for ( type in events ) {+ jQuery.event.remove( elem, type + types[ t ], handler, selector, true );+ }+ continue;+ }++ special = jQuery.event.special[ type ] || {};+ type = ( selector? special.delegateType : special.bindType ) || type;+ eventType = events[ type ] || [];+ origCount = eventType.length;+ namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null;++ // Remove matching events+ for ( j = 0; j < eventType.length; j++ ) {+ handleObj = eventType[ j ];++ if ( ( mappedTypes || origType === handleObj.origType ) &&+ ( !handler || handler.guid === handleObj.guid ) &&+ ( !namespaces || namespaces.test( handleObj.namespace ) ) &&+ ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {+ eventType.splice( j--, 1 );++ if ( handleObj.selector ) {+ eventType.delegateCount--;+ }+ if ( special.remove ) {+ special.remove.call( elem, handleObj );+ }+ }+ }++ // Remove generic event handler if we removed something and no more handlers exist+ // (avoids potential for endless recursion during removal of special event handlers)+ if ( eventType.length === 0 && origCount !== eventType.length ) {+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {+ jQuery.removeEvent( elem, type, elemData.handle );+ }++ delete events[ type ];+ }+ }++ // Remove the expando if it's no longer used+ if ( jQuery.isEmptyObject( events ) ) {+ handle = elemData.handle;+ if ( handle ) {+ handle.elem = null;+ }++ // removeData also checks for emptiness and clears the expando if empty+ // so use it instead of delete+ jQuery.removeData( elem, [ "events", "handle" ], true );+ }+ },++ // Events that are safe to short-circuit if no handlers are attached.+ // Native DOM events should not be added, they may have inline handlers.+ customEvent: {+ "getData": true,+ "setData": true,+ "changeData": true+ },++ trigger: function( event, data, elem, onlyHandlers ) {+ // Don't do events on text and comment nodes+ if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {+ return;+ }++ // Event object or event type+ var type = event.type || event,+ namespaces = [],+ cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType;++ // focus/blur morphs to focusin/out; ensure we're not firing them right now+ if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {+ return;+ }++ if ( type.indexOf( "!" ) >= 0 ) {+ // Exclusive events trigger only for the exact event (no namespaces)+ type = type.slice(0, -1);+ exclusive = true;+ }++ if ( type.indexOf( "." ) >= 0 ) {+ // Namespaced trigger; create a regexp to match event type in handle()+ namespaces = type.split(".");+ type = namespaces.shift();+ namespaces.sort();+ }++ if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {+ // No jQuery handlers for this event type, and it can't have inline handlers+ return;+ }++ // Caller can pass in an Event, Object, or just an event type string+ event = typeof event === "object" ?+ // jQuery.Event object+ event[ jQuery.expando ] ? event :+ // Object literal+ new jQuery.Event( type, event ) :+ // Just the event type (string)+ new jQuery.Event( type );++ event.type = type;+ event.isTrigger = true;+ event.exclusive = exclusive;+ event.namespace = namespaces.join( "." );+ event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null;+ ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";++ // Handle a global trigger+ if ( !elem ) {++ // TODO: Stop taunting the data cache; remove global events and always attach to document+ cache = jQuery.cache;+ for ( i in cache ) {+ if ( cache[ i ].events && cache[ i ].events[ type ] ) {+ jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );+ }+ }+ return;+ }++ // Clean up the event in case it is being reused+ event.result = undefined;+ if ( !event.target ) {+ event.target = elem;+ }++ // Clone any incoming data and prepend the event, creating the handler arg list+ data = data != null ? jQuery.makeArray( data ) : [];+ data.unshift( event );++ // Allow special events to draw outside the lines+ special = jQuery.event.special[ type ] || {};+ if ( special.trigger && special.trigger.apply( elem, data ) === false ) {+ return;+ }++ // Determine event propagation path in advance, per W3C events spec (#9951)+ // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)+ eventPath = [[ elem, special.bindType || type ]];+ if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {++ bubbleType = special.delegateType || type;+ cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;+ old = null;+ for ( ; cur; cur = cur.parentNode ) {+ eventPath.push([ cur, bubbleType ]);+ old = cur;+ }++ // Only add window if we got to document (e.g., not plain obj or detached DOM)+ if ( old && old === elem.ownerDocument ) {+ eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);+ }+ }++ // Fire handlers on the event path+ for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {++ cur = eventPath[i][0];+ event.type = eventPath[i][1];++ handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );+ if ( handle ) {+ handle.apply( cur, data );+ }+ // Note that this is a bare JS function and not a jQuery handler+ handle = ontype && cur[ ontype ];+ if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) {+ event.preventDefault();+ }+ }+ event.type = type;++ // If nobody prevented the default action, do it now+ if ( !onlyHandlers && !event.isDefaultPrevented() ) {++ if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&+ !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {++ // Call a native DOM method on the target with the same name name as the event.+ // Can't use an .isFunction() check here because IE6/7 fails that test.+ // Don't do default actions on window, that's where global variables be (#6170)+ // IE<9 dies on focus/blur to hidden element (#1486)+ if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {++ // Don't re-trigger an onFOO event when we call its FOO() method+ old = elem[ ontype ];++ if ( old ) {+ elem[ ontype ] = null;+ }++ // Prevent re-triggering of the same event, since we already bubbled it above+ jQuery.event.triggered = type;+ elem[ type ]();+ jQuery.event.triggered = undefined;++ if ( old ) {+ elem[ ontype ] = old;+ }+ }+ }+ }++ return event.result;+ },++ dispatch: function( event ) {++ // Make a writable jQuery.Event from the native event object+ event = jQuery.event.fix( event || window.event );++ var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),+ delegateCount = handlers.delegateCount,+ args = [].slice.call( arguments, 0 ),+ run_all = !event.exclusive && !event.namespace,+ special = jQuery.event.special[ event.type ] || {},+ handlerQueue = [],+ i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related;++ // Use the fix-ed jQuery.Event rather than the (read-only) native event+ args[0] = event;+ event.delegateTarget = this;++ // Call the preDispatch hook for the mapped type, and let it bail if desired+ if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {+ return;+ }++ // Determine handlers that should run if there are delegated events+ // Avoid non-left-click bubbling in Firefox (#3861)+ if ( delegateCount && !(event.button && event.type === "click") ) {++ // Pregenerate a single jQuery object for reuse with .is()+ jqcur = jQuery(this);+ jqcur.context = this.ownerDocument || this;++ for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {++ // Don't process events on disabled elements (#6911, #8165)+ if ( cur.disabled !== true ) {+ selMatch = {};+ matches = [];+ jqcur[0] = cur;+ for ( i = 0; i < delegateCount; i++ ) {+ handleObj = handlers[ i ];+ sel = handleObj.selector;++ if ( selMatch[ sel ] === undefined ) {+ selMatch[ sel ] = (+ handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel )+ );+ }+ if ( selMatch[ sel ] ) {+ matches.push( handleObj );+ }+ }+ if ( matches.length ) {+ handlerQueue.push({ elem: cur, matches: matches });+ }+ }+ }+ }++ // Add the remaining (directly-bound) handlers+ if ( handlers.length > delegateCount ) {+ handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });+ }++ // Run delegates first; they may want to stop propagation beneath us+ for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {+ matched = handlerQueue[ i ];+ event.currentTarget = matched.elem;++ for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {+ handleObj = matched.matches[ j ];++ // Triggered event must either 1) be non-exclusive and have no namespace, or+ // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).+ if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {++ event.data = handleObj.data;+ event.handleObj = handleObj;++ ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )+ .apply( matched.elem, args );++ if ( ret !== undefined ) {+ event.result = ret;+ if ( ret === false ) {+ event.preventDefault();+ event.stopPropagation();+ }+ }+ }+ }+ }++ // Call the postDispatch hook for the mapped type+ if ( special.postDispatch ) {+ special.postDispatch.call( this, event );+ }++ return event.result;+ },++ // Includes some event props shared by KeyEvent and MouseEvent+ // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 ***+ props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),++ fixHooks: {},++ keyHooks: {+ props: "char charCode key keyCode".split(" "),+ filter: function( event, original ) {++ // Add which for key events+ if ( event.which == null ) {+ event.which = original.charCode != null ? original.charCode : original.keyCode;+ }++ return event;+ }+ },++ mouseHooks: {+ props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),+ filter: function( event, original ) {+ var eventDoc, doc, body,+ button = original.button,+ fromElement = original.fromElement;++ // Calculate pageX/Y if missing and clientX/Y available+ if ( event.pageX == null && original.clientX != null ) {+ eventDoc = event.target.ownerDocument || document;+ doc = eventDoc.documentElement;+ body = eventDoc.body;++ event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );+ event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );+ }++ // Add relatedTarget, if necessary+ if ( !event.relatedTarget && fromElement ) {+ event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;+ }++ // Add which for click: 1 === left; 2 === middle; 3 === right+ // Note: button is not normalized, so don't use it+ if ( !event.which && button !== undefined ) {+ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );+ }++ return event;+ }+ },++ fix: function( event ) {+ if ( event[ jQuery.expando ] ) {+ return event;+ }++ // Create a writable copy of the event object and normalize some properties+ var i, prop,+ originalEvent = event,+ fixHook = jQuery.event.fixHooks[ event.type ] || {},+ copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;++ event = jQuery.Event( originalEvent );++ for ( i = copy.length; i; ) {+ prop = copy[ --i ];+ event[ prop ] = originalEvent[ prop ];+ }++ // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)+ if ( !event.target ) {+ event.target = originalEvent.srcElement || document;+ }++ // Target should not be a text node (#504, Safari)+ if ( event.target.nodeType === 3 ) {+ event.target = event.target.parentNode;+ }++ // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8)+ if ( event.metaKey === undefined ) {+ event.metaKey = event.ctrlKey;+ }++ return fixHook.filter? fixHook.filter( event, originalEvent ) : event;+ },++ special: {+ ready: {+ // Make sure the ready event is setup+ setup: jQuery.bindReady+ },++ load: {+ // Prevent triggered image.load events from bubbling to window.load+ noBubble: true+ },++ focus: {+ delegateType: "focusin"+ },+ blur: {+ delegateType: "focusout"+ },++ beforeunload: {+ setup: function( data, namespaces, eventHandle ) {+ // We only want to do this special case on windows+ if ( jQuery.isWindow( this ) ) {+ this.onbeforeunload = eventHandle;+ }+ },++ teardown: function( namespaces, eventHandle ) {+ if ( this.onbeforeunload === eventHandle ) {+ this.onbeforeunload = null;+ }+ }+ }+ },++ simulate: function( type, elem, event, bubble ) {+ // Piggyback on a donor event to simulate a different one.+ // Fake originalEvent to avoid donor's stopPropagation, but if the+ // simulated event prevents default then we do the same on the donor.+ var e = jQuery.extend(+ new jQuery.Event(),+ event,+ { type: type,+ isSimulated: true,+ originalEvent: {}+ }+ );+ if ( bubble ) {+ jQuery.event.trigger( e, null, elem );+ } else {+ jQuery.event.dispatch.call( elem, e );+ }+ if ( e.isDefaultPrevented() ) {+ event.preventDefault();+ }+ }+};++// Some plugins are using, but it's undocumented/deprecated and will be removed.+// The 1.7 special event interface should provide all the hooks needed now.+jQuery.event.handle = jQuery.event.dispatch;++jQuery.removeEvent = document.removeEventListener ?+ function( elem, type, handle ) {+ if ( elem.removeEventListener ) {+ elem.removeEventListener( type, handle, false );+ }+ } :+ function( elem, type, handle ) {+ if ( elem.detachEvent ) {+ elem.detachEvent( "on" + type, handle );+ }+ };++jQuery.Event = function( src, props ) {+ // Allow instantiation without the 'new' keyword+ if ( !(this instanceof jQuery.Event) ) {+ return new jQuery.Event( src, props );+ }++ // Event object+ if ( src && src.type ) {+ this.originalEvent = src;+ this.type = src.type;++ // Events bubbling up the document may have been marked as prevented+ // by a handler lower down the tree; reflect the correct value.+ this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||+ src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;++ // Event type+ } else {+ this.type = src;+ }++ // Put explicitly provided properties onto the event object+ if ( props ) {+ jQuery.extend( this, props );+ }++ // Create a timestamp if incoming event doesn't have one+ this.timeStamp = src && src.timeStamp || jQuery.now();++ // Mark it as fixed+ this[ jQuery.expando ] = true;+};++function returnFalse() {+ return false;+}+function returnTrue() {+ return true;+}++// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html+jQuery.Event.prototype = {+ preventDefault: function() {+ this.isDefaultPrevented = returnTrue;++ var e = this.originalEvent;+ if ( !e ) {+ return;+ }++ // if preventDefault exists run it on the original event+ if ( e.preventDefault ) {+ e.preventDefault();++ // otherwise set the returnValue property of the original event to false (IE)+ } else {+ e.returnValue = false;+ }+ },+ stopPropagation: function() {+ this.isPropagationStopped = returnTrue;++ var e = this.originalEvent;+ if ( !e ) {+ return;+ }+ // if stopPropagation exists run it on the original event+ if ( e.stopPropagation ) {+ e.stopPropagation();+ }+ // otherwise set the cancelBubble property of the original event to true (IE)+ e.cancelBubble = true;+ },+ stopImmediatePropagation: function() {+ this.isImmediatePropagationStopped = returnTrue;+ this.stopPropagation();+ },+ isDefaultPrevented: returnFalse,+ isPropagationStopped: returnFalse,+ isImmediatePropagationStopped: returnFalse+};++// Create mouseenter/leave events using mouseover/out and event-time checks+jQuery.each({+ mouseenter: "mouseover",+ mouseleave: "mouseout"+}, function( orig, fix ) {+ jQuery.event.special[ orig ] = {+ delegateType: fix,+ bindType: fix,++ handle: function( event ) {+ var target = this,+ related = event.relatedTarget,+ handleObj = event.handleObj,+ selector = handleObj.selector,+ ret;++ // For mousenter/leave call the handler if related is outside the target.+ // NB: No relatedTarget if the mouse left/entered the browser window+ if ( !related || (related !== target && !jQuery.contains( target, related )) ) {+ event.type = handleObj.origType;+ ret = handleObj.handler.apply( this, arguments );+ event.type = fix;+ }+ return ret;+ }+ };+});++// IE submit delegation+if ( !jQuery.support.submitBubbles ) {++ jQuery.event.special.submit = {+ setup: function() {+ // Only need this for delegated form submit events+ if ( jQuery.nodeName( this, "form" ) ) {+ return false;+ }++ // Lazy-add a submit handler when a descendant form may potentially be submitted+ jQuery.event.add( this, "click._submit keypress._submit", function( e ) {+ // Node name check avoids a VML-related crash in IE (#9807)+ var elem = e.target,+ form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;+ if ( form && !form._submit_attached ) {+ jQuery.event.add( form, "submit._submit", function( event ) {+ event._submit_bubble = true;+ });+ form._submit_attached = true;+ }+ });+ // return undefined since we don't need an event listener+ },+ + postDispatch: function( event ) {+ // If form was submitted by the user, bubble the event up the tree+ if ( event._submit_bubble ) {+ delete event._submit_bubble;+ if ( this.parentNode && !event.isTrigger ) {+ jQuery.event.simulate( "submit", this.parentNode, event, true );+ }+ }+ },++ teardown: function() {+ // Only need this for delegated form submit events+ if ( jQuery.nodeName( this, "form" ) ) {+ return false;+ }++ // Remove delegated handlers; cleanData eventually reaps submit handlers attached above+ jQuery.event.remove( this, "._submit" );+ }+ };+}++// IE change delegation and checkbox/radio fix+if ( !jQuery.support.changeBubbles ) {++ jQuery.event.special.change = {++ setup: function() {++ if ( rformElems.test( this.nodeName ) ) {+ // IE doesn't fire change on a check/radio until blur; trigger it on click+ // after a propertychange. Eat the blur-change in special.change.handle.+ // This still fires onchange a second time for check/radio after blur.+ if ( this.type === "checkbox" || this.type === "radio" ) {+ jQuery.event.add( this, "propertychange._change", function( event ) {+ if ( event.originalEvent.propertyName === "checked" ) {+ this._just_changed = true;+ }+ });+ jQuery.event.add( this, "click._change", function( event ) {+ if ( this._just_changed && !event.isTrigger ) {+ this._just_changed = false;+ jQuery.event.simulate( "change", this, event, true );+ }+ });+ }+ return false;+ }+ // Delegated event; lazy-add a change handler on descendant inputs+ jQuery.event.add( this, "beforeactivate._change", function( e ) {+ var elem = e.target;++ if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) {+ jQuery.event.add( elem, "change._change", function( event ) {+ if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {+ jQuery.event.simulate( "change", this.parentNode, event, true );+ }+ });+ elem._change_attached = true;+ }+ });+ },++ handle: function( event ) {+ var elem = event.target;++ // Swallow native change events from checkbox/radio, we already triggered them above+ if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {+ return event.handleObj.handler.apply( this, arguments );+ }+ },++ teardown: function() {+ jQuery.event.remove( this, "._change" );++ return rformElems.test( this.nodeName );+ }+ };+}++// Create "bubbling" focus and blur events+if ( !jQuery.support.focusinBubbles ) {+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {++ // Attach a single capturing handler while someone wants focusin/focusout+ var attaches = 0,+ handler = function( event ) {+ jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );+ };++ jQuery.event.special[ fix ] = {+ setup: function() {+ if ( attaches++ === 0 ) {+ document.addEventListener( orig, handler, true );+ }+ },+ teardown: function() {+ if ( --attaches === 0 ) {+ document.removeEventListener( orig, handler, true );+ }+ }+ };+ });+}++jQuery.fn.extend({++ on: function( types, selector, data, fn, /*INTERNAL*/ one ) {+ var origFn, type;++ // Types can be a map of types/handlers+ if ( typeof types === "object" ) {+ // ( types-Object, selector, data )+ if ( typeof selector !== "string" ) { // && selector != null+ // ( types-Object, data )+ data = data || selector;+ selector = undefined;+ }+ for ( type in types ) {+ this.on( type, selector, data, types[ type ], one );+ }+ return this;+ }++ if ( data == null && fn == null ) {+ // ( types, fn )+ fn = selector;+ data = selector = undefined;+ } else if ( fn == null ) {+ if ( typeof selector === "string" ) {+ // ( types, selector, fn )+ fn = data;+ data = undefined;+ } else {+ // ( types, data, fn )+ fn = data;+ data = selector;+ selector = undefined;+ }+ }+ if ( fn === false ) {+ fn = returnFalse;+ } else if ( !fn ) {+ return this;+ }++ if ( one === 1 ) {+ origFn = fn;+ fn = function( event ) {+ // Can use an empty set, since event contains the info+ jQuery().off( event );+ return origFn.apply( this, arguments );+ };+ // Use same guid so caller can remove using origFn+ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );+ }+ return this.each( function() {+ jQuery.event.add( this, types, fn, data, selector );+ });+ },+ one: function( types, selector, data, fn ) {+ return this.on( types, selector, data, fn, 1 );+ },+ off: function( types, selector, fn ) {+ if ( types && types.preventDefault && types.handleObj ) {+ // ( event ) dispatched jQuery.Event+ var handleObj = types.handleObj;+ jQuery( types.delegateTarget ).off(+ handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,+ handleObj.selector,+ handleObj.handler+ );+ return this;+ }+ if ( typeof types === "object" ) {+ // ( types-object [, selector] )+ for ( var type in types ) {+ this.off( type, selector, types[ type ] );+ }+ return this;+ }+ if ( selector === false || typeof selector === "function" ) {+ // ( types [, fn] )+ fn = selector;+ selector = undefined;+ }+ if ( fn === false ) {+ fn = returnFalse;+ }+ return this.each(function() {+ jQuery.event.remove( this, types, fn, selector );+ });+ },++ bind: function( types, data, fn ) {+ return this.on( types, null, data, fn );+ },+ unbind: function( types, fn ) {+ return this.off( types, null, fn );+ },++ live: function( types, data, fn ) {+ jQuery( this.context ).on( types, this.selector, data, fn );+ return this;+ },+ die: function( types, fn ) {+ jQuery( this.context ).off( types, this.selector || "**", fn );+ return this;+ },++ delegate: function( selector, types, data, fn ) {+ return this.on( types, selector, data, fn );+ },+ undelegate: function( selector, types, fn ) {+ // ( namespace ) or ( selector, types [, fn] )+ return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn );+ },++ trigger: function( type, data ) {+ return this.each(function() {+ jQuery.event.trigger( type, data, this );+ });+ },+ triggerHandler: function( type, data ) {+ if ( this[0] ) {+ return jQuery.event.trigger( type, data, this[0], true );+ }+ },++ toggle: function( fn ) {+ // Save reference to arguments for access in closure+ var args = arguments,+ guid = fn.guid || jQuery.guid++,+ i = 0,+ toggler = function( event ) {+ // Figure out which function to execute+ var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;+ jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );++ // Make sure that clicks stop+ event.preventDefault();++ // and execute the function+ return args[ lastToggle ].apply( this, arguments ) || false;+ };++ // link all the functions, so any of them can unbind this click handler+ toggler.guid = guid;+ while ( i < args.length ) {+ args[ i++ ].guid = guid;+ }++ return this.click( toggler );+ },++ hover: function( fnOver, fnOut ) {+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );+ }+});++jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " ++ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " ++ "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {++ // Handle event binding+ jQuery.fn[ name ] = function( data, fn ) {+ if ( fn == null ) {+ fn = data;+ data = null;+ }++ return arguments.length > 0 ?+ this.on( name, null, data, fn ) :+ this.trigger( name );+ };++ if ( jQuery.attrFn ) {+ jQuery.attrFn[ name ] = true;+ }++ if ( rkeyEvent.test( name ) ) {+ jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;+ }++ if ( rmouseEvent.test( name ) ) {+ jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;+ }+});++++/*!+ * Sizzle CSS Selector Engine+ * Copyright 2011, The Dojo Foundation+ * Released under the MIT, BSD, and GPL Licenses.+ * More information: http://sizzlejs.com/+ */+(function(){++var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,+ expando = "sizcache" + (Math.random() + '').replace('.', ''),+ done = 0,+ toString = Object.prototype.toString,+ hasDuplicate = false,+ baseHasDuplicate = true,+ rBackslash = /\\/g,+ rReturn = /\r\n/g,+ rNonWord = /\W/;++// Here we check if the JavaScript engine is using some sort of+// optimization where it does not always call our comparision+// function. If that is the case, discard the hasDuplicate value.+// Thus far that includes Google Chrome.+[0, 0].sort(function() {+ baseHasDuplicate = false;+ return 0;+});++var Sizzle = function( selector, context, results, seed ) {+ results = results || [];+ context = context || document;++ var origContext = context;++ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {+ return [];+ }++ if ( !selector || typeof selector !== "string" ) {+ return results;+ }++ var m, set, checkSet, extra, ret, cur, pop, i,+ prune = true,+ contextXML = Sizzle.isXML( context ),+ parts = [],+ soFar = selector;++ // Reset the position of the chunker regexp (start from head)+ do {+ chunker.exec( "" );+ m = chunker.exec( soFar );++ if ( m ) {+ soFar = m[3];++ parts.push( m[1] );++ if ( m[2] ) {+ extra = m[3];+ break;+ }+ }+ } while ( m );++ if ( parts.length > 1 && origPOS.exec( selector ) ) {++ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {+ set = posProcess( parts[0] + parts[1], context, seed );++ } else {+ set = Expr.relative[ parts[0] ] ?+ [ context ] :+ Sizzle( parts.shift(), context );++ while ( parts.length ) {+ selector = parts.shift();++ if ( Expr.relative[ selector ] ) {+ selector += parts.shift();+ }++ set = posProcess( selector, set, seed );+ }+ }++ } else {+ // Take a shortcut and set the context if the root selector is an ID+ // (but not if it'll be faster if the inner selector is an ID)+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {++ ret = Sizzle.find( parts.shift(), context, contextXML );+ context = ret.expr ?+ Sizzle.filter( ret.expr, ret.set )[0] :+ ret.set[0];+ }++ if ( context ) {+ ret = seed ?+ { expr: parts.pop(), set: makeArray(seed) } :+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );++ set = ret.expr ?+ Sizzle.filter( ret.expr, ret.set ) :+ ret.set;++ if ( parts.length > 0 ) {+ checkSet = makeArray( set );++ } else {+ prune = false;+ }++ while ( parts.length ) {+ cur = parts.pop();+ pop = cur;++ if ( !Expr.relative[ cur ] ) {+ cur = "";+ } else {+ pop = parts.pop();+ }++ if ( pop == null ) {+ pop = context;+ }++ Expr.relative[ cur ]( checkSet, pop, contextXML );+ }++ } else {+ checkSet = parts = [];+ }+ }++ if ( !checkSet ) {+ checkSet = set;+ }++ if ( !checkSet ) {+ Sizzle.error( cur || selector );+ }++ if ( toString.call(checkSet) === "[object Array]" ) {+ if ( !prune ) {+ results.push.apply( results, checkSet );++ } else if ( context && context.nodeType === 1 ) {+ for ( i = 0; checkSet[i] != null; i++ ) {+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {+ results.push( set[i] );+ }+ }++ } else {+ for ( i = 0; checkSet[i] != null; i++ ) {+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {+ results.push( set[i] );+ }+ }+ }++ } else {+ makeArray( checkSet, results );+ }++ if ( extra ) {+ Sizzle( extra, origContext, results, seed );+ Sizzle.uniqueSort( results );+ }++ return results;+};++Sizzle.uniqueSort = function( results ) {+ if ( sortOrder ) {+ hasDuplicate = baseHasDuplicate;+ results.sort( sortOrder );++ if ( hasDuplicate ) {+ for ( var i = 1; i < results.length; i++ ) {+ if ( results[i] === results[ i - 1 ] ) {+ results.splice( i--, 1 );+ }+ }+ }+ }++ return results;+};++Sizzle.matches = function( expr, set ) {+ return Sizzle( expr, null, null, set );+};++Sizzle.matchesSelector = function( node, expr ) {+ return Sizzle( expr, null, null, [node] ).length > 0;+};++Sizzle.find = function( expr, context, isXML ) {+ var set, i, len, match, type, left;++ if ( !expr ) {+ return [];+ }++ for ( i = 0, len = Expr.order.length; i < len; i++ ) {+ type = Expr.order[i];++ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {+ left = match[1];+ match.splice( 1, 1 );++ if ( left.substr( left.length - 1 ) !== "\\" ) {+ match[1] = (match[1] || "").replace( rBackslash, "" );+ set = Expr.find[ type ]( match, context, isXML );++ if ( set != null ) {+ expr = expr.replace( Expr.match[ type ], "" );+ break;+ }+ }+ }+ }++ if ( !set ) {+ set = typeof context.getElementsByTagName !== "undefined" ?+ context.getElementsByTagName( "*" ) :+ [];+ }++ return { set: set, expr: expr };+};++Sizzle.filter = function( expr, set, inplace, not ) {+ var match, anyFound,+ type, found, item, filter, left,+ i, pass,+ old = expr,+ result = [],+ curLoop = set,+ isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );++ while ( expr && set.length ) {+ for ( type in Expr.filter ) {+ if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {+ filter = Expr.filter[ type ];+ left = match[1];++ anyFound = false;++ match.splice(1,1);++ if ( left.substr( left.length - 1 ) === "\\" ) {+ continue;+ }++ if ( curLoop === result ) {+ result = [];+ }++ if ( Expr.preFilter[ type ] ) {+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );++ if ( !match ) {+ anyFound = found = true;++ } else if ( match === true ) {+ continue;+ }+ }++ if ( match ) {+ for ( i = 0; (item = curLoop[i]) != null; i++ ) {+ if ( item ) {+ found = filter( item, match, i, curLoop );+ pass = not ^ found;++ if ( inplace && found != null ) {+ if ( pass ) {+ anyFound = true;++ } else {+ curLoop[i] = false;+ }++ } else if ( pass ) {+ result.push( item );+ anyFound = true;+ }+ }+ }+ }++ if ( found !== undefined ) {+ if ( !inplace ) {+ curLoop = result;+ }++ expr = expr.replace( Expr.match[ type ], "" );++ if ( !anyFound ) {+ return [];+ }++ break;+ }+ }+ }++ // Improper expression+ if ( expr === old ) {+ if ( anyFound == null ) {+ Sizzle.error( expr );++ } else {+ break;+ }+ }++ old = expr;+ }++ return curLoop;+};++Sizzle.error = function( msg ) {+ throw new Error( "Syntax error, unrecognized expression: " + msg );+};++/**+ * Utility function for retreiving the text value of an array of DOM nodes+ * @param {Array|Element} elem+ */+var getText = Sizzle.getText = function( elem ) {+ var i, node,+ nodeType = elem.nodeType,+ ret = "";++ if ( nodeType ) {+ if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {+ // Use textContent || innerText for elements+ if ( typeof elem.textContent === 'string' ) {+ return elem.textContent;+ } else if ( typeof elem.innerText === 'string' ) {+ // Replace IE's carriage returns+ return elem.innerText.replace( rReturn, '' );+ } else {+ // Traverse it's children+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling) {+ ret += getText( elem );+ }+ }+ } else if ( nodeType === 3 || nodeType === 4 ) {+ return elem.nodeValue;+ }+ } else {++ // If no nodeType, this is expected to be an array+ for ( i = 0; (node = elem[i]); i++ ) {+ // Do not traverse comment nodes+ if ( node.nodeType !== 8 ) {+ ret += getText( node );+ }+ }+ }+ return ret;+};++var Expr = Sizzle.selectors = {+ order: [ "ID", "NAME", "TAG" ],++ match: {+ ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,+ CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,+ TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,+ CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,+ PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/+ },++ leftMatch: {},++ attrMap: {+ "class": "className",+ "for": "htmlFor"+ },++ attrHandle: {+ href: function( elem ) {+ return elem.getAttribute( "href" );+ },+ type: function( elem ) {+ return elem.getAttribute( "type" );+ }+ },++ relative: {+ "+": function(checkSet, part){+ var isPartStr = typeof part === "string",+ isTag = isPartStr && !rNonWord.test( part ),+ isPartStrNotTag = isPartStr && !isTag;++ if ( isTag ) {+ part = part.toLowerCase();+ }++ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {+ if ( (elem = checkSet[i]) ) {+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}++ checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?+ elem || false :+ elem === part;+ }+ }++ if ( isPartStrNotTag ) {+ Sizzle.filter( part, checkSet, true );+ }+ },++ ">": function( checkSet, part ) {+ var elem,+ isPartStr = typeof part === "string",+ i = 0,+ l = checkSet.length;++ if ( isPartStr && !rNonWord.test( part ) ) {+ part = part.toLowerCase();++ for ( ; i < l; i++ ) {+ elem = checkSet[i];++ if ( elem ) {+ var parent = elem.parentNode;+ checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;+ }+ }++ } else {+ for ( ; i < l; i++ ) {+ elem = checkSet[i];++ if ( elem ) {+ checkSet[i] = isPartStr ?+ elem.parentNode :+ elem.parentNode === part;+ }+ }++ if ( isPartStr ) {+ Sizzle.filter( part, checkSet, true );+ }+ }+ },++ "": function(checkSet, part, isXML){+ var nodeCheck,+ doneName = done++,+ checkFn = dirCheck;++ if ( typeof part === "string" && !rNonWord.test( part ) ) {+ part = part.toLowerCase();+ nodeCheck = part;+ checkFn = dirNodeCheck;+ }++ checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );+ },++ "~": function( checkSet, part, isXML ) {+ var nodeCheck,+ doneName = done++,+ checkFn = dirCheck;++ if ( typeof part === "string" && !rNonWord.test( part ) ) {+ part = part.toLowerCase();+ nodeCheck = part;+ checkFn = dirNodeCheck;+ }++ checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );+ }+ },++ find: {+ ID: function( match, context, isXML ) {+ if ( typeof context.getElementById !== "undefined" && !isXML ) {+ var m = context.getElementById(match[1]);+ // Check parentNode to catch when Blackberry 4.6 returns+ // nodes that are no longer in the document #6963+ return m && m.parentNode ? [m] : [];+ }+ },++ NAME: function( match, context ) {+ if ( typeof context.getElementsByName !== "undefined" ) {+ var ret = [],+ results = context.getElementsByName( match[1] );++ for ( var i = 0, l = results.length; i < l; i++ ) {+ if ( results[i].getAttribute("name") === match[1] ) {+ ret.push( results[i] );+ }+ }++ return ret.length === 0 ? null : ret;+ }+ },++ TAG: function( match, context ) {+ if ( typeof context.getElementsByTagName !== "undefined" ) {+ return context.getElementsByTagName( match[1] );+ }+ }+ },+ preFilter: {+ CLASS: function( match, curLoop, inplace, result, not, isXML ) {+ match = " " + match[1].replace( rBackslash, "" ) + " ";++ if ( isXML ) {+ return match;+ }++ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {+ if ( elem ) {+ if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {+ if ( !inplace ) {+ result.push( elem );+ }++ } else if ( inplace ) {+ curLoop[i] = false;+ }+ }+ }++ return false;+ },++ ID: function( match ) {+ return match[1].replace( rBackslash, "" );+ },++ TAG: function( match, curLoop ) {+ return match[1].replace( rBackslash, "" ).toLowerCase();+ },++ CHILD: function( match ) {+ if ( match[1] === "nth" ) {+ if ( !match[2] ) {+ Sizzle.error( match[0] );+ }++ match[2] = match[2].replace(/^\+|\s*/g, '');++ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'+ var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(+ match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);++ // calculate the numbers (first)n+(last) including if they are negative+ match[2] = (test[1] + (test[2] || 1)) - 0;+ match[3] = test[3] - 0;+ }+ else if ( match[2] ) {+ Sizzle.error( match[0] );+ }++ // TODO: Move to normal caching system+ match[0] = done++;++ return match;+ },++ ATTR: function( match, curLoop, inplace, result, not, isXML ) {+ var name = match[1] = match[1].replace( rBackslash, "" );++ if ( !isXML && Expr.attrMap[name] ) {+ match[1] = Expr.attrMap[name];+ }++ // Handle if an un-quoted value was used+ match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );++ if ( match[2] === "~=" ) {+ match[4] = " " + match[4] + " ";+ }++ return match;+ },++ PSEUDO: function( match, curLoop, inplace, result, not ) {+ if ( match[1] === "not" ) {+ // If we're dealing with a complex expression, or a simple one+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {+ match[3] = Sizzle(match[3], null, null, curLoop);++ } else {+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);++ if ( !inplace ) {+ result.push.apply( result, ret );+ }++ return false;+ }++ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {+ return true;+ }++ return match;+ },++ POS: function( match ) {+ match.unshift( true );++ return match;+ }+ },++ filters: {+ enabled: function( elem ) {+ return elem.disabled === false && elem.type !== "hidden";+ },++ disabled: function( elem ) {+ return elem.disabled === true;+ },++ checked: function( elem ) {+ return elem.checked === true;+ },++ selected: function( elem ) {+ // Accessing this property makes selected-by-default+ // options in Safari work properly+ if ( elem.parentNode ) {+ elem.parentNode.selectedIndex;+ }++ return elem.selected === true;+ },++ parent: function( elem ) {+ return !!elem.firstChild;+ },++ empty: function( elem ) {+ return !elem.firstChild;+ },++ has: function( elem, i, match ) {+ return !!Sizzle( match[3], elem ).length;+ },++ header: function( elem ) {+ return (/h\d/i).test( elem.nodeName );+ },++ text: function( elem ) {+ var attr = elem.getAttribute( "type" ), type = elem.type;+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)+ // use getAttribute instead to test this case+ return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );+ },++ radio: function( elem ) {+ return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;+ },++ checkbox: function( elem ) {+ return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;+ },++ file: function( elem ) {+ return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;+ },++ password: function( elem ) {+ return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;+ },++ submit: function( elem ) {+ var name = elem.nodeName.toLowerCase();+ return (name === "input" || name === "button") && "submit" === elem.type;+ },++ image: function( elem ) {+ return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;+ },++ reset: function( elem ) {+ var name = elem.nodeName.toLowerCase();+ return (name === "input" || name === "button") && "reset" === elem.type;+ },++ button: function( elem ) {+ var name = elem.nodeName.toLowerCase();+ return name === "input" && "button" === elem.type || name === "button";+ },++ input: function( elem ) {+ return (/input|select|textarea|button/i).test( elem.nodeName );+ },++ focus: function( elem ) {+ return elem === elem.ownerDocument.activeElement;+ }+ },+ setFilters: {+ first: function( elem, i ) {+ return i === 0;+ },++ last: function( elem, i, match, array ) {+ return i === array.length - 1;+ },++ even: function( elem, i ) {+ return i % 2 === 0;+ },++ odd: function( elem, i ) {+ return i % 2 === 1;+ },++ lt: function( elem, i, match ) {+ return i < match[3] - 0;+ },++ gt: function( elem, i, match ) {+ return i > match[3] - 0;+ },++ nth: function( elem, i, match ) {+ return match[3] - 0 === i;+ },++ eq: function( elem, i, match ) {+ return match[3] - 0 === i;+ }+ },+ filter: {+ PSEUDO: function( elem, match, i, array ) {+ var name = match[1],+ filter = Expr.filters[ name ];++ if ( filter ) {+ return filter( elem, i, match, array );++ } else if ( name === "contains" ) {+ return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;++ } else if ( name === "not" ) {+ var not = match[3];++ for ( var j = 0, l = not.length; j < l; j++ ) {+ if ( not[j] === elem ) {+ return false;+ }+ }++ return true;++ } else {+ Sizzle.error( name );+ }+ },++ CHILD: function( elem, match ) {+ var first, last,+ doneName, parent, cache,+ count, diff,+ type = match[1],+ node = elem;++ switch ( type ) {+ case "only":+ case "first":+ while ( (node = node.previousSibling) ) {+ if ( node.nodeType === 1 ) {+ return false;+ }+ }++ if ( type === "first" ) {+ return true;+ }++ node = elem;++ /* falls through */+ case "last":+ while ( (node = node.nextSibling) ) {+ if ( node.nodeType === 1 ) {+ return false;+ }+ }++ return true;++ case "nth":+ first = match[2];+ last = match[3];++ if ( first === 1 && last === 0 ) {+ return true;+ }++ doneName = match[0];+ parent = elem.parentNode;++ if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {+ count = 0;++ for ( node = parent.firstChild; node; node = node.nextSibling ) {+ if ( node.nodeType === 1 ) {+ node.nodeIndex = ++count;+ }+ }++ parent[ expando ] = doneName;+ }++ diff = elem.nodeIndex - last;++ if ( first === 0 ) {+ return diff === 0;++ } else {+ return ( diff % first === 0 && diff / first >= 0 );+ }+ }+ },++ ID: function( elem, match ) {+ return elem.nodeType === 1 && elem.getAttribute("id") === match;+ },++ TAG: function( elem, match ) {+ return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;+ },++ CLASS: function( elem, match ) {+ return (" " + (elem.className || elem.getAttribute("class")) + " ")+ .indexOf( match ) > -1;+ },++ ATTR: function( elem, match ) {+ var name = match[1],+ result = Sizzle.attr ?+ Sizzle.attr( elem, name ) :+ Expr.attrHandle[ name ] ?+ Expr.attrHandle[ name ]( elem ) :+ elem[ name ] != null ?+ elem[ name ] :+ elem.getAttribute( name ),+ value = result + "",+ type = match[2],+ check = match[4];++ return result == null ?+ type === "!=" :+ !type && Sizzle.attr ?+ result != null :+ type === "=" ?+ value === check :+ type === "*=" ?+ value.indexOf(check) >= 0 :+ type === "~=" ?+ (" " + value + " ").indexOf(check) >= 0 :+ !check ?+ value && result !== false :+ type === "!=" ?+ value !== check :+ type === "^=" ?+ value.indexOf(check) === 0 :+ type === "$=" ?+ value.substr(value.length - check.length) === check :+ type === "|=" ?+ value === check || value.substr(0, check.length + 1) === check + "-" :+ false;+ },++ POS: function( elem, match, i, array ) {+ var name = match[2],+ filter = Expr.setFilters[ name ];++ if ( filter ) {+ return filter( elem, i, match, array );+ }+ }+ }+};++var origPOS = Expr.match.POS,+ fescape = function(all, num){+ return "\\" + (num - 0 + 1);+ };++for ( var type in Expr.match ) {+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );+}+// Expose origPOS+// "global" as in regardless of relation to brackets/parens+Expr.match.globalPOS = origPOS;++var makeArray = function( array, results ) {+ array = Array.prototype.slice.call( array, 0 );++ if ( results ) {+ results.push.apply( results, array );+ return results;+ }++ return array;+};++// Perform a simple check to determine if the browser is capable of+// converting a NodeList to an array using builtin methods.+// Also verifies that the returned array holds DOM nodes+// (which is not the case in the Blackberry browser)+try {+ Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;++// Provide a fallback method if it does not work+} catch( e ) {+ makeArray = function( array, results ) {+ var i = 0,+ ret = results || [];++ if ( toString.call(array) === "[object Array]" ) {+ Array.prototype.push.apply( ret, array );++ } else {+ if ( typeof array.length === "number" ) {+ for ( var l = array.length; i < l; i++ ) {+ ret.push( array[i] );+ }++ } else {+ for ( ; array[i]; i++ ) {+ ret.push( array[i] );+ }+ }+ }++ return ret;+ };+}++var sortOrder, siblingCheck;++if ( document.documentElement.compareDocumentPosition ) {+ sortOrder = function( a, b ) {+ if ( a === b ) {+ hasDuplicate = true;+ return 0;+ }++ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {+ return a.compareDocumentPosition ? -1 : 1;+ }++ return a.compareDocumentPosition(b) & 4 ? -1 : 1;+ };++} else {+ sortOrder = function( a, b ) {+ // The nodes are identical, we can exit early+ if ( a === b ) {+ hasDuplicate = true;+ return 0;++ // Fallback to using sourceIndex (in IE) if it's available on both nodes+ } else if ( a.sourceIndex && b.sourceIndex ) {+ return a.sourceIndex - b.sourceIndex;+ }++ var al, bl,+ ap = [],+ bp = [],+ aup = a.parentNode,+ bup = b.parentNode,+ cur = aup;++ // If the nodes are siblings (or identical) we can do a quick check+ if ( aup === bup ) {+ return siblingCheck( a, b );++ // If no parents were found then the nodes are disconnected+ } else if ( !aup ) {+ return -1;++ } else if ( !bup ) {+ return 1;+ }++ // Otherwise they're somewhere else in the tree so we need+ // to build up a full list of the parentNodes for comparison+ while ( cur ) {+ ap.unshift( cur );+ cur = cur.parentNode;+ }++ cur = bup;++ while ( cur ) {+ bp.unshift( cur );+ cur = cur.parentNode;+ }++ al = ap.length;+ bl = bp.length;++ // Start walking down the tree looking for a discrepancy+ for ( var i = 0; i < al && i < bl; i++ ) {+ if ( ap[i] !== bp[i] ) {+ return siblingCheck( ap[i], bp[i] );+ }+ }++ // We ended someplace up the tree so do a sibling check+ return i === al ?+ siblingCheck( a, bp[i], -1 ) :+ siblingCheck( ap[i], b, 1 );+ };++ siblingCheck = function( a, b, ret ) {+ if ( a === b ) {+ return ret;+ }++ var cur = a.nextSibling;++ while ( cur ) {+ if ( cur === b ) {+ return -1;+ }++ cur = cur.nextSibling;+ }++ return 1;+ };+}++// Check to see if the browser returns elements by name when+// querying by getElementById (and provide a workaround)+(function(){+ // We're going to inject a fake input element with a specified name+ var form = document.createElement("div"),+ id = "script" + (new Date()).getTime(),+ root = document.documentElement;++ form.innerHTML = "<a name='" + id + "'/>";++ // Inject it into the root element, check its status, and remove it quickly+ root.insertBefore( form, root.firstChild );++ // The workaround has to do additional checks after a getElementById+ // Which slows things down for other browsers (hence the branching)+ if ( document.getElementById( id ) ) {+ Expr.find.ID = function( match, context, isXML ) {+ if ( typeof context.getElementById !== "undefined" && !isXML ) {+ var m = context.getElementById(match[1]);++ return m ?+ m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?+ [m] :+ undefined :+ [];+ }+ };++ Expr.filter.ID = function( elem, match ) {+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");++ return elem.nodeType === 1 && node && node.nodeValue === match;+ };+ }++ root.removeChild( form );++ // release memory in IE+ root = form = null;+})();++(function(){+ // Check to see if the browser returns only elements+ // when doing getElementsByTagName("*")++ // Create a fake element+ var div = document.createElement("div");+ div.appendChild( document.createComment("") );++ // Make sure no comments are found+ if ( div.getElementsByTagName("*").length > 0 ) {+ Expr.find.TAG = function( match, context ) {+ var results = context.getElementsByTagName( match[1] );++ // Filter out possible comments+ if ( match[1] === "*" ) {+ var tmp = [];++ for ( var i = 0; results[i]; i++ ) {+ if ( results[i].nodeType === 1 ) {+ tmp.push( results[i] );+ }+ }++ results = tmp;+ }++ return results;+ };+ }++ // Check to see if an attribute returns normalized href attributes+ div.innerHTML = "<a href='#'></a>";++ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&+ div.firstChild.getAttribute("href") !== "#" ) {++ Expr.attrHandle.href = function( elem ) {+ return elem.getAttribute( "href", 2 );+ };+ }++ // release memory in IE+ div = null;+})();++if ( document.querySelectorAll ) {+ (function(){+ var oldSizzle = Sizzle,+ div = document.createElement("div"),+ id = "__sizzle__";++ div.innerHTML = "<p class='TEST'></p>";++ // Safari can't handle uppercase or unicode characters when+ // in quirks mode.+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {+ return;+ }++ Sizzle = function( query, context, extra, seed ) {+ context = context || document;++ // Only use querySelectorAll on non-XML documents+ // (ID selectors don't work in non-HTML documents)+ if ( !seed && !Sizzle.isXML(context) ) {+ // See if we find a selector to speed up+ var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );++ if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {+ // Speed-up: Sizzle("TAG")+ if ( match[1] ) {+ return makeArray( context.getElementsByTagName( query ), extra );++ // Speed-up: Sizzle(".CLASS")+ } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {+ return makeArray( context.getElementsByClassName( match[2] ), extra );+ }+ }++ if ( context.nodeType === 9 ) {+ // Speed-up: Sizzle("body")+ // The body element only exists once, optimize finding it+ if ( query === "body" && context.body ) {+ return makeArray( [ context.body ], extra );++ // Speed-up: Sizzle("#ID")+ } else if ( match && match[3] ) {+ var elem = context.getElementById( match[3] );++ // Check parentNode to catch when Blackberry 4.6 returns+ // nodes that are no longer in the document #6963+ if ( elem && elem.parentNode ) {+ // Handle the case where IE and Opera return items+ // by name instead of ID+ if ( elem.id === match[3] ) {+ return makeArray( [ elem ], extra );+ }++ } else {+ return makeArray( [], extra );+ }+ }++ try {+ return makeArray( context.querySelectorAll(query), extra );+ } catch(qsaError) {}++ // qSA works strangely on Element-rooted queries+ // We can work around this by specifying an extra ID on the root+ // and working up from there (Thanks to Andrew Dupont for the technique)+ // IE 8 doesn't work on object elements+ } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {+ var oldContext = context,+ old = context.getAttribute( "id" ),+ nid = old || id,+ hasParent = context.parentNode,+ relativeHierarchySelector = /^\s*[+~]/.test( query );++ if ( !old ) {+ context.setAttribute( "id", nid );+ } else {+ nid = nid.replace( /'/g, "\\$&" );+ }+ if ( relativeHierarchySelector && hasParent ) {+ context = context.parentNode;+ }++ try {+ if ( !relativeHierarchySelector || hasParent ) {+ return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );+ }++ } catch(pseudoError) {+ } finally {+ if ( !old ) {+ oldContext.removeAttribute( "id" );+ }+ }+ }+ }++ return oldSizzle(query, context, extra, seed);+ };++ for ( var prop in oldSizzle ) {+ Sizzle[ prop ] = oldSizzle[ prop ];+ }++ // release memory in IE+ div = null;+ })();+}++(function(){+ var html = document.documentElement,+ matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;++ if ( matches ) {+ // Check to see if it's possible to do matchesSelector+ // on a disconnected node (IE 9 fails this)+ var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),+ pseudoWorks = false;++ try {+ // This should fail with an exception+ // Gecko does not error, returns false instead+ matches.call( document.documentElement, "[test!='']:sizzle" );++ } catch( pseudoError ) {+ pseudoWorks = true;+ }++ Sizzle.matchesSelector = function( node, expr ) {+ // Make sure that attribute selectors are quoted+ expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");++ if ( !Sizzle.isXML( node ) ) {+ try {+ if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {+ var ret = matches.call( node, expr );++ // IE 9's matchesSelector returns false on disconnected nodes+ if ( ret || !disconnectedMatch ||+ // As well, disconnected nodes are said to be in a document+ // fragment in IE 9, so check for that+ node.document && node.document.nodeType !== 11 ) {+ return ret;+ }+ }+ } catch(e) {}+ }++ return Sizzle(expr, null, null, [node]).length > 0;+ };+ }+})();++(function(){+ var div = document.createElement("div");++ div.innerHTML = "<div class='test e'></div><div class='test'></div>";++ // Opera can't find a second classname (in 9.6)+ // Also, make sure that getElementsByClassName actually exists+ if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {+ return;+ }++ // Safari caches class attributes, doesn't catch changes (in 3.2)+ div.lastChild.className = "e";++ if ( div.getElementsByClassName("e").length === 1 ) {+ return;+ }++ Expr.order.splice(1, 0, "CLASS");+ Expr.find.CLASS = function( match, context, isXML ) {+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {+ return context.getElementsByClassName(match[1]);+ }+ };++ // release memory in IE+ div = null;+})();++function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {+ var elem = checkSet[i];++ if ( elem ) {+ var match = false;++ elem = elem[dir];++ while ( elem ) {+ if ( elem[ expando ] === doneName ) {+ match = checkSet[elem.sizset];+ break;+ }++ if ( elem.nodeType === 1 && !isXML ){+ elem[ expando ] = doneName;+ elem.sizset = i;+ }++ if ( elem.nodeName.toLowerCase() === cur ) {+ match = elem;+ break;+ }++ elem = elem[dir];+ }++ checkSet[i] = match;+ }+ }+}++function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {+ var elem = checkSet[i];++ if ( elem ) {+ var match = false;++ elem = elem[dir];++ while ( elem ) {+ if ( elem[ expando ] === doneName ) {+ match = checkSet[elem.sizset];+ break;+ }++ if ( elem.nodeType === 1 ) {+ if ( !isXML ) {+ elem[ expando ] = doneName;+ elem.sizset = i;+ }++ if ( typeof cur !== "string" ) {+ if ( elem === cur ) {+ match = true;+ break;+ }++ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {+ match = elem;+ break;+ }+ }++ elem = elem[dir];+ }++ checkSet[i] = match;+ }+ }+}++if ( document.documentElement.contains ) {+ Sizzle.contains = function( a, b ) {+ return a !== b && (a.contains ? a.contains(b) : true);+ };++} else if ( document.documentElement.compareDocumentPosition ) {+ Sizzle.contains = function( a, b ) {+ return !!(a.compareDocumentPosition(b) & 16);+ };++} else {+ Sizzle.contains = function() {+ return false;+ };+}++Sizzle.isXML = function( elem ) {+ // documentElement is verified for cases where it doesn't yet exist+ // (such as loading iframes in IE - #4833)+ var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;++ return documentElement ? documentElement.nodeName !== "HTML" : false;+};++var posProcess = function( selector, context, seed ) {+ var match,+ tmpSet = [],+ later = "",+ root = context.nodeType ? [context] : context;++ // Position selectors must be done after the filter+ // And so must :not(positional) so we move all PSEUDOs to the end+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {+ later += match[0];+ selector = selector.replace( Expr.match.PSEUDO, "" );+ }++ selector = Expr.relative[selector] ? selector + "*" : selector;++ for ( var i = 0, l = root.length; i < l; i++ ) {+ Sizzle( selector, root[i], tmpSet, seed );+ }++ return Sizzle.filter( later, tmpSet );+};++// EXPOSE+// Override sizzle attribute retrieval+Sizzle.attr = jQuery.attr;+Sizzle.selectors.attrMap = {};+jQuery.find = Sizzle;+jQuery.expr = Sizzle.selectors;+jQuery.expr[":"] = jQuery.expr.filters;+jQuery.unique = Sizzle.uniqueSort;+jQuery.text = Sizzle.getText;+jQuery.isXMLDoc = Sizzle.isXML;+jQuery.contains = Sizzle.contains;+++})();+++var runtil = /Until$/,+ rparentsprev = /^(?:parents|prevUntil|prevAll)/,+ // Note: This RegExp should be improved, or likely pulled from Sizzle+ rmultiselector = /,/,+ isSimple = /^.[^:#\[\.,]*$/,+ slice = Array.prototype.slice,+ POS = jQuery.expr.match.globalPOS,+ // methods guaranteed to produce a unique set when starting from a unique set+ guaranteedUnique = {+ children: true,+ contents: true,+ next: true,+ prev: true+ };++jQuery.fn.extend({+ find: function( selector ) {+ var self = this,+ i, l;++ if ( typeof selector !== "string" ) {+ return jQuery( selector ).filter(function() {+ for ( i = 0, l = self.length; i < l; i++ ) {+ if ( jQuery.contains( self[ i ], this ) ) {+ return true;+ }+ }+ });+ }++ var ret = this.pushStack( "", "find", selector ),+ length, n, r;++ for ( i = 0, l = this.length; i < l; i++ ) {+ length = ret.length;+ jQuery.find( selector, this[i], ret );++ if ( i > 0 ) {+ // Make sure that the results are unique+ for ( n = length; n < ret.length; n++ ) {+ for ( r = 0; r < length; r++ ) {+ if ( ret[r] === ret[n] ) {+ ret.splice(n--, 1);+ break;+ }+ }+ }+ }+ }++ return ret;+ },++ has: function( target ) {+ var targets = jQuery( target );+ return this.filter(function() {+ for ( var i = 0, l = targets.length; i < l; i++ ) {+ if ( jQuery.contains( this, targets[i] ) ) {+ return true;+ }+ }+ });+ },++ not: function( selector ) {+ return this.pushStack( winnow(this, selector, false), "not", selector);+ },++ filter: function( selector ) {+ return this.pushStack( winnow(this, selector, true), "filter", selector );+ },++ is: function( selector ) {+ return !!selector && (+ typeof selector === "string" ?+ // If this is a positional selector, check membership in the returned set+ // so $("p:first").is("p:last") won't return true for a doc with two "p".+ POS.test( selector ) ?+ jQuery( selector, this.context ).index( this[0] ) >= 0 :+ jQuery.filter( selector, this ).length > 0 :+ this.filter( selector ).length > 0 );+ },++ closest: function( selectors, context ) {+ var ret = [], i, l, cur = this[0];++ // Array (deprecated as of jQuery 1.7)+ if ( jQuery.isArray( selectors ) ) {+ var level = 1;++ while ( cur && cur.ownerDocument && cur !== context ) {+ for ( i = 0; i < selectors.length; i++ ) {++ if ( jQuery( cur ).is( selectors[ i ] ) ) {+ ret.push({ selector: selectors[ i ], elem: cur, level: level });+ }+ }++ cur = cur.parentNode;+ level++;+ }++ return ret;+ }++ // String+ var pos = POS.test( selectors ) || typeof selectors !== "string" ?+ jQuery( selectors, context || this.context ) :+ 0;++ for ( i = 0, l = this.length; i < l; i++ ) {+ cur = this[i];++ while ( cur ) {+ if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {+ ret.push( cur );+ break;++ } else {+ cur = cur.parentNode;+ if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {+ break;+ }+ }+ }+ }++ ret = ret.length > 1 ? jQuery.unique( ret ) : ret;++ return this.pushStack( ret, "closest", selectors );+ },++ // Determine the position of an element within+ // the matched set of elements+ index: function( elem ) {++ // No argument, return index in parent+ if ( !elem ) {+ return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;+ }++ // index in selector+ if ( typeof elem === "string" ) {+ return jQuery.inArray( this[0], jQuery( elem ) );+ }++ // Locate the position of the desired element+ return jQuery.inArray(+ // If it receives a jQuery object, the first element is used+ elem.jquery ? elem[0] : elem, this );+ },++ add: function( selector, context ) {+ var set = typeof selector === "string" ?+ jQuery( selector, context ) :+ jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),+ all = jQuery.merge( this.get(), set );++ return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?+ all :+ jQuery.unique( all ) );+ },++ andSelf: function() {+ return this.add( this.prevObject );+ }+});++// A painfully simple check to see if an element is disconnected+// from a document (should be improved, where feasible).+function isDisconnected( node ) {+ return !node || !node.parentNode || node.parentNode.nodeType === 11;+}++jQuery.each({+ parent: function( elem ) {+ var parent = elem.parentNode;+ return parent && parent.nodeType !== 11 ? parent : null;+ },+ parents: function( elem ) {+ return jQuery.dir( elem, "parentNode" );+ },+ parentsUntil: function( elem, i, until ) {+ return jQuery.dir( elem, "parentNode", until );+ },+ next: function( elem ) {+ return jQuery.nth( elem, 2, "nextSibling" );+ },+ prev: function( elem ) {+ return jQuery.nth( elem, 2, "previousSibling" );+ },+ nextAll: function( elem ) {+ return jQuery.dir( elem, "nextSibling" );+ },+ prevAll: function( elem ) {+ return jQuery.dir( elem, "previousSibling" );+ },+ nextUntil: function( elem, i, until ) {+ return jQuery.dir( elem, "nextSibling", until );+ },+ prevUntil: function( elem, i, until ) {+ return jQuery.dir( elem, "previousSibling", until );+ },+ siblings: function( elem ) {+ return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );+ },+ children: function( elem ) {+ return jQuery.sibling( elem.firstChild );+ },+ contents: function( elem ) {+ return jQuery.nodeName( elem, "iframe" ) ?+ elem.contentDocument || elem.contentWindow.document :+ jQuery.makeArray( elem.childNodes );+ }+}, function( name, fn ) {+ jQuery.fn[ name ] = function( until, selector ) {+ var ret = jQuery.map( this, fn, until );++ if ( !runtil.test( name ) ) {+ selector = until;+ }++ if ( selector && typeof selector === "string" ) {+ ret = jQuery.filter( selector, ret );+ }++ ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;++ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {+ ret = ret.reverse();+ }++ return this.pushStack( ret, name, slice.call( arguments ).join(",") );+ };+});++jQuery.extend({+ filter: function( expr, elems, not ) {+ if ( not ) {+ expr = ":not(" + expr + ")";+ }++ return elems.length === 1 ?+ jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :+ jQuery.find.matches(expr, elems);+ },++ dir: function( elem, dir, until ) {+ var matched = [],+ cur = elem[ dir ];++ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {+ if ( cur.nodeType === 1 ) {+ matched.push( cur );+ }+ cur = cur[dir];+ }+ return matched;+ },++ nth: function( cur, result, dir, elem ) {+ result = result || 1;+ var num = 0;++ for ( ; cur; cur = cur[dir] ) {+ if ( cur.nodeType === 1 && ++num === result ) {+ break;+ }+ }++ return cur;+ },++ sibling: function( n, elem ) {+ var r = [];++ for ( ; n; n = n.nextSibling ) {+ if ( n.nodeType === 1 && n !== elem ) {+ r.push( n );+ }+ }++ return r;+ }+});++// Implement the identical functionality for filter and not+function winnow( elements, qualifier, keep ) {++ // Can't pass null or undefined to indexOf in Firefox 4+ // Set to 0 to skip string check+ qualifier = qualifier || 0;++ if ( jQuery.isFunction( qualifier ) ) {+ return jQuery.grep(elements, function( elem, i ) {+ var retVal = !!qualifier.call( elem, i, elem );+ return retVal === keep;+ });++ } else if ( qualifier.nodeType ) {+ return jQuery.grep(elements, function( elem, i ) {+ return ( elem === qualifier ) === keep;+ });++ } else if ( typeof qualifier === "string" ) {+ var filtered = jQuery.grep(elements, function( elem ) {+ return elem.nodeType === 1;+ });++ if ( isSimple.test( qualifier ) ) {+ return jQuery.filter(qualifier, filtered, !keep);+ } else {+ qualifier = jQuery.filter( qualifier, filtered );+ }+ }++ return jQuery.grep(elements, function( elem, i ) {+ return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;+ });+}+++++function createSafeFragment( document ) {+ var list = nodeNames.split( "|" ),+ safeFrag = document.createDocumentFragment();++ if ( safeFrag.createElement ) {+ while ( list.length ) {+ safeFrag.createElement(+ list.pop()+ );+ }+ }+ return safeFrag;+}++var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" ++ "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",+ rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,+ rleadingWhitespace = /^\s+/,+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,+ rtagName = /<([\w:]+)/,+ rtbody = /<tbody/i,+ rhtml = /<|&#?\w+;/,+ rnoInnerhtml = /<(?:script|style)/i,+ rnocache = /<(?:script|object|embed|option|style)/i,+ rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),+ // checked="checked" or checked+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,+ rscriptType = /\/(java|ecma)script/i,+ rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,+ wrapMap = {+ option: [ 1, "<select multiple='multiple'>", "</select>" ],+ legend: [ 1, "<fieldset>", "</fieldset>" ],+ thead: [ 1, "<table>", "</table>" ],+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],+ area: [ 1, "<map>", "</map>" ],+ _default: [ 0, "", "" ]+ },+ safeFragment = createSafeFragment( document );++wrapMap.optgroup = wrapMap.option;+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;+wrapMap.th = wrapMap.td;++// IE can't serialize <link> and <script> tags normally+if ( !jQuery.support.htmlSerialize ) {+ wrapMap._default = [ 1, "div<div>", "</div>" ];+}++jQuery.fn.extend({+ text: function( value ) {+ return jQuery.access( this, function( value ) {+ return value === undefined ?+ jQuery.text( this ) :+ this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );+ }, null, value, arguments.length );+ },++ wrapAll: function( html ) {+ if ( jQuery.isFunction( html ) ) {+ return this.each(function(i) {+ jQuery(this).wrapAll( html.call(this, i) );+ });+ }++ if ( this[0] ) {+ // The elements to wrap the target around+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);++ if ( this[0].parentNode ) {+ wrap.insertBefore( this[0] );+ }++ wrap.map(function() {+ var elem = this;++ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {+ elem = elem.firstChild;+ }++ return elem;+ }).append( this );+ }++ return this;+ },++ wrapInner: function( html ) {+ if ( jQuery.isFunction( html ) ) {+ return this.each(function(i) {+ jQuery(this).wrapInner( html.call(this, i) );+ });+ }++ return this.each(function() {+ var self = jQuery( this ),+ contents = self.contents();++ if ( contents.length ) {+ contents.wrapAll( html );++ } else {+ self.append( html );+ }+ });+ },++ wrap: function( html ) {+ var isFunction = jQuery.isFunction( html );++ return this.each(function(i) {+ jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );+ });+ },++ unwrap: function() {+ return this.parent().each(function() {+ if ( !jQuery.nodeName( this, "body" ) ) {+ jQuery( this ).replaceWith( this.childNodes );+ }+ }).end();+ },++ append: function() {+ return this.domManip(arguments, true, function( elem ) {+ if ( this.nodeType === 1 ) {+ this.appendChild( elem );+ }+ });+ },++ prepend: function() {+ return this.domManip(arguments, true, function( elem ) {+ if ( this.nodeType === 1 ) {+ this.insertBefore( elem, this.firstChild );+ }+ });+ },++ before: function() {+ if ( this[0] && this[0].parentNode ) {+ return this.domManip(arguments, false, function( elem ) {+ this.parentNode.insertBefore( elem, this );+ });+ } else if ( arguments.length ) {+ var set = jQuery.clean( arguments );+ set.push.apply( set, this.toArray() );+ return this.pushStack( set, "before", arguments );+ }+ },++ after: function() {+ if ( this[0] && this[0].parentNode ) {+ return this.domManip(arguments, false, function( elem ) {+ this.parentNode.insertBefore( elem, this.nextSibling );+ });+ } else if ( arguments.length ) {+ var set = this.pushStack( this, "after", arguments );+ set.push.apply( set, jQuery.clean(arguments) );+ return set;+ }+ },++ // keepData is for internal use only--do not document+ remove: function( selector, keepData ) {+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {+ if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {+ if ( !keepData && elem.nodeType === 1 ) {+ jQuery.cleanData( elem.getElementsByTagName("*") );+ jQuery.cleanData( [ elem ] );+ }++ if ( elem.parentNode ) {+ elem.parentNode.removeChild( elem );+ }+ }+ }++ return this;+ },++ empty: function() {+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {+ // Remove element nodes and prevent memory leaks+ if ( elem.nodeType === 1 ) {+ jQuery.cleanData( elem.getElementsByTagName("*") );+ }++ // Remove any remaining nodes+ while ( elem.firstChild ) {+ elem.removeChild( elem.firstChild );+ }+ }++ return this;+ },++ clone: function( dataAndEvents, deepDataAndEvents ) {+ dataAndEvents = dataAndEvents == null ? false : dataAndEvents;+ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;++ return this.map( function () {+ return jQuery.clone( this, dataAndEvents, deepDataAndEvents );+ });+ },++ html: function( value ) {+ return jQuery.access( this, function( value ) {+ var elem = this[0] || {},+ i = 0,+ l = this.length;++ if ( value === undefined ) {+ return elem.nodeType === 1 ?+ elem.innerHTML.replace( rinlinejQuery, "" ) :+ null;+ }+++ if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&+ ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&+ !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {++ value = value.replace( rxhtmlTag, "<$1></$2>" );++ try {+ for (; i < l; i++ ) {+ // Remove element nodes and prevent memory leaks+ elem = this[i] || {};+ if ( elem.nodeType === 1 ) {+ jQuery.cleanData( elem.getElementsByTagName( "*" ) );+ elem.innerHTML = value;+ }+ }++ elem = 0;++ // If using innerHTML throws an exception, use the fallback method+ } catch(e) {}+ }++ if ( elem ) {+ this.empty().append( value );+ }+ }, null, value, arguments.length );+ },++ replaceWith: function( value ) {+ if ( this[0] && this[0].parentNode ) {+ // Make sure that the elements are removed from the DOM before they are inserted+ // this can help fix replacing a parent with child elements+ if ( jQuery.isFunction( value ) ) {+ return this.each(function(i) {+ var self = jQuery(this), old = self.html();+ self.replaceWith( value.call( this, i, old ) );+ });+ }++ if ( typeof value !== "string" ) {+ value = jQuery( value ).detach();+ }++ return this.each(function() {+ var next = this.nextSibling,+ parent = this.parentNode;++ jQuery( this ).remove();++ if ( next ) {+ jQuery(next).before( value );+ } else {+ jQuery(parent).append( value );+ }+ });+ } else {+ return this.length ?+ this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :+ this;+ }+ },++ detach: function( selector ) {+ return this.remove( selector, true );+ },++ domManip: function( args, table, callback ) {+ var results, first, fragment, parent,+ value = args[0],+ scripts = [];++ // We can't cloneNode fragments that contain checked, in WebKit+ if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {+ return this.each(function() {+ jQuery(this).domManip( args, table, callback, true );+ });+ }++ if ( jQuery.isFunction(value) ) {+ return this.each(function(i) {+ var self = jQuery(this);+ args[0] = value.call(this, i, table ? self.html() : undefined);+ self.domManip( args, table, callback );+ });+ }++ if ( this[0] ) {+ parent = value && value.parentNode;++ // If we're in a fragment, just use that instead of building a new one+ if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {+ results = { fragment: parent };++ } else {+ results = jQuery.buildFragment( args, this, scripts );+ }++ fragment = results.fragment;++ if ( fragment.childNodes.length === 1 ) {+ first = fragment = fragment.firstChild;+ } else {+ first = fragment.firstChild;+ }++ if ( first ) {+ table = table && jQuery.nodeName( first, "tr" );++ for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {+ callback.call(+ table ?+ root(this[i], first) :+ this[i],+ // Make sure that we do not leak memory by inadvertently discarding+ // the original fragment (which might have attached data) instead of+ // using it; in addition, use the original fragment object for the last+ // item instead of first because it can end up being emptied incorrectly+ // in certain situations (Bug #8070).+ // Fragments from the fragment cache must always be cloned and never used+ // in place.+ results.cacheable || ( l > 1 && i < lastIndex ) ?+ jQuery.clone( fragment, true, true ) :+ fragment+ );+ }+ }++ if ( scripts.length ) {+ jQuery.each( scripts, function( i, elem ) {+ if ( elem.src ) {+ jQuery.ajax({+ type: "GET",+ global: false,+ url: elem.src,+ async: false,+ dataType: "script"+ });+ } else {+ jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );+ }++ if ( elem.parentNode ) {+ elem.parentNode.removeChild( elem );+ }+ });+ }+ }++ return this;+ }+});++function root( elem, cur ) {+ return jQuery.nodeName(elem, "table") ?+ (elem.getElementsByTagName("tbody")[0] ||+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :+ elem;+}++function cloneCopyEvent( src, dest ) {++ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {+ return;+ }++ var type, i, l,+ oldData = jQuery._data( src ),+ curData = jQuery._data( dest, oldData ),+ events = oldData.events;++ if ( events ) {+ delete curData.handle;+ curData.events = {};++ for ( type in events ) {+ for ( i = 0, l = events[ type ].length; i < l; i++ ) {+ jQuery.event.add( dest, type, events[ type ][ i ] );+ }+ }+ }++ // make the cloned public data object a copy from the original+ if ( curData.data ) {+ curData.data = jQuery.extend( {}, curData.data );+ }+}++function cloneFixAttributes( src, dest ) {+ var nodeName;++ // We do not need to do anything for non-Elements+ if ( dest.nodeType !== 1 ) {+ return;+ }++ // clearAttributes removes the attributes, which we don't want,+ // but also removes the attachEvent events, which we *do* want+ if ( dest.clearAttributes ) {+ dest.clearAttributes();+ }++ // mergeAttributes, in contrast, only merges back on the+ // original attributes, not the events+ if ( dest.mergeAttributes ) {+ dest.mergeAttributes( src );+ }++ nodeName = dest.nodeName.toLowerCase();++ // IE6-8 fail to clone children inside object elements that use+ // the proprietary classid attribute value (rather than the type+ // attribute) to identify the type of content to display+ if ( nodeName === "object" ) {+ dest.outerHTML = src.outerHTML;++ } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {+ // IE6-8 fails to persist the checked state of a cloned checkbox+ // or radio button. Worse, IE6-7 fail to give the cloned element+ // a checked appearance if the defaultChecked value isn't also set+ if ( src.checked ) {+ dest.defaultChecked = dest.checked = src.checked;+ }++ // IE6-7 get confused and end up setting the value of a cloned+ // checkbox/radio button to an empty string instead of "on"+ if ( dest.value !== src.value ) {+ dest.value = src.value;+ }++ // IE6-8 fails to return the selected option to the default selected+ // state when cloning options+ } else if ( nodeName === "option" ) {+ dest.selected = src.defaultSelected;++ // IE6-8 fails to set the defaultValue to the correct value when+ // cloning other types of input fields+ } else if ( nodeName === "input" || nodeName === "textarea" ) {+ dest.defaultValue = src.defaultValue;++ // IE blanks contents when cloning scripts+ } else if ( nodeName === "script" && dest.text !== src.text ) {+ dest.text = src.text;+ }++ // Event data gets referenced instead of copied if the expando+ // gets copied too+ dest.removeAttribute( jQuery.expando );++ // Clear flags for bubbling special change/submit events, they must+ // be reattached when the newly cloned events are first activated+ dest.removeAttribute( "_submit_attached" );+ dest.removeAttribute( "_change_attached" );+}++jQuery.buildFragment = function( args, nodes, scripts ) {+ var fragment, cacheable, cacheresults, doc,+ first = args[ 0 ];++ // nodes may contain either an explicit document object,+ // a jQuery collection or context object.+ // If nodes[0] contains a valid object to assign to doc+ if ( nodes && nodes[0] ) {+ doc = nodes[0].ownerDocument || nodes[0];+ }++ // Ensure that an attr object doesn't incorrectly stand in as a document object+ // Chrome and Firefox seem to allow this to occur and will throw exception+ // Fixes #8950+ if ( !doc.createDocumentFragment ) {+ doc = document;+ }++ // Only cache "small" (1/2 KB) HTML strings that are associated with the main document+ // Cloning options loses the selected state, so don't cache them+ // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment+ // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache+ // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501+ if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document &&+ first.charAt(0) === "<" && !rnocache.test( first ) &&+ (jQuery.support.checkClone || !rchecked.test( first )) &&+ (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {++ cacheable = true;++ cacheresults = jQuery.fragments[ first ];+ if ( cacheresults && cacheresults !== 1 ) {+ fragment = cacheresults;+ }+ }++ if ( !fragment ) {+ fragment = doc.createDocumentFragment();+ jQuery.clean( args, doc, fragment, scripts );+ }++ if ( cacheable ) {+ jQuery.fragments[ first ] = cacheresults ? fragment : 1;+ }++ return { fragment: fragment, cacheable: cacheable };+};++jQuery.fragments = {};++jQuery.each({+ appendTo: "append",+ prependTo: "prepend",+ insertBefore: "before",+ insertAfter: "after",+ replaceAll: "replaceWith"+}, function( name, original ) {+ jQuery.fn[ name ] = function( selector ) {+ var ret = [],+ insert = jQuery( selector ),+ parent = this.length === 1 && this[0].parentNode;++ if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {+ insert[ original ]( this[0] );+ return this;++ } else {+ for ( var i = 0, l = insert.length; i < l; i++ ) {+ var elems = ( i > 0 ? this.clone(true) : this ).get();+ jQuery( insert[i] )[ original ]( elems );+ ret = ret.concat( elems );+ }++ return this.pushStack( ret, name, insert.selector );+ }+ };+});++function getAll( elem ) {+ if ( typeof elem.getElementsByTagName !== "undefined" ) {+ return elem.getElementsByTagName( "*" );++ } else if ( typeof elem.querySelectorAll !== "undefined" ) {+ return elem.querySelectorAll( "*" );++ } else {+ return [];+ }+}++// Used in clean, fixes the defaultChecked property+function fixDefaultChecked( elem ) {+ if ( elem.type === "checkbox" || elem.type === "radio" ) {+ elem.defaultChecked = elem.checked;+ }+}+// Finds all inputs and passes them to fixDefaultChecked+function findInputs( elem ) {+ var nodeName = ( elem.nodeName || "" ).toLowerCase();+ if ( nodeName === "input" ) {+ fixDefaultChecked( elem );+ // Skip scripts, get other children+ } else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) {+ jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );+ }+}++// Derived From: http://www.iecss.com/shimprove/javascript/shimprove.1-0-1.js+function shimCloneNode( elem ) {+ var div = document.createElement( "div" );+ safeFragment.appendChild( div );++ div.innerHTML = elem.outerHTML;+ return div.firstChild;+}++jQuery.extend({+ clone: function( elem, dataAndEvents, deepDataAndEvents ) {+ var srcElements,+ destElements,+ i,+ // IE<=8 does not properly clone detached, unknown element nodes+ clone = jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ?+ elem.cloneNode( true ) :+ shimCloneNode( elem );++ if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&+ (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {+ // IE copies events bound via attachEvent when using cloneNode.+ // Calling detachEvent on the clone will also remove the events+ // from the original. In order to get around this, we use some+ // proprietary methods to clear the events. Thanks to MooTools+ // guys for this hotness.++ cloneFixAttributes( elem, clone );++ // Using Sizzle here is crazy slow, so we use getElementsByTagName instead+ srcElements = getAll( elem );+ destElements = getAll( clone );++ // Weird iteration because IE will replace the length property+ // with an element if you are cloning the body and one of the+ // elements on the page has a name or id of "length"+ for ( i = 0; srcElements[i]; ++i ) {+ // Ensure that the destination node is not null; Fixes #9587+ if ( destElements[i] ) {+ cloneFixAttributes( srcElements[i], destElements[i] );+ }+ }+ }++ // Copy the events from the original to the clone+ if ( dataAndEvents ) {+ cloneCopyEvent( elem, clone );++ if ( deepDataAndEvents ) {+ srcElements = getAll( elem );+ destElements = getAll( clone );++ for ( i = 0; srcElements[i]; ++i ) {+ cloneCopyEvent( srcElements[i], destElements[i] );+ }+ }+ }++ srcElements = destElements = null;++ // Return the cloned set+ return clone;+ },++ clean: function( elems, context, fragment, scripts ) {+ var checkScriptType, script, j,+ ret = [];++ context = context || document;++ // !context.createElement fails in IE with an error but returns typeof 'object'+ if ( typeof context.createElement === "undefined" ) {+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;+ }++ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {+ if ( typeof elem === "number" ) {+ elem += "";+ }++ if ( !elem ) {+ continue;+ }++ // Convert html string into DOM nodes+ if ( typeof elem === "string" ) {+ if ( !rhtml.test( elem ) ) {+ elem = context.createTextNode( elem );+ } else {+ // Fix "XHTML"-style tags in all browsers+ elem = elem.replace(rxhtmlTag, "<$1></$2>");++ // Trim whitespace, otherwise indexOf won't work as expected+ var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(),+ wrap = wrapMap[ tag ] || wrapMap._default,+ depth = wrap[0],+ div = context.createElement("div"),+ safeChildNodes = safeFragment.childNodes,+ remove;++ // Append wrapper element to unknown element safe doc fragment+ if ( context === document ) {+ // Use the fragment we've already created for this document+ safeFragment.appendChild( div );+ } else {+ // Use a fragment created with the owner document+ createSafeFragment( context ).appendChild( div );+ }++ // Go to html and back, then peel off extra wrappers+ div.innerHTML = wrap[1] + elem + wrap[2];++ // Move to the right depth+ while ( depth-- ) {+ div = div.lastChild;+ }++ // Remove IE's autoinserted <tbody> from table fragments+ if ( !jQuery.support.tbody ) {++ // String was a <table>, *may* have spurious <tbody>+ var hasBody = rtbody.test(elem),+ tbody = tag === "table" && !hasBody ?+ div.firstChild && div.firstChild.childNodes :++ // String was a bare <thead> or <tfoot>+ wrap[1] === "<table>" && !hasBody ?+ div.childNodes :+ [];++ for ( j = tbody.length - 1; j >= 0 ; --j ) {+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {+ tbody[ j ].parentNode.removeChild( tbody[ j ] );+ }+ }+ }++ // IE completely kills leading whitespace when innerHTML is used+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {+ div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );+ }++ elem = div.childNodes;++ // Clear elements from DocumentFragment (safeFragment or otherwise)+ // to avoid hoarding elements. Fixes #11356+ if ( div ) {+ div.parentNode.removeChild( div );++ // Guard against -1 index exceptions in FF3.6+ if ( safeChildNodes.length > 0 ) {+ remove = safeChildNodes[ safeChildNodes.length - 1 ];++ if ( remove && remove.parentNode ) {+ remove.parentNode.removeChild( remove );+ }+ }+ }+ }+ }++ // Resets defaultChecked for any radios and checkboxes+ // about to be appended to the DOM in IE 6/7 (#8060)+ var len;+ if ( !jQuery.support.appendChecked ) {+ if ( elem[0] && typeof (len = elem.length) === "number" ) {+ for ( j = 0; j < len; j++ ) {+ findInputs( elem[j] );+ }+ } else {+ findInputs( elem );+ }+ }++ if ( elem.nodeType ) {+ ret.push( elem );+ } else {+ ret = jQuery.merge( ret, elem );+ }+ }++ if ( fragment ) {+ checkScriptType = function( elem ) {+ return !elem.type || rscriptType.test( elem.type );+ };+ for ( i = 0; ret[i]; i++ ) {+ script = ret[i];+ if ( scripts && jQuery.nodeName( script, "script" ) && (!script.type || rscriptType.test( script.type )) ) {+ scripts.push( script.parentNode ? script.parentNode.removeChild( script ) : script );++ } else {+ if ( script.nodeType === 1 ) {+ var jsTags = jQuery.grep( script.getElementsByTagName( "script" ), checkScriptType );++ ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );+ }+ fragment.appendChild( script );+ }+ }+ }++ return ret;+ },++ cleanData: function( elems ) {+ var data, id,+ cache = jQuery.cache,+ special = jQuery.event.special,+ deleteExpando = jQuery.support.deleteExpando;++ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {+ continue;+ }++ id = elem[ jQuery.expando ];++ if ( id ) {+ data = cache[ id ];++ if ( data && data.events ) {+ for ( var type in data.events ) {+ if ( special[ type ] ) {+ jQuery.event.remove( elem, type );++ // This is a shortcut to avoid jQuery.event.remove's overhead+ } else {+ jQuery.removeEvent( elem, type, data.handle );+ }+ }++ // Null the DOM reference to avoid IE6/7/8 leak (#7054)+ if ( data.handle ) {+ data.handle.elem = null;+ }+ }++ if ( deleteExpando ) {+ delete elem[ jQuery.expando ];++ } else if ( elem.removeAttribute ) {+ elem.removeAttribute( jQuery.expando );+ }++ delete cache[ id ];+ }+ }+ }+});+++++var ralpha = /alpha\([^)]*\)/i,+ ropacity = /opacity=([^)]*)/,+ // fixed for IE9, see #8346+ rupper = /([A-Z]|^ms)/g,+ rnum = /^[\-+]?(?:\d*\.)?\d+$/i,+ rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,+ rrelNum = /^([\-+])=([\-+.\de]+)/,+ rmargin = /^margin/,++ cssShow = { position: "absolute", visibility: "hidden", display: "block" },++ // order is important!+ cssExpand = [ "Top", "Right", "Bottom", "Left" ],++ curCSS,++ getComputedStyle,+ currentStyle;++jQuery.fn.css = function( name, value ) {+ return jQuery.access( this, function( elem, name, value ) {+ return value !== undefined ?+ jQuery.style( elem, name, value ) :+ jQuery.css( elem, name );+ }, name, value, arguments.length > 1 );+};++jQuery.extend({+ // Add in style property hooks for overriding the default+ // behavior of getting and setting a style property+ cssHooks: {+ opacity: {+ get: function( elem, computed ) {+ if ( computed ) {+ // We should always get a number back from opacity+ var ret = curCSS( elem, "opacity" );+ return ret === "" ? "1" : ret;++ } else {+ return elem.style.opacity;+ }+ }+ }+ },++ // Exclude the following css properties to add px+ cssNumber: {+ "fillOpacity": true,+ "fontWeight": true,+ "lineHeight": true,+ "opacity": true,+ "orphans": true,+ "widows": true,+ "zIndex": true,+ "zoom": true+ },++ // Add in properties whose names you wish to fix before+ // setting or getting the value+ cssProps: {+ // normalize float css property+ "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"+ },++ // Get and set the style property on a DOM Node+ style: function( elem, name, value, extra ) {+ // Don't set styles on text and comment nodes+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {+ return;+ }++ // Make sure that we're working with the right name+ var ret, type, origName = jQuery.camelCase( name ),+ style = elem.style, hooks = jQuery.cssHooks[ origName ];++ name = jQuery.cssProps[ origName ] || origName;++ // Check if we're setting a value+ if ( value !== undefined ) {+ type = typeof value;++ // convert relative number strings (+= or -=) to relative numbers. #7345+ if ( type === "string" && (ret = rrelNum.exec( value )) ) {+ value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );+ // Fixes bug #9237+ type = "number";+ }++ // Make sure that NaN and null values aren't set. See: #7116+ if ( value == null || type === "number" && isNaN( value ) ) {+ return;+ }++ // If a number was passed in, add 'px' to the (except for certain CSS properties)+ if ( type === "number" && !jQuery.cssNumber[ origName ] ) {+ value += "px";+ }++ // If a hook was provided, use that value, otherwise just set the specified value+ if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {+ // Wrapped to prevent IE from throwing errors when 'invalid' values are provided+ // Fixes bug #5509+ try {+ style[ name ] = value;+ } catch(e) {}+ }++ } else {+ // If a hook was provided get the non-computed value from there+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {+ return ret;+ }++ // Otherwise just get the value from the style object+ return style[ name ];+ }+ },++ css: function( elem, name, extra ) {+ var ret, hooks;++ // Make sure that we're working with the right name+ name = jQuery.camelCase( name );+ hooks = jQuery.cssHooks[ name ];+ name = jQuery.cssProps[ name ] || name;++ // cssFloat needs a special treatment+ if ( name === "cssFloat" ) {+ name = "float";+ }++ // If a hook was provided get the computed value from there+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {+ return ret;++ // Otherwise, if a way to get the computed value exists, use that+ } else if ( curCSS ) {+ return curCSS( elem, name );+ }+ },++ // A method for quickly swapping in/out CSS properties to get correct calculations+ swap: function( elem, options, callback ) {+ var old = {},+ ret, name;++ // Remember the old values, and insert the new ones+ for ( name in options ) {+ old[ name ] = elem.style[ name ];+ elem.style[ name ] = options[ name ];+ }++ ret = callback.call( elem );++ // Revert the old values+ for ( name in options ) {+ elem.style[ name ] = old[ name ];+ }++ return ret;+ }+});++// DEPRECATED in 1.3, Use jQuery.css() instead+jQuery.curCSS = jQuery.css;++if ( document.defaultView && document.defaultView.getComputedStyle ) {+ getComputedStyle = function( elem, name ) {+ var ret, defaultView, computedStyle, width,+ style = elem.style;++ name = name.replace( rupper, "-$1" ).toLowerCase();++ if ( (defaultView = elem.ownerDocument.defaultView) &&+ (computedStyle = defaultView.getComputedStyle( elem, null )) ) {++ ret = computedStyle.getPropertyValue( name );+ if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {+ ret = jQuery.style( elem, name );+ }+ }++ // A tribute to the "awesome hack by Dean Edwards"+ // WebKit uses "computed value (percentage if specified)" instead of "used value" for margins+ // which is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values+ if ( !jQuery.support.pixelMargin && computedStyle && rmargin.test( name ) && rnumnonpx.test( ret ) ) {+ width = style.width;+ style.width = ret;+ ret = computedStyle.width;+ style.width = width;+ }++ return ret;+ };+}++if ( document.documentElement.currentStyle ) {+ currentStyle = function( elem, name ) {+ var left, rsLeft, uncomputed,+ ret = elem.currentStyle && elem.currentStyle[ name ],+ style = elem.style;++ // Avoid setting ret to empty string here+ // so we don't default to auto+ if ( ret == null && style && (uncomputed = style[ name ]) ) {+ ret = uncomputed;+ }++ // From the awesome hack by Dean Edwards+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291++ // If we're not dealing with a regular pixel number+ // but a number that has a weird ending, we need to convert it to pixels+ if ( rnumnonpx.test( ret ) ) {++ // Remember the original values+ left = style.left;+ rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;++ // Put in the new values to get a computed value out+ if ( rsLeft ) {+ elem.runtimeStyle.left = elem.currentStyle.left;+ }+ style.left = name === "fontSize" ? "1em" : ret;+ ret = style.pixelLeft + "px";++ // Revert the changed values+ style.left = left;+ if ( rsLeft ) {+ elem.runtimeStyle.left = rsLeft;+ }+ }++ return ret === "" ? "auto" : ret;+ };+}++curCSS = getComputedStyle || currentStyle;++function getWidthOrHeight( elem, name, extra ) {++ // Start with offset property+ var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,+ i = name === "width" ? 1 : 0,+ len = 4;++ if ( val > 0 ) {+ if ( extra !== "border" ) {+ for ( ; i < len; i += 2 ) {+ if ( !extra ) {+ val -= parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;+ }+ if ( extra === "margin" ) {+ val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0;+ } else {+ val -= parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;+ }+ }+ }++ return val + "px";+ }++ // Fall back to computed then uncomputed css if necessary+ val = curCSS( elem, name );+ if ( val < 0 || val == null ) {+ val = elem.style[ name ];+ }++ // Computed unit is not pixels. Stop here and return.+ if ( rnumnonpx.test(val) ) {+ return val;+ }++ // Normalize "", auto, and prepare for extra+ val = parseFloat( val ) || 0;++ // Add padding, border, margin+ if ( extra ) {+ for ( ; i < len; i += 2 ) {+ val += parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;+ if ( extra !== "padding" ) {+ val += parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;+ }+ if ( extra === "margin" ) {+ val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ]) ) || 0;+ }+ }+ }++ return val + "px";+}++jQuery.each([ "height", "width" ], function( i, name ) {+ jQuery.cssHooks[ name ] = {+ get: function( elem, computed, extra ) {+ if ( computed ) {+ if ( elem.offsetWidth !== 0 ) {+ return getWidthOrHeight( elem, name, extra );+ } else {+ return jQuery.swap( elem, cssShow, function() {+ return getWidthOrHeight( elem, name, extra );+ });+ }+ }+ },++ set: function( elem, value ) {+ return rnum.test( value ) ?+ value + "px" :+ value;+ }+ };+});++if ( !jQuery.support.opacity ) {+ jQuery.cssHooks.opacity = {+ get: function( elem, computed ) {+ // IE uses filters for opacity+ return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?+ ( parseFloat( RegExp.$1 ) / 100 ) + "" :+ computed ? "1" : "";+ },++ set: function( elem, value ) {+ var style = elem.style,+ currentStyle = elem.currentStyle,+ opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",+ filter = currentStyle && currentStyle.filter || style.filter || "";++ // IE has trouble with opacity if it does not have layout+ // Force it by setting the zoom level+ style.zoom = 1;++ // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652+ if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {++ // Setting style.filter to null, "" & " " still leave "filter:" in the cssText+ // if "filter:" is present at all, clearType is disabled, we want to avoid this+ // style.removeAttribute is IE Only, but so apparently is this code path...+ style.removeAttribute( "filter" );++ // if there there is no filter style applied in a css rule, we are done+ if ( currentStyle && !currentStyle.filter ) {+ return;+ }+ }++ // otherwise, set new filter values+ style.filter = ralpha.test( filter ) ?+ filter.replace( ralpha, opacity ) :+ filter + " " + opacity;+ }+ };+}++jQuery(function() {+ // This hook cannot be added until DOM ready because the support test+ // for it is not run until after DOM ready+ if ( !jQuery.support.reliableMarginRight ) {+ jQuery.cssHooks.marginRight = {+ get: function( elem, computed ) {+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right+ // Work around by temporarily setting element display to inline-block+ return jQuery.swap( elem, { "display": "inline-block" }, function() {+ if ( computed ) {+ return curCSS( elem, "margin-right" );+ } else {+ return elem.style.marginRight;+ }+ });+ }+ };+ }+});++if ( jQuery.expr && jQuery.expr.filters ) {+ jQuery.expr.filters.hidden = function( elem ) {+ var width = elem.offsetWidth,+ height = elem.offsetHeight;++ return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");+ };++ jQuery.expr.filters.visible = function( elem ) {+ return !jQuery.expr.filters.hidden( elem );+ };+}++// These hooks are used by animate to expand properties+jQuery.each({+ margin: "",+ padding: "",+ border: "Width"+}, function( prefix, suffix ) {++ jQuery.cssHooks[ prefix + suffix ] = {+ expand: function( value ) {+ var i,++ // assumes a single number if not a string+ parts = typeof value === "string" ? value.split(" ") : [ value ],+ expanded = {};++ for ( i = 0; i < 4; i++ ) {+ expanded[ prefix + cssExpand[ i ] + suffix ] =+ parts[ i ] || parts[ i - 2 ] || parts[ 0 ];+ }++ return expanded;+ }+ };+});+++++var r20 = /%20/g,+ rbracket = /\[\]$/,+ rCRLF = /\r?\n/g,+ rhash = /#.*$/,+ rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL+ rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,+ // #7653, #8125, #8152: local protocol detection+ rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,+ rnoContent = /^(?:GET|HEAD)$/,+ rprotocol = /^\/\//,+ rquery = /\?/,+ rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,+ rselectTextarea = /^(?:select|textarea)/i,+ rspacesAjax = /\s+/,+ rts = /([?&])_=[^&]*/,+ rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,++ // Keep a copy of the old load method+ _load = jQuery.fn.load,++ /* Prefilters+ * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)+ * 2) These are called:+ * - BEFORE asking for a transport+ * - AFTER param serialization (s.data is a string if s.processData is true)+ * 3) key is the dataType+ * 4) the catchall symbol "*" can be used+ * 5) execution will start with transport dataType and THEN continue down to "*" if needed+ */+ prefilters = {},++ /* Transports bindings+ * 1) key is the dataType+ * 2) the catchall symbol "*" can be used+ * 3) selection will start with transport dataType and THEN go to "*" if needed+ */+ transports = {},++ // Document location+ ajaxLocation,++ // Document location segments+ ajaxLocParts,++ // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression+ allTypes = ["*/"] + ["*"];++// #8138, IE may throw an exception when accessing+// a field from window.location if document.domain has been set+try {+ ajaxLocation = location.href;+} catch( e ) {+ // Use the href attribute of an A element+ // since IE will modify it given document.location+ ajaxLocation = document.createElement( "a" );+ ajaxLocation.href = "";+ ajaxLocation = ajaxLocation.href;+}++// Segment location into parts+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];++// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport+function addToPrefiltersOrTransports( structure ) {++ // dataTypeExpression is optional and defaults to "*"+ return function( dataTypeExpression, func ) {++ if ( typeof dataTypeExpression !== "string" ) {+ func = dataTypeExpression;+ dataTypeExpression = "*";+ }++ if ( jQuery.isFunction( func ) ) {+ var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),+ i = 0,+ length = dataTypes.length,+ dataType,+ list,+ placeBefore;++ // For each dataType in the dataTypeExpression+ for ( ; i < length; i++ ) {+ dataType = dataTypes[ i ];+ // We control if we're asked to add before+ // any existing element+ placeBefore = /^\+/.test( dataType );+ if ( placeBefore ) {+ dataType = dataType.substr( 1 ) || "*";+ }+ list = structure[ dataType ] = structure[ dataType ] || [];+ // then we add to the structure accordingly+ list[ placeBefore ? "unshift" : "push" ]( func );+ }+ }+ };+}++// Base inspection function for prefilters and transports+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,+ dataType /* internal */, inspected /* internal */ ) {++ dataType = dataType || options.dataTypes[ 0 ];+ inspected = inspected || {};++ inspected[ dataType ] = true;++ var list = structure[ dataType ],+ i = 0,+ length = list ? list.length : 0,+ executeOnly = ( structure === prefilters ),+ selection;++ for ( ; i < length && ( executeOnly || !selection ); i++ ) {+ selection = list[ i ]( options, originalOptions, jqXHR );+ // If we got redirected to another dataType+ // we try there if executing only and not done already+ if ( typeof selection === "string" ) {+ if ( !executeOnly || inspected[ selection ] ) {+ selection = undefined;+ } else {+ options.dataTypes.unshift( selection );+ selection = inspectPrefiltersOrTransports(+ structure, options, originalOptions, jqXHR, selection, inspected );+ }+ }+ }+ // If we're only executing or nothing was selected+ // we try the catchall dataType if not done already+ if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {+ selection = inspectPrefiltersOrTransports(+ structure, options, originalOptions, jqXHR, "*", inspected );+ }+ // unnecessary when only executing (prefilters)+ // but it'll be ignored by the caller in that case+ return selection;+}++// A special extend for ajax options+// that takes "flat" options (not to be deep extended)+// Fixes #9887+function ajaxExtend( target, src ) {+ var key, deep,+ flatOptions = jQuery.ajaxSettings.flatOptions || {};+ for ( key in src ) {+ if ( src[ key ] !== undefined ) {+ ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];+ }+ }+ if ( deep ) {+ jQuery.extend( true, target, deep );+ }+}++jQuery.fn.extend({+ load: function( url, params, callback ) {+ if ( typeof url !== "string" && _load ) {+ return _load.apply( this, arguments );++ // Don't do a request if no elements are being requested+ } else if ( !this.length ) {+ return this;+ }++ var off = url.indexOf( " " );+ if ( off >= 0 ) {+ var selector = url.slice( off, url.length );+ url = url.slice( 0, off );+ }++ // Default to a GET request+ var type = "GET";++ // If the second parameter was provided+ if ( params ) {+ // If it's a function+ if ( jQuery.isFunction( params ) ) {+ // We assume that it's the callback+ callback = params;+ params = undefined;++ // Otherwise, build a param string+ } else if ( typeof params === "object" ) {+ params = jQuery.param( params, jQuery.ajaxSettings.traditional );+ type = "POST";+ }+ }++ var self = this;++ // Request the remote document+ jQuery.ajax({+ url: url,+ type: type,+ dataType: "html",+ data: params,+ // Complete callback (responseText is used internally)+ complete: function( jqXHR, status, responseText ) {+ // Store the response as specified by the jqXHR object+ responseText = jqXHR.responseText;+ // If successful, inject the HTML into all the matched elements+ if ( jqXHR.isResolved() ) {+ // #4825: Get the actual response in case+ // a dataFilter is present in ajaxSettings+ jqXHR.done(function( r ) {+ responseText = r;+ });+ // See if a selector was specified+ self.html( selector ?+ // Create a dummy div to hold the results+ jQuery("<div>")+ // inject the contents of the document in, removing the scripts+ // to avoid any 'Permission Denied' errors in IE+ .append(responseText.replace(rscript, ""))++ // Locate the specified elements+ .find(selector) :++ // If not, just inject the full result+ responseText );+ }++ if ( callback ) {+ self.each( callback, [ responseText, status, jqXHR ] );+ }+ }+ });++ return this;+ },++ serialize: function() {+ return jQuery.param( this.serializeArray() );+ },++ serializeArray: function() {+ return this.map(function(){+ return this.elements ? jQuery.makeArray( this.elements ) : this;+ })+ .filter(function(){+ return this.name && !this.disabled &&+ ( this.checked || rselectTextarea.test( this.nodeName ) ||+ rinput.test( this.type ) );+ })+ .map(function( i, elem ){+ var val = jQuery( this ).val();++ return val == null ?+ null :+ jQuery.isArray( val ) ?+ jQuery.map( val, function( val, i ){+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };+ }) :+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };+ }).get();+ }+});++// Attach a bunch of functions for handling common AJAX events+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){+ jQuery.fn[ o ] = function( f ){+ return this.on( o, f );+ };+});++jQuery.each( [ "get", "post" ], function( i, method ) {+ jQuery[ method ] = function( url, data, callback, type ) {+ // shift arguments if data argument was omitted+ if ( jQuery.isFunction( data ) ) {+ type = type || callback;+ callback = data;+ data = undefined;+ }++ return jQuery.ajax({+ type: method,+ url: url,+ data: data,+ success: callback,+ dataType: type+ });+ };+});++jQuery.extend({++ getScript: function( url, callback ) {+ return jQuery.get( url, undefined, callback, "script" );+ },++ getJSON: function( url, data, callback ) {+ return jQuery.get( url, data, callback, "json" );+ },++ // Creates a full fledged settings object into target+ // with both ajaxSettings and settings fields.+ // If target is omitted, writes into ajaxSettings.+ ajaxSetup: function( target, settings ) {+ if ( settings ) {+ // Building a settings object+ ajaxExtend( target, jQuery.ajaxSettings );+ } else {+ // Extending ajaxSettings+ settings = target;+ target = jQuery.ajaxSettings;+ }+ ajaxExtend( target, settings );+ return target;+ },++ ajaxSettings: {+ url: ajaxLocation,+ isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),+ global: true,+ type: "GET",+ contentType: "application/x-www-form-urlencoded; charset=UTF-8",+ processData: true,+ async: true,+ /*+ timeout: 0,+ data: null,+ dataType: null,+ username: null,+ password: null,+ cache: null,+ traditional: false,+ headers: {},+ */++ accepts: {+ xml: "application/xml, text/xml",+ html: "text/html",+ text: "text/plain",+ json: "application/json, text/javascript",+ "*": allTypes+ },++ contents: {+ xml: /xml/,+ html: /html/,+ json: /json/+ },++ responseFields: {+ xml: "responseXML",+ text: "responseText"+ },++ // List of data converters+ // 1) key format is "source_type destination_type" (a single space in-between)+ // 2) the catchall symbol "*" can be used for source_type+ converters: {++ // Convert anything to text+ "* text": window.String,++ // Text to html (true = no transformation)+ "text html": true,++ // Evaluate text as a json expression+ "text json": jQuery.parseJSON,++ // Parse text as xml+ "text xml": jQuery.parseXML+ },++ // For options that shouldn't be deep extended:+ // you can add your own custom options here if+ // and when you create one that shouldn't be+ // deep extended (see ajaxExtend)+ flatOptions: {+ context: true,+ url: true+ }+ },++ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),+ ajaxTransport: addToPrefiltersOrTransports( transports ),++ // Main method+ ajax: function( url, options ) {++ // If url is an object, simulate pre-1.5 signature+ if ( typeof url === "object" ) {+ options = url;+ url = undefined;+ }++ // Force options to be an object+ options = options || {};++ var // Create the final options object+ s = jQuery.ajaxSetup( {}, options ),+ // Callbacks context+ callbackContext = s.context || s,+ // Context for global events+ // It's the callbackContext if one was provided in the options+ // and if it's a DOM node or a jQuery collection+ globalEventContext = callbackContext !== s &&+ ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?+ jQuery( callbackContext ) : jQuery.event,+ // Deferreds+ deferred = jQuery.Deferred(),+ completeDeferred = jQuery.Callbacks( "once memory" ),+ // Status-dependent callbacks+ statusCode = s.statusCode || {},+ // ifModified key+ ifModifiedKey,+ // Headers (they are sent all at once)+ requestHeaders = {},+ requestHeadersNames = {},+ // Response headers+ responseHeadersString,+ responseHeaders,+ // transport+ transport,+ // timeout handle+ timeoutTimer,+ // Cross-domain detection vars+ parts,+ // The jqXHR state+ state = 0,+ // To know if global events are to be dispatched+ fireGlobals,+ // Loop variable+ i,+ // Fake xhr+ jqXHR = {++ readyState: 0,++ // Caches the header+ setRequestHeader: function( name, value ) {+ if ( !state ) {+ var lname = name.toLowerCase();+ name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;+ requestHeaders[ name ] = value;+ }+ return this;+ },++ // Raw string+ getAllResponseHeaders: function() {+ return state === 2 ? responseHeadersString : null;+ },++ // Builds headers hashtable if needed+ getResponseHeader: function( key ) {+ var match;+ if ( state === 2 ) {+ if ( !responseHeaders ) {+ responseHeaders = {};+ while( ( match = rheaders.exec( responseHeadersString ) ) ) {+ responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];+ }+ }+ match = responseHeaders[ key.toLowerCase() ];+ }+ return match === undefined ? null : match;+ },++ // Overrides response content-type header+ overrideMimeType: function( type ) {+ if ( !state ) {+ s.mimeType = type;+ }+ return this;+ },++ // Cancel the request+ abort: function( statusText ) {+ statusText = statusText || "abort";+ if ( transport ) {+ transport.abort( statusText );+ }+ done( 0, statusText );+ return this;+ }+ };++ // Callback for when everything is done+ // It is defined here because jslint complains if it is declared+ // at the end of the function (which would be more logical and readable)+ function done( status, nativeStatusText, responses, headers ) {++ // Called once+ if ( state === 2 ) {+ return;+ }++ // State is "done" now+ state = 2;++ // Clear timeout if it exists+ if ( timeoutTimer ) {+ clearTimeout( timeoutTimer );+ }++ // Dereference transport for early garbage collection+ // (no matter how long the jqXHR object will be used)+ transport = undefined;++ // Cache response headers+ responseHeadersString = headers || "";++ // Set readyState+ jqXHR.readyState = status > 0 ? 4 : 0;++ var isSuccess,+ success,+ error,+ statusText = nativeStatusText,+ response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,+ lastModified,+ etag;++ // If successful, handle type chaining+ if ( status >= 200 && status < 300 || status === 304 ) {++ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.+ if ( s.ifModified ) {++ if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {+ jQuery.lastModified[ ifModifiedKey ] = lastModified;+ }+ if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {+ jQuery.etag[ ifModifiedKey ] = etag;+ }+ }++ // If not modified+ if ( status === 304 ) {++ statusText = "notmodified";+ isSuccess = true;++ // If we have data+ } else {++ try {+ success = ajaxConvert( s, response );+ statusText = "success";+ isSuccess = true;+ } catch(e) {+ // We have a parsererror+ statusText = "parsererror";+ error = e;+ }+ }+ } else {+ // We extract error from statusText+ // then normalize statusText and status for non-aborts+ error = statusText;+ if ( !statusText || status ) {+ statusText = "error";+ if ( status < 0 ) {+ status = 0;+ }+ }+ }++ // Set data for the fake xhr object+ jqXHR.status = status;+ jqXHR.statusText = "" + ( nativeStatusText || statusText );++ // Success/Error+ if ( isSuccess ) {+ deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );+ } else {+ deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );+ }++ // Status-dependent callbacks+ jqXHR.statusCode( statusCode );+ statusCode = undefined;++ if ( fireGlobals ) {+ globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),+ [ jqXHR, s, isSuccess ? success : error ] );+ }++ // Complete+ completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );++ if ( fireGlobals ) {+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );+ // Handle the global AJAX counter+ if ( !( --jQuery.active ) ) {+ jQuery.event.trigger( "ajaxStop" );+ }+ }+ }++ // Attach deferreds+ deferred.promise( jqXHR );+ jqXHR.success = jqXHR.done;+ jqXHR.error = jqXHR.fail;+ jqXHR.complete = completeDeferred.add;++ // Status-dependent callbacks+ jqXHR.statusCode = function( map ) {+ if ( map ) {+ var tmp;+ if ( state < 2 ) {+ for ( tmp in map ) {+ statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];+ }+ } else {+ tmp = map[ jqXHR.status ];+ jqXHR.then( tmp, tmp );+ }+ }+ return this;+ };++ // Remove hash character (#7531: and string promotion)+ // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)+ // We also use the url parameter if available+ s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );++ // Extract dataTypes list+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );++ // Determine if a cross-domain request is in order+ if ( s.crossDomain == null ) {+ parts = rurl.exec( s.url.toLowerCase() );+ s.crossDomain = !!( parts &&+ ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||+ ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=+ ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )+ );+ }++ // Convert data if not already a string+ if ( s.data && s.processData && typeof s.data !== "string" ) {+ s.data = jQuery.param( s.data, s.traditional );+ }++ // Apply prefilters+ inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );++ // If request was aborted inside a prefilter, stop there+ if ( state === 2 ) {+ return false;+ }++ // We can fire global events as of now if asked to+ fireGlobals = s.global;++ // Uppercase the type+ s.type = s.type.toUpperCase();++ // Determine if request has content+ s.hasContent = !rnoContent.test( s.type );++ // Watch for a new set of requests+ if ( fireGlobals && jQuery.active++ === 0 ) {+ jQuery.event.trigger( "ajaxStart" );+ }++ // More options handling for requests with no content+ if ( !s.hasContent ) {++ // If data is available, append data to url+ if ( s.data ) {+ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;+ // #9682: remove data so that it's not used in an eventual retry+ delete s.data;+ }++ // Get ifModifiedKey before adding the anti-cache parameter+ ifModifiedKey = s.url;++ // Add anti-cache in url if needed+ if ( s.cache === false ) {++ var ts = jQuery.now(),+ // try replacing _= if it is there+ ret = s.url.replace( rts, "$1_=" + ts );++ // if nothing was replaced, add timestamp to the end+ s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );+ }+ }++ // Set the correct header, if data is being sent+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {+ jqXHR.setRequestHeader( "Content-Type", s.contentType );+ }++ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.+ if ( s.ifModified ) {+ ifModifiedKey = ifModifiedKey || s.url;+ if ( jQuery.lastModified[ ifModifiedKey ] ) {+ jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );+ }+ if ( jQuery.etag[ ifModifiedKey ] ) {+ jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );+ }+ }++ // Set the Accepts header for the server, depending on the dataType+ jqXHR.setRequestHeader(+ "Accept",+ s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?+ s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :+ s.accepts[ "*" ]+ );++ // Check for headers option+ for ( i in s.headers ) {+ jqXHR.setRequestHeader( i, s.headers[ i ] );+ }++ // Allow custom headers/mimetypes and early abort+ if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {+ // Abort if not done already+ jqXHR.abort();+ return false;++ }++ // Install callbacks on deferreds+ for ( i in { success: 1, error: 1, complete: 1 } ) {+ jqXHR[ i ]( s[ i ] );+ }++ // Get transport+ transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );++ // If no transport, we auto-abort+ if ( !transport ) {+ done( -1, "No Transport" );+ } else {+ jqXHR.readyState = 1;+ // Send global event+ if ( fireGlobals ) {+ globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );+ }+ // Timeout+ if ( s.async && s.timeout > 0 ) {+ timeoutTimer = setTimeout( function(){+ jqXHR.abort( "timeout" );+ }, s.timeout );+ }++ try {+ state = 1;+ transport.send( requestHeaders, done );+ } catch (e) {+ // Propagate exception as error if not done+ if ( state < 2 ) {+ done( -1, e );+ // Simply rethrow otherwise+ } else {+ throw e;+ }+ }+ }++ return jqXHR;+ },++ // Serialize an array of form elements or a set of+ // key/values into a query string+ param: function( a, traditional ) {+ var s = [],+ add = function( key, value ) {+ // If value is a function, invoke it and return its value+ value = jQuery.isFunction( value ) ? value() : value;+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );+ };++ // Set traditional to true for jQuery <= 1.3.2 behavior.+ if ( traditional === undefined ) {+ traditional = jQuery.ajaxSettings.traditional;+ }++ // If an array was passed in, assume that it is an array of form elements.+ if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {+ // Serialize the form elements+ jQuery.each( a, function() {+ add( this.name, this.value );+ });++ } else {+ // If traditional, encode the "old" way (the way 1.3.2 or older+ // did it), otherwise encode params recursively.+ for ( var prefix in a ) {+ buildParams( prefix, a[ prefix ], traditional, add );+ }+ }++ // Return the resulting serialization+ return s.join( "&" ).replace( r20, "+" );+ }+});++function buildParams( prefix, obj, traditional, add ) {+ if ( jQuery.isArray( obj ) ) {+ // Serialize array item.+ jQuery.each( obj, function( i, v ) {+ if ( traditional || rbracket.test( prefix ) ) {+ // Treat each array item as a scalar.+ add( prefix, v );++ } else {+ // If array item is non-scalar (array or object), encode its+ // numeric index to resolve deserialization ambiguity issues.+ // Note that rack (as of 1.0.0) can't currently deserialize+ // nested arrays properly, and attempting to do so may cause+ // a server error. Possible fixes are to modify rack's+ // deserialization algorithm or to provide an option or flag+ // to force array serialization to be shallow.+ buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );+ }+ });++ } else if ( !traditional && jQuery.type( obj ) === "object" ) {+ // Serialize object item.+ for ( var name in obj ) {+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );+ }++ } else {+ // Serialize scalar item.+ add( prefix, obj );+ }+}++// This is still on the jQuery object... for now+// Want to move this to jQuery.ajax some day+jQuery.extend({++ // Counter for holding the number of active queries+ active: 0,++ // Last-Modified header cache for next request+ lastModified: {},+ etag: {}++});++/* Handles responses to an ajax request:+ * - sets all responseXXX fields accordingly+ * - finds the right dataType (mediates between content-type and expected dataType)+ * - returns the corresponding response+ */+function ajaxHandleResponses( s, jqXHR, responses ) {++ var contents = s.contents,+ dataTypes = s.dataTypes,+ responseFields = s.responseFields,+ ct,+ type,+ finalDataType,+ firstDataType;++ // Fill responseXXX fields+ for ( type in responseFields ) {+ if ( type in responses ) {+ jqXHR[ responseFields[type] ] = responses[ type ];+ }+ }++ // Remove auto dataType and get content-type in the process+ while( dataTypes[ 0 ] === "*" ) {+ dataTypes.shift();+ if ( ct === undefined ) {+ ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );+ }+ }++ // Check if we're dealing with a known content-type+ if ( ct ) {+ for ( type in contents ) {+ if ( contents[ type ] && contents[ type ].test( ct ) ) {+ dataTypes.unshift( type );+ break;+ }+ }+ }++ // Check to see if we have a response for the expected dataType+ if ( dataTypes[ 0 ] in responses ) {+ finalDataType = dataTypes[ 0 ];+ } else {+ // Try convertible dataTypes+ for ( type in responses ) {+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {+ finalDataType = type;+ break;+ }+ if ( !firstDataType ) {+ firstDataType = type;+ }+ }+ // Or just use first one+ finalDataType = finalDataType || firstDataType;+ }++ // If we found a dataType+ // We add the dataType to the list if needed+ // and return the corresponding response+ if ( finalDataType ) {+ if ( finalDataType !== dataTypes[ 0 ] ) {+ dataTypes.unshift( finalDataType );+ }+ return responses[ finalDataType ];+ }+}++// Chain conversions given the request and the original response+function ajaxConvert( s, response ) {++ // Apply the dataFilter if provided+ if ( s.dataFilter ) {+ response = s.dataFilter( response, s.dataType );+ }++ var dataTypes = s.dataTypes,+ converters = {},+ i,+ key,+ length = dataTypes.length,+ tmp,+ // Current and previous dataTypes+ current = dataTypes[ 0 ],+ prev,+ // Conversion expression+ conversion,+ // Conversion function+ conv,+ // Conversion functions (transitive conversion)+ conv1,+ conv2;++ // For each dataType in the chain+ for ( i = 1; i < length; i++ ) {++ // Create converters map+ // with lowercased keys+ if ( i === 1 ) {+ for ( key in s.converters ) {+ if ( typeof key === "string" ) {+ converters[ key.toLowerCase() ] = s.converters[ key ];+ }+ }+ }++ // Get the dataTypes+ prev = current;+ current = dataTypes[ i ];++ // If current is auto dataType, update it to prev+ if ( current === "*" ) {+ current = prev;+ // If no auto and dataTypes are actually different+ } else if ( prev !== "*" && prev !== current ) {++ // Get the converter+ conversion = prev + " " + current;+ conv = converters[ conversion ] || converters[ "* " + current ];++ // If there is no direct converter, search transitively+ if ( !conv ) {+ conv2 = undefined;+ for ( conv1 in converters ) {+ tmp = conv1.split( " " );+ if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {+ conv2 = converters[ tmp[1] + " " + current ];+ if ( conv2 ) {+ conv1 = converters[ conv1 ];+ if ( conv1 === true ) {+ conv = conv2;+ } else if ( conv2 === true ) {+ conv = conv1;+ }+ break;+ }+ }+ }+ }+ // If we found no converter, dispatch an error+ if ( !( conv || conv2 ) ) {+ jQuery.error( "No conversion from " + conversion.replace(" "," to ") );+ }+ // If found converter is not an equivalence+ if ( conv !== true ) {+ // Convert with 1 or 2 converters accordingly+ response = conv ? conv( response ) : conv2( conv1(response) );+ }+ }+ }+ return response;+}+++++var jsc = jQuery.now(),+ jsre = /(\=)\?(&|$)|\?\?/i;++// Default jsonp settings+jQuery.ajaxSetup({+ jsonp: "callback",+ jsonpCallback: function() {+ return jQuery.expando + "_" + ( jsc++ );+ }+});++// Detect, normalize options and install callbacks for jsonp requests+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {++ var inspectData = ( typeof s.data === "string" ) && /^application\/x\-www\-form\-urlencoded/.test( s.contentType );++ if ( s.dataTypes[ 0 ] === "jsonp" ||+ s.jsonp !== false && ( jsre.test( s.url ) ||+ inspectData && jsre.test( s.data ) ) ) {++ var responseContainer,+ jsonpCallback = s.jsonpCallback =+ jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,+ previous = window[ jsonpCallback ],+ url = s.url,+ data = s.data,+ replace = "$1" + jsonpCallback + "$2";++ if ( s.jsonp !== false ) {+ url = url.replace( jsre, replace );+ if ( s.url === url ) {+ if ( inspectData ) {+ data = data.replace( jsre, replace );+ }+ if ( s.data === data ) {+ // Add callback manually+ url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;+ }+ }+ }++ s.url = url;+ s.data = data;++ // Install callback+ window[ jsonpCallback ] = function( response ) {+ responseContainer = [ response ];+ };++ // Clean-up function+ jqXHR.always(function() {+ // Set callback back to previous value+ window[ jsonpCallback ] = previous;+ // Call if it was a function and we have a response+ if ( responseContainer && jQuery.isFunction( previous ) ) {+ window[ jsonpCallback ]( responseContainer[ 0 ] );+ }+ });++ // Use data converter to retrieve json after script execution+ s.converters["script json"] = function() {+ if ( !responseContainer ) {+ jQuery.error( jsonpCallback + " was not called" );+ }+ return responseContainer[ 0 ];+ };++ // force json dataType+ s.dataTypes[ 0 ] = "json";++ // Delegate to script+ return "script";+ }+});+++++// Install script dataType+jQuery.ajaxSetup({+ accepts: {+ script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"+ },+ contents: {+ script: /javascript|ecmascript/+ },+ converters: {+ "text script": function( text ) {+ jQuery.globalEval( text );+ return text;+ }+ }+});++// Handle cache's special case and global+jQuery.ajaxPrefilter( "script", function( s ) {+ if ( s.cache === undefined ) {+ s.cache = false;+ }+ if ( s.crossDomain ) {+ s.type = "GET";+ s.global = false;+ }+});++// Bind script tag hack transport+jQuery.ajaxTransport( "script", function(s) {++ // This transport only deals with cross domain requests+ if ( s.crossDomain ) {++ var script,+ head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;++ return {++ send: function( _, callback ) {++ script = document.createElement( "script" );++ script.async = "async";++ if ( s.scriptCharset ) {+ script.charset = s.scriptCharset;+ }++ script.src = s.url;++ // Attach handlers for all browsers+ script.onload = script.onreadystatechange = function( _, isAbort ) {++ if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {++ // Handle memory leak in IE+ script.onload = script.onreadystatechange = null;++ // Remove the script+ if ( head && script.parentNode ) {+ head.removeChild( script );+ }++ // Dereference the script+ script = undefined;++ // Callback if not abort+ if ( !isAbort ) {+ callback( 200, "success" );+ }+ }+ };+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.+ // This arises when a base node is used (#2709 and #4378).+ head.insertBefore( script, head.firstChild );+ },++ abort: function() {+ if ( script ) {+ script.onload( 0, 1 );+ }+ }+ };+ }+});+++++var // #5280: Internet Explorer will keep connections alive if we don't abort on unload+ xhrOnUnloadAbort = window.ActiveXObject ? function() {+ // Abort all pending requests+ for ( var key in xhrCallbacks ) {+ xhrCallbacks[ key ]( 0, 1 );+ }+ } : false,+ xhrId = 0,+ xhrCallbacks;++// Functions to create xhrs+function createStandardXHR() {+ try {+ return new window.XMLHttpRequest();+ } catch( e ) {}+}++function createActiveXHR() {+ try {+ return new window.ActiveXObject( "Microsoft.XMLHTTP" );+ } catch( e ) {}+}++// Create the request object+// (This is still attached to ajaxSettings for backward compatibility)+jQuery.ajaxSettings.xhr = window.ActiveXObject ?+ /* Microsoft failed to properly+ * implement the XMLHttpRequest in IE7 (can't request local files),+ * so we use the ActiveXObject when it is available+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so+ * we need a fallback.+ */+ function() {+ return !this.isLocal && createStandardXHR() || createActiveXHR();+ } :+ // For all other browsers, use the standard XMLHttpRequest object+ createStandardXHR;++// Determine support properties+(function( xhr ) {+ jQuery.extend( jQuery.support, {+ ajax: !!xhr,+ cors: !!xhr && ( "withCredentials" in xhr )+ });+})( jQuery.ajaxSettings.xhr() );++// Create transport if the browser can provide an xhr+if ( jQuery.support.ajax ) {++ jQuery.ajaxTransport(function( s ) {+ // Cross domain only allowed if supported through XMLHttpRequest+ if ( !s.crossDomain || jQuery.support.cors ) {++ var callback;++ return {+ send: function( headers, complete ) {++ // Get a new xhr+ var xhr = s.xhr(),+ handle,+ i;++ // Open the socket+ // Passing null username, generates a login popup on Opera (#2865)+ if ( s.username ) {+ xhr.open( s.type, s.url, s.async, s.username, s.password );+ } else {+ xhr.open( s.type, s.url, s.async );+ }++ // Apply custom fields if provided+ if ( s.xhrFields ) {+ for ( i in s.xhrFields ) {+ xhr[ i ] = s.xhrFields[ i ];+ }+ }++ // Override mime type if needed+ if ( s.mimeType && xhr.overrideMimeType ) {+ xhr.overrideMimeType( s.mimeType );+ }++ // X-Requested-With header+ // For cross-domain requests, seeing as conditions for a preflight are+ // akin to a jigsaw puzzle, we simply never set it to be sure.+ // (it can always be set on a per-request basis or even using ajaxSetup)+ // For same-domain requests, won't change header if already provided.+ if ( !s.crossDomain && !headers["X-Requested-With"] ) {+ headers[ "X-Requested-With" ] = "XMLHttpRequest";+ }++ // Need an extra try/catch for cross domain requests in Firefox 3+ try {+ for ( i in headers ) {+ xhr.setRequestHeader( i, headers[ i ] );+ }+ } catch( _ ) {}++ // Do send the request+ // This may raise an exception which is actually+ // handled in jQuery.ajax (so no try/catch here)+ xhr.send( ( s.hasContent && s.data ) || null );++ // Listener+ callback = function( _, isAbort ) {++ var status,+ statusText,+ responseHeaders,+ responses,+ xml;++ // Firefox throws exceptions when accessing properties+ // of an xhr when a network error occured+ // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)+ try {++ // Was never called and is aborted or complete+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {++ // Only called once+ callback = undefined;++ // Do not keep as active anymore+ if ( handle ) {+ xhr.onreadystatechange = jQuery.noop;+ if ( xhrOnUnloadAbort ) {+ delete xhrCallbacks[ handle ];+ }+ }++ // If it's an abort+ if ( isAbort ) {+ // Abort it manually if needed+ if ( xhr.readyState !== 4 ) {+ xhr.abort();+ }+ } else {+ status = xhr.status;+ responseHeaders = xhr.getAllResponseHeaders();+ responses = {};+ xml = xhr.responseXML;++ // Construct response list+ if ( xml && xml.documentElement /* #4958 */ ) {+ responses.xml = xml;+ }++ // When requesting binary data, IE6-9 will throw an exception+ // on any attempt to access responseText (#11426)+ try {+ responses.text = xhr.responseText;+ } catch( _ ) {+ }++ // Firefox throws an exception when accessing+ // statusText for faulty cross-domain requests+ try {+ statusText = xhr.statusText;+ } catch( e ) {+ // We normalize with Webkit giving an empty statusText+ statusText = "";+ }++ // Filter status for non standard behaviors++ // If the request is local and we have data: assume a success+ // (success with no data won't get notified, that's the best we+ // can do given current implementations)+ if ( !status && s.isLocal && !s.crossDomain ) {+ status = responses.text ? 200 : 404;+ // IE - #1450: sometimes returns 1223 when it should be 204+ } else if ( status === 1223 ) {+ status = 204;+ }+ }+ }+ } catch( firefoxAccessException ) {+ if ( !isAbort ) {+ complete( -1, firefoxAccessException );+ }+ }++ // Call complete if needed+ if ( responses ) {+ complete( status, statusText, responses, responseHeaders );+ }+ };++ // if we're in sync mode or it's in cache+ // and has been retrieved directly (IE6 & IE7)+ // we need to manually fire the callback+ if ( !s.async || xhr.readyState === 4 ) {+ callback();+ } else {+ handle = ++xhrId;+ if ( xhrOnUnloadAbort ) {+ // Create the active xhrs callbacks list if needed+ // and attach the unload handler+ if ( !xhrCallbacks ) {+ xhrCallbacks = {};+ jQuery( window ).unload( xhrOnUnloadAbort );+ }+ // Add to list of active xhrs callbacks+ xhrCallbacks[ handle ] = callback;+ }+ xhr.onreadystatechange = callback;+ }+ },++ abort: function() {+ if ( callback ) {+ callback(0,1);+ }+ }+ };+ }+ });+}+++++var elemdisplay = {},+ iframe, iframeDoc,+ rfxtypes = /^(?:toggle|show|hide)$/,+ rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,+ timerId,+ fxAttrs = [+ // height animations+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],+ // width animations+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],+ // opacity animations+ [ "opacity" ]+ ],+ fxNow;++jQuery.fn.extend({+ show: function( speed, easing, callback ) {+ var elem, display;++ if ( speed || speed === 0 ) {+ return this.animate( genFx("show", 3), speed, easing, callback );++ } else {+ for ( var i = 0, j = this.length; i < j; i++ ) {+ elem = this[ i ];++ if ( elem.style ) {+ display = elem.style.display;++ // Reset the inline display of this element to learn if it is+ // being hidden by cascaded rules or not+ if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {+ display = elem.style.display = "";+ }++ // Set elements which have been overridden with display: none+ // in a stylesheet to whatever the default browser style is+ // for such an element+ if ( (display === "" && jQuery.css(elem, "display") === "none") ||+ !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {+ jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );+ }+ }+ }++ // Set the display of most of the elements in a second loop+ // to avoid the constant reflow+ for ( i = 0; i < j; i++ ) {+ elem = this[ i ];++ if ( elem.style ) {+ display = elem.style.display;++ if ( display === "" || display === "none" ) {+ elem.style.display = jQuery._data( elem, "olddisplay" ) || "";+ }+ }+ }++ return this;+ }+ },++ hide: function( speed, easing, callback ) {+ if ( speed || speed === 0 ) {+ return this.animate( genFx("hide", 3), speed, easing, callback);++ } else {+ var elem, display,+ i = 0,+ j = this.length;++ for ( ; i < j; i++ ) {+ elem = this[i];+ if ( elem.style ) {+ display = jQuery.css( elem, "display" );++ if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) {+ jQuery._data( elem, "olddisplay", display );+ }+ }+ }++ // Set the display of the elements in a second loop+ // to avoid the constant reflow+ for ( i = 0; i < j; i++ ) {+ if ( this[i].style ) {+ this[i].style.display = "none";+ }+ }++ return this;+ }+ },++ // Save the old toggle function+ _toggle: jQuery.fn.toggle,++ toggle: function( fn, fn2, callback ) {+ var bool = typeof fn === "boolean";++ if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {+ this._toggle.apply( this, arguments );++ } else if ( fn == null || bool ) {+ this.each(function() {+ var state = bool ? fn : jQuery(this).is(":hidden");+ jQuery(this)[ state ? "show" : "hide" ]();+ });++ } else {+ this.animate(genFx("toggle", 3), fn, fn2, callback);+ }++ return this;+ },++ fadeTo: function( speed, to, easing, callback ) {+ return this.filter(":hidden").css("opacity", 0).show().end()+ .animate({opacity: to}, speed, easing, callback);+ },++ animate: function( prop, speed, easing, callback ) {+ var optall = jQuery.speed( speed, easing, callback );++ if ( jQuery.isEmptyObject( prop ) ) {+ return this.each( optall.complete, [ false ] );+ }++ // Do not change referenced properties as per-property easing will be lost+ prop = jQuery.extend( {}, prop );++ function doAnimation() {+ // XXX 'this' does not always have a nodeName when running the+ // test suite++ if ( optall.queue === false ) {+ jQuery._mark( this );+ }++ var opt = jQuery.extend( {}, optall ),+ isElement = this.nodeType === 1,+ hidden = isElement && jQuery(this).is(":hidden"),+ name, val, p, e, hooks, replace,+ parts, start, end, unit,+ method;++ // will store per property easing and be used to determine when an animation is complete+ opt.animatedProperties = {};++ // first pass over propertys to expand / normalize+ for ( p in prop ) {+ name = jQuery.camelCase( p );+ if ( p !== name ) {+ prop[ name ] = prop[ p ];+ delete prop[ p ];+ }++ if ( ( hooks = jQuery.cssHooks[ name ] ) && "expand" in hooks ) {+ replace = hooks.expand( prop[ name ] );+ delete prop[ name ];++ // not quite $.extend, this wont overwrite keys already present.+ // also - reusing 'p' from above because we have the correct "name"+ for ( p in replace ) {+ if ( ! ( p in prop ) ) {+ prop[ p ] = replace[ p ];+ }+ }+ }+ }++ for ( name in prop ) {+ val = prop[ name ];+ // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)+ if ( jQuery.isArray( val ) ) {+ opt.animatedProperties[ name ] = val[ 1 ];+ val = prop[ name ] = val[ 0 ];+ } else {+ opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';+ }++ if ( val === "hide" && hidden || val === "show" && !hidden ) {+ return opt.complete.call( this );+ }++ if ( isElement && ( name === "height" || name === "width" ) ) {+ // Make sure that nothing sneaks out+ // Record all 3 overflow attributes because IE does not+ // change the overflow attribute when overflowX and+ // overflowY are set to the same value+ opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];++ // Set display property to inline-block for height/width+ // animations on inline elements that are having width/height animated+ if ( jQuery.css( this, "display" ) === "inline" &&+ jQuery.css( this, "float" ) === "none" ) {++ // inline-level elements accept inline-block;+ // block-level elements need to be inline with layout+ if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) {+ this.style.display = "inline-block";++ } else {+ this.style.zoom = 1;+ }+ }+ }+ }++ if ( opt.overflow != null ) {+ this.style.overflow = "hidden";+ }++ for ( p in prop ) {+ e = new jQuery.fx( this, opt, p );+ val = prop[ p ];++ if ( rfxtypes.test( val ) ) {++ // Tracks whether to show or hide based on private+ // data attached to the element+ method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 );+ if ( method ) {+ jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" );+ e[ method ]();+ } else {+ e[ val ]();+ }++ } else {+ parts = rfxnum.exec( val );+ start = e.cur();++ if ( parts ) {+ end = parseFloat( parts[2] );+ unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );++ // We need to compute starting value+ if ( unit !== "px" ) {+ jQuery.style( this, p, (end || 1) + unit);+ start = ( (end || 1) / e.cur() ) * start;+ jQuery.style( this, p, start + unit);+ }++ // If a +=/-= token was provided, we're doing a relative animation+ if ( parts[1] ) {+ end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;+ }++ e.custom( start, end, unit );++ } else {+ e.custom( start, val, "" );+ }+ }+ }++ // For JS strict compliance+ return true;+ }++ return optall.queue === false ?+ this.each( doAnimation ) :+ this.queue( optall.queue, doAnimation );+ },++ stop: function( type, clearQueue, gotoEnd ) {+ if ( typeof type !== "string" ) {+ gotoEnd = clearQueue;+ clearQueue = type;+ type = undefined;+ }+ if ( clearQueue && type !== false ) {+ this.queue( type || "fx", [] );+ }++ return this.each(function() {+ var index,+ hadTimers = false,+ timers = jQuery.timers,+ data = jQuery._data( this );++ // clear marker counters if we know they won't be+ if ( !gotoEnd ) {+ jQuery._unmark( true, this );+ }++ function stopQueue( elem, data, index ) {+ var hooks = data[ index ];+ jQuery.removeData( elem, index, true );+ hooks.stop( gotoEnd );+ }++ if ( type == null ) {+ for ( index in data ) {+ if ( data[ index ] && data[ index ].stop && index.indexOf(".run") === index.length - 4 ) {+ stopQueue( this, data, index );+ }+ }+ } else if ( data[ index = type + ".run" ] && data[ index ].stop ){+ stopQueue( this, data, index );+ }++ for ( index = timers.length; index--; ) {+ if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {+ if ( gotoEnd ) {++ // force the next step to be the last+ timers[ index ]( true );+ } else {+ timers[ index ].saveState();+ }+ hadTimers = true;+ timers.splice( index, 1 );+ }+ }++ // start the next in the queue if the last step wasn't forced+ // timers currently will call their complete callbacks, which will dequeue+ // but only if they were gotoEnd+ if ( !( gotoEnd && hadTimers ) ) {+ jQuery.dequeue( this, type );+ }+ });+ }++});++// Animations created synchronously will run synchronously+function createFxNow() {+ setTimeout( clearFxNow, 0 );+ return ( fxNow = jQuery.now() );+}++function clearFxNow() {+ fxNow = undefined;+}++// Generate parameters to create a standard animation+function genFx( type, num ) {+ var obj = {};++ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() {+ obj[ this ] = type;+ });++ return obj;+}++// Generate shortcuts for custom animations+jQuery.each({+ slideDown: genFx( "show", 1 ),+ slideUp: genFx( "hide", 1 ),+ slideToggle: genFx( "toggle", 1 ),+ fadeIn: { opacity: "show" },+ fadeOut: { opacity: "hide" },+ fadeToggle: { opacity: "toggle" }+}, function( name, props ) {+ jQuery.fn[ name ] = function( speed, easing, callback ) {+ return this.animate( props, speed, easing, callback );+ };+});++jQuery.extend({+ speed: function( speed, easing, fn ) {+ var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {+ complete: fn || !fn && easing ||+ jQuery.isFunction( speed ) && speed,+ duration: speed,+ easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing+ };++ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :+ opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;++ // normalize opt.queue - true/undefined/null -> "fx"+ if ( opt.queue == null || opt.queue === true ) {+ opt.queue = "fx";+ }++ // Queueing+ opt.old = opt.complete;++ opt.complete = function( noUnmark ) {+ if ( jQuery.isFunction( opt.old ) ) {+ opt.old.call( this );+ }++ if ( opt.queue ) {+ jQuery.dequeue( this, opt.queue );+ } else if ( noUnmark !== false ) {+ jQuery._unmark( this );+ }+ };++ return opt;+ },++ easing: {+ linear: function( p ) {+ return p;+ },+ swing: function( p ) {+ return ( -Math.cos( p*Math.PI ) / 2 ) + 0.5;+ }+ },++ timers: [],++ fx: function( elem, options, prop ) {+ this.options = options;+ this.elem = elem;+ this.prop = prop;++ options.orig = options.orig || {};+ }++});++jQuery.fx.prototype = {+ // Simple function for setting a style value+ update: function() {+ if ( this.options.step ) {+ this.options.step.call( this.elem, this.now, this );+ }++ ( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this );+ },++ // Get the current size+ cur: function() {+ if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) {+ return this.elem[ this.prop ];+ }++ var parsed,+ r = jQuery.css( this.elem, this.prop );+ // Empty strings, null, undefined and "auto" are converted to 0,+ // complex values such as "rotate(1rad)" are returned as is,+ // simple values such as "10px" are parsed to Float.+ return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;+ },++ // Start an animation from one number to another+ custom: function( from, to, unit ) {+ var self = this,+ fx = jQuery.fx;++ this.startTime = fxNow || createFxNow();+ this.end = to;+ this.now = this.start = from;+ this.pos = this.state = 0;+ this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );++ function t( gotoEnd ) {+ return self.step( gotoEnd );+ }++ t.queue = this.options.queue;+ t.elem = this.elem;+ t.saveState = function() {+ if ( jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) {+ if ( self.options.hide ) {+ jQuery._data( self.elem, "fxshow" + self.prop, self.start );+ } else if ( self.options.show ) {+ jQuery._data( self.elem, "fxshow" + self.prop, self.end );+ }+ }+ };++ if ( t() && jQuery.timers.push(t) && !timerId ) {+ timerId = setInterval( fx.tick, fx.interval );+ }+ },++ // Simple 'show' function+ show: function() {+ var dataShow = jQuery._data( this.elem, "fxshow" + this.prop );++ // Remember where we started, so that we can go back to it later+ this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop );+ this.options.show = true;++ // Begin the animation+ // Make sure that we start at a small width/height to avoid any flash of content+ if ( dataShow !== undefined ) {+ // This show is picking up where a previous hide or show left off+ this.custom( this.cur(), dataShow );+ } else {+ this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() );+ }++ // Start by showing the element+ jQuery( this.elem ).show();+ },++ // Simple 'hide' function+ hide: function() {+ // Remember where we started, so that we can go back to it later+ this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop );+ this.options.hide = true;++ // Begin the animation+ this.custom( this.cur(), 0 );+ },++ // Each step of an animation+ step: function( gotoEnd ) {+ var p, n, complete,+ t = fxNow || createFxNow(),+ done = true,+ elem = this.elem,+ options = this.options;++ if ( gotoEnd || t >= options.duration + this.startTime ) {+ this.now = this.end;+ this.pos = this.state = 1;+ this.update();++ options.animatedProperties[ this.prop ] = true;++ for ( p in options.animatedProperties ) {+ if ( options.animatedProperties[ p ] !== true ) {+ done = false;+ }+ }++ if ( done ) {+ // Reset the overflow+ if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {++ jQuery.each( [ "", "X", "Y" ], function( index, value ) {+ elem.style[ "overflow" + value ] = options.overflow[ index ];+ });+ }++ // Hide the element if the "hide" operation was done+ if ( options.hide ) {+ jQuery( elem ).hide();+ }++ // Reset the properties, if the item has been hidden or shown+ if ( options.hide || options.show ) {+ for ( p in options.animatedProperties ) {+ jQuery.style( elem, p, options.orig[ p ] );+ jQuery.removeData( elem, "fxshow" + p, true );+ // Toggle data is no longer needed+ jQuery.removeData( elem, "toggle" + p, true );+ }+ }++ // Execute the complete function+ // in the event that the complete function throws an exception+ // we must ensure it won't be called twice. #5684++ complete = options.complete;+ if ( complete ) {++ options.complete = false;+ complete.call( elem );+ }+ }++ return false;++ } else {+ // classical easing cannot be used with an Infinity duration+ if ( options.duration == Infinity ) {+ this.now = t;+ } else {+ n = t - this.startTime;+ this.state = n / options.duration;++ // Perform the easing function, defaults to swing+ this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration );+ this.now = this.start + ( (this.end - this.start) * this.pos );+ }+ // Perform the next step of the animation+ this.update();+ }++ return true;+ }+};++jQuery.extend( jQuery.fx, {+ tick: function() {+ var timer,+ timers = jQuery.timers,+ i = 0;++ for ( ; i < timers.length; i++ ) {+ timer = timers[ i ];+ // Checks the timer has not already been removed+ if ( !timer() && timers[ i ] === timer ) {+ timers.splice( i--, 1 );+ }+ }++ if ( !timers.length ) {+ jQuery.fx.stop();+ }+ },++ interval: 13,++ stop: function() {+ clearInterval( timerId );+ timerId = null;+ },++ speeds: {+ slow: 600,+ fast: 200,+ // Default speed+ _default: 400+ },++ step: {+ opacity: function( fx ) {+ jQuery.style( fx.elem, "opacity", fx.now );+ },++ _default: function( fx ) {+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;+ } else {+ fx.elem[ fx.prop ] = fx.now;+ }+ }+ }+});++// Ensure props that can't be negative don't go there on undershoot easing+jQuery.each( fxAttrs.concat.apply( [], fxAttrs ), function( i, prop ) {+ // exclude marginTop, marginLeft, marginBottom and marginRight from this list+ if ( prop.indexOf( "margin" ) ) {+ jQuery.fx.step[ prop ] = function( fx ) {+ jQuery.style( fx.elem, prop, Math.max(0, fx.now) + fx.unit );+ };+ }+});++if ( jQuery.expr && jQuery.expr.filters ) {+ jQuery.expr.filters.animated = function( elem ) {+ return jQuery.grep(jQuery.timers, function( fn ) {+ return elem === fn.elem;+ }).length;+ };+}++// Try to restore the default display value of an element+function defaultDisplay( nodeName ) {++ if ( !elemdisplay[ nodeName ] ) {++ var body = document.body,+ elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),+ display = elem.css( "display" );+ elem.remove();++ // If the simple way fails,+ // get element's real default display by attaching it to a temp iframe+ if ( display === "none" || display === "" ) {+ // No iframe to use yet, so create it+ if ( !iframe ) {+ iframe = document.createElement( "iframe" );+ iframe.frameBorder = iframe.width = iframe.height = 0;+ }++ body.appendChild( iframe );++ // Create a cacheable copy of the iframe document on first call.+ // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML+ // document to it; WebKit & Firefox won't allow reusing the iframe document.+ if ( !iframeDoc || !iframe.createElement ) {+ iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;+ iframeDoc.write( ( jQuery.support.boxModel ? "<!doctype html>" : "" ) + "<html><body>" );+ iframeDoc.close();+ }++ elem = iframeDoc.createElement( nodeName );++ iframeDoc.body.appendChild( elem );++ display = jQuery.css( elem, "display" );+ body.removeChild( iframe );+ }++ // Store the correct default display+ elemdisplay[ nodeName ] = display;+ }++ return elemdisplay[ nodeName ];+}+++++var getOffset,+ rtable = /^t(?:able|d|h)$/i,+ rroot = /^(?:body|html)$/i;++if ( "getBoundingClientRect" in document.documentElement ) {+ getOffset = function( elem, doc, docElem, box ) {+ try {+ box = elem.getBoundingClientRect();+ } catch(e) {}++ // Make sure we're not dealing with a disconnected DOM node+ if ( !box || !jQuery.contains( docElem, elem ) ) {+ return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };+ }++ var body = doc.body,+ win = getWindow( doc ),+ clientTop = docElem.clientTop || body.clientTop || 0,+ clientLeft = docElem.clientLeft || body.clientLeft || 0,+ scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,+ scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,+ top = box.top + scrollTop - clientTop,+ left = box.left + scrollLeft - clientLeft;++ return { top: top, left: left };+ };++} else {+ getOffset = function( elem, doc, docElem ) {+ var computedStyle,+ offsetParent = elem.offsetParent,+ prevOffsetParent = elem,+ body = doc.body,+ defaultView = doc.defaultView,+ prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,+ top = elem.offsetTop,+ left = elem.offsetLeft;++ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {+ if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {+ break;+ }++ computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;+ top -= elem.scrollTop;+ left -= elem.scrollLeft;++ if ( elem === offsetParent ) {+ top += elem.offsetTop;+ left += elem.offsetLeft;++ if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {+ top += parseFloat( computedStyle.borderTopWidth ) || 0;+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;+ }++ prevOffsetParent = offsetParent;+ offsetParent = elem.offsetParent;+ }++ if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {+ top += parseFloat( computedStyle.borderTopWidth ) || 0;+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;+ }++ prevComputedStyle = computedStyle;+ }++ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {+ top += body.offsetTop;+ left += body.offsetLeft;+ }++ if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {+ top += Math.max( docElem.scrollTop, body.scrollTop );+ left += Math.max( docElem.scrollLeft, body.scrollLeft );+ }++ return { top: top, left: left };+ };+}++jQuery.fn.offset = function( options ) {+ if ( arguments.length ) {+ return options === undefined ?+ this :+ this.each(function( i ) {+ jQuery.offset.setOffset( this, options, i );+ });+ }++ var elem = this[0],+ doc = elem && elem.ownerDocument;++ if ( !doc ) {+ return null;+ }++ if ( elem === doc.body ) {+ return jQuery.offset.bodyOffset( elem );+ }++ return getOffset( elem, doc, doc.documentElement );+};++jQuery.offset = {++ bodyOffset: function( body ) {+ var top = body.offsetTop,+ left = body.offsetLeft;++ if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {+ top += parseFloat( jQuery.css(body, "marginTop") ) || 0;+ left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;+ }++ return { top: top, left: left };+ },++ setOffset: function( elem, options, i ) {+ var position = jQuery.css( elem, "position" );++ // set position first, in-case top/left are set even on static elem+ if ( position === "static" ) {+ elem.style.position = "relative";+ }++ var curElem = jQuery( elem ),+ curOffset = curElem.offset(),+ curCSSTop = jQuery.css( elem, "top" ),+ curCSSLeft = jQuery.css( elem, "left" ),+ calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,+ props = {}, curPosition = {}, curTop, curLeft;++ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed+ if ( calculatePosition ) {+ curPosition = curElem.position();+ curTop = curPosition.top;+ curLeft = curPosition.left;+ } else {+ curTop = parseFloat( curCSSTop ) || 0;+ curLeft = parseFloat( curCSSLeft ) || 0;+ }++ if ( jQuery.isFunction( options ) ) {+ options = options.call( elem, i, curOffset );+ }++ if ( options.top != null ) {+ props.top = ( options.top - curOffset.top ) + curTop;+ }+ if ( options.left != null ) {+ props.left = ( options.left - curOffset.left ) + curLeft;+ }++ if ( "using" in options ) {+ options.using.call( elem, props );+ } else {+ curElem.css( props );+ }+ }+};+++jQuery.fn.extend({++ position: function() {+ if ( !this[0] ) {+ return null;+ }++ var elem = this[0],++ // Get *real* offsetParent+ offsetParent = this.offsetParent(),++ // Get correct offsets+ offset = this.offset(),+ parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();++ // Subtract element margins+ // note: when an element has margin: auto the offsetLeft and marginLeft+ // are the same in Safari causing offset.left to incorrectly be 0+ offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;+ offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;++ // Add offsetParent borders+ parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;+ parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;++ // Subtract the two offsets+ return {+ top: offset.top - parentOffset.top,+ left: offset.left - parentOffset.left+ };+ },++ offsetParent: function() {+ return this.map(function() {+ var offsetParent = this.offsetParent || document.body;+ while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {+ offsetParent = offsetParent.offsetParent;+ }+ return offsetParent;+ });+ }+});+++// Create scrollLeft and scrollTop methods+jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {+ var top = /Y/.test( prop );++ jQuery.fn[ method ] = function( val ) {+ return jQuery.access( this, function( elem, method, val ) {+ var win = getWindow( elem );++ if ( val === undefined ) {+ return win ? (prop in win) ? win[ prop ] :+ jQuery.support.boxModel && win.document.documentElement[ method ] ||+ win.document.body[ method ] :+ elem[ method ];+ }++ if ( win ) {+ win.scrollTo(+ !top ? val : jQuery( win ).scrollLeft(),+ top ? val : jQuery( win ).scrollTop()+ );++ } else {+ elem[ method ] = val;+ }+ }, method, val, arguments.length, null );+ };+});++function getWindow( elem ) {+ return jQuery.isWindow( elem ) ?+ elem :+ elem.nodeType === 9 ?+ elem.defaultView || elem.parentWindow :+ false;+}+++++// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {+ var clientProp = "client" + name,+ scrollProp = "scroll" + name,+ offsetProp = "offset" + name;++ // innerHeight and innerWidth+ jQuery.fn[ "inner" + name ] = function() {+ var elem = this[0];+ return elem ?+ elem.style ?+ parseFloat( jQuery.css( elem, type, "padding" ) ) :+ this[ type ]() :+ null;+ };++ // outerHeight and outerWidth+ jQuery.fn[ "outer" + name ] = function( margin ) {+ var elem = this[0];+ return elem ?+ elem.style ?+ parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :+ this[ type ]() :+ null;+ };++ jQuery.fn[ type ] = function( value ) {+ return jQuery.access( this, function( elem, type, value ) {+ var doc, docElemProp, orig, ret;++ if ( jQuery.isWindow( elem ) ) {+ // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat+ doc = elem.document;+ docElemProp = doc.documentElement[ clientProp ];+ return jQuery.support.boxModel && docElemProp ||+ doc.body && doc.body[ clientProp ] || docElemProp;+ }++ // Get document width or height+ if ( elem.nodeType === 9 ) {+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater+ doc = elem.documentElement;++ // when a window > document, IE6 reports a offset[Width/Height] > client[Width/Height]+ // so we can't use max, as it'll choose the incorrect offset[Width/Height]+ // instead we use the correct client[Width/Height]+ // support:IE6+ if ( doc[ clientProp ] >= doc[ scrollProp ] ) {+ return doc[ clientProp ];+ }++ return Math.max(+ elem.body[ scrollProp ], doc[ scrollProp ],+ elem.body[ offsetProp ], doc[ offsetProp ]+ );+ }++ // Get width or height on the element+ if ( value === undefined ) {+ orig = jQuery.css( elem, type );+ ret = parseFloat( orig );+ return jQuery.isNumeric( ret ) ? ret : orig;+ }++ // Set the width or height on the element+ jQuery( elem ).css( type, value );+ }, type, value, arguments.length, null );+ };+});+++++// Expose jQuery to the global object+window.jQuery = window.$ = jQuery;++// Expose jQuery as an AMD module, but only for AMD loaders that+// understand the issues with loading multiple versions of jQuery+// in a page that all might call define(). The loader will indicate+// they have special allowances for multiple jQuery versions by+// specifying define.amd.jQuery = true. Register as a named module,+// since jQuery can be concatenated with other files that may use define,+// but not use a proper concatenation script that understands anonymous+// AMD modules. A named AMD is safest and most robust way to register.+// Lowercase jquery is used because AMD module names are derived from+// file names, and jQuery is normally delivered in a lowercase file name.+// Do this after creating the global so that if an AMD module wants to call+// noConflict to hide this version of jQuery, it will work.+if ( typeof define === "function" && define.amd && define.amd.jQuery ) {+ define( "jquery", [], function () { return jQuery; } );+}++++})( window );
+ example/static/screen.css view
@@ -0,0 +1,42 @@+html {+ padding: 0;+ margin: 0;+ background-color: #dcdccc;+ font-family: Verdana, Helvetica, sans-serif;+ color: #3f3f3f;+}+body {+ padding: 0;+ margin: 0;+}+a {+ color: #5c888b;+ text-decoration: underline;+}+a :hover {+ cursor: pointer;+ text-decoration: underline;+}+img {+ border: none;+}+#content {+ padding-left: 1em;+}++#formContainer {+ display: none;+ padding:1em;+ width:500px;+ border:1px solid #bcbccc;+}++#formContainer label, #formContainer input {+ display: block;+}++.status { display: none; padding: 1em; margin-top: 1em; }+.status.error { background-color: #bc8383; }+.status.notice { background-color: #7f9f7f; }++#loginStatus.status { width: 500px; }
+ example/static/underscore.js view
@@ -0,0 +1,1059 @@+// Underscore.js 1.3.3+// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.+// Underscore may be freely distributed under the MIT license.+// Portions of Underscore are inspired or borrowed from Prototype,+// Oliver Steele's Functional, and John Resig's Micro-Templating.+// For all details and documentation:+// http://documentcloud.github.com/underscore++(function() {++ // Baseline setup+ // --------------++ // Establish the root object, `window` in the browser, or `global` on the server.+ var root = this;++ // Save the previous value of the `_` variable.+ var previousUnderscore = root._;++ // Establish the object that gets returned to break out of a loop iteration.+ var breaker = {};++ // Save bytes in the minified (but not gzipped) version:+ var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;++ // Create quick reference variables for speed access to core prototypes.+ var slice = ArrayProto.slice,+ unshift = ArrayProto.unshift,+ toString = ObjProto.toString,+ hasOwnProperty = ObjProto.hasOwnProperty;++ // All **ECMAScript 5** native function implementations that we hope to use+ // are declared here.+ var+ nativeForEach = ArrayProto.forEach,+ nativeMap = ArrayProto.map,+ nativeReduce = ArrayProto.reduce,+ nativeReduceRight = ArrayProto.reduceRight,+ nativeFilter = ArrayProto.filter,+ nativeEvery = ArrayProto.every,+ nativeSome = ArrayProto.some,+ nativeIndexOf = ArrayProto.indexOf,+ nativeLastIndexOf = ArrayProto.lastIndexOf,+ nativeIsArray = Array.isArray,+ nativeKeys = Object.keys,+ nativeBind = FuncProto.bind;++ // Create a safe reference to the Underscore object for use below.+ var _ = function(obj) { return new wrapper(obj); };++ // Export the Underscore object for **Node.js**, with+ // backwards-compatibility for the old `require()` API. If we're in+ // the browser, add `_` as a global object via a string identifier,+ // for Closure Compiler "advanced" mode.+ if (typeof exports !== 'undefined') {+ if (typeof module !== 'undefined' && module.exports) {+ exports = module.exports = _;+ }+ exports._ = _;+ } else {+ root['_'] = _;+ }++ // Current version.+ _.VERSION = '1.3.3';++ // Collection Functions+ // --------------------++ // The cornerstone, an `each` implementation, aka `forEach`.+ // Handles objects with the built-in `forEach`, arrays, and raw objects.+ // Delegates to **ECMAScript 5**'s native `forEach` if available.+ var each = _.each = _.forEach = function(obj, iterator, context) {+ if (obj == null) return;+ if (nativeForEach && obj.forEach === nativeForEach) {+ obj.forEach(iterator, context);+ } else if (obj.length === +obj.length) {+ for (var i = 0, l = obj.length; i < l; i++) {+ if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;+ }+ } else {+ for (var key in obj) {+ if (_.has(obj, key)) {+ if (iterator.call(context, obj[key], key, obj) === breaker) return;+ }+ }+ }+ };++ // Return the results of applying the iterator to each element.+ // Delegates to **ECMAScript 5**'s native `map` if available.+ _.map = _.collect = function(obj, iterator, context) {+ var results = [];+ if (obj == null) return results;+ if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);+ each(obj, function(value, index, list) {+ results[results.length] = iterator.call(context, value, index, list);+ });+ if (obj.length === +obj.length) results.length = obj.length;+ return results;+ };++ // **Reduce** builds up a single result from a list of values, aka `inject`,+ // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.+ _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {+ var initial = arguments.length > 2;+ if (obj == null) obj = [];+ if (nativeReduce && obj.reduce === nativeReduce) {+ if (context) iterator = _.bind(iterator, context);+ return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);+ }+ each(obj, function(value, index, list) {+ if (!initial) {+ memo = value;+ initial = true;+ } else {+ memo = iterator.call(context, memo, value, index, list);+ }+ });+ if (!initial) throw new TypeError('Reduce of empty array with no initial value');+ return memo;+ };++ // The right-associative version of reduce, also known as `foldr`.+ // Delegates to **ECMAScript 5**'s native `reduceRight` if available.+ _.reduceRight = _.foldr = function(obj, iterator, memo, context) {+ var initial = arguments.length > 2;+ if (obj == null) obj = [];+ if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {+ if (context) iterator = _.bind(iterator, context);+ return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);+ }+ var reversed = _.toArray(obj).reverse();+ if (context && !initial) iterator = _.bind(iterator, context);+ return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);+ };++ // Return the first value which passes a truth test. Aliased as `detect`.+ _.find = _.detect = function(obj, iterator, context) {+ var result;+ any(obj, function(value, index, list) {+ if (iterator.call(context, value, index, list)) {+ result = value;+ return true;+ }+ });+ return result;+ };++ // Return all the elements that pass a truth test.+ // Delegates to **ECMAScript 5**'s native `filter` if available.+ // Aliased as `select`.+ _.filter = _.select = function(obj, iterator, context) {+ var results = [];+ if (obj == null) return results;+ if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);+ each(obj, function(value, index, list) {+ if (iterator.call(context, value, index, list)) results[results.length] = value;+ });+ return results;+ };++ // Return all the elements for which a truth test fails.+ _.reject = function(obj, iterator, context) {+ var results = [];+ if (obj == null) return results;+ each(obj, function(value, index, list) {+ if (!iterator.call(context, value, index, list)) results[results.length] = value;+ });+ return results;+ };++ // Determine whether all of the elements match a truth test.+ // Delegates to **ECMAScript 5**'s native `every` if available.+ // Aliased as `all`.+ _.every = _.all = function(obj, iterator, context) {+ var result = true;+ if (obj == null) return result;+ if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);+ each(obj, function(value, index, list) {+ if (!(result = result && iterator.call(context, value, index, list))) return breaker;+ });+ return !!result;+ };++ // Determine if at least one element in the object matches a truth test.+ // Delegates to **ECMAScript 5**'s native `some` if available.+ // Aliased as `any`.+ var any = _.some = _.any = function(obj, iterator, context) {+ iterator || (iterator = _.identity);+ var result = false;+ if (obj == null) return result;+ if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);+ each(obj, function(value, index, list) {+ if (result || (result = iterator.call(context, value, index, list))) return breaker;+ });+ return !!result;+ };++ // Determine if a given value is included in the array or object using `===`.+ // Aliased as `contains`.+ _.include = _.contains = function(obj, target) {+ var found = false;+ if (obj == null) return found;+ if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;+ found = any(obj, function(value) {+ return value === target;+ });+ return found;+ };++ // Invoke a method (with arguments) on every item in a collection.+ _.invoke = function(obj, method) {+ var args = slice.call(arguments, 2);+ return _.map(obj, function(value) {+ return (_.isFunction(method) ? method || value : value[method]).apply(value, args);+ });+ };++ // Convenience version of a common use case of `map`: fetching a property.+ _.pluck = function(obj, key) {+ return _.map(obj, function(value){ return value[key]; });+ };++ // Return the maximum element or (element-based computation).+ _.max = function(obj, iterator, context) {+ if (!iterator && _.isArray(obj) && obj[0] === +obj[0]) return Math.max.apply(Math, obj);+ if (!iterator && _.isEmpty(obj)) return -Infinity;+ var result = {computed : -Infinity};+ each(obj, function(value, index, list) {+ var computed = iterator ? iterator.call(context, value, index, list) : value;+ computed >= result.computed && (result = {value : value, computed : computed});+ });+ return result.value;+ };++ // Return the minimum element (or element-based computation).+ _.min = function(obj, iterator, context) {+ if (!iterator && _.isArray(obj) && obj[0] === +obj[0]) return Math.min.apply(Math, obj);+ if (!iterator && _.isEmpty(obj)) return Infinity;+ var result = {computed : Infinity};+ each(obj, function(value, index, list) {+ var computed = iterator ? iterator.call(context, value, index, list) : value;+ computed < result.computed && (result = {value : value, computed : computed});+ });+ return result.value;+ };++ // Shuffle an array.+ _.shuffle = function(obj) {+ var shuffled = [], rand;+ each(obj, function(value, index, list) {+ rand = Math.floor(Math.random() * (index + 1));+ shuffled[index] = shuffled[rand];+ shuffled[rand] = value;+ });+ return shuffled;+ };++ // Sort the object's values by a criterion produced by an iterator.+ _.sortBy = function(obj, val, context) {+ var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };+ return _.pluck(_.map(obj, function(value, index, list) {+ return {+ value : value,+ criteria : iterator.call(context, value, index, list)+ };+ }).sort(function(left, right) {+ var a = left.criteria, b = right.criteria;+ if (a === void 0) return 1;+ if (b === void 0) return -1;+ return a < b ? -1 : a > b ? 1 : 0;+ }), 'value');+ };++ // Groups the object's values by a criterion. Pass either a string attribute+ // to group by, or a function that returns the criterion.+ _.groupBy = function(obj, val) {+ var result = {};+ var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };+ each(obj, function(value, index) {+ var key = iterator(value, index);+ (result[key] || (result[key] = [])).push(value);+ });+ return result;+ };++ // Use a comparator function to figure out at what index an object should+ // be inserted so as to maintain order. Uses binary search.+ _.sortedIndex = function(array, obj, iterator) {+ iterator || (iterator = _.identity);+ var low = 0, high = array.length;+ while (low < high) {+ var mid = (low + high) >> 1;+ iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;+ }+ return low;+ };++ // Safely convert anything iterable into a real, live array.+ _.toArray = function(obj) {+ if (!obj) return [];+ if (_.isArray(obj)) return slice.call(obj);+ if (_.isArguments(obj)) return slice.call(obj);+ if (obj.toArray && _.isFunction(obj.toArray)) return obj.toArray();+ return _.values(obj);+ };++ // Return the number of elements in an object.+ _.size = function(obj) {+ return _.isArray(obj) ? obj.length : _.keys(obj).length;+ };++ // Array Functions+ // ---------------++ // Get the first element of an array. Passing **n** will return the first N+ // values in the array. Aliased as `head` and `take`. The **guard** check+ // allows it to work with `_.map`.+ _.first = _.head = _.take = function(array, n, guard) {+ return (n != null) && !guard ? slice.call(array, 0, n) : array[0];+ };++ // Returns everything but the last entry of the array. Especcialy useful on+ // the arguments object. Passing **n** will return all the values in+ // the array, excluding the last N. The **guard** check allows it to work with+ // `_.map`.+ _.initial = function(array, n, guard) {+ return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));+ };++ // Get the last element of an array. Passing **n** will return the last N+ // values in the array. The **guard** check allows it to work with `_.map`.+ _.last = function(array, n, guard) {+ if ((n != null) && !guard) {+ return slice.call(array, Math.max(array.length - n, 0));+ } else {+ return array[array.length - 1];+ }+ };++ // Returns everything but the first entry of the array. Aliased as `tail`.+ // Especially useful on the arguments object. Passing an **index** will return+ // the rest of the values in the array from that index onward. The **guard**+ // check allows it to work with `_.map`.+ _.rest = _.tail = function(array, index, guard) {+ return slice.call(array, (index == null) || guard ? 1 : index);+ };++ // Trim out all falsy values from an array.+ _.compact = function(array) {+ return _.filter(array, function(value){ return !!value; });+ };++ // Return a completely flattened version of an array.+ _.flatten = function(array, shallow) {+ return _.reduce(array, function(memo, value) {+ if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));+ memo[memo.length] = value;+ return memo;+ }, []);+ };++ // Return a version of the array that does not contain the specified value(s).+ _.without = function(array) {+ return _.difference(array, slice.call(arguments, 1));+ };++ // Produce a duplicate-free version of the array. If the array has already+ // been sorted, you have the option of using a faster algorithm.+ // Aliased as `unique`.+ _.uniq = _.unique = function(array, isSorted, iterator) {+ var initial = iterator ? _.map(array, iterator) : array;+ var results = [];+ // The `isSorted` flag is irrelevant if the array only contains two elements.+ if (array.length < 3) isSorted = true;+ _.reduce(initial, function (memo, value, index) {+ if (isSorted ? _.last(memo) !== value || !memo.length : !_.include(memo, value)) {+ memo.push(value);+ results.push(array[index]);+ }+ return memo;+ }, []);+ return results;+ };++ // Produce an array that contains the union: each distinct element from all of+ // the passed-in arrays.+ _.union = function() {+ return _.uniq(_.flatten(arguments, true));+ };++ // Produce an array that contains every item shared between all the+ // passed-in arrays. (Aliased as "intersect" for back-compat.)+ _.intersection = _.intersect = function(array) {+ var rest = slice.call(arguments, 1);+ return _.filter(_.uniq(array), function(item) {+ return _.every(rest, function(other) {+ return _.indexOf(other, item) >= 0;+ });+ });+ };++ // Take the difference between one array and a number of other arrays.+ // Only the elements present in just the first array will remain.+ _.difference = function(array) {+ var rest = _.flatten(slice.call(arguments, 1), true);+ return _.filter(array, function(value){ return !_.include(rest, value); });+ };++ // Zip together multiple lists into a single array -- elements that share+ // an index go together.+ _.zip = function() {+ var args = slice.call(arguments);+ var length = _.max(_.pluck(args, 'length'));+ var results = new Array(length);+ for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);+ return results;+ };++ // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),+ // we need this function. Return the position of the first occurrence of an+ // item in an array, or -1 if the item is not included in the array.+ // Delegates to **ECMAScript 5**'s native `indexOf` if available.+ // If the array is large and already in sort order, pass `true`+ // for **isSorted** to use binary search.+ _.indexOf = function(array, item, isSorted) {+ if (array == null) return -1;+ var i, l;+ if (isSorted) {+ i = _.sortedIndex(array, item);+ return array[i] === item ? i : -1;+ }+ if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);+ for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;+ return -1;+ };++ // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.+ _.lastIndexOf = function(array, item) {+ if (array == null) return -1;+ if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);+ var i = array.length;+ while (i--) if (i in array && array[i] === item) return i;+ return -1;+ };++ // Generate an integer Array containing an arithmetic progression. A port of+ // the native Python `range()` function. See+ // [the Python documentation](http://docs.python.org/library/functions.html#range).+ _.range = function(start, stop, step) {+ if (arguments.length <= 1) {+ stop = start || 0;+ start = 0;+ }+ step = arguments[2] || 1;++ var len = Math.max(Math.ceil((stop - start) / step), 0);+ var idx = 0;+ var range = new Array(len);++ while(idx < len) {+ range[idx++] = start;+ start += step;+ }++ return range;+ };++ // Function (ahem) Functions+ // ------------------++ // Reusable constructor function for prototype setting.+ var ctor = function(){};++ // Create a function bound to a given object (assigning `this`, and arguments,+ // optionally). Binding with arguments is also known as `curry`.+ // Delegates to **ECMAScript 5**'s native `Function.bind` if available.+ // We check for `func.bind` first, to fail fast when `func` is undefined.+ _.bind = function bind(func, context) {+ var bound, args;+ if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));+ if (!_.isFunction(func)) throw new TypeError;+ args = slice.call(arguments, 2);+ return bound = function() {+ if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));+ ctor.prototype = func.prototype;+ var self = new ctor;+ var result = func.apply(self, args.concat(slice.call(arguments)));+ if (Object(result) === result) return result;+ return self;+ };+ };++ // Bind all of an object's methods to that object. Useful for ensuring that+ // all callbacks defined on an object belong to it.+ _.bindAll = function(obj) {+ var funcs = slice.call(arguments, 1);+ if (funcs.length == 0) funcs = _.functions(obj);+ each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });+ return obj;+ };++ // Memoize an expensive function by storing its results.+ _.memoize = function(func, hasher) {+ var memo = {};+ hasher || (hasher = _.identity);+ return function() {+ var key = hasher.apply(this, arguments);+ return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));+ };+ };++ // Delays a function for the given number of milliseconds, and then calls+ // it with the arguments supplied.+ _.delay = function(func, wait) {+ var args = slice.call(arguments, 2);+ return setTimeout(function(){ return func.apply(null, args); }, wait);+ };++ // Defers a function, scheduling it to run after the current call stack has+ // cleared.+ _.defer = function(func) {+ return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));+ };++ // Returns a function, that, when invoked, will only be triggered at most once+ // during a given window of time.+ _.throttle = function(func, wait) {+ var context, args, timeout, throttling, more, result;+ var whenDone = _.debounce(function(){ more = throttling = false; }, wait);+ return function() {+ context = this; args = arguments;+ var later = function() {+ timeout = null;+ if (more) func.apply(context, args);+ whenDone();+ };+ if (!timeout) timeout = setTimeout(later, wait);+ if (throttling) {+ more = true;+ } else {+ result = func.apply(context, args);+ }+ whenDone();+ throttling = true;+ return result;+ };+ };++ // Returns a function, that, as long as it continues to be invoked, will not+ // be triggered. The function will be called after it stops being called for+ // N milliseconds. If `immediate` is passed, trigger the function on the+ // leading edge, instead of the trailing.+ _.debounce = function(func, wait, immediate) {+ var timeout;+ return function() {+ var context = this, args = arguments;+ var later = function() {+ timeout = null;+ if (!immediate) func.apply(context, args);+ };+ if (immediate && !timeout) func.apply(context, args);+ clearTimeout(timeout);+ timeout = setTimeout(later, wait);+ };+ };++ // Returns a function that will be executed at most one time, no matter how+ // often you call it. Useful for lazy initialization.+ _.once = function(func) {+ var ran = false, memo;+ return function() {+ if (ran) return memo;+ ran = true;+ return memo = func.apply(this, arguments);+ };+ };++ // Returns the first function passed as an argument to the second,+ // allowing you to adjust arguments, run code before and after, and+ // conditionally execute the original function.+ _.wrap = function(func, wrapper) {+ return function() {+ var args = [func].concat(slice.call(arguments, 0));+ return wrapper.apply(this, args);+ };+ };++ // Returns a function that is the composition of a list of functions, each+ // consuming the return value of the function that follows.+ _.compose = function() {+ var funcs = arguments;+ return function() {+ var args = arguments;+ for (var i = funcs.length - 1; i >= 0; i--) {+ args = [funcs[i].apply(this, args)];+ }+ return args[0];+ };+ };++ // Returns a function that will only be executed after being called N times.+ _.after = function(times, func) {+ if (times <= 0) return func();+ return function() {+ if (--times < 1) { return func.apply(this, arguments); }+ };+ };++ // Object Functions+ // ----------------++ // Retrieve the names of an object's properties.+ // Delegates to **ECMAScript 5**'s native `Object.keys`+ _.keys = nativeKeys || function(obj) {+ if (obj !== Object(obj)) throw new TypeError('Invalid object');+ var keys = [];+ for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;+ return keys;+ };++ // Retrieve the values of an object's properties.+ _.values = function(obj) {+ return _.map(obj, _.identity);+ };++ // Return a sorted list of the function names available on the object.+ // Aliased as `methods`+ _.functions = _.methods = function(obj) {+ var names = [];+ for (var key in obj) {+ if (_.isFunction(obj[key])) names.push(key);+ }+ return names.sort();+ };++ // Extend a given object with all the properties in passed-in object(s).+ _.extend = function(obj) {+ each(slice.call(arguments, 1), function(source) {+ for (var prop in source) {+ obj[prop] = source[prop];+ }+ });+ return obj;+ };++ // Return a copy of the object only containing the whitelisted properties.+ _.pick = function(obj) {+ var result = {};+ each(_.flatten(slice.call(arguments, 1)), function(key) {+ if (key in obj) result[key] = obj[key];+ });+ return result;+ };++ // Fill in a given object with default properties.+ _.defaults = function(obj) {+ each(slice.call(arguments, 1), function(source) {+ for (var prop in source) {+ if (obj[prop] == null) obj[prop] = source[prop];+ }+ });+ return obj;+ };++ // Create a (shallow-cloned) duplicate of an object.+ _.clone = function(obj) {+ if (!_.isObject(obj)) return obj;+ return _.isArray(obj) ? obj.slice() : _.extend({}, obj);+ };++ // Invokes interceptor with the obj, and then returns obj.+ // The primary purpose of this method is to "tap into" a method chain, in+ // order to perform operations on intermediate results within the chain.+ _.tap = function(obj, interceptor) {+ interceptor(obj);+ return obj;+ };++ // Internal recursive comparison function.+ function eq(a, b, stack) {+ // Identical objects are equal. `0 === -0`, but they aren't identical.+ // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.+ if (a === b) return a !== 0 || 1 / a == 1 / b;+ // A strict comparison is necessary because `null == undefined`.+ if (a == null || b == null) return a === b;+ // Unwrap any wrapped objects.+ if (a._chain) a = a._wrapped;+ if (b._chain) b = b._wrapped;+ // Invoke a custom `isEqual` method if one is provided.+ if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);+ if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);+ // Compare `[[Class]]` names.+ var className = toString.call(a);+ if (className != toString.call(b)) return false;+ switch (className) {+ // Strings, numbers, dates, and booleans are compared by value.+ case '[object String]':+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is+ // equivalent to `new String("5")`.+ return a == String(b);+ case '[object Number]':+ // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for+ // other numeric values.+ return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);+ case '[object Date]':+ case '[object Boolean]':+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their+ // millisecond representations. Note that invalid dates with millisecond representations+ // of `NaN` are not equivalent.+ return +a == +b;+ // RegExps are compared by their source patterns and flags.+ case '[object RegExp]':+ return a.source == b.source &&+ a.global == b.global &&+ a.multiline == b.multiline &&+ a.ignoreCase == b.ignoreCase;+ }+ if (typeof a != 'object' || typeof b != 'object') return false;+ // Assume equality for cyclic structures. The algorithm for detecting cyclic+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.+ var length = stack.length;+ while (length--) {+ // Linear search. Performance is inversely proportional to the number of+ // unique nested structures.+ if (stack[length] == a) return true;+ }+ // Add the first object to the stack of traversed objects.+ stack.push(a);+ var size = 0, result = true;+ // Recursively compare objects and arrays.+ if (className == '[object Array]') {+ // Compare array lengths to determine if a deep comparison is necessary.+ size = a.length;+ result = size == b.length;+ if (result) {+ // Deep compare the contents, ignoring non-numeric properties.+ while (size--) {+ // Ensure commutative equality for sparse arrays.+ if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;+ }+ }+ } else {+ // Objects with different constructors are not equivalent.+ if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;+ // Deep compare objects.+ for (var key in a) {+ if (_.has(a, key)) {+ // Count the expected number of properties.+ size++;+ // Deep compare each member.+ if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;+ }+ }+ // Ensure that both objects contain the same number of properties.+ if (result) {+ for (key in b) {+ if (_.has(b, key) && !(size--)) break;+ }+ result = !size;+ }+ }+ // Remove the first object from the stack of traversed objects.+ stack.pop();+ return result;+ }++ // Perform a deep comparison to check if two objects are equal.+ _.isEqual = function(a, b) {+ return eq(a, b, []);+ };++ // Is a given array, string, or object empty?+ // An "empty" object has no enumerable own-properties.+ _.isEmpty = function(obj) {+ if (obj == null) return true;+ if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;+ for (var key in obj) if (_.has(obj, key)) return false;+ return true;+ };++ // Is a given value a DOM element?+ _.isElement = function(obj) {+ return !!(obj && obj.nodeType == 1);+ };++ // Is a given value an array?+ // Delegates to ECMA5's native Array.isArray+ _.isArray = nativeIsArray || function(obj) {+ return toString.call(obj) == '[object Array]';+ };++ // Is a given variable an object?+ _.isObject = function(obj) {+ return obj === Object(obj);+ };++ // Is a given variable an arguments object?+ _.isArguments = function(obj) {+ return toString.call(obj) == '[object Arguments]';+ };+ if (!_.isArguments(arguments)) {+ _.isArguments = function(obj) {+ return !!(obj && _.has(obj, 'callee'));+ };+ }++ // Is a given value a function?+ _.isFunction = function(obj) {+ return toString.call(obj) == '[object Function]';+ };++ // Is a given value a string?+ _.isString = function(obj) {+ return toString.call(obj) == '[object String]';+ };++ // Is a given value a number?+ _.isNumber = function(obj) {+ return toString.call(obj) == '[object Number]';+ };++ // Is a given object a finite number?+ _.isFinite = function(obj) {+ return _.isNumber(obj) && isFinite(obj);+ };++ // Is the given value `NaN`?+ _.isNaN = function(obj) {+ // `NaN` is the only value for which `===` is not reflexive.+ return obj !== obj;+ };++ // Is a given value a boolean?+ _.isBoolean = function(obj) {+ return obj === true || obj === false || toString.call(obj) == '[object Boolean]';+ };++ // Is a given value a date?+ _.isDate = function(obj) {+ return toString.call(obj) == '[object Date]';+ };++ // Is the given value a regular expression?+ _.isRegExp = function(obj) {+ return toString.call(obj) == '[object RegExp]';+ };++ // Is a given value equal to null?+ _.isNull = function(obj) {+ return obj === null;+ };++ // Is a given variable undefined?+ _.isUndefined = function(obj) {+ return obj === void 0;+ };++ // Has own property?+ _.has = function(obj, key) {+ return hasOwnProperty.call(obj, key);+ };++ // Utility Functions+ // -----------------++ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its+ // previous owner. Returns a reference to the Underscore object.+ _.noConflict = function() {+ root._ = previousUnderscore;+ return this;+ };++ // Keep the identity function around for default iterators.+ _.identity = function(value) {+ return value;+ };++ // Run a function **n** times.+ _.times = function (n, iterator, context) {+ for (var i = 0; i < n; i++) iterator.call(context, i);+ };++ // Escape a string for HTML interpolation.+ _.escape = function(string) {+ return (''+string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/');+ };++ // If the value of the named property is a function then invoke it;+ // otherwise, return it.+ _.result = function(object, property) {+ if (object == null) return null;+ var value = object[property];+ return _.isFunction(value) ? value.call(object) : value;+ };++ // Add your own custom functions to the Underscore object, ensuring that+ // they're correctly added to the OOP wrapper as well.+ _.mixin = function(obj) {+ each(_.functions(obj), function(name){+ addToWrapper(name, _[name] = obj[name]);+ });+ };++ // Generate a unique integer id (unique within the entire client session).+ // Useful for temporary DOM ids.+ var idCounter = 0;+ _.uniqueId = function(prefix) {+ var id = idCounter++;+ return prefix ? prefix + id : id;+ };++ // By default, Underscore uses ERB-style template delimiters, change the+ // following template settings to use alternative delimiters.+ _.templateSettings = {+ evaluate : /<%([\s\S]+?)%>/g,+ interpolate : /<%=([\s\S]+?)%>/g,+ escape : /<%-([\s\S]+?)%>/g+ };++ // When customizing `templateSettings`, if you don't want to define an+ // interpolation, evaluation or escaping regex, we need one that is+ // guaranteed not to match.+ var noMatch = /.^/;++ // Certain characters need to be escaped so that they can be put into a+ // string literal.+ var escapes = {+ '\\': '\\',+ "'": "'",+ 'r': '\r',+ 'n': '\n',+ 't': '\t',+ 'u2028': '\u2028',+ 'u2029': '\u2029'+ };++ for (var p in escapes) escapes[escapes[p]] = p;+ var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;+ var unescaper = /\\(\\|'|r|n|t|u2028|u2029)/g;++ // Within an interpolation, evaluation, or escaping, remove HTML escaping+ // that had been previously added.+ var unescape = function(code) {+ return code.replace(unescaper, function(match, escape) {+ return escapes[escape];+ });+ };++ // JavaScript micro-templating, similar to John Resig's implementation.+ // Underscore templating handles arbitrary delimiters, preserves whitespace,+ // and correctly escapes quotes within interpolated code.+ _.template = function(text, data, settings) {+ settings = _.defaults(settings || {}, _.templateSettings);++ // Compile the template source, taking care to escape characters that+ // cannot be included in a string literal and then unescape them in code+ // blocks.+ var source = "__p+='" + text+ .replace(escaper, function(match) {+ return '\\' + escapes[match];+ })+ .replace(settings.escape || noMatch, function(match, code) {+ return "'+\n_.escape(" + unescape(code) + ")+\n'";+ })+ .replace(settings.interpolate || noMatch, function(match, code) {+ return "'+\n(" + unescape(code) + ")+\n'";+ })+ .replace(settings.evaluate || noMatch, function(match, code) {+ return "';\n" + unescape(code) + "\n;__p+='";+ }) + "';\n";++ // If a variable is not specified, place data values in local scope.+ if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';++ source = "var __p='';" ++ "var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n" ++ source + "return __p;\n";++ var render = new Function(settings.variable || 'obj', '_', source);+ if (data) return render(data, _);+ var template = function(data) {+ return render.call(this, data, _);+ };++ // Provide the compiled function source as a convenience for build time+ // precompilation.+ template.source = 'function(' + (settings.variable || 'obj') + '){\n' ++ source + '}';++ return template;+ };++ // Add a "chain" function, which will delegate to the wrapper.+ _.chain = function(obj) {+ return _(obj).chain();+ };++ // The OOP Wrapper+ // ---------------++ // If Underscore is called as a function, it returns a wrapped object that+ // can be used OO-style. This wrapper holds altered versions of all the+ // underscore functions. Wrapped objects may be chained.+ var wrapper = function(obj) { this._wrapped = obj; };++ // Expose `wrapper.prototype` as `_.prototype`+ _.prototype = wrapper.prototype;++ // Helper function to continue chaining intermediate results.+ var result = function(obj, chain) {+ return chain ? _(obj).chain() : obj;+ };++ // A method to easily add functions to the OOP wrapper.+ var addToWrapper = function(name, func) {+ wrapper.prototype[name] = function() {+ var args = slice.call(arguments);+ unshift.call(args, this._wrapped);+ return result(func.apply(_, args), this._chain);+ };+ };++ // Add all of the Underscore functions to the wrapper object.+ _.mixin(_);++ // Add all mutator Array functions to the wrapper.+ each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {+ var method = ArrayProto[name];+ wrapper.prototype[name] = function() {+ var wrapped = this._wrapped;+ method.apply(wrapped, arguments);+ var length = wrapped.length;+ if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];+ return result(wrapped, this._chain);+ };+ });++ // Add all accessor Array functions to the wrapper.+ each(['concat', 'join', 'slice'], function(name) {+ var method = ArrayProto[name];+ wrapper.prototype[name] = function() {+ return result(method.apply(this._wrapped, arguments), this._chain);+ };+ });++ // Start chaining a wrapped Underscore object.+ wrapper.prototype.chain = function() {+ this._chain = true;+ return this;+ };++ // Extracts the result from a wrapped and chained object.+ wrapper.prototype.value = function() {+ return this._wrapped;+ };++}).call(this);
snaplet-fay.cabal view
@@ -5,28 +5,28 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.3.1.0+version: 0.3.1.1 synopsis: Fay integration for Snap with request- and pre-compilation. description: Fay integration for Snap with request based compilation during development and precompilation in production.- For more information, please see <https://github.com/faylang/snaplet-fay>.+ For more information, please see <https://github.com/bergmark/snaplet-fay>. license: BSD3 license-file: LICENSE author: Adam Bergmark maintainer: adam@edea.se-homepage: https://github.com/faylang/snaplet-fay-bug-reports: https://github.com/faylang/snaplet-fay/issues-category: Web, Snap+homepage: https://github.com/bergmark/snaplet-fay+bug-reports: https://github.com/bergmark/snaplet-fay/issues+category: Web, Snap, Fay build-type: Simple cabal-version: >=1.8 -extra-source-files: LICENSE+extra-source-files: LICENSE, README.md example/example.cabal example/snaplets/fay/devel.cfg example/snaplets/fay/js/.gitignore example/snaplets/fay/src/Application/SharedTypes.hs example/snaplets/fay/src/BrokenFile.hs example/snaplets/fay/src/Dom.hs example/snaplets/fay/src/Index.hs example/snaplets/heist/templates/index.tpl example/snaplets/heist/templates/login-form.tpl example/snaplets/heist/templates/register-form.tpl example/log/.gitignore example/src/Application.hs example/src/Main.hs example/src/Site.hs example/static/broken.html example/static/index.js example/static/jquery.js example/static/screen.css example/static/underscore.js data-files: resources/devel.cfg source-repository head type: git- location: https://github.com/faylang/snaplet-fay.git+ location: https://github.com/bergmark/snaplet-fay.git library ghc-options: -Wall@@ -39,13 +39,13 @@ Snap.Snaplet.Fay.Internal, Paths_snaplet_fay build-depends:- base == 4.*+ base >= 4 && < 5 , aeson >= 0.6 , bytestring >= 0.9 , configurator >= 0.2 , data-default >= 0.5 , directory >= 1.1- , fay >= 0.14.1+ , fay >= 0.14.2.0 , filepath >= 1.3 , mtl >= 2.1 , snap >= 0.11.1
src/Snap/Snaplet/Fay/Internal.hs view
@@ -52,14 +52,7 @@ putStrLn $ "snaplet-fay: Could not find: " ++ hsRelativePath f return NotFound else do- print config- putStrLn ""- let cfg' = F.addConfigPackages (packages config) $ F.addConfigDirectoryIncludePaths (includeDirs config) $ def { F.configPrettyPrint = prettyPrint config }- print cfg'- putStrLn "" f' <- canonicalizePath f- print f'- putStrLn "" res <- flip F.compileFile f' $ F.addConfigPackages (packages config) $ F.addConfigDirectoryIncludePaths (includeDirs config) $ def { F.configPrettyPrint = prettyPrint config