Updated with smarter commentary and better code.

This commit is contained in:
Ken Sternberg 2011-02-03 19:15:16 -08:00
parent ab8aa78c7c
commit e448dd503e
7 changed files with 8962 additions and 770 deletions

58
Makefile Normal file
View File

@ -0,0 +1,58 @@
.SUFFIXES: .nw .js .pdf .html .tex
NOTANGLE= notangle
NOWEAVE= noweave
ECHO= /bin/echo
all: index.html store.js
.nw.html:
$(NOWEAVE) -filter l2h -delay -x -index -autodefs c -html $*.nw > $*.html
.nw.tex:
$(NOWEAVE) -x -delay $*.nw > $*.tex #$
.tex.pdf:
xelatex $*.tex; \
while grep -s 'Rerun to get cross-references right' $*.log; \
do \
xelatex *$.tex; \
done
.nw.js:
@ $(ECHO) $(NOTANGLE) -c -R$@ $<
@ - $(NOTANGLE) -c -R$@ $< > $*.nw-js-tmp
@ if [ -s "$*.nw-js-tmp" ]; then \
mv $*.nw-js-tmp $@; \
else \
echo "$@ not found in $<"; \
rm $*.nw-js-tmp; \
fi
store.js: backbonestore.nw
@ $(ECHO) $(NOTANGLE) -c -R$@ $<
@ - $(NOTANGLE) -c -R$@ $< > $*.nw-html-tmp
@ if [ -s "$*.nw-html-tmp" ]; then \
mv $*.nw-html-tmp $@; \
else \
echo "$@ not found in $<"; \
rm $*.nw-tmp; \
fi
index.html:
@ $(ECHO) $(NOTANGLE) -c -R$@ $<
@ - $(NOTANGLE) -c -R$@ $< > $*.nw-html-tmp
@ if [ -s "$*.nw-html-tmp" ]; then \
mv $*.nw-html-tmp $@; \
else \
echo "$@ not found in $<"; \
rm $*.nw-tmp; \
fi
clean:
- rm -f *.tex *.dvi *.aux *.toc *.log *.out *.html *.js
realclean: clean
- rm -f *.pdf

View File

@ -1,4 +1,4 @@
// Backbone.js 0.3.2 // Backbone.js 0.3.3
// (c) 2010 Jeremy Ashkenas, DocumentCloud Inc. // (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
// Backbone may be freely distributed under the MIT license. // Backbone may be freely distributed under the MIT license.
// For all details and documentation: // For all details and documentation:
@ -19,14 +19,14 @@
} }
// Current version of the library. Keep in sync with `package.json`. // Current version of the library. Keep in sync with `package.json`.
Backbone.VERSION = '0.3.2'; Backbone.VERSION = '0.3.3';
// Require Underscore, if we're on the server, and it's not already present. // Require Underscore, if we're on the server, and it's not already present.
var _ = this._; var _ = this._;
if (!_ && (typeof require !== 'undefined')) _ = require("underscore")._; if (!_ && (typeof require !== 'undefined')) _ = require("underscore")._;
// For Backbone's purposes, jQuery owns the `$` variable. // For Backbone's purposes, either jQuery or Zepto owns the `$` variable.
var $ = this.jQuery; var $ = this.jQuery || this.Zepto;
// Turn on `emulateHTTP` to use support legacy HTTP servers. Setting this option will // Turn on `emulateHTTP` to use support legacy HTTP servers. Setting this option will
// fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and set a // fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and set a
@ -116,6 +116,7 @@
attributes || (attributes = {}); attributes || (attributes = {});
if (this.defaults) attributes = _.extend({}, this.defaults, attributes); if (this.defaults) attributes = _.extend({}, this.defaults, attributes);
this.attributes = {}; this.attributes = {};
this._escapedAttributes = {};
this.cid = _.uniqueId('c'); this.cid = _.uniqueId('c');
this.set(attributes, {silent : true}); this.set(attributes, {silent : true});
this._previousAttributes = _.clone(this.attributes); this._previousAttributes = _.clone(this.attributes);
@ -147,6 +148,14 @@
return this.attributes[attr]; return this.attributes[attr];
}, },
// Get the HTML-escaped value of an attribute.
escape : function(attr) {
var html;
if (html = this._escapedAttributes[attr]) return html;
var val = this.attributes[attr];
return this._escapedAttributes[attr] = escapeHTML(val == null ? '' : val);
},
// Set a hash of model attributes on the object, firing `"change"` unless you // Set a hash of model attributes on the object, firing `"change"` unless you
// choose to silence it. // choose to silence it.
set : function(attrs, options) { set : function(attrs, options) {
@ -155,7 +164,7 @@
options || (options = {}); options || (options = {});
if (!attrs) return this; if (!attrs) return this;
if (attrs.attributes) attrs = attrs.attributes; if (attrs.attributes) attrs = attrs.attributes;
var now = this.attributes; var now = this.attributes, escaped = this._escapedAttributes;
// Run validation. // Run validation.
if (!options.silent && this.validate && !this._performValidation(attrs, options)) return false; if (!options.silent && this.validate && !this._performValidation(attrs, options)) return false;
@ -168,15 +177,16 @@
var val = attrs[attr]; var val = attrs[attr];
if (!_.isEqual(now[attr], val)) { if (!_.isEqual(now[attr], val)) {
now[attr] = val; now[attr] = val;
delete escaped[attr];
if (!options.silent) { if (!options.silent) {
this._changed = true; this._changed = true;
this.trigger('change:' + attr, this, val); this.trigger('change:' + attr, this, val, options);
} }
} }
} }
// Fire the `"change"` event, if the model has been changed. // Fire the `"change"` event, if the model has been changed.
if (!options.silent && this._changed) this.change(); if (!options.silent && this._changed) this.change(options);
return this; return this;
}, },
@ -193,10 +203,11 @@
// Remove the attribute. // Remove the attribute.
delete this.attributes[attr]; delete this.attributes[attr];
delete this._escapedAttributes[attr];
if (!options.silent) { if (!options.silent) {
this._changed = true; this._changed = true;
this.trigger('change:' + attr, this); this.trigger('change:' + attr, this, void 0, options);
this.change(); this.change(options);
} }
return this; return this;
}, },
@ -213,12 +224,13 @@
if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false; if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false;
this.attributes = {}; this.attributes = {};
this._escapedAttributes = {};
if (!options.silent) { if (!options.silent) {
this._changed = true; this._changed = true;
for (attr in old) { for (attr in old) {
this.trigger('change:' + attr, this); this.trigger('change:' + attr, this, void 0, options);
} }
this.change(); this.change(options);
} }
return this; return this;
}, },
@ -233,7 +245,7 @@
if (!model.set(model.parse(resp), options)) return false; if (!model.set(model.parse(resp), options)) return false;
if (options.success) options.success(model, resp); if (options.success) options.success(model, resp);
}; };
var error = options.error && _.bind(options.error, null, model); var error = wrapError(options.error, model, options);
(this.sync || Backbone.sync)('read', this, success, error); (this.sync || Backbone.sync)('read', this, success, error);
return this; return this;
}, },
@ -249,7 +261,7 @@
if (!model.set(model.parse(resp), options)) return false; if (!model.set(model.parse(resp), options)) return false;
if (options.success) options.success(model, resp); if (options.success) options.success(model, resp);
}; };
var error = options.error && _.bind(options.error, null, model); var error = wrapError(options.error, model, options);
var method = this.isNew() ? 'create' : 'update'; var method = this.isNew() ? 'create' : 'update';
(this.sync || Backbone.sync)(method, this, success, error); (this.sync || Backbone.sync)(method, this, success, error);
return this; return this;
@ -264,7 +276,7 @@
if (model.collection) model.collection.remove(model); if (model.collection) model.collection.remove(model);
if (options.success) options.success(model, resp); if (options.success) options.success(model, resp);
}; };
var error = options.error && _.bind(options.error, null, model); var error = wrapError(options.error, model, options);
(this.sync || Backbone.sync)('delete', this, success, error); (this.sync || Backbone.sync)('delete', this, success, error);
return this; return this;
}, },
@ -297,8 +309,8 @@
// Call this method to manually fire a `change` event for this model. // Call this method to manually fire a `change` event for this model.
// Calling this will cause all objects observing the model to update. // Calling this will cause all objects observing the model to update.
change : function() { change : function(options) {
this.trigger('change', this); this.trigger('change', this, options);
this._previousAttributes = _.clone(this.attributes); this._previousAttributes = _.clone(this.attributes);
this._changed = false; this._changed = false;
}, },
@ -349,7 +361,7 @@
if (options.error) { if (options.error) {
options.error(this, error); options.error(this, error);
} else { } else {
this.trigger('error', this, error); this.trigger('error', this, error, options);
} }
return false; return false;
} }
@ -441,7 +453,7 @@
options || (options = {}); options || (options = {});
if (!this.comparator) throw new Error('Cannot sort a set without a comparator'); if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
this.models = this.sortBy(this.comparator); this.models = this.sortBy(this.comparator);
if (!options.silent) this.trigger('refresh', this); if (!options.silent) this.trigger('refresh', this, options);
return this; return this;
}, },
@ -458,7 +470,7 @@
options || (options = {}); options || (options = {});
this._reset(); this._reset();
this.add(models, {silent: true}); this.add(models, {silent: true});
if (!options.silent) this.trigger('refresh', this); if (!options.silent) this.trigger('refresh', this, options);
return this; return this;
}, },
@ -471,7 +483,7 @@
collection.refresh(collection.parse(resp)); collection.refresh(collection.parse(resp));
if (options.success) options.success(collection, resp); if (options.success) options.success(collection, resp);
}; };
var error = options.error && _.bind(options.error, null, collection); var error = wrapError(options.error, collection, options);
(this.sync || Backbone.sync)('read', this, success, error); (this.sync || Backbone.sync)('read', this, success, error);
return this; return this;
}, },
@ -530,7 +542,7 @@
this.models.splice(index, 0, model); this.models.splice(index, 0, model);
model.bind('all', this._boundOnModelEvent); model.bind('all', this._boundOnModelEvent);
this.length++; this.length++;
if (!options.silent) model.trigger('add', model, this); if (!options.silent) model.trigger('add', model, this, options);
return model; return model;
}, },
@ -545,7 +557,7 @@
delete model.collection; delete model.collection;
this.models.splice(this.indexOf(model), 1); this.models.splice(this.indexOf(model), 1);
this.length--; this.length--;
if (!options.silent) model.trigger('remove', model, this); if (!options.silent) model.trigger('remove', model, this, options);
model.unbind('all', this._boundOnModelEvent); model.unbind('all', this._boundOnModelEvent);
return model; return model;
}, },
@ -669,8 +681,7 @@
// Get the cross-browser normalized URL fragment. // Get the cross-browser normalized URL fragment.
getFragment : function(loc) { getFragment : function(loc) {
var frag = (loc || window.location).hash.replace(hashStrip, ''); return (loc || window.location).hash.replace(hashStrip, '');
return frag;
}, },
// Start the hash change handling, returning `true` if the current URL matches // Start the hash change handling, returning `true` if the current URL matches
@ -751,10 +762,10 @@
this.initialize(options); this.initialize(options);
}; };
// jQuery lookup, scoped to DOM elements within the current view. // Element lookup, scoped to DOM elements within the current view.
// This should be prefered to global jQuery lookups, if you're dealing with // This should be prefered to global lookups, if you're dealing with
// a specific view. // a specific view.
var jQueryDelegate = function(selector) { var selectorDelegate = function(selector) {
return $(selector, this.el); return $(selector, this.el);
}; };
@ -767,9 +778,8 @@
// The default `tagName` of a View's element is `"div"`. // The default `tagName` of a View's element is `"div"`.
tagName : 'div', tagName : 'div',
// Attach the jQuery function as the `$` and `jQuery` properties. // Attach the `selectorDelegate` function as the `$` property.
$ : jQueryDelegate, $ : selectorDelegate,
jQuery : jQueryDelegate,
// Initialize is an empty function by default. Override it with your own // Initialize is an empty function by default. Override it with your own
// initialization logic. // initialization logic.
@ -811,7 +821,7 @@
// } // }
// //
// pairs. Callbacks will be bound to the view, with `this` set properly. // pairs. Callbacks will be bound to the view, with `this` set properly.
// Uses jQuery event delegation for efficiency. // Uses event delegation for efficiency.
// Omitting the selector binds the event to `this.el`. // Omitting the selector binds the event to `this.el`.
// This only works for delegate-able events: not `focus`, `blur`, and // This only works for delegate-able events: not `focus`, `blur`, and
// not `change`, `submit`, and `reset` in Internet Explorer. // not `change`, `submit`, and `reset` in Internet Explorer.
@ -850,7 +860,7 @@
if (this.el) return; if (this.el) return;
var attrs = {}; var attrs = {};
if (this.id) attrs.id = this.id; if (this.id) attrs.id = this.id;
if (this.className) attrs.className = this.className; if (this.className) attrs["class"] = this.className;
this.el = this.make(this.tagName, attrs); this.el = this.make(this.tagName, attrs);
} }
@ -880,7 +890,7 @@
// Override this function to change the manner in which Backbone persists // Override this function to change the manner in which Backbone persists
// models to the server. You will be passed the type of request, and the // models to the server. You will be passed the type of request, and the
// model in question. By default, uses jQuery to make a RESTful Ajax request // model in question. By default, uses makes a RESTful Ajax request
// to the model's `url()`. Some possible customizations could be: // to the model's `url()`. Some possible customizations could be:
// //
// * Use `setTimeout` to batch rapid-fire updates into a single request. // * Use `setTimeout` to batch rapid-fire updates into a single request.
@ -982,4 +992,20 @@
return _.isFunction(object.url) ? object.url() : object.url; return _.isFunction(object.url) ? object.url() : object.url;
}; };
// Wrap an optional error callback with a fallback error event.
var wrapError = function(onError, model, options) {
return function(resp) {
if (onError) {
onError(model, resp);
} else {
model.trigger('error', model, resp, options);
}
};
};
// Helper function to escape a string for HTML rendering.
var escapeHTML = function(string) {
return string.replace(/&(?!\w+;)/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
};
})(); })();

View File

@ -1,3 +1,4 @@
% -*- Mode: noweb; noweb-code-mode: javascript-mode ; noweb-doc-mode: latex-mode -*-
\documentclass{article} \documentclass{article}
\usepackage{noweb} \usepackage{noweb}
\usepackage{hyperref} \usepackage{hyperref}
@ -9,44 +10,84 @@
% notangle -Rstore.js backbonestore.nw > store.js % notangle -Rstore.js backbonestore.nw > store.js
% notangle -Rindex.html backbonestore.nw > index.html % notangle -Rindex.html backbonestore.nw > index.html
I've been learning how to use \nwanchorto{http://documentcloud.github.com/backbone/}{Backbone.js}, a nifty little library for \section{Introduction}
organizing your client-side Javascript into a classic
Model-View-Controller paradigm while trying (and to some extent,
succeeding) in trying to burden you, the user, with as little
additional learning as possible. I consider this a good thing; the
overhead of learning a library and its accompaning DSL represent
additional cognitive loads that developers can better use elsewhere.
Keeping as much as possible within familiar paradigms is not just
useful, it's necessary as our programs get bigger.
The tutorial for Backbone is woefully lacking in specifics, and the I've been playing with
example program, Todo, doesn't really have much chops in teaching you \nwanchorto{http://documentcloud.github.com/backbone/}{Backbone.js}, a
the ins and outs of Backbone, especially not its new Controller and small but nifty Javascript library that provides a small
History modules. But in the announcement for Backbone.Controller, Model-View-Controller framework where Models can generate events that
Jeremy Ashkenas hid a clue: There's another library, Sammy.js, that trigger View changes, and vice versa, along with a Collections models
does something similar, and they do have a tutorial called \nwanchorto{http://code.quirkey.com/sammy/tutorials/json_store_part1.html}{The JsonStore}. so groups of models can cause view-level events, and a Sync library
that provides a basic REST architecture for propagating client-made
changes back to the server.
In the spirit of The JSON Store, I present The Backbone Store, and There are a number of good tutorials for Backbone (See:
online store written entirely in JSON and operating entirely within a \nwanchorto{http://www.plexical.com/blog/2010/11/18/backbone-js-tutorial/}{Meta
single page. Cloud},
\nwanchorto{http://andyet.net/blog/2010/oct/29/building-a-single-page-app-with-backbonejs-undersc/?utm_source=twitterfeed&utm_medium=twitter}{&Yet's
Tutorial},
\nwanchor{http://bennolan.com/2010/11/24/backbone-jquery-demo.html}{Backbone
Mobile} (which is written in
\nwanchorto{http://jashkenas.github.com/coffee-script/}{Coffee}), and
\nwanchor{http://joshbohde.com/2010/11/25/backbonejs-and-django/}{Backbone
and Django}. However, a couple of months ago I was attempting to
learn Sammy.js, a library very similar to Backbone, and they had a
nifty tutorial called
\nwanchorto{http://code.quirkey.com/sammy/tutorials/json_store_part1.html}{The
JsonStore}.
Let's start by showing you the HTML that we're going to be exploiting: In the spirit of The JSON Store, I present The Backbone Store.
\subsection{Literate Program}
A note: this article was written with the
\nwanchorto{http://en.wikipedia.org/wiki/Literate_programming}{Literate
Programming} toolkit
\nwanchorto{http://www.cs.tufts.edu/~nr/noweb/}{Noweb}. Where you see
something that looks like \<\<this\>\>, it's a placeholder for code
described elsewhere in the document. Placeholders with an equal sign
at the end of them indicate the place where that code is defined. The
link (U->) indicates that the code you're seeing is used later in the
document, and (<-U) indicates it was used earlier but is being defined
here.
\subsection{Revision}
This is version 1.2 of \textit{The Backbone Store}. It includes
changes to the store based upon a better understanding of what
Backbone.js can do. This version uses jQuery 1.5 and Backbone 0.3.3.
\subsection{The Store}
The store has three features: A list of products, a product detail
page, and a ``shopping cart'' that does nothing but tally up the
number of products total that you might wish to order. The main
viewport flips between a list of products and a product detail; the
shopping cart quantity tally is always visible.
Let's start by showing you the HTML that we're going to be
exploiting. As you can see, the shopping cart's primary display is
already present, with zero items shoving. DOM ID ``main'' is empty.
We'll fill it with templated data later.
\subsection{HTML}
<<index.html>>= <<index.html>>=
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>
The Backbone Store
<title>The Backbone Store</title> </title>
<link rel="stylesheet" href="jsonstore.css" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="jsonstore.css" type="text/css" media="screen" charset="utf-8" />
<<index template>> <<product list template>>
<<product template>> <<product template>>
</head> </head>
<body> <body>
<div id="container"> <div id="container">
<div id="header"> <div id="header">
@ -59,10 +100,9 @@ Let's start by showing you the HTML that we're going to be exploiting:
</div> </div>
</div> </div>
<div id="main"> <div id="main"> </div>
</div> </div>
</div> <script src="jquery-1.5.js" type="text/javascript"></script>
<script src="jquery-1.4.4.min.js" type="text/javascript"></script>
<script src="jquery.tmpl.min.js" type="text/javascript"></script> <script src="jquery.tmpl.min.js" type="text/javascript"></script>
<script src="underscore.js" type="text/javascript"></script> <script src="underscore.js" type="text/javascript"></script>
<script src="backbone.js" type="text/javascript"></script> <script src="backbone.js" type="text/javascript"></script>
@ -73,347 +113,244 @@ Let's start by showing you the HTML that we're going to be exploiting:
This is taken, more or less, straight from The JSON Store. I've This is taken, more or less, straight from The JSON Store. I've
included one extra thing, aside from jQuery and Backbone, and that's included one extra thing, aside from jQuery and Backbone, and that's
the \nwanchorto{https://github.com/jquery/jquery-tmpl}{jQuery Templates kit}. We'll discuss those in a minute. There's a the \nwanchorto{https://github.com/jquery/jquery-tmpl}{jQuery
simplified JSON file that comes in the download; it contains six Templates kit}. There is also a simplified JSON file that comes in
record albums that the store sells. (Unlike the JSON store, these the download; it contains six record albums that the store sells.
albums don't exist; the covers were generated during a round of \nwanchorto{http://elfs.livejournal.com/756709.html}{The Album Cover (Unlike the JSON store, these albums do not exist; the covers were
Game}.) generated during a round of
\nwanchorto{http://elfs.livejournal.com/756709.html}{The Album Cover
Game}.)
There are two views, the index and the item. So, using \section{The Program}
[[Backbone.Controller]], we're going to route the following:
<<routes>>= And here's the skeleton of the program we're going to be writing:
routes: {
"": "index",
"item/:id": "item",
},
@
Unlike Sammy, Backbone mostly only routes GET commands. Routes are to <<store.js>>=
routes to views; everything else happens more or less under the (function() {
covers.
As Backbone is running, the [[Backbone.History]] module is listening to <<product models>>
the hash object, waiting for it to change so that it can trigger a
``route'' event, in which case the function named as the value in the
route is called.
There are a few things I want to track: the index view, the individual <<shopping cart models>>
product views, and the shopping cart.
<<application variables>>= <<shopping cart view>>
_index: null,
_products: null,
_cart :null,
@
Using backbone, I have a list of products. So, I should declare <<product list view>>
those. The basic product is just a model, with nothing to show for
it; the list of products is a [[Backbone.Collection]], with one feature,
the [[comparator]], which sorts the albums in order by album title.
<<product models>>= <<product view>>
var Product = Backbone.Model.extend({});
var ProductCollection = Backbone.Collection.extend({ <<application>>
model: Product,
comparator: function(item) {
return item.get('title');
}
});
@
That's not very exciting. Let's show this list, with a View. Let's
call it IndexView:
<<index view>>=
var IndexView = Backbone.View.extend({
el: $('#main'),
indexTemplate: $("#indexTmpl").template(),
render: function() {
var sg = this;
this.el.fadeOut('fast', function() {
sg.el.empty();
$.tmpl(sg.indexTemplate, sg.model.toArray()).appendTo(sg.el);
sg.el.fadeIn('fast');
});
return this;
}
});
@
This code defines a [[Backbone.View]] object, in which the parent element
is \#main, the render function fades out the existing elements in that
position and replaces them with the contents of a rendered jQuery
template, and then fades the element back in.
The index template looks like this:
<<index template>>=
<script id="indexTmpl" type="text/x-jquery-tmpl">
<div class="item">
<div class="item-image">
<a href="#item/${cid}"><img src="${attributes.image}" alt="${attributes.title}" /></a>
</div>
<div class="item-artist">${attributes.artist}</div>
<div class="item-title">${attributes.title}</div>
<div class="item-price">$${attributes.price}</div>
</div>
</script>
@
There's some
\nwanchorto{http://en.wikipedia.org/wiki/Law_of_Demeter}{Demeter violations}
going on here, in that I have to know about the [[attributes]] of a
Backbone model, something that's normally hidden within the class.
But this is good enough for our purposes. The above is a jQuery
template, and the [[\$\{\}]] syntax is what's used to dereference
variables within a template.
(As an aside, I think that the [[set]] and [[get]] methods of
[[Backbone.Model]] are a poor access mechanism. I understand why they're
there, and I can only hope that someday
\nwanchorto{http://ejohn.org/blog/javascript-getters-and-setters/}{Javascript
Getter and Setters} become so well-established as to make [[set]]
and [[get]] irrelevant.)
Now, we can render the index view:
<<index render call>>=
index: function() {
this._index.render();
},
@
At this point, well, we need an application. A controller. And we
need to initialize it, and call it. Here's what it looks like (some
of this, you've already seen):
<<workspace>>=
var Workspace = Backbone.Controller.extend({
<<application variables>>
<<routes>>
<<initialization>> <<initialization>>
<<index render call>> }).call(this);
<<product render call>>
});
workspace = new Workspace();
Backbone.history.start();
@ @
There are two things left in our workspace, that we haven't defined. \section{Models and Collections for the Store}
The intialization, and the product render.
Initialization consists of getting our product list, creating a Products are basically what we're selling. In Backbone, a product
shopping cart to hold ``desired'' products (and in quantity!), and maps to a Backbone Model. Backbone's Model class provides a full
creating the index view. (Product views, we'll discuss in a moment). suite of methods for setting and deleting attributes.
<<initialization>>= One of things I've found useful is to expose the CID (an internal and
initialize: function() { locally unique ``client ID'' generated by Backbone) and use it to
var ws = this; decorate DOM id's and classes. So, here, I override the Models's
if (this._index === null) { [[toJSON()]] and add the CID to the representation. In production,
$.ajax({ I've typically created a parent class for all of my classes, overriden
url: 'data/items.json', [[toJSON()]], and extended that instead.
dataType: 'json',
data: {}, <<product models>>=
success: function(data) { var Product = Backbone.Model.extend({
ws._cart = new Cart(); toJSON: function() {
new CartView({model: ws._cart}); return _.extend(_.clone(this.attributes), {cid: this.cid})
ws._products = new ProductCollection(data);
ws._index = new IndexView({model: ws._products});
Backbone.history.loadUrl();
} }
}); });
return this;
}
return this;
},
@ @
We haven't defined the Cart yet, but that's all right. We'll get to A store has a lot of products, so we use a Backbone Collection to keep
it.) But here you see a lot of what's already existent being used: we track of them. A Collection always has a Model object associated with
get a ProductCollection, and an IndexView. it; if you attempt to add an object to the Collection that is not an
instance of [[Backbone.Model]], the Collection will attempt to coerce
that object into it [[model]] type.
That last line is curious. It's an instruction to Backbone to look at Both Models and Collections have a [[toJSON()]] method. The Model
the URL; if the user navigated to something other than the home page, creates a JSON representation of its attributes, and the collection
it's to use the routes defined to go there. Users can now bookmark creates a JSON representation of an array, calling [[Model.toJSON()]]
places in your site other than the home page. Yes, the bookmark will for each model in contains.
be funny and have at least one
\nwanchorto{http://en.wiktionary.org/wiki/octothorpe}{octothorpe} in it, but
it will work.
Let's deal with the shopping cart:
The other novel thing here is the comparator; Backbone uses it define
the default ordering for the collection. If not defined, calling
[[sort()]] on the collection raises an exception.
<<product models>>=
var ProductCollection = Backbone.Collection.extend({
model: Product,
comparator: function(item) {
return item.get('title');
}
});
@
Shopping carts are a bit strange. The typical cart has items: each
item represents one product and the quantity the user wants to buy.
So a cart may have two items, but the user may be buying five things:
one of the first item, and four of the second, and so forth.
For our (simple) purpose, I'm just going to have an item that you can
add amounts to, that get stored as a 'quantity'.
<<shopping cart models>>= <<shopping cart models>>=
var CartItem = Backbone.Model.extend({ var CartItem = Backbone.Model.extend({
update: function(amount) { update: function(amount) {
this.set({'quantity': this.get('quantity') + amount}); this.set({'quantity': this.get('quantity') + amount});
} }
}); });
var Cart = Backbone.Collection.extend({
model: CartItem,
getByPid: function(pid) {
return this.detect(function(obj) { return (obj.get('product').cid == pid); });
},
});
@ @
A little rocket science here: A [[Cart]] contains [[CartItems]]. Each The other feature is that, for the collection, I will want to find the
``item'' represents a quantity of a [[Product]]. (I know, that always CartItem not by its ID, but by the ID of the product it contains. So
struck me as odd, but that's how most online stores do it.) I have added the method [[getByProductId]].
[[CartItem]] has an update method that allows you to add more (but not
remove any-- hey, the Sammy store wasn't any smarter, and this is For
Demonstration Purposes Only), and we use the [[set]] method to make
sure that a ``change'' event is triggered.
The [[Cart]], in turn, has a method, getByPid (``Product ID''), which <<shopping cart models>>=
is meant to assist other objects in finding the [[CartItem]] var Cart = Backbone.Collection.extend({
associated with a specific product. Here, I'm just using the Backbone model: CartItem,
default client id. getByProductId: function(pid) {
return this.detect(function(obj) { return (obj.get('product').cid == pid); });
},
});
The cart is represented by a little tag in the upper right-hand corner @
of the view; it never goes away, and its count is always the total
number of [[Products]] (not [[CartItem]]s) ordered. So the \section{Views}
[[CartView]] needs to update whenever a [[CartItem]] is added or
updated. And we want a nifty little animation to go with it: Backbone Views are simple policy objects. They often have a root
element, the contents of which they manipulate, a model or collection
they represent within that root element, events that may occur within
that root element that they monitor and consequently act on. Views
are not rigid; it's just Javascript and the DOM, and you can hook
external events as needed. (This can be useful, for example, when
doing drag-and-drop with jQueryUI to highlight valid drop zones.)
More importantly, it is sensitive to events \textit{within its model
or collection}, and can respond to changes automatically, without
having to manually invoke the view.
There are three views here: the CartView, the ProductListView, and a
single ProductView.
The [[CartView]] lives in the upper-right-hand corner of our screen,
and just shows the quantity of items in our shopping cart. It has a
default [[el]], where it will draw its quantity. This view
illustrates the binding to its collection: whenever the collection is
updated in some way, the [[CartView]] automagically updates itself.
The programmer is now relieved of any responsibility of remembering to
update the view, which is a huge win. The [[\_.bind()]] method
associates the [[render]] with the instance of the [[CartView]].
The [[render()]] method is the conventional name for rendering the
elements. Nothing in Backbone calls [[render()]] directly; it's up to
the developer to decide how and when an object should should be
rendered.
This also illustrates the use of jQuery animations in Backbone.
<<shopping cart view>>= <<shopping cart view>>=
var CartView = Backbone.View.extend({ var CartView = Backbone.View.extend({
el: $('.cart-info'), el: $('.cart-info'),
initialize: function() { initialize: function() {
this.model.bind('change', _.bind(this.render, this)); this.collection.bind('change', _.bind(this.render, this));
}, },
render: function() { render: function() {
var sum = this.model.reduce(function(m, n) { return m + n.get('quantity'); }, 0); var sum = this.collection.reduce(function(m, n) { return m + n.get('quantity'); }, 0);
this.el this.el
.find('.cart-items').text(sum).end() .find('.cart-items').text(sum).end()
.animate({paddingTop: '30px'}) .animate({paddingTop: '30px'})
.animate({paddingTop: '10px'}); .animate({paddingTop: '10px'});
} }
}); });
@ @
%$
A couple of things here: the render is rebound to [[this]] to make The [[ProductListView]] again has a root element, this time the
sure it renders in the context of the view. I found that that was not [[#main]] DIV of our HTML, into which we're going to draw a jQuery
always happening. Note the use of [[reduce]], a nifty method from template list of our record albums.
[[underscore.js]] that allows you to build a result out an array using
an anonymous function. This reduce, obviously, sums up the total
quantity of items in the cart. Also, jQuery enthusiasts could learn
(I certainly did!) from the [[.find()]] and [[.end()]] methods, which
push a child object onto the stack to be animated, and then pop it off
after the operation has been applied.
The biggest thing left is the [[ProductView]]. It's skeleton looks The only tricks here are the compilation of the jQuery template when
like this: the View is instantiated, and the use of an enclosured (is that a
word?) [[self]] variable to provide a hard context for the [[this]]
variable within inner jQuery calls.
<<product view>>= <<product list view>>=
var ProductView = Backbone.View.extend({ var ProductListView = Backbone.View.extend({
el: $('#main'), el: $('#main'),
itemTemplate: $("#itemTmpl").template(), indexTemplate: $("#indexTmpl").template(),
<<product events>>
initialize: function(options) {
this.cart = options.cart;
},
<<update product>>
<<render product>>
});
@
First, we find the element we're going to work with, and the template.
I expect the ProductView to be where we'll add items to the cart, so
the initializer here expects to have a handle on the cart.
And the template:
<<product template>>=
<script id="itemTmpl" type="text/x-jquery-tmpl">
<div class="item-detail">
<div class="item-image"><img src="${attributes.large_image}" alt="${attributes.title}" /></div>
<div class="item-info">
<div class="item-artist">${attributes.artist}</div>
<div class="item-title">${attributes.title}</div>
<div class="item-price">$${attributes.price}</div>
<div class="item-form">
<form action="#/cart" method="post">
<input type="hidden" name="item_id" value="${cid}" />
<p>
<label>Quantity:</label>
<input type="text" size="2" name="quantity" value="1" class="uqf" />
</p>
<p><input type="submit" value="Add to Cart" class="uq" /></p>
</form>
</div>
<div class="item-link"><a href="${attributes.url}">Buy this item on Amazon</a></div>
<div class="back-link"><a href="#">&laquo; Back to Items</a></div>
</div>
</div>
</script>
@
One extra item: note the octothorpe used as the target link for
``Home''. I kept thinking an empty link or just ``/'' would be
appropriate, but no, it's an octothorpe.
Rendering the product is not difficult:
<<render product>>=
render: function() { render: function() {
var sg = this; var self = this;
this.el.fadeOut('fast', function() { this.el.fadeOut('fast', function() {
sg.el.empty(); self.el.html($.tmpl(self.indexTemplate, self.model.toJSON()));
$.tmpl(sg.itemTemplate, sg.model).appendTo(sg.el); self.el.fadeIn('fast');
sg.el.fadeIn('fast');
}); });
return this; return this;
} }
});
@ @
That looks familiar. The view uses a jQuery template. This is a simple, repeatable
template that jQuery.Template, upon encountering an array, repeats
until the array is exhausted. Note the presence of [[\${cid}]].
Updating the product, however, is a whole 'nother story. Note that <<product list template>>=
each product has a form associated with it. We need to intercept any <script id="indexTmpl" type="text/x-jquery-tmpl">
form update events and manipulate our shopping cart. We have two <div class="item">
objects that can do that: the input field, and the submit button. I <div class="item-image">
need to intercept those events: <a href="#item/${cid}"><img src="${image}" alt="${title}" /></a>
</div>
<div class="item-artist">${artist}</div>
<div class="item-title">${title}</div>
<div class="item-price">$${price}</div>
</div>
</script>
@
%$
<<product events>>= The most complicated object in our ecosystem is the product view. It
events: { actually does something! The prefix ought to be familiar, but note
"keypress .uqf" : "updateOnEnter", that we're again using [[#main]] as our target; we'll be replacing
"click .uq" : "update", these contents over and over.
<<product view>>=
var ProductView = Backbone.View.extend({
el: $('#main'),
itemTemplate: $("#itemTmpl").template(),
initialize: function(options) {
this.cart = options.cart;
return this;
}, },
@ @
Backbone uses a curious definition of an event with an ``event We want to update the cart as needed. Remember that when we update
selector'', followed by a target method of the View class. Backbone the cart item, the CartView will be notified automagically. Later,
is also limited about what events can be used here, as the following I'll show how when we initialize and route to a product view, we pass
events cannot be wrapped by jQuery's delegate method and do not work: in the model associated with it. This code ought to be fairly
``focus'', ``blur'', ``change'', ``submit'', and ``reset''. readable: the only specialness is that it's receiving an event, and
we're ``silencing'' the call to [[cart.add()]], which means that the
cart collection will not publish any events. There are only events
when the item has more than zero, and that gets called on
[[cart_item.update()]].
The update then becomes straightforward. We're in a view for a <<product view>>=
specific product; we must see if the customer has a [[CartItem]] for
that product in the [[Cart]], and add or update it as needed. Like
so:
<<update product>>=
update: function(e) { update: function(e) {
e.preventDefault(); e.preventDefault();
var cart_item = this.cart.getByPid(this.model.cid); var cart_item = this.cart.getByProductId(this.model.cid);
if (_.isUndefined(cart_item)) { if (_.isUndefined(cart_item)) {
cart_item = new CartItem({product: this.model, quantity: 0}); cart_item = new CartItem({product: this.model, quantity: 0});
this.cart.add(cart_item, {silent: true}); this.cart.add(cart_item, {silent: true});
@ -426,48 +363,199 @@ so:
return this.update(e); return this.update(e);
} }
}, },
@
%$
These are the events in which we're interested: keypresses and clicks
on the update button and the quantity form. (Okay, ``UQ'' isn't the
best for ``update quantity''. I admit that.) Note the peculiar
syntax of ``EVENT SELECTOR'': ``methodByName'' for each event.
Backbone tells us that the only events it can track by itself are
those that jQuery's ``delegate'' understands. As of 1.5, that seems
to be just about all of them.
One thing that I was not aware of until recently: if you remove and
replace the [[el]] object during the lifespan of your view (including
in [[initialize()]]), you must then call [[delegateEvents()]] again on
the new object for these events to work.
<<product view>>=
events: {
"keypress .uqf" : "updateOnEnter",
"click .uq" : "update",
},
@ @
We [[preventDefault]] to keep the traditional meaning of the submit And finally the render. There is no rocket science here. You've seen
button from triggering. When the [[CartItem]] is updated, it triggers this before.
a ``change'' event, and the [[CartView]] will update itself
automatically. I added the ``silent'' option to keep the ``change''
event from triggering twice when adding a new [[CartItem]] to the
[[Cart]].
And now I'm down to one last thing. I haven't defined that product %'
render call in the application controller. The one thing I don't want <<product view>>=
to do is have [[ProductViews]] for every product, if I don't need render: function() {
them. So I want to build them as-needed, but keep them, and associate var self = this;
them with the local [[Product]], so they can be recalled whenever we this.el.fadeOut('fast', function() {
want. The underscore function [[isUndefined]] is excellent for this. self.el.html($.tmpl(self.itemTemplate, self.model.toJSON()));
self.el.fadeIn('fast');
});
return this;
}
});
<<product render call>>= @
The template for a ProductView is straightforward. It contains the
form with the [[uq]] objects, the actions of which we intercept and
operate on internally. Backbone does this automatically using
jQuery's [[delegate]] method.
<<product template>>=
<script id="itemTmpl" type="text/x-jquery-tmpl">
<div class="item-detail">
<div class="item-image"><img src="${large_image}" alt="${title}" /></div>
<div class="item-info">
<div class="item-artist">${artist}</div>
<div class="item-title">${title}</div>
<div class="item-price">$${price}</div>
<div class="item-form">
<form action="#/cart" method="post">
<input type="hidden" name="item_id" value="${cid}" />
<p>
<label>Quantity:</label>
<input type="text" size="2" name="quantity" value="1" class="uqf" />
</p>
<p><input type="submit" value="Add to Cart" class="uq" /></p>
</form>
</div>
<div class="item-link"><a href="${url}">Buy this item on Amazon</a></div>
<div class="back-link"><a href="#">&laquo; Back to Items</a></div>
</div>
</div>
</script>
@
%'
\section{The Router}
The router is a fairly straightforward component. It's purpose is to
pay attention to the ``\#hash'' portion of your URL and, when it
changes, do something. Anything, really. [[Backbone.History]] is the
event listener for the hash, so it has to be activated after the
application. In many ways, a Backbone ``Controller'' is just a big
View with authority over the entire Viewport.
To begin with, I'm going to keep track of the ``three'' views I care
about: the CartView, the ProductListView, and the ProductView. I'm
going to cheat by attaching the ProductViews to their individual
products, and invoke that view as necessary.
<<application>>=
var BackboneStore = Backbone.Controller.extend({
_index: null,
_products: null,
_cart :null,
@
%$
There are only two routes: home, and item:
<<application>>=
routes: {
"": "index",
"item/:id": "item",
},
@
Here's where things get interesting. There are two schools of thought
over the Controller; one, that the Controller ought to be able to get
all the data it needs, and two, that the Controller ought to begin
with enough data to do the job sensibly. I fall into the second camp.
I'm going to pass in to the [[initialize()]] method an array of
objects representing all the products in the system.
<<application>>=
initialize: function(data) {
this._cart = new Cart();
new CartView({collection: this._cart});
this._products = new ProductCollection(data);
this._index = new ProductListView({model: this._products});
return this;
},
@
When we're routed to the [[index]] method, all we need to do is render
the index:
<<application>>=
index: function() {
this._index.render();
},
@
When we are routed to a product, we need to find that product, get its
view if it has one or create one if it doesn't, then call render:
<<application>>=
item: function(id) { item: function(id) {
if (_.isUndefined(this._products.getByCid(id)._view)) { var product = this._products.getByCid(id);
this._products.getByCid(id)._view = new ProductView({model: this._products.getByCid(id), if (_.isUndefined(product._view)) {
product._view = new ProductView({model: product,
cart: this._cart}); cart: this._cart});
} }
this._products.getByCid(id)._view.render(); product._view.render();
} }
});
@ @
And now my store looks like And that's the entirety of the application.
<<store.js>>= \section{Initialization}
<<product models>>
<<shopping cart models>> Initialization for most single-page applications happens when the DOM
is ready. So I'll do exactly that.
<<shopping cart view>> This should be obvious, except what the Hell is that when/then
construct? That's a new feature of jQuery 1.5 called Deferreds (also
known as Promises or Futures). All jQuery 1.5 ajax calls are
Deferreds that return data when you dereference them; [[when()]] is an
instruction to wait until the ajax call is done, and [[then()]] is a
chained instruction on what to do next.
<<product view>> This is a trivial example, but when you have multiple streams of data
coming in (say, you're loading independent schemas, or you have
multiple, orthagonal data sets in your application, each with their
own URL as per the Richardson Maturity Model), you can pass the array
of ajax objects to [[when()]] and [[then()]] won't fire until they're
all done. Automagic synchronization is a miracle.
<<index view>> <<initialization>>=
$(document).ready(function() {
var fetch_items = function() {
return $.ajax({
url: 'data/items.json',
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json"
});
};
<<workspace>> $.when(fetch_items()).then(function(data) {
new BackboneStore(data);
Backbone.history.start();
});
});
@ @
And that's it. Put it all together, and you've got yourself a working
Backbone Store.
As always, this code is available at github. This code is available at my github at
\nwanchorto{https://github.com/elfsternberg/The-Backbone-Store}{The
Backbone Store}.
\end{document} \end{document}

View File

@ -2,29 +2,29 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>
The Backbone Store
<title>The Backbone Store</title> </title>
<link rel="stylesheet" href="jsonstore.css" type="text/css" media="screen" charset="utf-8" /> <link rel="stylesheet" href="jsonstore.css" type="text/css" media="screen" charset="utf-8" />
<script id="indexTmpl" type="text/x-jquery-tmpl"> <script id="indexTmpl" type="text/x-jquery-tmpl">
<div class="item"> <div class="item">
<div class="item-image"> <div class="item-image">
<a href="#item/${cid}"><img src="${attributes.image}" alt="${attributes.title}" /></a> <a href="#item/${cid}"><img src="${image}" alt="${title}" /></a>
</div> </div>
<div class="item-artist">${attributes.artist}</div> <div class="item-artist">${artist}</div>
<div class="item-title">${attributes.title}</div> <div class="item-title">${title}</div>
<div class="item-price">$${attributes.price}</div> <div class="item-price">$${price}</div>
</div> </div>
</script> </script>
<script id="itemTmpl" type="text/x-jquery-tmpl"> <script id="itemTmpl" type="text/x-jquery-tmpl">
<div class="item-detail"> <div class="item-detail">
<div class="item-image"><img src="${attributes.large_image}" alt="${attributes.title}" /></div> <div class="item-image"><img src="${large_image}" alt="${title}" /></div>
<div class="item-info"> <div class="item-info">
<div class="item-artist">${attributes.artist}</div> <div class="item-artist">${artist}</div>
<div class="item-title">${attributes.title}</div> <div class="item-title">${title}</div>
<div class="item-price">$${attributes.price}</div> <div class="item-price">$${price}</div>
<div class="item-form"> <div class="item-form">
<form action="#/cart" method="post"> <form action="#/cart" method="post">
<input type="hidden" name="item_id" value="${cid}" /> <input type="hidden" name="item_id" value="${cid}" />
@ -35,13 +35,14 @@
<p><input type="submit" value="Add to Cart" class="uq" /></p> <p><input type="submit" value="Add to Cart" class="uq" /></p>
</form> </form>
</div> </div>
<div class="item-link"><a href="${attributes.url}">Buy this item on Amazon</a></div> <div class="item-link"><a href="${url}">Buy this item on Amazon</a></div>
<div class="back-link"><a href="#">&laquo; Back to Items</a></div> <div class="back-link"><a href="#">&laquo; Back to Items</a></div>
</div> </div>
</div> </div>
</script> </script>
</head> </head>
<body> <body>
<div id="container"> <div id="container">
<div id="header"> <div id="header">
@ -54,10 +55,9 @@
</div> </div>
</div> </div>
<div id="main"> <div id="main"> </div>
</div> </div>
</div> <script src="jquery-1.5.js" type="text/javascript"></script>
<script src="jquery-1.4.4.min.js" type="text/javascript"></script>
<script src="jquery.tmpl.min.js" type="text/javascript"></script> <script src="jquery.tmpl.min.js" type="text/javascript"></script>
<script src="underscore.js" type="text/javascript"></script> <script src="underscore.js" type="text/javascript"></script>
<script src="backbone.js" type="text/javascript"></script> <script src="backbone.js" type="text/javascript"></script>

167
jquery-1.4.4.min.js vendored
View File

@ -1,167 +0,0 @@
/*!
* jQuery JavaScript Library v1.4.4
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Thu Nov 11 19:04:53 2010 -0500
*/
(function(E,B){function ka(a,b,d){if(d===B&&a.nodeType===1){d=a.getAttribute("data-"+b);if(typeof d==="string"){try{d=d==="true"?true:d==="false"?false:d==="null"?null:!c.isNaN(d)?parseFloat(d):Ja.test(d)?c.parseJSON(d):d}catch(e){}c.data(a,b,d)}else d=B}return d}function U(){return false}function ca(){return true}function la(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function Ka(a){var b,d,e,f,h,l,k,o,x,r,A,C=[];f=[];h=c.data(this,this.nodeType?"events":"__events__");if(typeof h==="function")h=
h.events;if(!(a.liveFired===this||!h||!h.live||a.button&&a.type==="click")){if(a.namespace)A=RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)");a.liveFired=this;var J=h.live.slice(0);for(k=0;k<J.length;k++){h=J[k];h.origType.replace(X,"")===a.type?f.push(h.selector):J.splice(k--,1)}f=c(a.target).closest(f,a.currentTarget);o=0;for(x=f.length;o<x;o++){r=f[o];for(k=0;k<J.length;k++){h=J[k];if(r.selector===h.selector&&(!A||A.test(h.namespace))){l=r.elem;e=null;if(h.preType==="mouseenter"||
h.preType==="mouseleave"){a.type=h.preType;e=c(a.relatedTarget).closest(h.selector)[0]}if(!e||e!==l)C.push({elem:l,handleObj:h,level:r.level})}}}o=0;for(x=C.length;o<x;o++){f=C[o];if(d&&f.level>d)break;a.currentTarget=f.elem;a.data=f.handleObj.data;a.handleObj=f.handleObj;A=f.handleObj.origHandler.apply(f.elem,arguments);if(A===false||a.isPropagationStopped()){d=f.level;if(A===false)b=false;if(a.isImmediatePropagationStopped())break}}return b}}function Y(a,b){return(a&&a!=="*"?a+".":"")+b.replace(La,
"`").replace(Ma,"&")}function ma(a,b,d){if(c.isFunction(b))return c.grep(a,function(f,h){return!!b.call(f,h,f)===d});else if(b.nodeType)return c.grep(a,function(f){return f===b===d});else if(typeof b==="string"){var e=c.grep(a,function(f){return f.nodeType===1});if(Na.test(b))return c.filter(b,e,!d);else b=c.filter(b,e)}return c.grep(a,function(f){return c.inArray(f,b)>=0===d})}function na(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var e=c.data(a[d++]),f=c.data(this,
e);if(e=e&&e.events){delete f.handle;f.events={};for(var h in e)for(var l in e[h])c.event.add(this,h,e[h][l],e[h][l].data)}}})}function Oa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function oa(a,b,d){var e=b==="width"?a.offsetWidth:a.offsetHeight;if(d==="border")return e;c.each(b==="width"?Pa:Qa,function(){d||(e-=parseFloat(c.css(a,"padding"+this))||0);if(d==="margin")e+=parseFloat(c.css(a,
"margin"+this))||0;else e-=parseFloat(c.css(a,"border"+this+"Width"))||0});return e}function da(a,b,d,e){if(c.isArray(b)&&b.length)c.each(b,function(f,h){d||Ra.test(a)?e(a,h):da(a+"["+(typeof h==="object"||c.isArray(h)?f:"")+"]",h,d,e)});else if(!d&&b!=null&&typeof b==="object")c.isEmptyObject(b)?e(a,""):c.each(b,function(f,h){da(a+"["+f+"]",h,d,e)});else e(a,b)}function S(a,b){var d={};c.each(pa.concat.apply([],pa.slice(0,b)),function(){d[this]=a});return d}function qa(a){if(!ea[a]){var b=c("<"+
a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d==="")d="block";ea[a]=d}return ea[a]}function fa(a){return c.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var t=E.document,c=function(){function a(){if(!b.isReady){try{t.documentElement.doScroll("left")}catch(j){setTimeout(a,1);return}b.ready()}}var b=function(j,s){return new b.fn.init(j,s)},d=E.jQuery,e=E.$,f,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,l=/\S/,k=/^\s+/,o=/\s+$/,x=/\W/,r=/\d/,A=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,
C=/^[\],:{}\s]*$/,J=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,w=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,I=/(?:^|:|,)(?:\s*\[)+/g,L=/(webkit)[ \/]([\w.]+)/,g=/(opera)(?:.*version)?[ \/]([\w.]+)/,i=/(msie) ([\w.]+)/,n=/(mozilla)(?:.*? rv:([\w.]+))?/,m=navigator.userAgent,p=false,q=[],u,y=Object.prototype.toString,F=Object.prototype.hasOwnProperty,M=Array.prototype.push,N=Array.prototype.slice,O=String.prototype.trim,D=Array.prototype.indexOf,R={};b.fn=b.prototype={init:function(j,
s){var v,z,H;if(!j)return this;if(j.nodeType){this.context=this[0]=j;this.length=1;return this}if(j==="body"&&!s&&t.body){this.context=t;this[0]=t.body;this.selector="body";this.length=1;return this}if(typeof j==="string")if((v=h.exec(j))&&(v[1]||!s))if(v[1]){H=s?s.ownerDocument||s:t;if(z=A.exec(j))if(b.isPlainObject(s)){j=[t.createElement(z[1])];b.fn.attr.call(j,s,true)}else j=[H.createElement(z[1])];else{z=b.buildFragment([v[1]],[H]);j=(z.cacheable?z.fragment.cloneNode(true):z.fragment).childNodes}return b.merge(this,
j)}else{if((z=t.getElementById(v[2]))&&z.parentNode){if(z.id!==v[2])return f.find(j);this.length=1;this[0]=z}this.context=t;this.selector=j;return this}else if(!s&&!x.test(j)){this.selector=j;this.context=t;j=t.getElementsByTagName(j);return b.merge(this,j)}else return!s||s.jquery?(s||f).find(j):b(s).find(j);else if(b.isFunction(j))return f.ready(j);if(j.selector!==B){this.selector=j.selector;this.context=j.context}return b.makeArray(j,this)},selector:"",jquery:"1.4.4",length:0,size:function(){return this.length},
toArray:function(){return N.call(this,0)},get:function(j){return j==null?this.toArray():j<0?this.slice(j)[0]:this[j]},pushStack:function(j,s,v){var z=b();b.isArray(j)?M.apply(z,j):b.merge(z,j);z.prevObject=this;z.context=this.context;if(s==="find")z.selector=this.selector+(this.selector?" ":"")+v;else if(s)z.selector=this.selector+"."+s+"("+v+")";return z},each:function(j,s){return b.each(this,j,s)},ready:function(j){b.bindReady();if(b.isReady)j.call(t,b);else q&&q.push(j);return this},eq:function(j){return j===
-1?this.slice(j):this.slice(j,+j+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(N.apply(this,arguments),"slice",N.call(arguments).join(","))},map:function(j){return this.pushStack(b.map(this,function(s,v){return j.call(s,v,s)}))},end:function(){return this.prevObject||b(null)},push:M,sort:[].sort,splice:[].splice};b.fn.init.prototype=b.fn;b.extend=b.fn.extend=function(){var j,s,v,z,H,G=arguments[0]||{},K=1,Q=arguments.length,ga=false;
if(typeof G==="boolean"){ga=G;G=arguments[1]||{};K=2}if(typeof G!=="object"&&!b.isFunction(G))G={};if(Q===K){G=this;--K}for(;K<Q;K++)if((j=arguments[K])!=null)for(s in j){v=G[s];z=j[s];if(G!==z)if(ga&&z&&(b.isPlainObject(z)||(H=b.isArray(z)))){if(H){H=false;v=v&&b.isArray(v)?v:[]}else v=v&&b.isPlainObject(v)?v:{};G[s]=b.extend(ga,v,z)}else if(z!==B)G[s]=z}return G};b.extend({noConflict:function(j){E.$=e;if(j)E.jQuery=d;return b},isReady:false,readyWait:1,ready:function(j){j===true&&b.readyWait--;
if(!b.readyWait||j!==true&&!b.isReady){if(!t.body)return setTimeout(b.ready,1);b.isReady=true;if(!(j!==true&&--b.readyWait>0))if(q){var s=0,v=q;for(q=null;j=v[s++];)j.call(t,b);b.fn.trigger&&b(t).trigger("ready").unbind("ready")}}},bindReady:function(){if(!p){p=true;if(t.readyState==="complete")return setTimeout(b.ready,1);if(t.addEventListener){t.addEventListener("DOMContentLoaded",u,false);E.addEventListener("load",b.ready,false)}else if(t.attachEvent){t.attachEvent("onreadystatechange",u);E.attachEvent("onload",
b.ready);var j=false;try{j=E.frameElement==null}catch(s){}t.documentElement.doScroll&&j&&a()}}},isFunction:function(j){return b.type(j)==="function"},isArray:Array.isArray||function(j){return b.type(j)==="array"},isWindow:function(j){return j&&typeof j==="object"&&"setInterval"in j},isNaN:function(j){return j==null||!r.test(j)||isNaN(j)},type:function(j){return j==null?String(j):R[y.call(j)]||"object"},isPlainObject:function(j){if(!j||b.type(j)!=="object"||j.nodeType||b.isWindow(j))return false;if(j.constructor&&
!F.call(j,"constructor")&&!F.call(j.constructor.prototype,"isPrototypeOf"))return false;for(var s in j);return s===B||F.call(j,s)},isEmptyObject:function(j){for(var s in j)return false;return true},error:function(j){throw j;},parseJSON:function(j){if(typeof j!=="string"||!j)return null;j=b.trim(j);if(C.test(j.replace(J,"@").replace(w,"]").replace(I,"")))return E.JSON&&E.JSON.parse?E.JSON.parse(j):(new Function("return "+j))();else b.error("Invalid JSON: "+j)},noop:function(){},globalEval:function(j){if(j&&
l.test(j)){var s=t.getElementsByTagName("head")[0]||t.documentElement,v=t.createElement("script");v.type="text/javascript";if(b.support.scriptEval)v.appendChild(t.createTextNode(j));else v.text=j;s.insertBefore(v,s.firstChild);s.removeChild(v)}},nodeName:function(j,s){return j.nodeName&&j.nodeName.toUpperCase()===s.toUpperCase()},each:function(j,s,v){var z,H=0,G=j.length,K=G===B||b.isFunction(j);if(v)if(K)for(z in j){if(s.apply(j[z],v)===false)break}else for(;H<G;){if(s.apply(j[H++],v)===false)break}else if(K)for(z in j){if(s.call(j[z],
z,j[z])===false)break}else for(v=j[0];H<G&&s.call(v,H,v)!==false;v=j[++H]);return j},trim:O?function(j){return j==null?"":O.call(j)}:function(j){return j==null?"":j.toString().replace(k,"").replace(o,"")},makeArray:function(j,s){var v=s||[];if(j!=null){var z=b.type(j);j.length==null||z==="string"||z==="function"||z==="regexp"||b.isWindow(j)?M.call(v,j):b.merge(v,j)}return v},inArray:function(j,s){if(s.indexOf)return s.indexOf(j);for(var v=0,z=s.length;v<z;v++)if(s[v]===j)return v;return-1},merge:function(j,
s){var v=j.length,z=0;if(typeof s.length==="number")for(var H=s.length;z<H;z++)j[v++]=s[z];else for(;s[z]!==B;)j[v++]=s[z++];j.length=v;return j},grep:function(j,s,v){var z=[],H;v=!!v;for(var G=0,K=j.length;G<K;G++){H=!!s(j[G],G);v!==H&&z.push(j[G])}return z},map:function(j,s,v){for(var z=[],H,G=0,K=j.length;G<K;G++){H=s(j[G],G,v);if(H!=null)z[z.length]=H}return z.concat.apply([],z)},guid:1,proxy:function(j,s,v){if(arguments.length===2)if(typeof s==="string"){v=j;j=v[s];s=B}else if(s&&!b.isFunction(s)){v=
s;s=B}if(!s&&j)s=function(){return j.apply(v||this,arguments)};if(j)s.guid=j.guid=j.guid||s.guid||b.guid++;return s},access:function(j,s,v,z,H,G){var K=j.length;if(typeof s==="object"){for(var Q in s)b.access(j,Q,s[Q],z,H,v);return j}if(v!==B){z=!G&&z&&b.isFunction(v);for(Q=0;Q<K;Q++)H(j[Q],s,z?v.call(j[Q],Q,H(j[Q],s)):v,G);return j}return K?H(j[0],s):B},now:function(){return(new Date).getTime()},uaMatch:function(j){j=j.toLowerCase();j=L.exec(j)||g.exec(j)||i.exec(j)||j.indexOf("compatible")<0&&n.exec(j)||
[];return{browser:j[1]||"",version:j[2]||"0"}},browser:{}});b.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(j,s){R["[object "+s+"]"]=s.toLowerCase()});m=b.uaMatch(m);if(m.browser){b.browser[m.browser]=true;b.browser.version=m.version}if(b.browser.webkit)b.browser.safari=true;if(D)b.inArray=function(j,s){return D.call(s,j)};if(!/\s/.test("\u00a0")){k=/^[\s\xA0]+/;o=/[\s\xA0]+$/}f=b(t);if(t.addEventListener)u=function(){t.removeEventListener("DOMContentLoaded",u,
false);b.ready()};else if(t.attachEvent)u=function(){if(t.readyState==="complete"){t.detachEvent("onreadystatechange",u);b.ready()}};return E.jQuery=E.$=b}();(function(){c.support={};var a=t.documentElement,b=t.createElement("script"),d=t.createElement("div"),e="script"+c.now();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var f=d.getElementsByTagName("*"),h=d.getElementsByTagName("a")[0],l=t.createElement("select"),
k=l.appendChild(t.createElement("option"));if(!(!f||!f.length||!h)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(h.getAttribute("style")),hrefNormalized:h.getAttribute("href")==="/a",opacity:/^0.55$/.test(h.style.opacity),cssFloat:!!h.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:k.selected,deleteExpando:true,optDisabled:false,checkClone:false,
scriptEval:false,noCloneEvent:true,boxModel:null,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableHiddenOffsets:true};l.disabled=true;c.support.optDisabled=!k.disabled;b.type="text/javascript";try{b.appendChild(t.createTextNode("window."+e+"=1;"))}catch(o){}a.insertBefore(b,a.firstChild);if(E[e]){c.support.scriptEval=true;delete E[e]}try{delete b.test}catch(x){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function r(){c.support.noCloneEvent=
false;d.detachEvent("onclick",r)});d.cloneNode(true).fireEvent("onclick")}d=t.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=t.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var r=t.createElement("div");r.style.width=r.style.paddingLeft="1px";t.body.appendChild(r);c.boxModel=c.support.boxModel=r.offsetWidth===2;if("zoom"in r.style){r.style.display="inline";r.style.zoom=
1;c.support.inlineBlockNeedsLayout=r.offsetWidth===2;r.style.display="";r.innerHTML="<div style='width:4px;'></div>";c.support.shrinkWrapBlocks=r.offsetWidth!==2}r.innerHTML="<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";var A=r.getElementsByTagName("td");c.support.reliableHiddenOffsets=A[0].offsetHeight===0;A[0].style.display="";A[1].style.display="none";c.support.reliableHiddenOffsets=c.support.reliableHiddenOffsets&&A[0].offsetHeight===0;r.innerHTML="";t.body.removeChild(r).style.display=
"none"});a=function(r){var A=t.createElement("div");r="on"+r;var C=r in A;if(!C){A.setAttribute(r,"return;");C=typeof A[r]==="function"}return C};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=f=h=null}})();var ra={},Ja=/^(?:\{.*\}|\[.*\])$/;c.extend({cache:{},uuid:0,expando:"jQuery"+c.now(),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},data:function(a,b,d){if(c.acceptData(a)){a=a==E?ra:a;var e=a.nodeType,f=e?a[c.expando]:null,h=
c.cache;if(!(e&&!f&&typeof b==="string"&&d===B)){if(e)f||(a[c.expando]=f=++c.uuid);else h=a;if(typeof b==="object")if(e)h[f]=c.extend(h[f],b);else c.extend(h,b);else if(e&&!h[f])h[f]={};a=e?h[f]:h;if(d!==B)a[b]=d;return typeof b==="string"?a[b]:a}}},removeData:function(a,b){if(c.acceptData(a)){a=a==E?ra:a;var d=a.nodeType,e=d?a[c.expando]:a,f=c.cache,h=d?f[e]:e;if(b){if(h){delete h[b];d&&c.isEmptyObject(h)&&c.removeData(a)}}else if(d&&c.support.deleteExpando)delete a[c.expando];else if(a.removeAttribute)a.removeAttribute(c.expando);
else if(d)delete f[e];else for(var l in a)delete a[l]}},acceptData:function(a){if(a.nodeName){var b=c.noData[a.nodeName.toLowerCase()];if(b)return!(b===true||a.getAttribute("classid")!==b)}return true}});c.fn.extend({data:function(a,b){var d=null;if(typeof a==="undefined"){if(this.length){var e=this[0].attributes,f;d=c.data(this[0]);for(var h=0,l=e.length;h<l;h++){f=e[h].name;if(f.indexOf("data-")===0){f=f.substr(5);ka(this[0],f,d[f])}}}return d}else if(typeof a==="object")return this.each(function(){c.data(this,
a)});var k=a.split(".");k[1]=k[1]?"."+k[1]:"";if(b===B){d=this.triggerHandler("getData"+k[1]+"!",[k[0]]);if(d===B&&this.length){d=c.data(this[0],a);d=ka(this[0],a,d)}return d===B&&k[1]?this.data(k[0]):d}else return this.each(function(){var o=c(this),x=[k[0],b];o.triggerHandler("setData"+k[1]+"!",x);c.data(this,a,b);o.triggerHandler("changeData"+k[1]+"!",x)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var e=
c.data(a,b);if(!d)return e||[];if(!e||c.isArray(d))e=c.data(a,b,c.makeArray(d));else e.push(d);return e}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),e=d.shift();if(e==="inprogress")e=d.shift();if(e){b==="fx"&&d.unshift("inprogress");e.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===B)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,
a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var sa=/[\n\t]/g,ha=/\s+/,Sa=/\r/g,Ta=/^(?:href|src|style)$/,Ua=/^(?:button|input)$/i,Va=/^(?:button|input|object|select|textarea)$/i,Wa=/^a(?:rea)?$/i,ta=/^(?:radio|checkbox)$/i;c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",
colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};c.fn.extend({attr:function(a,b){return c.access(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(x){var r=c(this);r.addClass(a.call(this,x,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ha),d=0,e=this.length;d<e;d++){var f=this[d];if(f.nodeType===
1)if(f.className){for(var h=" "+f.className+" ",l=f.className,k=0,o=b.length;k<o;k++)if(h.indexOf(" "+b[k]+" ")<0)l+=" "+b[k];f.className=c.trim(l)}else f.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(o){var x=c(this);x.removeClass(a.call(this,o,x.attr("class")))});if(a&&typeof a==="string"||a===B)for(var b=(a||"").split(ha),d=0,e=this.length;d<e;d++){var f=this[d];if(f.nodeType===1&&f.className)if(a){for(var h=(" "+f.className+" ").replace(sa," "),
l=0,k=b.length;l<k;l++)h=h.replace(" "+b[l]+" "," ");f.className=c.trim(h)}else f.className=""}return this},toggleClass:function(a,b){var d=typeof a,e=typeof b==="boolean";if(c.isFunction(a))return this.each(function(f){var h=c(this);h.toggleClass(a.call(this,f,h.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var f,h=0,l=c(this),k=b,o=a.split(ha);f=o[h++];){k=e?k:!l.hasClass(f);l[k?"addClass":"removeClass"](f)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,
"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(sa," ").indexOf(a)>-1)return true;return false},val:function(a){if(!arguments.length){var b=this[0];if(b){if(c.nodeName(b,"option")){var d=b.attributes.value;return!d||d.specified?b.value:b.text}if(c.nodeName(b,"select")){var e=b.selectedIndex;d=[];var f=b.options;b=b.type==="select-one";
if(e<0)return null;var h=b?e:0;for(e=b?e+1:f.length;h<e;h++){var l=f[h];if(l.selected&&(c.support.optDisabled?!l.disabled:l.getAttribute("disabled")===null)&&(!l.parentNode.disabled||!c.nodeName(l.parentNode,"optgroup"))){a=c(l).val();if(b)return a;d.push(a)}}return d}if(ta.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Sa,"")}return B}var k=c.isFunction(a);return this.each(function(o){var x=c(this),r=a;if(this.nodeType===1){if(k)r=
a.call(this,o,x.val());if(r==null)r="";else if(typeof r==="number")r+="";else if(c.isArray(r))r=c.map(r,function(C){return C==null?"":C+""});if(c.isArray(r)&&ta.test(this.type))this.checked=c.inArray(x.val(),r)>=0;else if(c.nodeName(this,"select")){var A=c.makeArray(r);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),A)>=0});if(!A.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},
attr:function(a,b,d,e){if(!a||a.nodeType===3||a.nodeType===8)return B;if(e&&b in c.attrFn)return c(a)[b](d);e=a.nodeType!==1||!c.isXMLDoc(a);var f=d!==B;b=e&&c.props[b]||b;var h=Ta.test(b);if((b in a||a[b]!==B)&&e&&!h){if(f){b==="type"&&Ua.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");if(d===null)a.nodeType===1&&a.removeAttribute(b);else a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&
b.specified?b.value:Va.test(a.nodeName)||Wa.test(a.nodeName)&&a.href?0:B;return a[b]}if(!c.support.style&&e&&b==="style"){if(f)a.style.cssText=""+d;return a.style.cssText}f&&a.setAttribute(b,""+d);if(!a.attributes[b]&&a.hasAttribute&&!a.hasAttribute(b))return B;a=!c.support.hrefNormalized&&e&&h?a.getAttribute(b,2):a.getAttribute(b);return a===null?B:a}});var X=/\.(.*)$/,ia=/^(?:textarea|input|select)$/i,La=/\./g,Ma=/ /g,Xa=/[^\w\s.|`]/g,Ya=function(a){return a.replace(Xa,"\\$&")},ua={focusin:0,focusout:0};
c.event={add:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(c.isWindow(a)&&a!==E&&!a.frameElement)a=E;if(d===false)d=U;else if(!d)return;var f,h;if(d.handler){f=d;d=f.handler}if(!d.guid)d.guid=c.guid++;if(h=c.data(a)){var l=a.nodeType?"events":"__events__",k=h[l],o=h.handle;if(typeof k==="function"){o=k.handle;k=k.events}else if(!k){a.nodeType||(h[l]=h=function(){});h.events=k={}}if(!o)h.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,
arguments):B};o.elem=a;b=b.split(" ");for(var x=0,r;l=b[x++];){h=f?c.extend({},f):{handler:d,data:e};if(l.indexOf(".")>-1){r=l.split(".");l=r.shift();h.namespace=r.slice(0).sort().join(".")}else{r=[];h.namespace=""}h.type=l;if(!h.guid)h.guid=d.guid;var A=k[l],C=c.event.special[l]||{};if(!A){A=k[l]=[];if(!C.setup||C.setup.call(a,e,r,o)===false)if(a.addEventListener)a.addEventListener(l,o,false);else a.attachEvent&&a.attachEvent("on"+l,o)}if(C.add){C.add.call(a,h);if(!h.handler.guid)h.handler.guid=
d.guid}A.push(h);c.event.global[l]=true}a=null}}},global:{},remove:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(d===false)d=U;var f,h,l=0,k,o,x,r,A,C,J=a.nodeType?"events":"__events__",w=c.data(a),I=w&&w[J];if(w&&I){if(typeof I==="function"){w=I;I=I.events}if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(f in I)c.event.remove(a,f+b)}else{for(b=b.split(" ");f=b[l++];){r=f;k=f.indexOf(".")<0;o=[];if(!k){o=f.split(".");f=o.shift();x=RegExp("(^|\\.)"+
c.map(o.slice(0).sort(),Ya).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(A=I[f])if(d){r=c.event.special[f]||{};for(h=e||0;h<A.length;h++){C=A[h];if(d.guid===C.guid){if(k||x.test(C.namespace)){e==null&&A.splice(h--,1);r.remove&&r.remove.call(a,C)}if(e!=null)break}}if(A.length===0||e!=null&&A.length===1){if(!r.teardown||r.teardown.call(a,o)===false)c.removeEvent(a,f,w.handle);delete I[f]}}else for(h=0;h<A.length;h++){C=A[h];if(k||x.test(C.namespace)){c.event.remove(a,r,C.handler,h);A.splice(h--,1)}}}if(c.isEmptyObject(I)){if(b=
w.handle)b.elem=null;delete w.events;delete w.handle;if(typeof w==="function")c.removeData(a,J);else c.isEmptyObject(w)&&c.removeData(a)}}}}},trigger:function(a,b,d,e){var f=a.type||a;if(!e){a=typeof a==="object"?a[c.expando]?a:c.extend(c.Event(f),a):c.Event(f);if(f.indexOf("!")>=0){a.type=f=f.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[f]&&c.each(c.cache,function(){this.events&&this.events[f]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===
8)return B;a.result=B;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(e=d.nodeType?c.data(d,"handle"):(c.data(d,"__events__")||{}).handle)&&e.apply(d,b);e=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+f]&&d["on"+f].apply(d,b)===false){a.result=false;a.preventDefault()}}catch(h){}if(!a.isPropagationStopped()&&e)c.event.trigger(a,b,e,true);else if(!a.isDefaultPrevented()){var l;e=a.target;var k=f.replace(X,""),o=c.nodeName(e,"a")&&k===
"click",x=c.event.special[k]||{};if((!x._default||x._default.call(d,a)===false)&&!o&&!(e&&e.nodeName&&c.noData[e.nodeName.toLowerCase()])){try{if(e[k]){if(l=e["on"+k])e["on"+k]=null;c.event.triggered=true;e[k]()}}catch(r){}if(l)e["on"+k]=l;c.event.triggered=false}}},handle:function(a){var b,d,e,f;d=[];var h=c.makeArray(arguments);a=h[0]=c.event.fix(a||E.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;if(!b){e=a.type.split(".");a.type=e.shift();d=e.slice(0).sort();e=RegExp("(^|\\.)"+
d.join("\\.(?:.*\\.)?")+"(\\.|$)")}a.namespace=a.namespace||d.join(".");f=c.data(this,this.nodeType?"events":"__events__");if(typeof f==="function")f=f.events;d=(f||{})[a.type];if(f&&d){d=d.slice(0);f=0;for(var l=d.length;f<l;f++){var k=d[f];if(b||e.test(k.namespace)){a.handler=k.handler;a.data=k.data;a.handleObj=k;k=k.handler.apply(this,h);if(k!==B){a.result=k;if(k===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[c.expando])return a;var b=a;a=c.Event(b);for(var d=this.props.length,e;d;){e=this.props[--d];a[e]=b[e]}if(!a.target)a.target=a.srcElement||t;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=t.documentElement;d=t.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(a.which==null&&(a.charCode!=null||a.keyCode!=null))a.which=a.charCode!=null?a.charCode:a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==B)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,Y(a.origType,a.selector),c.extend({},a,{handler:Ka,guid:a.handler.guid}))},remove:function(a){c.event.remove(this,
Y(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,d){if(c.isWindow(this))this.onbeforeunload=d},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.removeEvent=t.removeEventListener?function(a,b,d){a.removeEventListener&&a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent&&a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=
c.now();this[c.expando]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=ca;var a=this.originalEvent;if(a)if(a.preventDefault)a.preventDefault();else a.returnValue=false},stopPropagation:function(){this.isPropagationStopped=ca;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=ca;this.stopPropagation()},isDefaultPrevented:U,isPropagationStopped:U,isImmediatePropagationStopped:U};
var va=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},wa=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?wa:va,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?wa:va)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(){if(this.nodeName.toLowerCase()!==
"form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length){a.liveFired=B;return la("submit",this,arguments)}});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13){a.liveFired=B;return la("submit",this,arguments)}})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};if(!c.support.changeBubbles){var V,
xa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(e){return e.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},Z=function(a,b){var d=a.target,e,f;if(!(!ia.test(d.nodeName)||d.readOnly)){e=c.data(d,"_change_data");f=xa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",f);if(!(e===B||f===e))if(e!=null||f){a.type="change";a.liveFired=
B;return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:Z,beforedeactivate:Z,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return Z.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return Z.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,"_change_data",xa(a))}},setup:function(){if(this.type===
"file")return false;for(var a in V)c.event.add(this,a+".specialChange",V[a]);return ia.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return ia.test(this.nodeName)}};V=c.event.special.change.filters;V.focus=V.beforeactivate}t.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.trigger(e,null,e.target)}c.event.special[b]={setup:function(){ua[b]++===0&&t.addEventListener(a,d,true)},teardown:function(){--ua[b]===
0&&t.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,e,f){if(typeof d==="object"){for(var h in d)this[b](h,e,d[h],f);return this}if(c.isFunction(e)||e===false){f=e;e=B}var l=b==="one"?c.proxy(f,function(o){c(this).unbind(o,l);return f.apply(this,arguments)}):f;if(d==="unload"&&b!=="one")this.one(d,e,f);else{h=0;for(var k=this.length;h<k;h++)c.event.add(this[h],d,l,e)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&!a.preventDefault)for(var d in a)this.unbind(d,
a[d]);else{d=0;for(var e=this.length;d<e;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,e){return this.live(b,d,e,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){var d=c.Event(a);d.preventDefault();d.stopPropagation();c.event.trigger(d,b,this[0]);return d.result}},toggle:function(a){for(var b=arguments,d=
1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(e){var f=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,f+1);e.preventDefault();return b[f].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var ya={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,e,f,h){var l,k=0,o,x,r=h||this.selector;h=h?this:c(this.context);if(typeof d===
"object"&&!d.preventDefault){for(l in d)h[b](l,e,d[l],r);return this}if(c.isFunction(e)){f=e;e=B}for(d=(d||"").split(" ");(l=d[k++])!=null;){o=X.exec(l);x="";if(o){x=o[0];l=l.replace(X,"")}if(l==="hover")d.push("mouseenter"+x,"mouseleave"+x);else{o=l;if(l==="focus"||l==="blur"){d.push(ya[l]+x);l+=x}else l=(ya[l]||l)+x;if(b==="live"){x=0;for(var A=h.length;x<A;x++)c.event.add(h[x],"live."+Y(l,r),{data:e,selector:r,handler:f,origType:l,origHandler:f,preType:o})}else h.unbind("live."+Y(l,r),f)}}return this}});
c.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".split(" "),function(a,b){c.fn[b]=function(d,e){if(e==null){e=d;d=null}return arguments.length>0?this.bind(b,d,e):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});E.attachEvent&&!E.addEventListener&&c(E).bind("unload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});
(function(){function a(g,i,n,m,p,q){p=0;for(var u=m.length;p<u;p++){var y=m[p];if(y){var F=false;for(y=y[g];y;){if(y.sizcache===n){F=m[y.sizset];break}if(y.nodeType===1&&!q){y.sizcache=n;y.sizset=p}if(y.nodeName.toLowerCase()===i){F=y;break}y=y[g]}m[p]=F}}}function b(g,i,n,m,p,q){p=0;for(var u=m.length;p<u;p++){var y=m[p];if(y){var F=false;for(y=y[g];y;){if(y.sizcache===n){F=m[y.sizset];break}if(y.nodeType===1){if(!q){y.sizcache=n;y.sizset=p}if(typeof i!=="string"){if(y===i){F=true;break}}else if(k.filter(i,
[y]).length>0){F=y;break}}y=y[g]}m[p]=F}}}var d=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,h=false,l=true;[0,0].sort(function(){l=false;return 0});var k=function(g,i,n,m){n=n||[];var p=i=i||t;if(i.nodeType!==1&&i.nodeType!==9)return[];if(!g||typeof g!=="string")return n;var q,u,y,F,M,N=true,O=k.isXML(i),D=[],R=g;do{d.exec("");if(q=d.exec(R)){R=q[3];D.push(q[1]);if(q[2]){F=q[3];
break}}}while(q);if(D.length>1&&x.exec(g))if(D.length===2&&o.relative[D[0]])u=L(D[0]+D[1],i);else for(u=o.relative[D[0]]?[i]:k(D.shift(),i);D.length;){g=D.shift();if(o.relative[g])g+=D.shift();u=L(g,u)}else{if(!m&&D.length>1&&i.nodeType===9&&!O&&o.match.ID.test(D[0])&&!o.match.ID.test(D[D.length-1])){q=k.find(D.shift(),i,O);i=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]}if(i){q=m?{expr:D.pop(),set:C(m)}:k.find(D.pop(),D.length===1&&(D[0]==="~"||D[0]==="+")&&i.parentNode?i.parentNode:i,O);u=q.expr?k.filter(q.expr,
q.set):q.set;if(D.length>0)y=C(u);else N=false;for(;D.length;){q=M=D.pop();if(o.relative[M])q=D.pop();else M="";if(q==null)q=i;o.relative[M](y,q,O)}}else y=[]}y||(y=u);y||k.error(M||g);if(f.call(y)==="[object Array]")if(N)if(i&&i.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&k.contains(i,y[g])))n.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&n.push(u[g]);else n.push.apply(n,y);else C(y,n);if(F){k(F,p,n,m);k.uniqueSort(n)}return n};k.uniqueSort=function(g){if(w){h=
l;g.sort(w);if(h)for(var i=1;i<g.length;i++)g[i]===g[i-1]&&g.splice(i--,1)}return g};k.matches=function(g,i){return k(g,null,null,i)};k.matchesSelector=function(g,i){return k(i,null,null,[g]).length>0};k.find=function(g,i,n){var m;if(!g)return[];for(var p=0,q=o.order.length;p<q;p++){var u,y=o.order[p];if(u=o.leftMatch[y].exec(g)){var F=u[1];u.splice(1,1);if(F.substr(F.length-1)!=="\\"){u[1]=(u[1]||"").replace(/\\/g,"");m=o.find[y](u,i,n);if(m!=null){g=g.replace(o.match[y],"");break}}}}m||(m=i.getElementsByTagName("*"));
return{set:m,expr:g}};k.filter=function(g,i,n,m){for(var p,q,u=g,y=[],F=i,M=i&&i[0]&&k.isXML(i[0]);g&&i.length;){for(var N in o.filter)if((p=o.leftMatch[N].exec(g))!=null&&p[2]){var O,D,R=o.filter[N];D=p[1];q=false;p.splice(1,1);if(D.substr(D.length-1)!=="\\"){if(F===y)y=[];if(o.preFilter[N])if(p=o.preFilter[N](p,F,n,y,m,M)){if(p===true)continue}else q=O=true;if(p)for(var j=0;(D=F[j])!=null;j++)if(D){O=R(D,p,j,F);var s=m^!!O;if(n&&O!=null)if(s)q=true;else F[j]=false;else if(s){y.push(D);q=true}}if(O!==
B){n||(F=y);g=g.replace(o.match[N],"");if(!q)return[];break}}}if(g===u)if(q==null)k.error(g);else break;u=g}return F};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var o=k.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|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},relative:{"+":function(g,i){var n=typeof i==="string",m=n&&!/\W/.test(i);n=n&&!m;if(m)i=i.toLowerCase();m=0;for(var p=g.length,q;m<p;m++)if(q=g[m]){for(;(q=q.previousSibling)&&q.nodeType!==1;);g[m]=n||q&&q.nodeName.toLowerCase()===
i?q||false:q===i}n&&k.filter(i,g,true)},">":function(g,i){var n,m=typeof i==="string",p=0,q=g.length;if(m&&!/\W/.test(i))for(i=i.toLowerCase();p<q;p++){if(n=g[p]){n=n.parentNode;g[p]=n.nodeName.toLowerCase()===i?n:false}}else{for(;p<q;p++)if(n=g[p])g[p]=m?n.parentNode:n.parentNode===i;m&&k.filter(i,g,true)}},"":function(g,i,n){var m,p=e++,q=b;if(typeof i==="string"&&!/\W/.test(i)){m=i=i.toLowerCase();q=a}q("parentNode",i,p,g,m,n)},"~":function(g,i,n){var m,p=e++,q=b;if(typeof i==="string"&&!/\W/.test(i)){m=
i=i.toLowerCase();q=a}q("previousSibling",i,p,g,m,n)}},find:{ID:function(g,i,n){if(typeof i.getElementById!=="undefined"&&!n)return(g=i.getElementById(g[1]))&&g.parentNode?[g]:[]},NAME:function(g,i){if(typeof i.getElementsByName!=="undefined"){for(var n=[],m=i.getElementsByName(g[1]),p=0,q=m.length;p<q;p++)m[p].getAttribute("name")===g[1]&&n.push(m[p]);return n.length===0?null:n}},TAG:function(g,i){return i.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,i,n,m,p,q){g=" "+g[1].replace(/\\/g,
"")+" ";if(q)return g;q=0;for(var u;(u=i[q])!=null;q++)if(u)if(p^(u.className&&(" "+u.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))n||m.push(u);else if(n)i[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var i=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=i[1]+(i[2]||1)-0;g[3]=i[3]-0}g[0]=e++;return g},ATTR:function(g,i,n,
m,p,q){i=g[1].replace(/\\/g,"");if(!q&&o.attrMap[i])g[1]=o.attrMap[i];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,i,n,m,p){if(g[1]==="not")if((d.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,i);else{g=k.filter(g[3],i,n,true^p);n||m.push.apply(m,g);return false}else if(o.match.POS.test(g[0])||o.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===
true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,i,n){return!!k(n[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===
g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,i){return i===0},last:function(g,i,n,m){return i===m.length-1},even:function(g,i){return i%2===0},odd:function(g,i){return i%2===1},lt:function(g,i,n){return i<n[3]-0},gt:function(g,i,n){return i>n[3]-0},nth:function(g,i,n){return n[3]-
0===i},eq:function(g,i,n){return n[3]-0===i}},filter:{PSEUDO:function(g,i,n,m){var p=i[1],q=o.filters[p];if(q)return q(g,n,i,m);else if(p==="contains")return(g.textContent||g.innerText||k.getText([g])||"").indexOf(i[3])>=0;else if(p==="not"){i=i[3];n=0;for(m=i.length;n<m;n++)if(i[n]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+p)},CHILD:function(g,i){var n=i[1],m=g;switch(n){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(n===
"first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":n=i[2];var p=i[3];if(n===1&&p===0)return true;var q=i[0],u=g.parentNode;if(u&&(u.sizcache!==q||!g.nodeIndex)){var y=0;for(m=u.firstChild;m;m=m.nextSibling)if(m.nodeType===1)m.nodeIndex=++y;u.sizcache=q}m=g.nodeIndex-p;return n===0?m===0:m%n===0&&m/n>=0}},ID:function(g,i){return g.nodeType===1&&g.getAttribute("id")===i},TAG:function(g,i){return i==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===
i},CLASS:function(g,i){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(i)>-1},ATTR:function(g,i){var n=i[1];n=o.attrHandle[n]?o.attrHandle[n](g):g[n]!=null?g[n]:g.getAttribute(n);var m=n+"",p=i[2],q=i[4];return n==null?p==="!=":p==="="?m===q:p==="*="?m.indexOf(q)>=0:p==="~="?(" "+m+" ").indexOf(q)>=0:!q?m&&n!==false:p==="!="?m!==q:p==="^="?m.indexOf(q)===0:p==="$="?m.substr(m.length-q.length)===q:p==="|="?m===q||m.substr(0,q.length+1)===q+"-":false},POS:function(g,i,n,m){var p=o.setFilters[i[2]];
if(p)return p(g,n,i,m)}}},x=o.match.POS,r=function(g,i){return"\\"+(i-0+1)},A;for(A in o.match){o.match[A]=RegExp(o.match[A].source+/(?![^\[]*\])(?![^\(]*\))/.source);o.leftMatch[A]=RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[A].source.replace(/\\(\d+)/g,r))}var C=function(g,i){g=Array.prototype.slice.call(g,0);if(i){i.push.apply(i,g);return i}return g};try{Array.prototype.slice.call(t.documentElement.childNodes,0)}catch(J){C=function(g,i){var n=0,m=i||[];if(f.call(g)==="[object Array]")Array.prototype.push.apply(m,
g);else if(typeof g.length==="number")for(var p=g.length;n<p;n++)m.push(g[n]);else for(;g[n];n++)m.push(g[n]);return m}}var w,I;if(t.documentElement.compareDocumentPosition)w=function(g,i){if(g===i){h=true;return 0}if(!g.compareDocumentPosition||!i.compareDocumentPosition)return g.compareDocumentPosition?-1:1;return g.compareDocumentPosition(i)&4?-1:1};else{w=function(g,i){var n,m,p=[],q=[];n=g.parentNode;m=i.parentNode;var u=n;if(g===i){h=true;return 0}else if(n===m)return I(g,i);else if(n){if(!m)return 1}else return-1;
for(;u;){p.unshift(u);u=u.parentNode}for(u=m;u;){q.unshift(u);u=u.parentNode}n=p.length;m=q.length;for(u=0;u<n&&u<m;u++)if(p[u]!==q[u])return I(p[u],q[u]);return u===n?I(g,q[u],-1):I(p[u],i,1)};I=function(g,i,n){if(g===i)return n;for(g=g.nextSibling;g;){if(g===i)return-1;g=g.nextSibling}return 1}}k.getText=function(g){for(var i="",n,m=0;g[m];m++){n=g[m];if(n.nodeType===3||n.nodeType===4)i+=n.nodeValue;else if(n.nodeType!==8)i+=k.getText(n.childNodes)}return i};(function(){var g=t.createElement("div"),
i="script"+(new Date).getTime(),n=t.documentElement;g.innerHTML="<a name='"+i+"'/>";n.insertBefore(g,n.firstChild);if(t.getElementById(i)){o.find.ID=function(m,p,q){if(typeof p.getElementById!=="undefined"&&!q)return(p=p.getElementById(m[1]))?p.id===m[1]||typeof p.getAttributeNode!=="undefined"&&p.getAttributeNode("id").nodeValue===m[1]?[p]:B:[]};o.filter.ID=function(m,p){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===p}}n.removeChild(g);
n=g=null})();(function(){var g=t.createElement("div");g.appendChild(t.createComment(""));if(g.getElementsByTagName("*").length>0)o.find.TAG=function(i,n){var m=n.getElementsByTagName(i[1]);if(i[1]==="*"){for(var p=[],q=0;m[q];q++)m[q].nodeType===1&&p.push(m[q]);m=p}return m};g.innerHTML="<a href='#'></a>";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")o.attrHandle.href=function(i){return i.getAttribute("href",2)};g=null})();t.querySelectorAll&&
function(){var g=k,i=t.createElement("div");i.innerHTML="<p class='TEST'></p>";if(!(i.querySelectorAll&&i.querySelectorAll(".TEST").length===0)){k=function(m,p,q,u){p=p||t;m=m.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!u&&!k.isXML(p))if(p.nodeType===9)try{return C(p.querySelectorAll(m),q)}catch(y){}else if(p.nodeType===1&&p.nodeName.toLowerCase()!=="object"){var F=p.getAttribute("id"),M=F||"__sizzle__";F||p.setAttribute("id",M);try{return C(p.querySelectorAll("#"+M+" "+m),q)}catch(N){}finally{F||
p.removeAttribute("id")}}return g(m,p,q,u)};for(var n in g)k[n]=g[n];i=null}}();(function(){var g=t.documentElement,i=g.matchesSelector||g.mozMatchesSelector||g.webkitMatchesSelector||g.msMatchesSelector,n=false;try{i.call(t.documentElement,"[test!='']:sizzle")}catch(m){n=true}if(i)k.matchesSelector=function(p,q){q=q.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(p))try{if(n||!o.match.PSEUDO.test(q)&&!/!=/.test(q))return i.call(p,q)}catch(u){}return k(q,null,null,[p]).length>0}})();(function(){var g=
t.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){o.order.splice(1,0,"CLASS");o.find.CLASS=function(i,n,m){if(typeof n.getElementsByClassName!=="undefined"&&!m)return n.getElementsByClassName(i[1])};g=null}}})();k.contains=t.documentElement.contains?function(g,i){return g!==i&&(g.contains?g.contains(i):true)}:t.documentElement.compareDocumentPosition?
function(g,i){return!!(g.compareDocumentPosition(i)&16)}:function(){return false};k.isXML=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false};var L=function(g,i){for(var n,m=[],p="",q=i.nodeType?[i]:i;n=o.match.PSEUDO.exec(g);){p+=n[0];g=g.replace(o.match.PSEUDO,"")}g=o.relative[g]?g+"*":g;n=0;for(var u=q.length;n<u;n++)k(g,q[n],m);return k.filter(p,m)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=k.getText;c.isXMLDoc=k.isXML;
c.contains=k.contains})();var Za=/Until$/,$a=/^(?:parents|prevUntil|prevAll)/,ab=/,/,Na=/^.[^:#\[\.,]*$/,bb=Array.prototype.slice,cb=c.expr.match.POS;c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,e=0,f=this.length;e<f;e++){d=b.length;c.find(a,this[e],b);if(e>0)for(var h=d;h<b.length;h++)for(var l=0;l<d;l++)if(b[l]===b[h]){b.splice(h--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,e=b.length;d<e;d++)if(c.contains(this,b[d]))return true})},
not:function(a){return this.pushStack(ma(this,a,false),"not",a)},filter:function(a){return this.pushStack(ma(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){var d=[],e,f,h=this[0];if(c.isArray(a)){var l,k={},o=1;if(h&&a.length){e=0;for(f=a.length;e<f;e++){l=a[e];k[l]||(k[l]=c.expr.match.POS.test(l)?c(l,b||this.context):l)}for(;h&&h.ownerDocument&&h!==b;){for(l in k){e=k[l];if(e.jquery?e.index(h)>-1:c(h).is(e))d.push({selector:l,elem:h,level:o})}h=
h.parentNode;o++}}return d}l=cb.test(a)?c(a,b||this.context):null;e=0;for(f=this.length;e<f;e++)for(h=this[e];h;)if(l?l.index(h)>-1:c.find.matchesSelector(h,a)){d.push(h);break}else{h=h.parentNode;if(!h||!h.ownerDocument||h===b)break}d=d.length>1?c.unique(d):d;return this.pushStack(d,"closest",a)},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var d=typeof a==="string"?c(a,b||this.context):
c.makeArray(a),e=c.merge(this.get(),d);return this.pushStack(!d[0]||!d[0].parentNode||d[0].parentNode.nodeType===11||!e[0]||!e[0].parentNode||e[0].parentNode.nodeType===11?e:c.unique(e))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,
2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,
b){c.fn[a]=function(d,e){var f=c.map(this,b,d);Za.test(a)||(e=d);if(e&&typeof e==="string")f=c.filter(e,f);f=this.length>1?c.unique(f):f;if((this.length>1||ab.test(e))&&$a.test(a))f=f.reverse();return this.pushStack(f,a,bb.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return b.length===1?c.find.matchesSelector(b[0],a)?[b[0]]:[]:c.find.matches(a,b)},dir:function(a,b,d){var e=[];for(a=a[b];a&&a.nodeType!==9&&(d===B||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&
e.push(a);a=a[b]}return e},nth:function(a,b,d){b=b||1;for(var e=0;a;a=a[d])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var za=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,Aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Ba=/<([\w:]+)/,db=/<tbody/i,eb=/<|&#?\w+;/,Ca=/<(?:script|object|embed|option|style)/i,Da=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/\=([^="'>\s]+\/)>/g,P={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,"",""]};P.optgroup=P.option;P.tbody=P.tfoot=P.colgroup=P.caption=P.thead;P.th=P.td;if(!c.support.htmlSerialize)P._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==B)return this.empty().append((this[0]&&this[0].ownerDocument||t).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,e;(e=this[d])!=null;d++)if(!a||c.filter(a,[e]).length){if(!b&&e.nodeType===1){c.cleanData(e.getElementsByTagName("*"));c.cleanData([e])}e.parentNode&&e.parentNode.removeChild(e)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,e=this.ownerDocument;if(!d){d=e.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(za,"").replace(fb,'="$1">').replace($,"")],e)[0]}else return this.cloneNode(true)});if(a===true){na(this,b);na(this.find("*"),b.find("*"))}return b},html:function(a){if(a===B)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(za,""):null;
else if(typeof a==="string"&&!Ca.test(a)&&(c.support.leadingWhitespace||!$.test(a))&&!P[(Ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Aa,"<$1></$2>");try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(e){this.empty().append(a)}}else c.isFunction(a)?this.each(function(f){var h=c(this);h.html(a.call(this,f,h.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=
c(this),e=d.html();d.replaceWith(a.call(this,b,e))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){var e,f,h,l=a[0],k=[];if(!c.support.checkClone&&arguments.length===3&&typeof l==="string"&&Da.test(l))return this.each(function(){c(this).domManip(a,
b,d,true)});if(c.isFunction(l))return this.each(function(x){var r=c(this);a[0]=l.call(this,x,b?r.html():B);r.domManip(a,b,d)});if(this[0]){e=l&&l.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:c.buildFragment(a,this,k);h=e.fragment;if(f=h.childNodes.length===1?h=h.firstChild:h.firstChild){b=b&&c.nodeName(f,"tr");f=0;for(var o=this.length;f<o;f++)d.call(b?c.nodeName(this[f],"table")?this[f].getElementsByTagName("tbody")[0]||this[f].appendChild(this[f].ownerDocument.createElement("tbody")):
this[f]:this[f],f>0||e.cacheable||this.length>1?h.cloneNode(true):h)}k.length&&c.each(k,Oa)}return this}});c.buildFragment=function(a,b,d){var e,f,h;b=b&&b[0]?b[0].ownerDocument||b[0]:t;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===t&&!Ca.test(a[0])&&(c.support.checkClone||!Da.test(a[0]))){f=true;if(h=c.fragments[a[0]])if(h!==1)e=h}if(!e){e=b.createDocumentFragment();c.clean(a,b,e,d)}if(f)c.fragments[a[0]]=h?e:1;return{fragment:e,cacheable:f}};c.fragments={};c.each({appendTo:"append",
prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var e=[];d=c(d);var f=this.length===1&&this[0].parentNode;if(f&&f.nodeType===11&&f.childNodes.length===1&&d.length===1){d[b](this[0]);return this}else{f=0;for(var h=d.length;f<h;f++){var l=(f>0?this.clone(true):this).get();c(d[f])[b](l);e=e.concat(l)}return this.pushStack(e,a,d.selector)}}});c.extend({clean:function(a,b,d,e){b=b||t;if(typeof b.createElement==="undefined")b=b.ownerDocument||
b[0]&&b[0].ownerDocument||t;for(var f=[],h=0,l;(l=a[h])!=null;h++){if(typeof l==="number")l+="";if(l){if(typeof l==="string"&&!eb.test(l))l=b.createTextNode(l);else if(typeof l==="string"){l=l.replace(Aa,"<$1></$2>");var k=(Ba.exec(l)||["",""])[1].toLowerCase(),o=P[k]||P._default,x=o[0],r=b.createElement("div");for(r.innerHTML=o[1]+l+o[2];x--;)r=r.lastChild;if(!c.support.tbody){x=db.test(l);k=k==="table"&&!x?r.firstChild&&r.firstChild.childNodes:o[1]==="<table>"&&!x?r.childNodes:[];for(o=k.length-
1;o>=0;--o)c.nodeName(k[o],"tbody")&&!k[o].childNodes.length&&k[o].parentNode.removeChild(k[o])}!c.support.leadingWhitespace&&$.test(l)&&r.insertBefore(b.createTextNode($.exec(l)[0]),r.firstChild);l=r.childNodes}if(l.nodeType)f.push(l);else f=c.merge(f,l)}}if(d)for(h=0;f[h];h++)if(e&&c.nodeName(f[h],"script")&&(!f[h].type||f[h].type.toLowerCase()==="text/javascript"))e.push(f[h].parentNode?f[h].parentNode.removeChild(f[h]):f[h]);else{f[h].nodeType===1&&f.splice.apply(f,[h+1,0].concat(c.makeArray(f[h].getElementsByTagName("script"))));
d.appendChild(f[h])}return f},cleanData:function(a){for(var b,d,e=c.cache,f=c.event.special,h=c.support.deleteExpando,l=0,k;(k=a[l])!=null;l++)if(!(k.nodeName&&c.noData[k.nodeName.toLowerCase()]))if(d=k[c.expando]){if((b=e[d])&&b.events)for(var o in b.events)f[o]?c.event.remove(k,o):c.removeEvent(k,o,b.handle);if(h)delete k[c.expando];else k.removeAttribute&&k.removeAttribute(c.expando);delete e[d]}}});var Ea=/alpha\([^)]*\)/i,gb=/opacity=([^)]*)/,hb=/-([a-z])/ig,ib=/([A-Z])/g,Fa=/^-?\d+(?:px)?$/i,
jb=/^-?\d/,kb={position:"absolute",visibility:"hidden",display:"block"},Pa=["Left","Right"],Qa=["Top","Bottom"],W,Ga,aa,lb=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){if(arguments.length===2&&b===B)return this;return c.access(this,a,b,true,function(d,e,f){return f!==B?c.style(d,e,f):c.css(d,e)})};c.extend({cssHooks:{opacity:{get:function(a,b){if(b){var d=W(a,"opacity","opacity");return d===""?"1":d}else return a.style.opacity}}},cssNumber:{zIndex:true,fontWeight:true,opacity:true,
zoom:true,lineHeight:true},cssProps:{"float":c.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,d,e){if(!(!a||a.nodeType===3||a.nodeType===8||!a.style)){var f,h=c.camelCase(b),l=a.style,k=c.cssHooks[h];b=c.cssProps[h]||h;if(d!==B){if(!(typeof d==="number"&&isNaN(d)||d==null)){if(typeof d==="number"&&!c.cssNumber[h])d+="px";if(!k||!("set"in k)||(d=k.set(a,d))!==B)try{l[b]=d}catch(o){}}}else{if(k&&"get"in k&&(f=k.get(a,false,e))!==B)return f;return l[b]}}},css:function(a,b,d){var e,f=c.camelCase(b),
h=c.cssHooks[f];b=c.cssProps[f]||f;if(h&&"get"in h&&(e=h.get(a,true,d))!==B)return e;else if(W)return W(a,b,f)},swap:function(a,b,d){var e={},f;for(f in b){e[f]=a.style[f];a.style[f]=b[f]}d.call(a);for(f in b)a.style[f]=e[f]},camelCase:function(a){return a.replace(hb,lb)}});c.curCSS=c.css;c.each(["height","width"],function(a,b){c.cssHooks[b]={get:function(d,e,f){var h;if(e){if(d.offsetWidth!==0)h=oa(d,b,f);else c.swap(d,kb,function(){h=oa(d,b,f)});if(h<=0){h=W(d,b,b);if(h==="0px"&&aa)h=aa(d,b,b);
if(h!=null)return h===""||h==="auto"?"0px":h}if(h<0||h==null){h=d.style[b];return h===""||h==="auto"?"0px":h}return typeof h==="string"?h:h+"px"}},set:function(d,e){if(Fa.test(e)){e=parseFloat(e);if(e>=0)return e+"px"}else return e}}});if(!c.support.opacity)c.cssHooks.opacity={get:function(a,b){return gb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var d=a.style;d.zoom=1;var e=c.isNaN(b)?"":"alpha(opacity="+b*100+")",f=
d.filter||"";d.filter=Ea.test(f)?f.replace(Ea,e):d.filter+" "+e}};if(t.defaultView&&t.defaultView.getComputedStyle)Ga=function(a,b,d){var e;d=d.replace(ib,"-$1").toLowerCase();if(!(b=a.ownerDocument.defaultView))return B;if(b=b.getComputedStyle(a,null)){e=b.getPropertyValue(d);if(e===""&&!c.contains(a.ownerDocument.documentElement,a))e=c.style(a,d)}return e};if(t.documentElement.currentStyle)aa=function(a,b){var d,e,f=a.currentStyle&&a.currentStyle[b],h=a.style;if(!Fa.test(f)&&jb.test(f)){d=h.left;
e=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;h.left=b==="fontSize"?"1em":f||0;f=h.pixelLeft+"px";h.left=d;a.runtimeStyle.left=e}return f===""?"auto":f};W=Ga||aa;if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetHeight;return a.offsetWidth===0&&b===0||!c.support.reliableHiddenOffsets&&(a.style.display||c.css(a,"display"))==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var mb=c.now(),nb=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
ob=/^(?:select|textarea)/i,pb=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,qb=/^(?:GET|HEAD)$/,Ra=/\[\]$/,T=/\=\?(&|$)/,ja=/\?/,rb=/([?&])_=[^&]*/,sb=/^(\w+:)?\/\/([^\/?#]+)/,tb=/%20/g,ub=/#.*$/,Ha=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!=="string"&&Ha)return Ha.apply(this,arguments);else if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var f=a.slice(e,a.length);a=a.slice(0,e)}e="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b===
"object"){b=c.param(b,c.ajaxSettings.traditional);e="POST"}var h=this;c.ajax({url:a,type:e,dataType:"html",data:b,complete:function(l,k){if(k==="success"||k==="notmodified")h.html(f?c("<div>").append(l.responseText.replace(nb,"")).find(f):l.responseText);d&&h.each(d,[l.responseText,k,l])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&
!this.disabled&&(this.checked||ob.test(this.nodeName)||pb.test(this.type))}).map(function(a,b){var d=c(this).val();return d==null?null:c.isArray(d)?c.map(d,function(e){return{name:b.name,value:e}}):{name:b.name,value:d}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:e})},
getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:e})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return new E.XMLHttpRequest},accepts:{xml:"application/xml, text/xml",html:"text/html",
script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},ajax:function(a){var b=c.extend(true,{},c.ajaxSettings,a),d,e,f,h=b.type.toUpperCase(),l=qb.test(h);b.url=b.url.replace(ub,"");b.context=a&&a.context!=null?a.context:b;if(b.data&&b.processData&&typeof b.data!=="string")b.data=c.param(b.data,b.traditional);if(b.dataType==="jsonp"){if(h==="GET")T.test(b.url)||(b.url+=(ja.test(b.url)?"&":"?")+(b.jsonp||"callback")+"=?");else if(!b.data||
!T.test(b.data))b.data=(b.data?b.data+"&":"")+(b.jsonp||"callback")+"=?";b.dataType="json"}if(b.dataType==="json"&&(b.data&&T.test(b.data)||T.test(b.url))){d=b.jsonpCallback||"jsonp"+mb++;if(b.data)b.data=(b.data+"").replace(T,"="+d+"$1");b.url=b.url.replace(T,"="+d+"$1");b.dataType="script";var k=E[d];E[d]=function(m){if(c.isFunction(k))k(m);else{E[d]=B;try{delete E[d]}catch(p){}}f=m;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);r&&r.removeChild(A)}}if(b.dataType==="script"&&b.cache===null)b.cache=
false;if(b.cache===false&&l){var o=c.now(),x=b.url.replace(rb,"$1_="+o);b.url=x+(x===b.url?(ja.test(b.url)?"&":"?")+"_="+o:"")}if(b.data&&l)b.url+=(ja.test(b.url)?"&":"?")+b.data;b.global&&c.active++===0&&c.event.trigger("ajaxStart");o=(o=sb.exec(b.url))&&(o[1]&&o[1].toLowerCase()!==location.protocol||o[2].toLowerCase()!==location.host);if(b.dataType==="script"&&h==="GET"&&o){var r=t.getElementsByTagName("head")[0]||t.documentElement,A=t.createElement("script");if(b.scriptCharset)A.charset=b.scriptCharset;
A.src=b.url;if(!d){var C=false;A.onload=A.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);A.onload=A.onreadystatechange=null;r&&A.parentNode&&r.removeChild(A)}}}r.insertBefore(A,r.firstChild);return B}var J=false,w=b.xhr();if(w){b.username?w.open(h,b.url,b.async,b.username,b.password):w.open(h,b.url,b.async);try{if(b.data!=null&&!l||a&&a.contentType)w.setRequestHeader("Content-Type",
b.contentType);if(b.ifModified){c.lastModified[b.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[b.url]);c.etag[b.url]&&w.setRequestHeader("If-None-Match",c.etag[b.url])}o||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",b.dataType&&b.accepts[b.dataType]?b.accepts[b.dataType]+", */*; q=0.01":b.accepts._default)}catch(I){}if(b.beforeSend&&b.beforeSend.call(b.context,w,b)===false){b.global&&c.active--===1&&c.event.trigger("ajaxStop");w.abort();return false}b.global&&
c.triggerGlobal(b,"ajaxSend",[w,b]);var L=w.onreadystatechange=function(m){if(!w||w.readyState===0||m==="abort"){J||c.handleComplete(b,w,e,f);J=true;if(w)w.onreadystatechange=c.noop}else if(!J&&w&&(w.readyState===4||m==="timeout")){J=true;w.onreadystatechange=c.noop;e=m==="timeout"?"timeout":!c.httpSuccess(w)?"error":b.ifModified&&c.httpNotModified(w,b.url)?"notmodified":"success";var p;if(e==="success")try{f=c.httpData(w,b.dataType,b)}catch(q){e="parsererror";p=q}if(e==="success"||e==="notmodified")d||
c.handleSuccess(b,w,e,f);else c.handleError(b,w,e,p);d||c.handleComplete(b,w,e,f);m==="timeout"&&w.abort();if(b.async)w=null}};try{var g=w.abort;w.abort=function(){w&&Function.prototype.call.call(g,w);L("abort")}}catch(i){}b.async&&b.timeout>0&&setTimeout(function(){w&&!J&&L("timeout")},b.timeout);try{w.send(l||b.data==null?null:b.data)}catch(n){c.handleError(b,w,null,n);c.handleComplete(b,w,e,f)}b.async||L();return w}},param:function(a,b){var d=[],e=function(h,l){l=c.isFunction(l)?l():l;d[d.length]=
encodeURIComponent(h)+"="+encodeURIComponent(l)};if(b===B)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){e(this.name,this.value)});else for(var f in a)da(f,a[f],b,e);return d.join("&").replace(tb,"+")}});c.extend({active:0,lastModified:{},etag:{},handleError:function(a,b,d,e){a.error&&a.error.call(a.context,b,d,e);a.global&&c.triggerGlobal(a,"ajaxError",[b,a,e])},handleSuccess:function(a,b,d,e){a.success&&a.success.call(a.context,e,d,b);a.global&&c.triggerGlobal(a,"ajaxSuccess",
[b,a])},handleComplete:function(a,b,d){a.complete&&a.complete.call(a.context,b,d);a.global&&c.triggerGlobal(a,"ajaxComplete",[b,a]);a.global&&c.active--===1&&c.event.trigger("ajaxStop")},triggerGlobal:function(a,b,d){(a.context&&a.context.url==null?c(a.context):c.event).trigger(b,d)},httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),
e=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(e)c.etag[b]=e;return a.status===304},httpData:function(a,b,d){var e=a.getResponseHeader("content-type")||"",f=b==="xml"||!b&&e.indexOf("xml")>=0;a=f?a.responseXML:a.responseText;f&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&e.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&e.indexOf("javascript")>=0)c.globalEval(a);return a}});
if(E.ActiveXObject)c.ajaxSettings.xhr=function(){if(E.location.protocol!=="file:")try{return new E.XMLHttpRequest}catch(a){}try{return new E.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}};c.support.ajax=!!c.ajaxSettings.xhr();var ea={},vb=/^(?:toggle|show|hide)$/,wb=/^([+\-]=)?([\d+.\-]+)(.*)$/,ba,pa=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b,d){if(a||a===0)return this.animate(S("show",
3),a,b,d);else{d=0;for(var e=this.length;d<e;d++){a=this[d];b=a.style.display;if(!c.data(a,"olddisplay")&&b==="none")b=a.style.display="";b===""&&c.css(a,"display")==="none"&&c.data(a,"olddisplay",qa(a.nodeName))}for(d=0;d<e;d++){a=this[d];b=a.style.display;if(b===""||b==="none")a.style.display=c.data(a,"olddisplay")||""}return this}},hide:function(a,b,d){if(a||a===0)return this.animate(S("hide",3),a,b,d);else{a=0;for(b=this.length;a<b;a++){d=c.css(this[a],"display");d!=="none"&&c.data(this[a],"olddisplay",
d)}for(a=0;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b,d){var e=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||e?this.each(function(){var f=e?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(S("toggle",3),a,b,d);return this},fadeTo:function(a,b,d,e){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d,e)},animate:function(a,b,d,e){var f=c.speed(b,
d,e);if(c.isEmptyObject(a))return this.each(f.complete);return this[f.queue===false?"each":"queue"](function(){var h=c.extend({},f),l,k=this.nodeType===1,o=k&&c(this).is(":hidden"),x=this;for(l in a){var r=c.camelCase(l);if(l!==r){a[r]=a[l];delete a[l];l=r}if(a[l]==="hide"&&o||a[l]==="show"&&!o)return h.complete.call(this);if(k&&(l==="height"||l==="width")){h.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY];if(c.css(this,"display")==="inline"&&c.css(this,"float")==="none")if(c.support.inlineBlockNeedsLayout)if(qa(this.nodeName)===
"inline")this.style.display="inline-block";else{this.style.display="inline";this.style.zoom=1}else this.style.display="inline-block"}if(c.isArray(a[l])){(h.specialEasing=h.specialEasing||{})[l]=a[l][1];a[l]=a[l][0]}}if(h.overflow!=null)this.style.overflow="hidden";h.curAnim=c.extend({},a);c.each(a,function(A,C){var J=new c.fx(x,h,A);if(vb.test(C))J[C==="toggle"?o?"show":"hide":C](a);else{var w=wb.exec(C),I=J.cur()||0;if(w){var L=parseFloat(w[2]),g=w[3]||"px";if(g!=="px"){c.style(x,A,(L||1)+g);I=(L||
1)/J.cur()*I;c.style(x,A,I+g)}if(w[1])L=(w[1]==="-="?-1:1)*L+I;J.custom(I,L,g)}else J.custom(I,C,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var e=d.length-1;e>=0;e--)if(d[e].elem===this){b&&d[e](true);d.splice(e,1)}});b||this.dequeue();return this}});c.each({slideDown:S("show",1),slideUp:S("hide",1),slideToggle:S("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){c.fn[a]=function(d,e,f){return this.animate(b,
d,e,f)}});c.extend({speed:function(a,b,d){var e=a&&typeof a==="object"?c.extend({},a):{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};e.duration=c.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in c.fx.speeds?c.fx.speeds[e.duration]:c.fx.speeds._default;e.old=e.complete;e.complete=function(){e.queue!==false&&c(this).dequeue();c.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,d,e){return d+e*a},swing:function(a,b,d,e){return(-Math.cos(a*
Math.PI)/2+0.5)*e+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a=parseFloat(c.css(this.elem,this.prop));return a&&a>-1E4?a:0},custom:function(a,b,d){function e(l){return f.step(l)}
var f=this,h=c.fx;this.startTime=c.now();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;e.elem=this.elem;if(e()&&c.timers.push(e)&&!ba)ba=setInterval(h.tick,h.interval)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;
this.custom(this.cur(),0)},step:function(a){var b=c.now(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var e in this.options.curAnim)if(this.options.curAnim[e]!==true)d=false;if(d){if(this.options.overflow!=null&&!c.support.shrinkWrapBlocks){var f=this.elem,h=this.options;c.each(["","X","Y"],function(k,o){f.style["overflow"+o]=h.overflow[k]})}this.options.hide&&c(this.elem).hide();if(this.options.hide||
this.options.show)for(var l in this.options.curAnim)c.style(this.elem,l,this.options.orig[l]);this.options.complete.call(this.elem)}return false}else{a=b-this.startTime;this.state=a/this.options.duration;b=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||b](this.state,a,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=
c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},interval:13,stop:function(){clearInterval(ba);ba=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===
b.elem}).length};var xb=/^t(?:able|d|h)$/i,Ia=/^(?:body|html)$/i;c.fn.offset="getBoundingClientRect"in t.documentElement?function(a){var b=this[0],d;if(a)return this.each(function(l){c.offset.setOffset(this,a,l)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);try{d=b.getBoundingClientRect()}catch(e){}var f=b.ownerDocument,h=f.documentElement;if(!d||!c.contains(h,b))return d||{top:0,left:0};b=f.body;f=fa(f);return{top:d.top+(f.pageYOffset||c.support.boxModel&&
h.scrollTop||b.scrollTop)-(h.clientTop||b.clientTop||0),left:d.left+(f.pageXOffset||c.support.boxModel&&h.scrollLeft||b.scrollLeft)-(h.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(x){c.offset.setOffset(this,a,x)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d,e=b.offsetParent,f=b.ownerDocument,h=f.documentElement,l=f.body;d=(f=f.defaultView)?f.getComputedStyle(b,null):b.currentStyle;
for(var k=b.offsetTop,o=b.offsetLeft;(b=b.parentNode)&&b!==l&&b!==h;){if(c.offset.supportsFixedPosition&&d.position==="fixed")break;d=f?f.getComputedStyle(b,null):b.currentStyle;k-=b.scrollTop;o-=b.scrollLeft;if(b===e){k+=b.offsetTop;o+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&xb.test(b.nodeName))){k+=parseFloat(d.borderTopWidth)||0;o+=parseFloat(d.borderLeftWidth)||0}e=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"){k+=
parseFloat(d.borderTopWidth)||0;o+=parseFloat(d.borderLeftWidth)||0}d=d}if(d.position==="relative"||d.position==="static"){k+=l.offsetTop;o+=l.offsetLeft}if(c.offset.supportsFixedPosition&&d.position==="fixed"){k+=Math.max(h.scrollTop,l.scrollTop);o+=Math.max(h.scrollLeft,l.scrollLeft)}return{top:k,left:o}};c.offset={initialize:function(){var a=t.body,b=t.createElement("div"),d,e,f,h=parseFloat(c.css(a,"marginTop"))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",
height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);d=b.firstChild;e=d.firstChild;f=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=e.offsetTop!==5;this.doesAddBorderForTableAndCells=
f.offsetTop===5;e.style.position="fixed";e.style.top="20px";this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15;e.style.position=e.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==h;a.removeChild(b);c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.css(a,
"marginTop"))||0;d+=parseFloat(c.css(a,"marginLeft"))||0}return{top:b,left:d}},setOffset:function(a,b,d){var e=c.css(a,"position");if(e==="static")a.style.position="relative";var f=c(a),h=f.offset(),l=c.css(a,"top"),k=c.css(a,"left"),o=e==="absolute"&&c.inArray("auto",[l,k])>-1;e={};var x={};if(o)x=f.position();l=o?x.top:parseInt(l,10)||0;k=o?x.left:parseInt(k,10)||0;if(c.isFunction(b))b=b.call(a,d,h);if(b.top!=null)e.top=b.top-h.top+l;if(b.left!=null)e.left=b.left-h.left+k;"using"in b?b.using.call(a,
e):f.css(e)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),e=Ia.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.css(a,"marginTop"))||0;d.left-=parseFloat(c.css(a,"marginLeft"))||0;e.top+=parseFloat(c.css(b[0],"borderTopWidth"))||0;e.left+=parseFloat(c.css(b[0],"borderLeftWidth"))||0;return{top:d.top-e.top,left:d.left-e.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||t.body;a&&!Ia.test(a.nodeName)&&
c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(e){var f=this[0],h;if(!f)return null;if(e!==B)return this.each(function(){if(h=fa(this))h.scrollTo(!a?e:c(h).scrollLeft(),a?e:c(h).scrollTop());else this[d]=e});else return(h=fa(f))?"pageXOffset"in h?h[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&h.document.documentElement[d]||h.document.body[d]:f[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();
c.fn["inner"+b]=function(){return this[0]?parseFloat(c.css(this[0],d,"padding")):null};c.fn["outer"+b]=function(e){return this[0]?parseFloat(c.css(this[0],d,e?"margin":"border")):null};c.fn[d]=function(e){var f=this[0];if(!f)return e==null?null:this;if(c.isFunction(e))return this.each(function(l){var k=c(this);k[d](e.call(this,l,k[d]()))});if(c.isWindow(f))return f.document.compatMode==="CSS1Compat"&&f.document.documentElement["client"+b]||f.document.body["client"+b];else if(f.nodeType===9)return Math.max(f.documentElement["client"+
b],f.body["scroll"+b],f.documentElement["scroll"+b],f.body["offset"+b],f.documentElement["offset"+b]);else if(e===B){f=c.css(f,d);var h=parseFloat(f);return c.isNaN(h)?f:h}else return this.css(d,typeof e==="string"?e:e+"px")}})})(window);

8176
jquery-1.5.js vendored Normal file

File diff suppressed because it is too large Load Diff

141
store.js
View File

@ -1,58 +1,77 @@
var Product = Backbone.Model.extend({}); (function() {
var ProductCollection = Backbone.Collection.extend({ var Product = Backbone.Model.extend({
toJSON: function() {
return _.extend(_.clone(this.attributes), {cid: this.cid})
}
});
var ProductCollection = Backbone.Collection.extend({
model: Product, model: Product,
comparator: function(item) { comparator: function(item) {
return item.get('title'); return item.get('title');
} }
}); });
var CartItem = Backbone.Model.extend({ var CartItem = Backbone.Model.extend({
update: function(amount) { update: function(amount) {
this.set({'quantity': this.get('quantity') + amount}); this.set({'quantity': this.get('quantity') + amount});
} }
}); });
var Cart = Backbone.Collection.extend({
var Cart = Backbone.Collection.extend({
model: CartItem, model: CartItem,
getByPid: function(pid) { getByProductId: function(pid) {
return this.detect(function(obj) { return (obj.get('product').cid == pid); }); return this.detect(function(obj) { return (obj.get('product').cid == pid); });
}, },
}); });
var CartView = Backbone.View.extend({
var CartView = Backbone.View.extend({
el: $('.cart-info'), el: $('.cart-info'),
initialize: function() { initialize: function() {
this.model.bind('change', _.bind(this.render, this)); this.collection.bind('change', _.bind(this.render, this));
}, },
render: function() { render: function() {
var sum = this.model.reduce(function(m, n) { return m + n.get('quantity'); }, 0); var sum = this.collection.reduce(function(m, n) { return m + n.get('quantity'); }, 0);
this.el this.el
.find('.cart-items').text(sum).end() .find('.cart-items').text(sum).end()
.animate({paddingTop: '30px'}) .animate({paddingTop: '30px'})
.animate({paddingTop: '10px'}); .animate({paddingTop: '10px'});
} }
}); });
var ProductView = Backbone.View.extend({
var ProductListView = Backbone.View.extend({
el: $('#main'),
indexTemplate: $("#indexTmpl").template(),
render: function() {
var self = this;
this.el.fadeOut('fast', function() {
self.el.html($.tmpl(self.indexTemplate, self.model.toJSON()));
self.el.fadeIn('fast');
});
return this;
}
});
var ProductView = Backbone.View.extend({
el: $('#main'), el: $('#main'),
itemTemplate: $("#itemTmpl").template(), itemTemplate: $("#itemTmpl").template(),
events: {
"keypress .uqf" : "updateOnEnter",
"click .uq" : "update",
},
initialize: function(options) { initialize: function(options) {
this.cart = options.cart; this.cart = options.cart;
return this;
}, },
update: function(e) { update: function(e) {
e.preventDefault(); e.preventDefault();
var cart_item = this.cart.getByPid(this.model.cid); var cart_item = this.cart.getByProductId(this.model.cid);
if (_.isUndefined(cart_item)) { if (_.isUndefined(cart_item)) {
cart_item = new CartItem({product: this.model, quantity: 0}); cart_item = new CartItem({product: this.model, quantity: 0});
this.cart.add(cart_item, {silent: true}); this.cart.add(cart_item, {silent: true});
@ -66,61 +85,36 @@ var ProductView = Backbone.View.extend({
} }
}, },
events: {
"keypress .uqf" : "updateOnEnter",
"click .uq" : "update",
},
render: function() { render: function() {
var sg = this; var self = this;
this.el.fadeOut('fast', function() { this.el.fadeOut('fast', function() {
sg.el.empty(); self.el.html($.tmpl(self.itemTemplate, self.model.toJSON()));
$.tmpl(sg.itemTemplate, sg.model).appendTo(sg.el); self.el.fadeIn('fast');
sg.el.fadeIn('fast');
}); });
return this; return this;
} }
});
var IndexView = Backbone.View.extend({
el: $('#main'),
indexTemplate: $("#indexTmpl").template(),
render: function() {
var sg = this;
this.el.fadeOut('fast', function() {
sg.el.empty();
$.tmpl(sg.indexTemplate, sg.model.toArray()).appendTo(sg.el);
sg.el.fadeIn('fast');
}); });
return this;
}
});
var Workspace = Backbone.Controller.extend({ var BackboneStore = Backbone.Controller.extend({
_index: null, _index: null,
_products: null, _products: null,
_cart :null, _cart :null,
routes: { routes: {
"": "index", "": "index",
"item/:id": "item", "item/:id": "item",
}, },
initialize: function() { initialize: function(data) {
var ws = this; this._cart = new Cart();
if (this._index === null) { new CartView({collection: this._cart});
$.ajax({ this._products = new ProductCollection(data);
url: 'data/items.json', this._index = new ProductListView({model: this._products});
dataType: 'json',
data: {},
success: function(data) {
ws._cart = new Cart();
new CartView({model: ws._cart});
ws._products = new ProductCollection(data);
ws._index = new IndexView({model: ws._products});
Backbone.history.loadUrl();
}
});
return this;
}
return this; return this;
}, },
@ -129,13 +123,30 @@ var Workspace = Backbone.Controller.extend({
}, },
item: function(id) { item: function(id) {
if (_.isUndefined(this._products.getByCid(id)._view)) { var product = this._products.getByCid(id);
this._products.getByCid(id)._view = new ProductView({model: this._products.getByCid(id), if (_.isUndefined(product._view)) {
product._view = new ProductView({model: product,
cart: this._cart}); cart: this._cart});
} }
this._products.getByCid(id)._view.render(); product._view.render();
} }
}); });
workspace = new Workspace();
Backbone.history.start(); $(document).ready(function() {
var fetch_items = function() {
return $.ajax({
url: 'data/items.json',
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json"
});
};
$.when(fetch_items()).then(function(data) {
new BackboneStore(data);
Backbone.history.start();
});
});
}).call(this);