[
  {
    "path": ".gitignore",
    "content": "*.pyc\napp/static_dev/publish\napp/static_dev/intermediate\n"
  },
  {
    "path": "README.md",
    "content": "App Engine Boilerplate is a versatile yet minimalistic setup for new App Engine projects.\n\n* [html5-boilerplate 2.0](https://github.com/paulirish/html5-boilerplate)\n(including it's automated build toolchain for minification and concatenation of js+css)\n* Beautiful OpenID login with [openid-selector](http://code.google.com/p/openid-selector/)\n* Flexible user-preferences model with auto-caching (plus Gravatar link)\n* `BaseRequestHandler` for simplified rendering and access to user preferences\n* `@login_required` decorator\n* Memcaching setup\n* Templates and template addons\n* Tools such as `is_testenv()` and `slugify(url)`\n* Automatically subscribe users to your MailChimp newsletter\n* `app.yaml` configuration for admin areas, static files\n* Released under the [BSD license](http://www.opensource.org/licenses/bsd-license.php)\n\nThis project does not contain a lot of code. To get the best understanding of it's features \nwe recommend to simply **browse through the files**! You can see a rather minimalistic live version [here](http://www.appengine-boilerplate.com).\n\n\nOpenID Authentication\n---------------------\n\nUser authentication with OpenID works out of the box, including a nice user interface via the [openid-selector] [1] jQuery plugin (also used by [stackoverflow] [2]). Be sure to enable OpenID authentication in your app settings on app engine.\n\n![Alt text](http://lh4.ggpht.com/_IfEh7XYTTeE/STA1yGHn79I/AAAAAAAAADc/IXKrRpick4w/step1.png)\n\nMore infos about appengine and openid:\n\n* [http://code.google.com/appengine/articles/openid.html](http://code.google.com/appengine/articles/openid.html)\n* [http://blog.notdot.net/2010/05/Using-OpenID-authentication-on-App-Engine](http://code.google.com/appengine/articles/openid.html)\n    \n   [1]: http://code.google.com/p/openid-selector/\n   [2]: http://stackoverflow.com/users/login\n\n\nMemcaching\n----------\n\nReturning cached data usually improves the performance of a website. App Engine provides \na custom  version of memcache to store various data types, which can be used to efficiently \ncache the results of datastore queries, or commonly used elements on the homepage.\n\n[`app/mc/cache.py`](https://github.com/metachris/appengine-boilerplate/blob/master/app/mc/cache.py) contains an exemplary method of querying data from\nmemcache with a datastore fallback if not yet cached. Simply adapt as you need it!\n\n\nHTML5-Boilerplate\n-----------------\n\n[html5 boilerplate] [1] is a great base setup for building the website frontend, and furthermore \nincludes a build script which minifies and compresses html, css, javascript and images. \n\nhtml5-boilerplate is located in ``/static_dev``, and it's build script outputs an optimized release version to ``/static_dev/publish``.The only modification to the standard html5-boilerplate is adding a few blocks to  ``/static_dev/index.html``: ``{% block header|main|scripts|footer %}``\n\nDuring development the symlink ``/static`` points to ``/static_dev``. On publishing \nthe project ``upload_to_appengine.sh`` invokes the html5-boilerplate build script \nand changes the symlink ``/static`` to ``/static_dev/publish``, in order to upload \nthe optimized version. \n\n\nupload_to_appengine.sh\n----------------------\n\n`upload_to_appengine.sh` is a tiny shell script which simplifies invoking the html5-boilerplate build tools before testing and uploading your app to app engine. To use it you need to set ``CMD_APPCFG`` to your local `dev_appserver.py`.\n\nExact steps of `./upload_to_appengine.sh`:\n\n- Asks if it should run the build process with ``ant minify``\n- Changes the /static symlink to the production version\n- Waits for you to test and confirm\n- Uploads the app to appengine\n- Reverts /static to the development environment\n\nThese would be the manual steps:\n\n    # go into html5-boilerplate's build directory    \n    $ cd static_dev/build \n    \n    # run ant, which compiles an optimized version into static_dev/publish\n    $ ant minify\n    \n    # go back into the main directory\n    $ cd ../../\n    \n    # change reference of /static symlink to optimized version\n    $ rm static\n    $ ln -s static_dev/publish static\n    \n    # Test the optimized version\n    # Publish to web with appcfg.py\n    \n    # After publishing you can change back to static_dev\n    $ rm static\n    $ ln -s static_dev static\n     \n   [1]: https://github.com/paulirish/html5-boilerplate\n\n\nAdding CSS Files\n----------------\n\nCSS files are no longer imported from `index.html` but exclusively through using\n`@import` in style.css.\n\nhtml5 boilerplate automatically includes, minifies and concatenates css files\nwhich are imported via an `@import` statement from within `style.css`. Add\nreferences to your custom stylesheets from there, never from within index.html.\n\n\nWorking in Windows\n-------------------\nThere are a couple of posix symlinks within the project that will need to be updated to work with Windows.\n\n* \"/static\" which points to \"/static_dev\" during development\n* \"/templates/base.html\" which points to \"/static/index.html\"\n\nTo create the new links, delete the existing links and use the mklink command from an command prompt run with Administration privileges.\n\n* [mklink](http://technet.microsoft.com/en-us/library/cc753194\\(WS.10\\).aspx) [[/D] | [/H] | [/J]] Link Target\n\nMaking these two changes will enable you to launch the project using the Google App Engine SDK Launcher.  During deployment the current .sh script changes the /static link to /static_dev/publish and a forthcoming .bat script will include this functionality.\n\n\nEnjoy\n----------\n\nFeedback, improvements and critique are greatly appreciated. **Fork away!**\n\n\nIdeas\n-----\n\nSome ideas for future improvements:\n\n* Check for unique username\n* Email verification\n* Update openid-selector\n* OAuth login: Twitter, Facebook, LinkedIn, Dropbox, etc.\n* About page with feedback form\n* Feedback dialog\n* akismet, twitter, bit.ly modules?\n"
  },
  {
    "path": "app/app.py",
    "content": "# -*- coding: utf-8 -*-\nimport os\nfrom google.appengine.dist import use_library\nos.environ['DJANGO_SETTINGS_MODULE'] = 'settings'\nuse_library('django', '1.2')\n\nfrom google.appengine.ext import webapp\nfrom google.appengine.ext.webapp.util import run_wsgi_app\n\n# Load request handlers\nimport handlers\n\n# Map url's to handlers\nurls = [\n    (r'/', handlers.Main),\n    (r'/login', handlers.LogIn),\n    (r'/_ah/login_required', handlers.LogIn),\n    (r'/logout', handlers.LogOut),\n    (r'/account', handlers.Account),\n    (r'/account/setup', handlers.AccountSetup),\n]\n\napplication = webapp.WSGIApplication(urls, debug=True)\n\n\ndef main():\n    run_wsgi_app(application)\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "app/app.yaml",
    "content": "# Replace 'ae-boilerplate' with your application name\napplication: ae-boilerplate\nversion: 1 \nruntime: python\napi_version: 1\n\ndefault_expiration: \"30d\"\n\nbuiltins:\n- datastore_admin: on\n\nhandlers:\n# Cron jobs and other secured things\n- url: /services.*\n  script: services.py\n  login: admin\n\n# If non-authenticated user, appengine will ask for login and redirect afterwards: \n- url: /account\n  script: app.py\n  login: required\n\n# Override appengine url to provide custom OpenID login page \n- url: /_ah/login_required\n  script: app.py\n\n# html-5 boilerplate redirects from /... to /static/... \n- url: /apple-touch-icon\\.png\n  mime_type: image/png\n  static_files: static/apple-touch-icon.png\n  upload: static/apple-touch-icon.png\n\n- url: /favicon\\.ico\n  mime_type: image/png\n  static_files: static/favicon.ico\n  upload: static/favicon.ico\n\n- url: /(robots\\.txt|humans\\.txt|crossdomain\\.xml)\n  static_files: static/\\1\n  upload: static/(robots\\.txt|humans\\.txt|crossdomain\\.xml)\n\n- url: /img/(.*\\.(gif|png|jpg))\n  static_files: static/img/\\1\n  upload: static/img/(.*\\.(gif|png|jpg))\n  \n- url: /swf/(.*\\.swf)\n  static_files: static/swf/\\1\n  upload: static/swf/(.*\\.swf)\n\n- url: /css/(.*\\.css)\n  mime_type: text/css\n  static_files: static/css/\\1\n  upload: static/css/(.*\\.css)\n\n- url: /js/(.*\\.js)\n  mime_type: text/javascript\n  static_files: static/js/\\1\n  upload: static/js/(.*\\.js)\n\n- url: /(.*\\.html)\n  mime_type: text/html\n  static_files: static/\\1\n  upload: static/(.*\\.html)\n    \n# All other requests go to app.py\n- url: /.*\n  script: app.py\n"
  },
  {
    "path": "app/common/__init__.py",
    "content": ""
  },
  {
    "path": "app/common/templateaddons.py",
    "content": "# -*- coding: utf-8 -*-\nfrom google.appengine.ext import webapp\nfrom django.template import Node\n\n\"\"\"\nCustom template tags, for use from within the templates.\n\nBefore rendering a relevant template from within a handler, you need to include\nthe custom tags with this line of code:\n\n    webapp.template.register_template_library('common.templateaddons')\n\nMore infos about custom template tags:\n\n- http://docs.djangoproject.com/en/dev/howto/custom-template-tags/\n\"\"\"\n\n# get registry, we need it to register our filter later.\nregister = webapp.template.create_template_register()\n\n\ndef truncate_chars(value, maxlen):\n    \"\"\"Truncates value and appends '...' if longer than maxlen.\n    Usage inside template to limit my_var to 20 characters max:\n\n        {{ my_var|truncate_chars:20 }}\n\n    \"\"\"\n    if len(value) < maxlen:\n        return value\n    else:\n        return \"%s...\" % value[:maxlen - 3]\n\n\nregister.filter(truncate_chars)\n"
  },
  {
    "path": "app/cron.yaml",
    "content": "cron:\n#- description: hourly 1\n#  url: /services/task1\n#  schedule: every 1 hours synchronized\n#  \n#- description: every minute \n#  url: /services/task2\n#  schedule: every 1 minutes synchronized\n\n"
  },
  {
    "path": "app/handlers/__init__.py",
    "content": "from main import *\n"
  },
  {
    "path": "app/handlers/baserequesthandler.py",
    "content": "# -*- coding: utf-8 -*-\nimport os\nfrom google.appengine.api import users\nfrom google.appengine.ext import webapp\n\nimport models\nimport tools.common\nimport settings\n\nTEMPLATE_DIR = os.path.join(os.path.dirname(__file__),\n        '../%s' % settings.TEMPLATE_DIR)\n\n\nclass BaseRequestHandler(webapp.RequestHandler):\n    \"\"\"Extension of the normal RequestHandler\n\n    - self.userprefs provides the UserPrefs object of the current user.\n    - self.render() provides a quick way to render templates with\n      common template variables already preset.\n    \"\"\"\n    def __init__(self):\n        super(BaseRequestHandler, self).__init__()\n        self.userprefs = models.UserPrefs.from_user(users.get_current_user())\n\n    def render(self, template_name, template_values={}):\n        # Preset values for the template\n        values = {\n          'request': self.request,\n          'prefs': self.userprefs,\n          'login_url': users.create_login_url(self.request.uri),\n          'logout_url': users.create_logout_url(self.request.uri),\n        }\n\n        # Add manually supplied template values\n        values.update(template_values)\n\n        # Render template\n        fn = os.path.join(TEMPLATE_DIR, template_name)\n        self.response.out.write(webapp.template.render(fn, values,\n                debug=tools.common.is_testenv()))\n\n    def head(self, *args):\n        \"\"\"Head is used by Twitter. If not there the tweet button shows 0\"\"\"\n        pass\n"
  },
  {
    "path": "app/handlers/main.py",
    "content": "# -*- coding: utf-8 -*-\nimport os\nimport logging\n\nfrom hashlib import md5\nfrom google.appengine.ext import db\nfrom google.appengine.ext import webapp\nfrom google.appengine.ext.webapp import template\n\n# Import packages from the project\nimport mc\nimport settings\nimport tools.mailchimp\n\nfrom models import *\nfrom baserequesthandler import BaseRequestHandler\nfrom tools.common import decode\nfrom tools.decorators import login_required\n\n\n# OpenID login\nclass LogIn(BaseRequestHandler):\n    \"\"\"\n    Redirects a user to the OpenID login site. After successful login the user\n    redirected to the target_url (via /login?continue=/<target_url>).\n    \"\"\"\n    def get(self):\n        # Wrap target url to redirect new users to the account setup step\n        target_url = \"/account?continue=%s\" % \\\n                decode(self.request.get('continue'))\n\n        action = decode(self.request.get('action'))\n        if action and action == \"verify\":\n            fid = decode(self.request.get('openid_identifier'))\n            url = users.create_login_url(target_url, federated_identity=fid)\n            self.redirect(url)\n        else:\n            # BaseRequestHandler provides .render() for rendering a template\n            self.render(\"login.html\", {\"continue_to\": target_url})\n\n\n# LogOut redirects the user to the GAE logout url, and then redirects to /\nclass LogOut(webapp.RequestHandler):\n    def get(self):\n        url = users.create_logout_url(\"/\")\n        self.redirect(url)\n\n\n# Main page request handler\nclass Main(BaseRequestHandler):\n    def get(self):\n        # Render the template\n        self.render(\"index.html\")\n\n\n# Account page and after-login handler\nclass Account(BaseRequestHandler):\n    \"\"\"\n    The user's account and preferences. After the first login, the user is sent\n    to /account?continue=<target_url> in order to finish setting up the account\n    (email, username, newsletter).\n    \"\"\"\n    def get(self):\n        target_url = decode(self.request.get('continue'))\n        # Circumvent a bug in gae which prepends the url again\n        if target_url and \"?continue=\" in target_url:\n            target_url = target_url[target_url.index(\"?continue=\") + 10:]\n\n        if not self.userprefs.is_setup:\n            # First log in of user. Finish setup before forwarding.\n            self.render(\"account_setup.html\", {\"target_url\": target_url})\n            return\n\n        elif target_url:\n            # If not a new user but ?continue=<url> supplied, redirect\n            self.redirect(target_url)\n            return\n\n        # Render the account website\n        self.render(\"account.html\")\n\n\nclass AccountSetup(BaseRequestHandler):\n    \"\"\"Initial setup of the account, after user logs in the first time\"\"\"\n    def post(self):\n        username = decode(self.request.get(\"username\"))\n        email = decode(self.request.get(\"email\"))\n        subscribe = decode(self.request.get(\"subscribe\"))\n        target_url = decode(self.request.get('continue'))\n        target_url = target_url or \"/account\"\n\n        # Set a flag whether newsletter subscription setting has changed\n        subscription_changed = bool(self.userprefs.subscribed_to_newsletter) \\\n                is not bool(subscribe)\n\n        # Update UserPrefs object\n        self.userprefs.is_setup = True\n        self.userprefs.nickname = username\n        self.userprefs.email = email\n        self.userprefs.email_md5 = md5(email.strip().lower()).hexdigest()\n        self.userprefs.subscribed_to_newsletter = bool(subscribe)\n        self.userprefs.put()\n\n        # Subscribe this user to the email newsletter now (if wanted). By\n        # default does not subscribe users to mailchimp in Test Environment!\n        if subscription_changed and settings.MAILCHIMP_ENABLED:\n            if subscribe:\n                tools.mailchimp.mailchimp_subscribe(email)\n            else:\n                tools.mailchimp.mailchimp_unsubscribe(email)\n\n        # After updating UserPrefs, redirect\n        self.redirect(target_url)\n"
  },
  {
    "path": "app/mc/__init__.py",
    "content": "import cache\n"
  },
  {
    "path": "app/mc/cache.py",
    "content": "# -*- coding: utf-8 -*-\nimport logging\nfrom google.appengine.api import memcache\n\nimport models\n\n\ndef get_someitems(clear=False):\n    \"\"\"Boilerplate for your customization\"\"\"\n    if clear:\n        memcache.delete(\"someitems\")\n        return\n\n    someitems = memcache.get(\"someitems\")\n    if someitems:\n        #logging.info(\"return cached someitem\")\n        return someitems\n\n    someitems = []\n    for someitem in Someitem.all().fetch(100):\n        someitems.append(someitem)\n\n    memcache.set(\"someitems\", someitems)\n    logging.info(\"cached someitems\")\n    return someitems\n\n\ndef get_userprefs(user, clear=False):\n    \"\"\"\n    Get the UserPrefs for the current user either from memcache or, if not\n    yet cached, from the datastore and put it into memcache. Used by \n    UserPrefs.from_user(user)\n    \"\"\"\n    if not user:\n        return user\n\n    if user.federated_identity():\n        key = \"userprefs_fid_%s\" % user.federated_identity()\n    else:\n        key = \"userprefs_gid_%s\" % user.user_id()\n\n    # Clearing the cache does not return anything\n    if clear:\n        memcache.delete(key)\n        logging.info(\"- cache cleared key: %s\", key)\n        return\n\n    # Try to grab the cached UserPrefs\n    prefs = memcache.get(key)\n    if prefs:\n        logging.info(\"- returning cached userprefs for key: %s\", key)\n        return prefs\n\n    # If not cached, query the datastore, put into cache and return object\n    prefs = models.UserPrefs._from_user(user)\n    memcache.set(key, prefs)\n    logging.info(\"cached userprefs key: %s\", key)\n    return prefs\n"
  },
  {
    "path": "app/models.py",
    "content": "# -*- coding: utf-8 -*-\nimport logging\n\nfrom hashlib import md5\nfrom google.appengine.ext import db\nfrom google.appengine.api import users\n\nimport mc\n\n\nclass UserPrefs(db.Model):\n    \"\"\"Storage for custom properties related to a user. Provides caching\n    for super-fast access to the UserPrefs object.\n\n    All models with user relations should reference the specific UserPrefs\n    model, never the GAE internal user model (due to a known GAE bug).\n\n    The UserPrefs can be retrieved/created via from_user(user):\n\n        userprefs = UserPrefs.from_user(users.get_current_user())\n\n    This retrieves the UserPrefs object is automatically from memcache or, if\n    not already cached, from the datastore and put into memcache. The cached\n    object is cleared whenever the .put() or .delete() method is called.\n\n    If users.get_current_user() is not logged in, from_user() returns None.\n\n    The BaseRequestHandler (see handlers/baserequesthandler.py and main.py)\n    automatically provides the current UserPref object via self.userprefs.\n    \"\"\"\n    # Base settings. Copied over from OpenID at first login (may not be valid)\n    nickname = db.StringProperty()\n    email = db.StringProperty(default=\"\")\n\n    # The md5 has of the email is used for gravatar image urls\n    email_md5 = db.StringProperty(default=\"\")\n\n    # email_verified is set after user clicked the link in verification mail\n    email_verified = db.BooleanProperty(default=False)\n\n    # The main reference to the Google-internal user object\n    federated_identity = db.StringProperty()\n    federated_provider = db.StringProperty()\n\n    # Google user id is only used on the dev server\n    google_user_id = db.StringProperty()\n\n    # Various meta information\n    date_joined = db.DateTimeProperty(auto_now_add=True)\n    date_lastlogin = db.DateTimeProperty(auto_now_add=True)  # TODO\n    date_lastactivity = db.DateTimeProperty(auto_now_add=True)  # TODO\n\n    # is_setup: set to true after setting username and email at first login\n    is_setup = db.BooleanProperty(default=False)\n\n    # Cursom properties\n    subscribed_to_newsletter = db.BooleanProperty(default=False)\n\n    @staticmethod\n    def from_user(user):\n        \"\"\"Returns the cached UserPrefs object. If not cached, get from DB and\n        put it into memcache.\"\"\"\n        if not user:\n            return None\n\n        return mc.cache.get_userprefs(user)\n\n    @staticmethod\n    def _from_user(user):\n        \"\"\"Gets UserPrefs object from database. Used by\n        mc.cache.get_userprefs() if not cached.\"\"\"\n        if user.federated_identity():\n            # Standard OpenID user object\n            q = db.GqlQuery(\"SELECT * FROM UserPrefs WHERE \\\n                federated_identity = :1\", user.federated_identity())\n\n        else:\n            # On local devserver there is only the google user object\n            q = db.GqlQuery(\"SELECT * FROM UserPrefs WHERE \\\n                google_user_id = :1\", user.user_id())\n\n        # Try to get the UserPrefs from the data store\n        prefs = q.get()\n\n        # If not existing, create now\n        if not prefs:\n            nick = user.nickname()\n            if user.email():\n                if not nick or \"http://\" in nick or \"https://\" in nick:\n                    # If user has email and openid-url is nickname, replace\n                    nick = user.email()\n\n            # Create new user preference entity\n            logging.info(\"Creating new UserPrefs for %s\" % nick)\n            prefs = UserPrefs(nickname=nick,\n                    email=user.email(),\n                    email_md5=md5(user.email().strip().lower()).hexdigest(),\n                    federated_identity=user.federated_identity(),\n                    federated_provider=user.federated_provider(),\n                    google_user_id=user.user_id())\n\n            # Save the newly created UserPrefs\n            prefs.put()\n\n        # Keep an internal reference to the Google user object (for\n        # clearing the cache).\n        prefs._user = user\n\n        # Return either found or just created user preferences\n        return prefs\n\n    def put(self):\n        \"\"\"\n        Overrides db.Model.put() to remove the cached object after an update.\n        \"\"\"\n        # Call the put() method of the db.Model and keep the result\n        key = super(UserPrefs, self).put()\n\n        # Remove previously cached object. If put() is called the first time\n        # (after creating the object) there would be no self._user.\n        if hasattr(self, \"_user\"):\n            self._clear_cache()\n\n        # Return key provided by db.Model.put()\n        return key\n\n    def delete(self):\n        \"\"\"\n        Overrides db.Model.delete() to remove the object from memcache.\n        \"\"\"\n        super(UserPrefs, self).delete()\n        self._clear_cache()\n\n    def _clear_cache(self):\n        \"\"\"\n        Removes the object from memcache. Automatically called on .put()\n        and .delete().\n        \"\"\"\n        mc.cache.get_userprefs(self._user, clear=True)\n\n\nclass YourCustomModel(db.Model):\n    userprefs = db.ReferenceProperty(UserPrefs)\n\n    demo_string_property = db.StringProperty()\n    demo_boolean_property = db.BooleanProperty(default=True)\n    demo_integer_property = db.IntegerProperty(default=1)\n    demo_datetime_property = db.DateTimeProperty(auto_now_add=True)\n"
  },
  {
    "path": "app/queue.yaml",
    "content": "# Task queue configuration\n# http://code.google.com/appengine/docs/python/config/queue.html\n#\nqueue:\n#- name: fooqueue\n#  rate: 1/s\n#  bucked_size:40\n#  retry_parameters:\n#    task_retry_limit: 7\n#    task_age_limit: 2d\n#- name: barqueue\n#  rate: 1/s\n#  retry_parameters:\n#    min_backoff_seconds: 10\n#    max_backoff_seconds: 200\n#    max_doublings: 0\n#- name: bazqueue\n#  rate: 1/s\n#  retry_parameters:\n#    min_backoff_seconds: 10\n#    max_backoff_seconds: 200\n#    max_doublings: 2"
  },
  {
    "path": "app/services.py",
    "content": "# -*- coding: utf-8 -*-\nimport os\nfrom google.appengine.dist import use_library\nos.environ['DJANGO_SETTINGS_MODULE'] = 'settings'\nuse_library('django', '1.2')\n\n\"\"\"\nServices that are accessible to admin only (eg. cron).\n\"\"\"\n\nfrom google.appengine.api import mail\nfrom google.appengine.api import taskqueue\nfrom google.appengine.ext import webapp\nfrom google.appengine.ext.webapp.util import run_wsgi_app\n\nfrom models import Emails\nfrom handlers import *\n\n\nclass Cron1(webapp.RequestHandler):\n    def get(self):\n        \"\"\"Cron job that queries the db and forks a worker for each entry\"\"\"\n        emails = db.GqlQuery(\"SELECT * FROM emails WHERE 1\")\n\n        # Start worker requests in the background\n        for email in emails:\n            taskqueue.add(url='/services/cron1-worker1/%s' % email.key())\n\n\nclass Cron1_Worker1(webapp.RequestHandler):\n    def post(self, key):\n        \"\"\"Worker that runs in the 'background'\"\"\"\n        # Get the object from the database\n        email = Emails.get(key)\n\n        # Construct a appengine.api.mail object\n        message = mail.EmailMessage()\n        message.sender = \"Your Name <you@domain.x>\"\n        message.to = email.to\n        message.subject = email.subject\n\n        # Set text and html body\n        message.body = email.body_text\n        message.html = email.body_html\n\n        # Send. Important: Sometimes emails fail to send, which will throw an\n        # exception and end the function there. Next round tries again.\n        message.send()\n\n        # Now the message was sent and we can safely delete it.\n        email.delete()\n\n\nurls = [\n    (r'/services/cron1', Cron1),\n    (r'/services/cron1-worker1', Cron1_Worker1),\n]\n\napplication = webapp.WSGIApplication(urls, debug=True)\n\n\ndef main():\n    run_wsgi_app(application)\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "app/settings.py",
    "content": "#\n# Update the settings as needed\n#\nTEMPLATE_DIR = \"templates/\"\n\n# MailChimp settings to subscribe users after signup\nMAILCHIMP_API_KEY = \"\"\n\n# Find it on mailchimp.com via \"settings\" -> \"list settings and unique id\"\nMAILCHIMP_LIST_ID = \"\"\n\n# Use this switch to turn the MailChimp API calls on and off. Set to True only\n# for testing and production. Set to False during development.\nMAILCHIMP_ENABLED = False\n"
  },
  {
    "path": "app/static_dev/.htaccess",
    "content": "# Apache configuration file\n# httpd.apache.org/docs/2.2/mod/quickreference.html\n\n# Note .htaccess files are an overhead, this logic should be in your Apache config if possible\n# httpd.apache.org/docs/2.2/howto/htaccess.html\n\n# Techniques in here adapted from all over, including:\n#   Kroc Camen: camendesign.com/.htaccess\n#   perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/\n#   Sample .htaccess file of CMS MODx: modxcms.com\n\n\n###\n### If you run a webserver other than apache, consider:\n### github.com/paulirish/html5-boilerplate-server-configs\n###\n\n\n\n# ----------------------------------------------------------------------\n# Better website experience for IE users\n# ----------------------------------------------------------------------\n\n# Force the latest IE version, in various cases when it may fall back to IE7 mode\n#  github.com/rails/rails/commit/123eb25#commitcomment-118920\n# Use ChromeFrame if it's installed for a better experience for the poor IE folk\n\n<IfModule mod_setenvif.c>\n  <IfModule mod_headers.c>\n    BrowserMatch MSIE ie\n    Header set X-UA-Compatible \"IE=Edge,chrome=1\" env=ie\n  </IfModule>\n</IfModule>\n\n<IfModule mod_headers.c>\n# Because X-UA-Compatible isn't sent to non-IE (to save header bytes),\n#   We need to inform proxies that content changes based on UA\n  Header append Vary User-Agent\n# Cache control is set only if mod_headers is enabled, so that's unncessary to declare\n</IfModule>\n\n\n# ----------------------------------------------------------------------\n# Cross-domain AJAX requests\n# ----------------------------------------------------------------------\n\n# Serve cross-domain ajax requests, disabled.   \n# enable-cors.org\n# code.google.com/p/html5security/wiki/CrossOriginRequestSecurity\n\n#  <IfModule mod_headers.c>\n#    Header set Access-Control-Allow-Origin \"*\"\n#  </IfModule>\n\n\n\n# ----------------------------------------------------------------------\n# Webfont access\n# ----------------------------------------------------------------------\n\n# allow access from all domains for webfonts\n# alternatively you could only whitelist\n#   your subdomains like \"sub.domain.com\"\n\n<FilesMatch \"\\.(ttf|otf|eot|woff|font.css)$\">\n  <IfModule mod_headers.c>\n    Header set Access-Control-Allow-Origin \"*\"\n  </IfModule>\n</FilesMatch>\n\n\n\n# ----------------------------------------------------------------------\n# Proper MIME type for all files\n# ----------------------------------------------------------------------\n\n# audio\nAddType audio/ogg                      oga ogg\n\n# video\nAddType video/ogg                      ogv\nAddType video/mp4                      mp4\nAddType video/webm                     webm\n\n# Proper svg serving. Required for svg webfonts on iPad\n#   twitter.com/FontSquirrel/status/14855840545\nAddType     image/svg+xml              svg svgz \nAddEncoding gzip                       svgz\n                                       \n# webfonts                             \nAddType application/vnd.ms-fontobject  eot\nAddType font/truetype                  ttf\nAddType font/opentype                  otf\nAddType application/x-font-woff        woff\n\n# assorted types                                      \nAddType image/x-icon                   ico\nAddType image/webp                     webp\nAddType text/cache-manifest            appcache manifest\nAddType text/x-component               htc\nAddType application/x-chrome-extension crx\nAddType application/x-xpinstall        xpi\nAddType application/octet-stream       safariextz\n\n\n\n# ----------------------------------------------------------------------\n# Allow concatenation from within specific js and css files \n# ----------------------------------------------------------------------\n\n# e.g. Inside of script.combined.js you could have\n#   <!--#include file=\"libs/jquery-1.5.0.min.js\" -->\n#   <!--#include file=\"plugins/jquery.idletimer.js\" -->\n# and they would be included into this single file\n\n# this is not in use in the boilerplate as it stands. you may\n#   choose to name your files in this way for this advantage\n#   or concatenate and minify them manually.\n# Disabled by default.\n\n# <FilesMatch \"\\.combined\\.(js|css)$\">\n#         Options +Includes\n#         SetOutputFilter INCLUDES\n# </FilesMatch>\n\n\n\n# ----------------------------------------------------------------------\n# gzip compression\n# ----------------------------------------------------------------------\n\n<IfModule mod_deflate.c>\n\n\n# force deflate for mangled headers developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping/\n<IfModule mod_setenvif.c>\n  <IfModule mod_headers.c>\n    SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\\s,?\\s(gzip|deflate)?|X{4,13}|~{4,13}|-{4,13})$ HAVE_Accept-Encoding\n    RequestHeader append Accept-Encoding \"gzip,deflate\" env=HAVE_Accept-Encoding\n  </IfModule>\n</IfModule>\n# html, txt, css, js, json, xml, htc:\n<IfModule filter_module>\n  FilterDeclare   COMPRESS\n  FilterProvider  COMPRESS  DEFLATE resp=Content-Type /text/(html|css|javascript|plain|x(ml|-component))/\n  FilterProvider  COMPRESS  DEFLATE resp=Content-Type /application/(javascript|json|xml|x-javascript)/\n  FilterChain     COMPRESS\n  FilterProtocol  COMPRESS  change=yes;byteranges=no\n</IfModule>\n\n<IfModule !mod_filter.c>\n  # Legacy versions of Apache\n  AddOutputFilterByType DEFLATE text/html text/plain text/css application/json\n  AddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript \n  AddOutputFilterByType DEFLATE text/xml application/xml text/x-component\n</IfModule>\n\n# webfonts and svg:\n  <FilesMatch \"\\.(ttf|otf|eot|svg)$\" >\n    SetOutputFilter DEFLATE\n  </FilesMatch>\n</IfModule>\n\n\n\n# ----------------------------------------------------------------------\n# Expires headers (for better cache control)\n# ----------------------------------------------------------------------\n\n# these are pretty far-future expires headers\n# they assume you control versioning with cachebusting query params like\n#   <script src=\"application.js?20100608\">\n# additionally, consider that outdated proxies may miscache \n#   www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/\n\n# if you don't use filenames to version, lower the css and js to something like\n#   \"access plus 1 week\" or so\n\n<IfModule mod_expires.c>\n  ExpiresActive on\n\n# Perhaps better to whitelist expires rules? Perhaps.\n  ExpiresDefault                          \"access plus 1 month\"\n\n# cache.appcache needs re-requests in FF 3.6 (thx Remy ~Introducing HTML5)\n  ExpiresByType text/cache-manifest       \"access plus 0 seconds\"\n\n# your document html \n  ExpiresByType text/html                 \"access plus 0 seconds\"\n  \n# data\n  ExpiresByType text/xml                  \"access plus 0 seconds\"\n  ExpiresByType application/xml           \"access plus 0 seconds\"\n  ExpiresByType application/json          \"access plus 0 seconds\"\n\n# rss feed\n  ExpiresByType application/rss+xml       \"access plus 1 hour\"\n\n# favicon (cannot be renamed)\n  ExpiresByType image/x-icon              \"access plus 1 week\" \n\n# media: images, video, audio\n  ExpiresByType image/gif                 \"access plus 1 month\"\n  ExpiresByType image/png                 \"access plus 1 month\"\n  ExpiresByType image/jpg                 \"access plus 1 month\"\n  ExpiresByType image/jpeg                \"access plus 1 month\"\n  ExpiresByType video/ogg                 \"access plus 1 month\"\n  ExpiresByType audio/ogg                 \"access plus 1 month\"\n  ExpiresByType video/mp4                 \"access plus 1 month\"\n  ExpiresByType video/webm                \"access plus 1 month\"\n  \n# htc files  (css3pie)\n  ExpiresByType text/x-component          \"access plus 1 month\"\n  \n# webfonts\n  ExpiresByType font/truetype             \"access plus 1 month\"\n  ExpiresByType font/opentype             \"access plus 1 month\"\n  ExpiresByType application/x-font-woff   \"access plus 1 month\"\n  ExpiresByType image/svg+xml             \"access plus 1 month\"\n  ExpiresByType application/vnd.ms-fontobject \"access plus 1 month\"\n    \n# css and javascript\n  ExpiresByType text/css                  \"access plus 2 months\"\n  ExpiresByType application/javascript    \"access plus 2 months\"\n  ExpiresByType text/javascript           \"access plus 2 months\"\n  \n  <IfModule mod_headers.c>\n    Header append Cache-Control \"public\"\n  </IfModule>\n  \n</IfModule>\n\n\n\n# ----------------------------------------------------------------------\n# ETag removal\n# ----------------------------------------------------------------------\n\n# Since we're sending far-future expires, we don't need ETags for\n# static content.\n#   developer.yahoo.com/performance/rules.html#etags\nFileETag None\n\n\n\n# ----------------------------------------------------------------------\n# Stop screen flicker in IE on CSS rollovers\n# ----------------------------------------------------------------------\n\n# The following directives stop screen flicker in IE on CSS rollovers - in\n# combination with the \"ExpiresByType\" rules for images (see above). If\n# needed, un-comment the following rules.\n\n# BrowserMatch \"MSIE\" brokenvary=1\n# BrowserMatch \"Mozilla/4.[0-9]{2}\" brokenvary=1\n# BrowserMatch \"Opera\" !brokenvary\n# SetEnvIf brokenvary 1 force-no-vary\n\n\n\n# ----------------------------------------------------------------------\n# Cookie setting from iframes\n# ----------------------------------------------------------------------\n\n# Allow cookies to be set from iframes (for IE only)\n# If needed, uncomment and specify a path or regex in the Location directive\n\n# <IfModule mod_headers.c>\n#   <Location />\n#     Header set P3P \"policyref=\\\"/w3c/p3p.xml\\\", CP=\\\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\\\"\"\n#   </Location>\n# </IfModule>\n\n\n\n# ----------------------------------------------------------------------\n# Start rewrite engine\n# ----------------------------------------------------------------------\n\n# Turning on the rewrite engine is necessary for the following rules and features.\n\n<IfModule mod_rewrite.c>\n  RewriteEngine On\n</IfModule>\n\n\n\n# ----------------------------------------------------------------------\n# Suppress or force the \"www.\" at the beginning of URLs\n# ----------------------------------------------------------------------\n\n# The same content should never be available under two different URLs - especially not with and\n# without \"www.\" at the beginning, since this can cause SEO problems (duplicate content).\n# That's why you should choose one of the alternatives and redirect the other one.\n\n# By default option 1 (no \"www.\") is activated. Remember: Shorter URLs are sexier.\n# no-www.org/faq.php?q=class_b\n\n# If you rather want to use option 2, just comment out all option 1 lines\n# and uncomment option 2.\n# IMPORTANT: NEVER USE BOTH RULES AT THE SAME TIME!\n\n# ----------------------------------------------------------------------\n\n# Option 1:\n# Rewrite \"www.domain.com -> domain.com\" \n\n<IfModule mod_rewrite.c>\n  RewriteCond %{HTTPS} !=on\n  RewriteCond %{HTTP_HOST} ^www\\.(.+)$ [NC]\n  RewriteRule ^(.*)$ http://%1/$1 [R=301,L]\n</IfModule>\n\n# ----------------------------------------------------------------------\n\n# Option 2:\n# To rewrite \"domain.com -> www.domain.com\" uncomment the following lines.\n# Be aware that the following rule might not be a good idea if you\n# use \"real\" subdomains for certain parts of your website.\n\n# <IfModule mod_rewrite.c>\n#   RewriteCond %{HTTPS} !=on\n#   RewriteCond %{HTTP_HOST} !^www\\..+$ [NC]\n#   RewriteCond %{HTTP_HOST} (.+)$ [NC]\n#   RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L]\n# </IfModule>\n\n\n\n# ----------------------------------------------------------------------\n# Add/remove trailing slash to (non-file) URLs\n# ----------------------------------------------------------------------\n\n# Google treats URLs with and without trailing slashes separately.\n# Forcing a trailing slash is usually preferred, but all that's really\n# important is that one correctly redirects to the other.\n\n# By default option 1 (force trailing slash) is activated.\n# http://googlewebmastercentral.blogspot.com/2010/04/to-slash-or-not-to-slash.html\n# http://www.alistapart.com/articles/slashforward/\n# http://httpd.apache.org/docs/2.0/misc/rewriteguide.html#url Trailing Slash Problem\n\n# ----------------------------------------------------------------------\n\n# Option 1:\n# Rewrite \"domain.com/foo -> domain.com/foo/\"\n\n<IfModule mod_rewrite.c>\n  RewriteCond %{REQUEST_FILENAME} !-f\n  RewriteCond %{REQUEST_URI} !(\\.[a-zA-Z0-9]{1,5}|/|#(.*))$\n  RewriteRule ^(.*)$ /$1/ [R=301,L]\n</IfModule>\n\n# ----------------------------------------------------------------------\n\n# Option 2:\n# Rewrite \"domain.com/foo/ -> domain.com/foo\"\n\n#<IfModule mod_rewrite.c>\n#  RewriteRule ^(.*)/$ /$1 [R=301,L]\n#</IfModule>\n\n\n\n# ----------------------------------------------------------------------\n# Built-in filename-based cache busting\n# ----------------------------------------------------------------------\n\n# If you're not using the build script to manage your filename version revving,\n# you might want to consider enabling this, which will route requests for\n# /css/style.20110203.css to /css/style.css\n\n# To understand why this is important and a better idea than all.css?v1231,\n# read: github.com/paulirish/html5-boilerplate/wiki/Version-Control-with-Cachebusting\n\n# Uncomment to enable.\n# <IfModule mod_rewrite.c>\n#   RewriteCond %{REQUEST_FILENAME} !-f\n#   RewriteCond %{REQUEST_FILENAME} !-d\n#   RewriteRule ^(.+)\\.(\\d+)\\.(js|css|png|jpg|gif)$ $1.$3 [L]\n# </IfModule>\n\n\n\t\n# ----------------------------------------------------------------------\n# Prevent SSL cert warnings\n# ----------------------------------------------------------------------\n\n# Rewrite secure requests properly to prevent SSL cert warnings, e.g. prevent \n# https://www.domain.com when your cert only allows https://secure.domain.com\n# Uncomment the following lines to use this feature.\n\n# <IfModule mod_rewrite.c>\n#   RewriteCond %{SERVER_PORT} !^443\n#   RewriteRule (.*) https://example-domain-please-change-me.com/$1 [R=301,L]\n# </IfModule>\n\n\n\n# ----------------------------------------------------------------------\n# Prevent 404 errors for non-existing redirected folders\n# ----------------------------------------------------------------------\n\n# without -MultiViews, Apache will give a 404 for a rewrite if a folder of the same name does not exist \n#   e.g. /blog/hello : webmasterworld.com/apache/3808792.htm\n\nOptions -MultiViews \n\n\n\n# ----------------------------------------------------------------------\n# custom 404 page\n# ----------------------------------------------------------------------\n\n# You can add custom pages to handle 500 or 403 pretty easily, if you like.\nErrorDocument 404 /404.html\n\n\n\n# ----------------------------------------------------------------------\n# UTF-8 encoding\n# ----------------------------------------------------------------------\n\n# use utf-8 encoding for anything served text/plain or text/html\nAddDefaultCharset utf-8\n\n# force utf-8 for a number of file formats\nAddCharset utf-8 .html .css .js .xml .json .rss\n\n\n\n# ----------------------------------------------------------------------\n# A little more security\n# ----------------------------------------------------------------------\n\n\n# Do we want to advertise the exact version number of Apache we're running?\n# Probably not.\n## This can only be enabled if used in httpd.conf - It will not work in .htaccess\n# ServerTokens Prod\n\n\n# \"-Indexes\" will have Apache block users from browsing folders without a default document\n# Usually you should leave this activated, because you shouldn't allow everybody to surf through\n# every folder on your server (which includes rather private places like CMS system folders).\n# Options -Indexes\n\n\n# Block access to \"hidden\" directories whose names begin with a period. This\n# includes directories used by version control systems such as Subversion or Git.\n<IfModule mod_rewrite.c>\n  RewriteRule \"(^|/)\\.\" - [F]\n</IfModule>\n\n\n# If your server is not already configured as such, the following directive\n# should be uncommented in order to set PHP's register_globals option to OFF.\n# This closes a major security hole that is abused by most XSS (cross-site\n# scripting) attacks. For more information: http://php.net/register_globals\n#\n# IF REGISTER_GLOBALS DIRECTIVE CAUSES 500 INTERNAL SERVER ERRORS :\n#\n# Your server does not allow PHP directives to be set via .htaccess. In that\n# case you must make this change in your php.ini file instead. If you are\n# using a commercial web host, contact the administrators for assistance in\n# doing this. Not all servers allow local php.ini files, and they should\n# include all PHP configurations (not just this one), or you will effectively\n# reset everything to PHP defaults. Consult www.php.net for more detailed\n# information about setting PHP directives.\n\n# php_flag register_globals Off\n\n\n\n\n"
  },
  {
    "path": "app/static_dev/404.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n  <title>Page Not Found :(</title> \n  <style>\n\t  body { text-align: center;}\n\t  h1 { font-size: 50px; text-align: center }\n\t  span[frown] { transform: rotate(90deg); display:inline-block; color: #bbb; }\n\t  body { font: 20px Constantia, 'Hoefler Text',  \"Adobe Caslon Pro\", Baskerville, Georgia, Times, serif; color: #999; text-shadow: 2px 2px 2px rgba(200, 200, 200, 0.5); }\n\t  ::-moz-selection{ background:#FF5E99; color:#fff; }\n\t  ::selection { background:#FF5E99; color:#fff; } \n\t  article {display:block; text-align: left; width: 500px; margin: 0 auto; }\n\t  \n\t  a { color: rgb(36, 109, 56); text-decoration:none; }\n\t  a:hover { color: rgb(96, 73, 141) ; text-shadow: 2px 2px 2px rgba(36, 109, 56, 0.5); }\n  </style>\n</head>\n<body>\n     <article>\n\t  <h1>Not found <span frown>:(</span></h1>\n\t   <div>\n\t       <p>Sorry, but the page you were trying to view does not exist.</p>\n\t       <p>It looks like this was the result of either:</p>\n\t       <ul>\n\t\t   <li>a mistyped address</li>\n\t\t   <li>an out-of-date link</li>\n\t       </ul>\n\t   </div>\n\t    \n\t    <script>\n\t    var GOOG_FIXURL_LANG = (navigator.language || '').slice(0,2),\n\t\tGOOG_FIXURL_SITE = location.host;\n\t    </script>\n\t    <script src=\"http://linkhelp.clients.google.com/tbproxy/lh/wm/fixurl.js\"></script>\n     </article>\n</body>\n</html>"
  },
  {
    "path": "app/static_dev/README.md",
    "content": "#  HTML5 Boilerplate [http://html5boilerplate.com](http://html5boilerplate.com)\n\n## Changelog:\n\n### v.2.0 : August 10th, 2011\n\n### v2.0 HIGHLIGHTS\n\n#### NORMALIZE.CSS\n\nWe are now using [normalize.css](http://github.com/necolas/normalize.css/) developed by Nicolas Gallagher along with Jonathan Neal instead of the traditional CSS Reset stylesheet.\n\nnormalize.css retains useful browser defaults and includes several common fixes to improve cross-browser (desktop and mobile) styling consistency.\n\nLots of research has gone into normalize, verifying what are the default user agent styles provided by each browser. We can very specifically change only the ones we need to instead of the bulldozer approach.\n\n##### Why this is great news:\n\n* Who likes being so damn redundant and declaring: em, i { font-style: italic; }\n* By using normalization instead of a reset + building up default styles, we use less styles and save bytes\n* Less noise in your dev tools: when debugging, you don't have to trawl through every reset selector to reach the actual style that is causing the issue.\n* More details here: http://necolas.github.com/normalize.css/\n\n\n#### PROMPT CHROME FRAME FOR IE6\n* With the latest release of Chrome frame which does not require admin access to be installed, we felt it was a good time to prompt IE 6 users to install Chrome Frame. (Using protocol-relative url and exact version for higher expires headers)\n\n\n####BUILD SCRIPT++: Faster, @import inlining, appcache generation\n*  If 15 seconds was too long to wait before, you'll be happy with the changes. Via a new \"intermediate\" folder, we cut down build time by 80% or more.\n*  If you use <code>@import</code>s in your CSS to author in multiple files, the build script will inline all these together. This way, you have a maintainable authoring experience, and still a highly performant production version.\n* Making an app that works offline is a badge of honor. Now with a flick of a config switch, the H5BP build script can autogenerate your cache manifest file with all the right info and wire it up. It'll also keep the manifest revved as you deploy new changes.\n\n##### ADDING RESPOND.JS\n* Add respond.js as a shift to a responsive approach. Updated it to improved, comment-free version which would enable IEs to also apply styles using media queries. \n\n\n#### PNGFIX & HANDHELD REMOVED\n* Remove handheld.css as we do not think it was useful among the diverse feature phones\n* We feel tools like imagealpha and pngquant are more useful than using stopgap fixes like belatedpng.\n\n### detailed 2.0 changelog\n\n#### .HTACCESS\n* Disable directory browsing by default \n* removed trailing slash redirects in htaccess. More: https://github.com/paulirish/html5-boilerplate/wiki/Proper-usage-of-trailing-slash-redirects #493 #515\n* Updating TTF mimetype to fix Google Chrome warning\n* Improved support for all versions of Apache, incl workaround for bug in mod_filter: Fixes #441. Fixes #499. Fixes #535. Closes #549. (the grouping ticket) Ref #576\n* Use substring matching in gzip filter_module and re-enable gzip for some common MIME-types\n* mod_deflate trigger rules modifications\n* Add gzip support for XHTML, RSS, Atom\n* Move font & SVG compression from FilesMatch to FilterProvider / AddOutputFilterByType\n* Added m4a (Need it for IE9) and m4v (HandBrake default) MIME types.\n* moved ETag removal configs closer\n* added Header unset ETag In some servers setting \"FileETag None\" alone, is not enough. Removing header and setting it to None fixes the issue.\n* Add `Options +FollowSymlinks` when `RewriteEngine` is used. Fixes #489.\n* Some more security for PHP: turn off error display and turn on error logging\n* Allow Blackberry to read vCards\n\n\n#### BUILD SCRIPT\n* CSSLint, JSLint, JSHint tools are now optionally available in the build script\n* New features in build script:\n* Added a files.bypass property  which when set, will not compress the listed JavaScript files, but just silently passes it on to the publish folder without any change. \n* Added a images.bypass with a list of image files or folders within the img directory that you do not want to be optimized. Fixes #564\n* Build script is compatible with php files now. it appears. fixes #392.\n* Build script now generates appcache manifest. see #652 \n* Test for ant version to head off problems with ant < 1.8.2\n* removes concatenated css files from index.html when they are linked to with link tag. Fixes #452\n* Added DOCTYPE so Eclipse and other IDE's do not complain about the lack of schema. http://stackoverflow.com/questions/363768/disable-dtd-warning-for-ant-scripts-in-eclipse\n* Updated Windows optipng and jpegtran paths to include ${basedir}\n* Minification affects all .css and .js files in /css and /js dirs,  not just the ones explicitly included in concatenation.\n* Build script: compress all images in subfolders, too. \n* Added gae.js_dir and gae.css_dir so that App Engine projects can have the correct directory names swapped in their templates.\n* added a second replace token statement so that \"/css/style.css\" gets swapped too.\n* change *.png and *.jpg to **/*.png and **/*.jpg so that optimize commands reach subdirectories.\n* Improved build script compatibility with Netbeans IDE. default.properties: added IDE generated files/folders to exclude from build script .gitignore: Filename case correction for Windows generated Thumb.db Fix #374\n* Adding properties to project.properties so that Google App Engine builds don't have \"static\" prepended when swapping for minified versions.\n* console.log messages are no longer commented out. use log() instead\n\n* Much faster build process\n\nIntermediate stages are stored in a new intermediate folder, and only\nfiles that should be published are copied into the publish folder.\n\nFiles are not deleted at the beginning of every build, and files that\nhave already been processed will not be reprocessed unless the source\nhas changed.\n\n* Files are revved by SHA, not incrementally at each build\n\nVersioned files are referenced by a SHA-1 hash of the content rather\nthan a build number. This means that changing your HTML and rebuilding\nwill not cause your users to redownload the same CSS and JavaScript, and\na reverted change may cause users to use a copy that was previously\ndownloaded. It may be better to use only part of the hash so the HTTP\nrequest is shorter.\n\n* copy files last This slightly simplifies copying because we don't have to exclude PNG, JPEG, or HTML files from the copy stage. it comes preminified, and we don't need to minify it again This also updates the HTML so that the script is not missing if the unminified scripts are unavailable on the server. This commit requires a change to existing HTML files :/\n* change the source htaccess rather than updating it\n* update yuicompressor to 2.4.5. fixes media query minification issue.\n* update htmlcompressor to 1.1 which uses the new yuicompressor for CSS. \n* try not to re-optimize the same images every time\n* Lots of bug fixes for edge cases and improved techniques..\n\n\n\n#### INDEX.HTML\n* Use minified jQuery by default. / jQuery updated to 1.6.2\n* Add respond.js as part of shift to 'mobile first' approach. \n* Updated to Modernizr 2.0 Complete, Production minified.\n* Prompt IE 6 users to install Chrome Frame, update chromeframe install to 1.0.3.  Move chromeframe to bottom of page after the other scripts. also reference exact version for higher expires headers. Use protocol-relative url for chrome frame URL Fixes #495\n* Removing touch icon link tags and retaining only the comment.\n* Encourage people to send the X-UA-Compatible HTTP header instead of leaving it in the HTML, to avoid edge case issues. Fixes #378.\n* Remove the cache-busting query parameters from the HTML. \n* Simplify the conditional comment containing code for IE 9+ and modern browsers\n* Simpler escape for `</script>`. See http://mathiasbynens.be/notes/etago for more information.\n* Encourage people to use a custom Modernizr build containing only the features they need for that particular project.\n* Added maximum touch-icon support as per http://mathiasbynens.be/notes/touch-icons#sizes\n* Add a link to optional <meta> tags that could be added to the <head> element: https://github.com/paulirish/html5-boilerplate/issues/482\n* Standardize the use of single and double quotes as per http://h5bp.com/d/The-markup★quotes\n* Added Site Speed tracking for Google Analytics\n* Using Modernizr.load/yepnope for loading Google Analytics. Fixes #542\n* Google Analytics now retrieved with <code>Modernizr.load()</code> for byte brevity and optimal speed\n\n#### STYLE.CSS\n* Major: Now using css normalization instead of css reset + building up default styles.  Fixes #412, #500, #534. Closes #456. Links #566\n* Add `'oldie'` class to conditional `<html>` classnames. Fix #522\n* Add `img { max-width: 100%; }` to print styles to prevent images from getting cut off.\n* Update clearfix to use 'micro' clearfix http://nicolasgallagher.com/micro-clearfix-hack/\n* Add placeholder CSS MQs for mobile-first approach\n* Tweaking our hot pink ::selection. It is now #fe57a1, which is Festal (adj): pertaining to or befitting a feast, festival, holiday, or gala occasion.\n* Use black for links when printing, refs #147\n* added vertical-align: middle to fix borders on image containers. Fixes #440\n* Add `<svg>` overflow fix for IE9. Group `<img>` and `<svg>` rules in an 'embedded content' section of CSS file. Add {cursor:pointer} to <label> element.\n* Switch to outline:0 for accesible focus treatment. Avoids Opera bug when combined with transitions. Also saves bytes.\n* Set `{overflow:auto}` for `<button>` and `<input>` in `<table>` in IE6/7. Avoids numerous layout and whitespace issues that result from setting {overflow:visible} to fix the odd inner spacing of those form elements.\n* Add `{resize: vertical}` to `<textarea>`. Only allow vertical resizing\n \n\n#### MISC\n\n* gitignore additions: textmate project folder, older CVS folders,  sass_cache.\n* Update HTML elements demo: reduce repetition, remove deprecated elements, add certain HTML5 elements, add more comprehensive collection of HTML5 input types, include different form markup styles, add form elements box-sizing test\n* Add .gitattributes to help with consistent line endings\n* Changed curly quotes to straight quotes in crossdomain.xml\n\n\n#### Significant commits: \n\n* 26a391c60d0356e2e0dcf1929381583622e1be9c Revert \"Added native iOS inertia scrolling\" \n* ddaf66a515c09f835603f95fe723d7da691324e6 Major: Now using css normalization instead of css reset + building up default styles\n* e5e057e53815ed55f4ecfaef3057bf2940c7c0b2 Change our conditional comments around the HTML tag to use a single .oldie class.\n* 7f53f98ec734e6b655d7a50fd245277d388fac1e Revert \"Change our conditional comments around the HTML tag to use a single .oldie class.\"\n* 648026d780dc6b9ecad8d37d61a92b69be5fd654 Tweaking our hot pink ::selection based on a suggestion from David Murdoch and research from Adam Diehm.\n* 0e1c7ba929caddec63971cccfb7de7c0d343e060 Use minified jQuery by default.\n* a0ac99a4d96453e68ff4e650fca3055767ec26aa optimize build process\n* bb22ca66a8619808a87c1b5438845ed44baa4d3e Remove the cache-busting query parameters from the HTML. \n\n\n#### CONTRIBUTORS\n[alrra](https://github.com/alrra) [Adeel Ejaz](http://adeelejaz.com/) [David Murdoch](http://www.vervestudios.co/) [Jonathan Fielding](https://github.com/jonathan-fielding) [Robert Ros](https://github.com/rros) [Rob Larsen](http://htmlcssjavascript.com/) [William Meleyal](http://meleyal.com/) [Bruno De Barros](http://terraduo.com/) [Mike Almond](http://mikealmond.com/) [Frank](https://github.com/thatcoolguy) [Joey Baker](http://byjoeybaker.com/) [Ben Word](http://benword.com/) [Mike Botsko](http://www.botsko.net/) [Carlos Rosquillas](https://github.com/disusered) [Todd H. Gardner](https://github.com/toddhgardner) [rdeknijf](https://github.com/rdeknijf) [John Attebury](https://github.com/johnattebury) [Calvin Rien](https://github.com/darktable) [Ryan Seddon](https://github.com/ryanseddon) [Dayle Rees](http://www.daylerees.com/) [Ryan Smith-Roberts](https://lab.net/) [Brian Blakely](https://github.com/brianblakely) [Steve Heffernan](http://www.steveheffernan.com) [Barney Carroll](http://barneycarroll.com/) [Osman Gormus](https://github.com/gormus) [Jason Tokoph](http://www.mozes.com/) [See Guo Lin](http://see.guol.in/) [Jeremey Hustman](http://www.ukontrol.com/) [James Williams](http://jameswilliams.be/blog) [John-Scott Atlakson](https://github.com/jsma) [stereobooster](https://github.com/stereobooster) [walker](http://walkerhamilton.com/) [François Robichet](http://www.francois.robichet.com/) [leobetosouza](http://leobetosouza.com/) [Matthew Donoughe](http://static.dyndns.org/~mdonoughe/) [Patrick Hall](http://lotsofwords.org/) [Andy Dawson](http://www.ad7six.com/) [Daniel Filho](http://danielfilho.info/blog/) [Clément](https://github.com/clemos) [Joe Morgan](https://github.com/JoeMorgan) [Han Lin Yap](http://www.zencodez.net/) [Gregg Gajic](https://github.com/gg) [Michael Cetrulo](http://www.linkedin.com/in/web2samus) [Robert Doucette](https://github.com/robbyrice) [lexadecimal.com](http://lexadecimal.com/) [Adam Diehm](http://twitter.com/atdiehm) \n\n\n### v.1.0 : March 21st, 2011\n\n#### Build Script\n<ul>\n\t<li>Files linked via <code>@import</code> will be inlined into the files they are imported to using Corey Hart's CSS Compressor.</li>\n\t<li>Environments are definable.</li>\n\t<li>htaccess Expires headers are upgraded to 1year, as the filenames are revved</li>\n\t<li>Massive rewrite so you can define which HTML, CSS, and JS files to operate on in your configurable project.properties files. This allows you to let the build script operate on unique folder architectures (including non-H5BP projects).</li>\n\t<li>Added a source directory option in the build config, so your source files can be in a different directory from the final generated files. (Useful for other CMSes/frameworks like Django.) </li>\t\t\n</ul>\n\n#### index.html\n<ul>\n\t<li>We use a <a href=\"http://paulirish.com/2010/the-protocol-relative-url/\">protocol-relative URL</a> for the jQuery include, to prevent the mixed content warning.</li>\n\t<li>The order of <code>&lt;meta></code> tags, <code>&lt;title></code>, and <code>charset</code> has been <a href=\"https://github.com/paulirish/html5-boilerplate/wiki/The-markup\">documented more extensively now</a>. TL;DR: You are <a href=\"https://github.com/paulirish/html5-boilerplate/commit/4b67ea5cabb8c2b75faf2e255344cdffdf190464\">safe to use the boilerplate's order of tags</a>.</li>\n\t<li>We've shortened up the Google Analytics snippet.</li>\n\t<li>Added an ARIA <code>role</code> attribute to <code>div#main</code>. This assumes your main content goes within that container.</li>\n\t<li>IE9 doesn't get its own conditional class! Yay!</li>\t\t\n</ul>\n\n#### style.css\n<ul>\n\t<li>Added <code>.focusable</code> helper class, which extends <code>.visuallyhidden</code> to allow the element to be focusable when navigated to via the keyboard.</li>\n\t<li>Anchor links are no longer reset. Basically our reset is effectively merged with Eric Meyer's recent CSS reset update, and the HTML5 Doctor reset.</li>\n\t<li>An unordered list within a <code>&lt;nav></code> element will no longer have a margin.</li>\n\t<li>All helper classes are now after primary styles to ensure correct overrides and not be burdened with resets. </li>\n\t<li><code>.visuallyhidden</code> is no longer camelCase for consistency with other classname formats.</li>\n\t<li>Updated the specificity of <code>.visuallyhidden</code> to make sure it overrides all other declarations. </li>\n\t<li>Removed reset on <code>&lt;img></code> elements within table cells as they look ugly alongside multiline texts. Browsers default to baseline alignment for images, which works better than top alignment.</li>\n\t<li>Increased margin-left on <code>&lt;ol></code>, to allow for 2-digit list numbers.</li>\n\t<li>Added a print reset on IE's proprietary filters.</li>\n\t<li>Print styles no longer prints hash links or JavaScript links.</li>\n\t<li>Updated <code>&lt;sub></code>/<code>&lt;sup></code> CSS so that they're not impacted by <code>line-height</code>, so now you can do sub/superscripts without worrying.</li>\t\t\n</ul>\n\n#### Project\n<ul>\n\t<li>Added a <a href=\"http://humanstxt.org\">humans.txt</a> so you can clarify authorship and tools used.</li>\n\t<li>Removed YUI profiling. You probably weren't using it anyway.</li>\n\t<li>Removed QUnit's unit tests. There is no need to ship with them, really.</li>\t\t\n</ul>\n\n#### Webserver Configs\n#### .htaccess\n<ul>\n\t<li>.htaccess is far more documented now. Take a read through it!</li>\n\t<li><a href=\"https://github.com/paulirish/html5-boilerplate/commit/37b5fec090d00f38de64b591bcddcb205aadf8ee\">Changed mimetype of <code>.ico</code> files to <code>image/x-icon</code></a>.</li>\n\t<li>HTML Manifest files now use <code>.appcache</code> extension instead of <code>.manifest</code>, as per <a href=\"http://html5.org/r/5812\">http://html5.org/r/5812</a>.</li>\n\t<li>Force deflate for accept-encoding headers mangled by turtle tappers, courtesy of <a href=\"http://developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping/\">Yahoo!'s research</a></li>\n\t<li>We nerfed some of the directives in case you're on a server without <code>mod_headers</code>. (Which is totally crazy, man!)</li>\n\t<li>Block access to <code>.git</code> and <code>.svn</code> folders.</li>\n\t<li>Eradicating Chrome's console warning on WOFF font downloads.</li>\n\t<li>More optimizations available if you set the <code>.htaccess</code> details up in your <code>httpd.conf</code></li>\n\t<li><code>.htaccess</code> now caches <code>.htc</code> files</li>\n  \n\t<li>Moved all server configurations (except Apache's <code>.htaccess</code>) over to <a href =\"https://github.com/paulirish/html5-boilerplate-server-configs\">the new html5-boilerplate-server-configs repo</a>. Head over there if you're not using Apache. </li>\n\t\n\t<li>Updated <code>.htaccess</code> and <code>mime.types</code> for <code>ogg</code> formats.</li>\n\t<li>Fixed regression where EOT fonts had been excluded from DEFLATE compression</li>\n\t<li>Apache version independence: Use <code>mod_filter</code> for compression, with fallback to AddOutputFilterByType directive for legacy versions</li>\n\t<li>Added plugin/extension mime types for Safari, Chrome, Firefox</li>\n</ul>\n#### nginx\n<ul>\n\t<li>Cleaned up cache expires directives.</li>\n\t<li>Now includes SVG and font formats for gzipping.</li>\n\t<li>expires header bug fixed.</li>\n</ul>\n#### IIS\n<ul>\n\t<li>Added Flash video mime types to IIS server</li>\n\t<li>Fixed some mimetype weirdness that was preventing proper caching</li>\n</ul>\n\n<ul>\n\t<li>Also Google App Engine, Lighttpd, and NodeJS <a href=\"https://github.com/paulirish/html5-boilerplate-server-configs\">configurations were added</a></li>\n</ul>\n\n<p>Basically a lot of great updates were made for 1.0. <a href=\"https://github.com/paulirish/html5-boilerplate/compare/v0.9.5...v1.0\">Here are all 220 commits since last release.</a>. You may ask though, <a href=\"http://html5boilerplate.com/docs/#FAQs★do-i-need-to-upgrade-my-sites-to-a-new-version\">do I need to upgrade existing sites</a>? Short answer: nah, you're good.</p>\n\n#### Contributors\n[Mickael Daniel](http://blog.mklog.fr/), Dave Kirk, [Jonathan Verrecchia](http://www.html5-css3.fr/), [nlogax](https://github.com/nlogax), [Rob Larsen](http://htmlcssjavascript.com/), \n[David Murdoch](http://www.vervestudios.co/), [AD7six](http://www.ad7six.com/), \n[Mathias Bynens](http://mathiasbynens.be/), [Michael van Laar](http://www.michael-van-laar.de/), [Mike West](http://mikewest.org/), [Mikko Tikkanen](http://www.mintusability.com/), [Velir](http://velir.com/), [Stephen Gariepy](http://garowetz.ca/)\n\n##### Boilerplate \n[Adam J. McIntyre](http://www.amodernfable.com/), [Adeel Ejaz](http://adeelejaz.com/), akolesnikov, [Alex Dunae](http://dialect.ca/), [Andrew Le](http://andrewdle.com/), [ashnur](https://github.com/ashnur), [Ben Truyman](http://bentruyman.com/), [Bruno Aguirre](http://brunoaguirre.com/), [Chris Hager](http://metachris.org/), [Corey Ward](http://blog.coreyward.net/), [Craig Barnes](https://github.com/craigbarnes), crappish, [Daniel Schildt](http://autiomaa.org/), [Dave DeSandro](https://github.com/daveatnclud), [Dustin Whittle](http://dustinwhittle.com/), grigio, [Irakli Nadareishvili](http://freshblurbs.com/), [Jaime Bueza](http://jaime.bueza.com/), [Jake Ingman](https://github.com/jingman), [James A. Rosen](http://jamesarosen.com/), [Jeremy Balch](https://github.com/balchjd), [joe bartlett](http://twitter.com/jdbartlett), [Joe Sak](http://www.joesak.com/), [John Bacon](https://github.com/johnbacon)\n[Jonathan Fielding](https://github.com/jonathan-fielding), [Jonathan Neal](http://iecss.com/), [kblomqvist](https://github.com/kblomqvist), [Kenneth Nordahl](http://nordahl.me/), [Maarten Verbaarschot](https://github.com/mverbaar), [Manuel Strehl](http://www.manuel-strehl.de/), [Marcel Turi](http://marcel.turi.co/), [Martin Hintzmann](https://github.com/Hintzmann), [mikealmond](https://github.com/mikealmond)\n[mikkotikkanen](http://www.mintusability.com/), [Nic Pottier](https://github.com/nicpottier), [Paul Neave](http://www.neave.com/), [Peter Beverloo](http://peter.sh/), [Rick Waldron](http://weblog.bocoup.com/), [Rob Flaherty](http://www.ravelrumba.com/), [S Anand](http://www.s-anand.net/), [Sam Sherlock](http://samsherlock.com/), [Michael Cetrulo](http://www.linkedin.com/in/web2samus), [simshaun](https://github.com/simshaun), [Sirupsen](http://sirupsen.com/), [Stephen Gariepy](http://garowetz.ca/), [timemachine3030 ](https://github.com/timemachine3030), [Vinay](http://www.artminister.com/), [Weston Ruter](http://weston.ruter.net/), [WraithKenny](http://unfocus.com/), [Yann Mainier](http://yann.mainier.com/), [Michael van Laar](http://www.michael-van-laar.de/), [Massimo Lombardo](http://unwiredbrain.com/), [Ivan Nikolić ](http://twitter.com/niksy), [Kaelig](http://kaelig.fr/), [Richard Bradshaw](http://bradshawenterprises.com/), [SammyK](http://sammyk.me/), [alrra](https://github.com/alrra), [Rizky Syazuli](http://id.linkedin.com/in/rizky), [iszak](https://github.com/Iszak), [aaron peters](https://github.com/aaronpeters), [Swaroop C H](http://www.swaroopch.com/), [Mike Połtyn](http://mike.poltyn.com/), Marco d'Itri, Mike Lamb , [BIG Folio](http://bigfolio.com/), Philip von Bargen, Meander, Daniel Harttman, rse, timwillison, ken nordahl, [Erik Dahlström](http://my.opera.com/macdev_ed), christopherjacob, [Chew Choon Keat](http://blog.choonkeat.com/), benalman, stoyan, Markus, [Vladimir Carrer](http://www.vcarrer.com/), [aristidesfl](https://github.com/aristidesfl), [Trevor Norris](http://blog.trevorjnorris.com/) [Miloš Gavrilović](http://www.arvag.net/)\n\n\n\n#####Configs\n[Dusan Hlavaty](http://sk.linkedin.com/in/dusanhlavaty), [Sean Caetano Martin](http://www.xonecas.com/), [yaph](http://www.ramiro.org/), [michaud](https://github.com/michaud), Paul Sarena, [Graham Weldon](http://grahamweldon.com/), [Ron. Adams](http://visual-assault.org/)\n\n#####Translators\n[alrra](http://twitter.com/alrra), [Anton Kovalyov](http://self.kovalyov.net/), [Milos Gavrilovic](http://www.arvag.net/), [jorge-vitrubio](https://github.com/jorge-vitrubio), Julian Wachholz, [laviperchik](https://github.com/laviperchik), [lenzcom](https://github.com/lenzcom), [Mathias Bynens](http://mathiasbynens.be/), [Mickael Daniel](http://blog.mklog.fr/), [Mike West](http://mikewest.org/), [Niels Bom](http://www.nielsbom.com/), Ricardo Tomasi, [skill83 ](https://github.com/skill83), [Sean Caetano Martin](http://www.xonecas.com/), [Yuya Saito](http://css.studiomohawk.com/), [Zee-Julien](https://github.com/Zee-Julien)\n\n\n### v.0.9.5 : October 25th, 2010\n\nMajor changes:\n\n<ul>\n<li>Removed <code>-webkit-font-smoothing: antialiased;</code> it makes monospace too thin.</li>\n<li>IE conditional classes have moved from the <code>&lt;body&gt;</code> tag to the <code>&lt;html&gt;</code> tag ( #44 ).</li>\n<li>Dropped <code>text-rendering: <a href=\"http://www.aestheticallyloyal.com/public/optimize-legibility/\">optimizeLegibility</a></code> as it breaks small-caps, looks odd on Linux machines, and goes invisible on WebOS.</li> \n<li>Added a IE6 call for the minified <code>dd_belatedpng</code>.</li>\n<li>Revised viewport declaration to allow user scaling and clear Webkit console errors ( #37 ).</li>\n<li>Updated Modernizr to 1.6 </li>\n<li>Added <code>web.config</code> file for Microsoft IIS</li>\n<li>Beta release of the <a href=\"http://github.com/paulirish/html5-boilerplate/wiki/Build-script\">Build Script</a> (this is HUGE)</li>\n<li>New project scaffolding <a href=\"http://github.com/paulirish/html5-boilerplate/wiki/makep.sh\">bash script</a>.</li>\n</ul>\n\n#### General\n* Updated Modernizr to 1.6 (smaller and faster)\n* Added web.config file for Microsoft IIS. Now forcing latest IE version and ChromeFrame, if installed.\n* Added <code>favicon</code> and <code>default icon</code> for iOS.\n* Updated <code>crossdomain.xml</code> wording for better security guidelines ( #124 ).\n* Expires value for <code>nginx.conf</code> corrected.\n* License clarified.\n\n#### style.css\n* Removed <code>-webkit-font-smoothing: antialiased</code> as it made monospace too thin.\n* Updated fonts normalization to YUI 3.2.0 PR1.\n* Table Header set explicitly for IE6, and table row now has <code>page-break: avoid</code> in print CSS.\n* <code>text-shadow:none !important</code> set for all text in print CSS.\n* Removed scrollbar from <code>&lt;textarea></code>s in IE.\n* Fixed <code>&lt;textarea></code> stylings and form field treatment for validity. Added default <code>background-color</code>.\n* New robust clearfix solution without IE 5.5 hack ( #45 #126 ).\n* Margins for form-elements explicitly set to <code>0</code> as webkit adds 2px space around form elements' chrome. \n* Dropped <code>text-rendering: optimizeLegibility</code> as it breaks <code>small-caps</code> and looks odd on Linux machines. \n* Lists now have a left margin of <code>1.8em</code>. Default <code>list-style-type</code> for ordered list is <code>decimal</code>.\n* Image Replacement now works with right-to-left text ( #68 ).\n* Removed \"Star Hack\" for checkboxes in favor of <code>.ie7</code> selector.\n\n#### index.html\n* IE conditional classes have moved from the <code>&lt;body></code> tag to the <code>&lt;html></code> tag ( #44 ).\n* Added a IE6 call for the minified <code>dd_belatedpng</code>.\n* Google Analytics script will now work with SSL in IE6.\n* Added protocol independent absolute path for cdn jquery, with improved fallback-to-local code to protect against edge case IE bug.\n* Commented out handheld CSS ( #73 ).\n* Mobile viewport and textsize styles adjusted per group feedback ( #37 ).\n\n#### .htaccess\n* More files are served via gzip like <code>.htc</code> ( #55 ).\n* Added Expires header for content types image/gif and video/webm.\n* Fixed favicon display in IE6 ( #113 ).\n* Corrected mimetypes for fonts.\n* Removed caching for files of type json/xml.\n* Better use of <code>ifmodule</code> for more stability in different Apache environments.\n\n[View full diff and commit history](http://github.com/paulirish/html5-boilerplate/compare/v0.9.1...v0.9.5)\n\n\n#### Contributors\nShi Chuan, Rob Larsen, Ivan Nikolić, Mikko Tikkanen, Velir, Paul Neave, Weston Ruter, Jeffrey Barke, Robert Meissner, SirFunk, Philip von Bargen, Kroc Camen, Rick Waldron, Andreas Madsen, Marco d'Itri, Adeelejaz, James Rosen, Dave DeSandro, Ken Newman, Daniel Lenz, Swaroop C H, Yann Mainier, Joe Sak, Irakli, Rob Flaherty, Jeff Starr, Mike Lamb, Holek, Aaron Peters, Kaelig, Meander, Charlie Ussery, Ciney, Région Wallonne, Sirupsen, and Paul Hayes.\n\n\n\n### v.0.9.1 : August 13th, 2010\n* HTML5 Boilerplate is now in the Public Domain\n* Nginx configuration added\n* Font stacks (sans-serif and monospace) simplified\n* Very accessible <code>a:focus</code> styles.\n* Corrected IE=edge,chromeframe enabling (As a result, the base HTML [does not validate](http://bit.ly/cGSSgr))\n* ServerSideIncludes disabled by default.\n* Apache config bugfixes\n* Conditional body tag class combined \n* dd_belatedPNG updated to 0.0.8. Redundant BackgroundImageCache fix removed.\n\n[View full diff and commit history](http://github.com/paulirish/html5-boilerplate/compare/v0.9...v0.9.1)\n\n##### Thanks:\n\nvoodootikigod, garowetz, fearphage, christopherjacob, mathias bynens, daniel harttman, rse, chris dary, erik dahlstrom, timwillison, kenneth nordahl, riddle, elcuervo, andreas kuckartz, 3rdEden, riley willis, majic3\n\n### v0.9 : August 10th, 2010 - Initial release\n\n\n## License:\n\nMajor components:\n\n* Modernizr: MIT/BSD license\n* jQuery: MIT/GPL license\n* DD_belatedPNG: MIT license\n* YUI Profiling: BSD license\n* HTML5Doctor CSS reset: Public Domain\n* CSS Reset Reloaded: Public Domain\n\nEverything else:\n\n* [The Unlicense](http://unlicense.org) (aka: public domain) \n\n\n## Summary:\n\nThis is a set of files that a front-end developer can use to get started on a website, with following included:\n\n1. Cross-browser compatible (IE6? Yeah, we got that.)\n2. HTML5 ready. Use the new tags with certainty.\n3. Optimal caching and compression rules for Grade-A performance\n4. Best practice site configuration defaults\n5. Think there's too much? The HTML5 Boilerplate is delete-key friendly. :)\n6. Mobile browser optimizations\n7. Progressive enhancement graceful degredation ........ yeah yeah we got that\n8. IE-specific classes for maximum cross-browser control\n9. Want to write unit tests but lazy? A full, hooked up test suite is waiting for you.\n10. Javascript profiling…in IE6 and IE7? Sure, no problem.\n11. Console.log nerfing so you won't break anyone by mistake.\n12. Never go wrong with your doctype or markup!\n13. An optimal print stylesheet, performance optimized\n14. iOS, Android, Opera Mobile-adaptable markup and CSS skeleton.\n15. IE6 pngfix baked in.\n16. jQuery, waiting for you\n\n## Releases \n\nThere are two releases: a documented release (which is exactly what you see here), and a \"stripped\" release (with most of the descriptive comments stripped out).\n\nWatch the [current tickets](http://github.com/paulirish/html5-boilerplate/issues) to view the areas of active development.\n\n"
  },
  {
    "path": "app/static_dev/build/build.xml",
    "content": "﻿<?xml version=\"1.0\"?>\n<!DOCTYPE project>\n<project name=\"Boilerplate Build\" default=\"build\" basedir=\"../\"> <!-- one back since we're in build/ -->\n\n\n    <!-- Load in Ant-Contrib to give us access to some very useful tasks! -->\n    <!-- the .jar file is located in the tools directory -->\n    <taskdef resource=\"net/sf/antcontrib/antlib.xml\">\n        <classpath>\n            <pathelement location=\"${basedir}/build/tools/ant-contrib-1.0b3.jar\"/>\n        </classpath>\n    </taskdef>\n    \n    <!-- load shell environment -->\n    <property environment=\"ENV\" />\n\n    <!-- load property files -->\n    <property file=\"build/config/project.properties\"/>\n    <property file=\"build/config/default.properties\"/>\n\n    <!-- merge the stylesheet properties -->\n    <var name=\"stylesheet-files\" value=\"${file.default.stylesheets}, ${file.stylesheets}\"/>\n\n    <!-- merge the pages properties -->\n    <var name=\"page-files\" value=\"${file.pages}, ${file.pages.default.include}\"/>\n\n    <!-- Test for Ant Version Delete this task and all instances of overwrite='no' if you can't upgrade to 1.8.2-->\n    <fail message=\"All features of the build script require Ant version 1.8.2. Please upgrade to 1.8.2 or remove all instances of 'overwrite=no' (and this fail task) from the build script to continue\">\n        <condition>\n            <not>\n                <contains string=\"${ant.version}\" substring=\"1.8.2\"/>\n            </not>\n        </condition>\n    </fail>\n\n    <!--\n    *************************************************\n    * BASE TARGETS                                  *\n    *************************************************\n    -->\n    <target name=\"basics\">\n    <if>\n        <equals arg1=\"${env}\" arg2=\"dev\"/>\n        <then>\n            <!-- Build a dev environment -->\n            <echo message=\"Building a Development Environment...\"/>\n            <antcall target=\"-basics.dev\"/>\n        </then>\n\n        <elseif>\n            <equals arg1=\"${env}\" arg2=\"test\"/>\n            <then>\n                <!-- Build a test environment -->\n                <echo message=\"Building a Test Environment...\"/>\n                <antcall target=\"-basics.test\"/>\n            </then>\n        </elseif>\n\n        <else>\n            <!-- Build a production environment -->\n            <echo message=\"Building a Production Environment...\"/>\n            <antcall target=\"-basics.production\"/>\n        </else>\n    </if>\n    </target>\n\n\n    <target name=\"text\">\n    <if>\n        <equals arg1=\"${env}\" arg2=\"dev\"/>\n        <then>\n            <!-- Build a dev environment -->\n            <echo message=\"Building a Development Environment...\"/>\n            <antcall target=\"-text.dev\"/>\n        </then>\n\n        <elseif>\n            <equals arg1=\"${env}\" arg2=\"test\"/>\n            <then>\n                <!-- Build a test environment -->\n                <echo message=\"Building a Test Environment...\"/>\n                <antcall target=\"-text.test\"/>\n            </then>\n        </elseif>\n\n        <else>\n            <!-- Build a production environment -->\n            <echo message=\"Building a Production Environment...\"/>\n            <antcall target=\"-text.production\"/>\n        </else>\n    </if>\n    <antcall target=\"-imgcopy\"/>\n    </target>\n\n\n    <target name=\"buildkit\">\n    <if>\n        <equals arg1=\"${env}\" arg2=\"dev\"/>\n        <then>\n            <!-- Build a dev environment -->\n            <echo message=\"Building a Development Environment...\"/>\n            <antcall target=\"-buildkit.dev\"/>\n        </then>\n\n        <elseif>\n            <equals arg1=\"${env}\" arg2=\"test\"/>\n            <then>\n                <!-- Build a test environment -->\n                <echo message=\"Building a Test Environment...\"/>\n                <antcall target=\"-buildkit.test\"/>\n            </then>\n        </elseif>\n\n        <else>\n            <!-- Build a production environment -->\n            <echo message=\"Building a Production Environment...\"/>\n            <antcall target=\"-buildkit.production\"/>\n        </else>\n    </if>\n    </target>\n\n\n    <target name=\"build\">\n    <if>\n        <equals arg1=\"${env}\" arg2=\"dev\"/>\n        <then>\n            <!-- Build a dev environment -->\n            <echo message=\"Building a Development Environment...\"/>\n            <antcall target=\"-build.dev\" />\n        </then>\n\n        <elseif>\n            <equals arg1=\"${env}\" arg2=\"test\"/>\n            <then>\n                <!-- Build a test environment -->\n                <echo message=\"Building a Test Environment...\"/>\n                <antcall target=\"-build.test\" />\n            </then>\n        </elseif>\n\n        <else>\n            <!-- Build a production environment -->\n            <echo message=\"Building a Production Environment...\"/>\n            <antcall target=\"-build.production\" />\n        </else>\n    </if>\n    </target>\n\n\n    <target name=\"minify\">\n    <if>\n        <equals arg1=\"${env}\" arg2=\"dev\"/>\n        <then>\n            <!-- Build a dev environment -->\n            <echo message=\"Building a Development Environment...\"/>\n            <antcall target=\"-minify.dev\"/>\n        </then>\n\n        <elseif>\n            <equals arg1=\"${env}\" arg2=\"test\"/>\n            <then>\n                <!-- Build a test environment -->\n                <echo message=\"Building a Test Environment...\"/>\n                <antcall target=\"-minify.test\"/>\n            </then>\n        </elseif>\n\n        <else>\n            <!-- Build a production environment -->\n            <echo message=\"Building a Production Environment...\"/>\n            <antcall target=\"-minify.production\"/>\n        </else>\n    </if>\n    </target>\n\n    <target name=\"clean\" depends=\"-clean\"/>\n    \n    \n    \n    <!-- JSLint target, run separately -->\n    <target name=\"jslint\">\n      <apply dir=\"${dir.source}/${dir.js}\" executable=\"java\" parallel=\"false\" failonerror=\"true\">\n            <fileset dir=\"./${dir.source}/\">\n        <include name=\"**/${dir.js}/*.js\"/>\n        <exclude name=\"**/*.min.js\"/>\n        <exclude name=\"**/${dir.js.libs}/\"/>\n        <exclude name=\"**/${dir.publish}/\"/>\n          </fileset> \n            <arg value=\"-jar\" />\n            <arg path=\"./${dir.build.tools}/${tool.rhino}\" />\n            <arg path=\"./${dir.build.tools}/${tool.jslint}\" />\n            <srcfile/>\n            <arg value=\"${tool.jslint.opts}\" />\n        </apply>        \n        <echo>JSLint Successful</echo>\n    </target>     \n  \n  \n    <!-- JSHint target, run separately -->\n    <target name=\"jshint\">\n      <apply dir=\"${dir.source}/${dir.js}\" executable=\"java\" parallel=\"false\" failonerror=\"true\">\n            <fileset dir=\"./${dir.source}/\">\n        <include name=\"**/${dir.js}/*.js\"/>\n        <exclude name=\"**/*.min.js\"/>\n        <exclude name=\"**/${dir.js.libs}/\"/>\n        <exclude name=\"**/${dir.publish}/\"/>\n          </fileset> \n            <arg value=\"-jar\" />\n            <arg path=\"./${dir.build.tools}/${tool.rhino}\" />\n            <arg path=\"./${dir.build.tools}/${tool.jshint}\" />\n            <srcfile/>\n            <arg value=\"${tool.jshint.opts}\" />\n        </apply>        \n        <echo>JSHint Successful</echo>\n    </target>    \n       \n    <!-- CSSLint target, run separately -->\n    <target name=\"csslint\">\n        <apply dir=\"${dir.source}/${dir.css}\" executable=\"java\" parallel=\"false\" failonerror=\"true\">\n            <fileset dir=\"./${dir.source}/\">\n                <include name=\"**/${dir.css}/*.css\"/>\n                <exclude name=\"**/*.min.css\"/>\n                <exclude name=\"**/${dir.publish}/\"/>\n            </fileset> \n            <arg value=\"-jar\" />\n            <arg path=\"./${dir.build.tools}/${tool.rhino}\" />\n            <arg path=\"./${dir.build.tools}/${tool.csslint}\" />\n            <srcfile/>\n            <arg value=\"${tool.csslint.opts}\" />\n        </apply>\n        <echo>CSSLint Successful</echo>\n    </target>\n    \n    <!--\n    *************************************************\n    * BUILD TARGETS                                 *\n    *************************************************\n    -->\n\n    <!-- Target: basics -->\n    <target name=\"-basics.dev\"\n            depends=\"-rev,\n                     -copy\"/>\n\n    <target name=\"-basics.test\"\n            depends=\"-rev,\n                     -usemin,\n                     -js.all.minify,\n                     -js.main.concat,\n                     -js.mylibs.concat,\n                     -js.scripts.concat,\n                     -css,\n                     -manifest,\n                     -copy\"/>\n\n    <target name=\"-basics.production\"\n            depends=\"-rev,\n                     -usemin,\n                     -js.all.minify,\n                     -js.main.concat,\n                     -js.mylibs.concat,\n                     -js.scripts.concat,\n                     -css,\n                     -manifest,\n                     -copy\"/>\n\n    <!-- Target: text -->\n    <target name=\"-text.dev\"\n            depends=\"-rev,\n                     -copy\"/>\n\n    <target name=\"-text.test\"\n            depends=\"-rev,\n                     -usemin,\n                     -js.all.minify,\n                     -js.main.concat,\n                     -js.mylibs.concat,\n                     -js.scripts.concat,\n                     -css,\n                     -manifest,\n                     -htmlclean,\n                     -copy\"/>\n\n    <target name=\"-text.production\"\n            depends=\"-rev,\n                     -usemin,\n                     -js.all.minify,\n                     -js.main.concat,\n                     -js.mylibs.concat,\n                     -js.scripts.concat,\n                     -css,\n                     -manifest,\n                     -htmlclean,\n                     -copy\"/>\n\n    <!-- Target: buildkit -->\n    <target name=\"-buildkit.dev\"\n            depends=\"-rev,\n                     -imagespng,\n                     -imagesjpg,\n                     -copy\"/>\n\n    <target name=\"-buildkit.test\"\n            depends=\"-rev,\n                     -usemin,\n                     -js.all.minify,\n                     -js.main.concat,\n                     -js.mylibs.concat,\n                     -js.scripts.concat,\n                     -css,\n                     -manifest,\n                     -htmlbuildkit,\n                     -imagespng,\n                     -imagesjpg,\n                     -copy\"/>\n\n    <target name=\"-buildkit.production\"\n            depends=\"-rev,\n                     -usemin,\n                     -js.all.minify,\n                     -js.main.concat,\n                     -js.mylibs.concat,\n                     -js.scripts.concat,\n                     -css,\n                     -manifest,\n                     -htmlbuildkit,\n                     -imagespng,\n                     -imagesjpg,\n                     -copy\"/>\n\n    <!-- Target: build -->\n    <target name=\"-build.dev\"\n            depends=\"-rev,\n                     -imagespng,\n                     -imagesjpg,\n                     -copy\"/>\n\n    <target name=\"-build.test\"\n            depends=\"-rev,\n                     -usemin,\n                     -js.all.minify,\n                     -js.main.concat,\n                     -js.mylibs.concat,\n                     -js.scripts.concat,\n                     -css,\n                     -manifest,\n                     -htmlclean,\n                     -imagespng,\n                     -imagesjpg,\n                     -copy\"/>\n\n    <target name=\"-build.production\"\n            depends=\"-rev,\n                     -usemin,\n                     -js.all.minify,\n                     -js.main.concat,\n                     -js.mylibs.concat,\n                     -js.scripts.concat,\n                     -css,\n                     -manifest,\n                     -htmlclean,\n                     -imagespng,\n                     -imagesjpg,\n                     -copy\"/>\n\n    <!-- Target: minify -->\n    <target name=\"-minify.dev\"\n            depends=\"-rev,\n                     -imagespng,\n                     -imagesjpg,\n                     -copy\"/>\n\n    <target name=\"-minify.test\"\n            depends=\"-rev,\n                     -usemin,\n                     -js.all.minify,\n                     -js.main.concat,\n                     -js.mylibs.concat,\n                     -js.scripts.concat,\n                     -css,\n                     -manifest,\n                     -htmlcompress,\n                     -imagespng,\n                     -imagesjpg,\n                     -copy\"/>\n\n    <target name=\"-minify.production\"\n            depends=\"-rev,\n                     -usemin,\n                     -js.all.minify,\n                     -js.main.concat,\n                     -js.mylibs.concat,\n                     -js.scripts.concat,\n                     -css,\n                     -manifest,\n                     -htmlcompress,\n                     -imagespng,\n                     -imagesjpg,\n                     -copy\"/>\n\n    <!--\n    *************************************************\n    * FUNCTION TARGETS                              *\n    *************************************************\n    -->\n        \n    <target name=\"-clean\" description=\"(PRIVATE) Wipe the previous build (Deletes the dir.publish directory\">\n    <!-- This is a private target -->        \n        <echo message=\"Cleaning up previous build directory...\"/>\n        <delete dir=\"./${dir.intermediate}/\"/>\n        <delete dir=\"./${dir.publish}/\"/>\n    </target>\n    \n    \n    <target name=\"-rev\" description=\"(PRIVATE) Increase the current build number by one and set build date\">\n    <!-- This is a private target -->\n    \n        <echo message=\"=====================================================================\"/>\n        <echo message=\"Welcome to the HTML5 Boilerplate Build Script!\"/>\n        <echo message=\" \"/>\n        <echo message=\"We're going to get your site all ship-shape and ready for prime time.\"/>\n        <echo message=\" \"/>\n        <echo message=\"This should take somewhere between 15 seconds and a few minutes,\"/>\n        <echo message=\"mostly depending on how many images we're going to compress.\"/>\n        <echo message=\" \"/>\n        <echo message=\"Feel free to come back or stay here and follow along.\"/>\n        <echo message=\"=====================================================================\"/>\n        <echo message=\" \"/>\n        <echo message=\" \"/>\n    \n    </target>\n    \n    <target name=\"-mkdirs\">\n      <if>\n          <or>\n            <equals arg1=\"${dir.publish}\" arg2=\".\"/>            \n            <equals arg1=\"${dir.publish}\" arg2=\"..\"/>                      \n            <equals arg1=\"${dir.publish}\" arg2=\"/\"/>                      \n            <equals arg1=\"${dir.publish}\" arg2=\"./\"/>                      \n            <equals arg1=\"${dir.publish}\" arg2=\"../\"/>                      \n          </or>\n          <then>\n            <fail message=\"Your dir.publish folder is set to ${dir.publish} which could delete your entire site or worse. Change it in project.properties\"/>      \n          </then>\n          <else>\n            <echo message=\"Creating directory structure... ${dir.publish}\"/>\n\n            <mkdir dir=\"${dir.intermediate}\"/>\n            <copy todir=\"${dir.intermediate}\" includeEmptyDirs=\"true\">\n                <fileset dir=\"${dir.source}/\" excludes=\"${file.default.exclude}, ${file.exclude}\">\n                    <type type=\"dir\"/>\n                </fileset>\n            </copy>\n              <mkdir dir=\"${dir.publish}\"/>\n              <copy todir=\"${dir.publish}\" includeEmptyDirs=\"true\">\n                  <fileset dir=\"${dir.source}/\" excludes=\"${file.default.exclude}, ${file.exclude}\">\n                      <type type=\"dir\"/>\n                  </fileset>\n              </copy>                      \n          </else>\n      </if>                  \n    </target>\n    \n    <target name=\"-copy\" depends=\"-mkdirs\">\n    <!-- This is a private target -->\n    \n        <echo message=\"Copying over new files...\"/>\n\n        <copy todir=\"./${dir.publish}\">\n            <fileset dir=\"${dir.source}/\" excludes=\"${file.default.exclude}, ${file.exclude}\">\n                <!-- exclude files that are superseded by optimized versions with different names -->\n                <!-- this is not strictly necessary, but it avoids putting unreferenced files into your server -->\n                <exclude name=\"${dir.js}/**/*.js\"/>\n                <exclude name=\"${dir.css}/**/*.css\"/>\n                <exclude name=\"${file.manifest}\"/>\n            </fileset>\n        </copy>\n        \n        <echo message=\"A copy of all non-dev files are now in: ./${dir.publish}.\"/>\n    </target>\n    \n    <!-- JAVASCRIPT -->\n    <target name=\"-js.main.concat\" depends=\"-js.all.minify\" description=\"(PRIVATE) Concatenates the JS files in dir.js\">\n        <echo message=\"Concatenating Main JS scripts...\"/>\n        <!-- overwrite=no here means not to overwrite if the target is newer than the sources -->\n        <concat destfile=\"./${dir.intermediate}/${dir.js}/scripts-concat.js\" overwrite=\"no\">\n            <fileset dir=\"./${dir.intermediate}/\">\n                <include name=\"${dir.js.main}/plugins.js\"/>\n                <include name=\"${dir.js.main}/script.js\"/>\n            </fileset>      \n        </concat>\n    </target>\n    \n    <target name=\"-js.mylibs.concat\" depends=\"-js.all.minify\" description=\"(PRIVATE) Concatenates the JS files in dir.js.mylibs\">\n        <mkdir dir=\"./${dir.intermediate}/${dir.js.mylibs}\"/>\n\n        <echo message=\"Concatenating JS libraries\"/>\n        <!-- overwrite=no here means not to overwrite if the target is newer than the sources -->\n        <concat destfile=\"./${dir.intermediate}/${dir.js}/mylibs-concat.js\" overwrite=\"no\">\n            <fileset dir=\"./${dir.intermediate}/${dir.js.mylibs}/\"\n                includes=\"**/*.js\" \n                excludes=\"${file.js.bypass}\"/>                \n                  \n        </concat>\n    </target>\n    \n    \n    <target name=\"-js.scripts.concat\" depends=\"-js.main.concat,-js.mylibs.concat\" if=\"build.concat.scripts\">\n        <echo message=\"Concatenating library file with main script file\"/>\n        <!-- overwrite=no here means not to overwrite if the target is newer than the sources -->\n        <concat destfile=\"./${dir.intermediate}/${dir.js}/scripts-concat.min.js\" overwrite=\"no\">\n            <fileset dir=\"./${dir.intermediate}/${dir.js}/\">\n                <include name=\"mylibs-concat.js\"/>\n                <include name=\"scripts-concat.js\"/>\n            </fileset>      \n        </concat>\n\n        <checksum file=\"${dir.intermediate}/${dir.js}/scripts-concat.min.js\" algorithm=\"sha\" property=\"scripts.sha\" />\n        <if>\n            <isset property=\"gae.js_dir\" />\n            <then>\n                <property name=\"scripts.js\" value=\"${gae.js_dir}/${scripts.sha}.js\" />\n            </then>\n            <else>\n                <property name=\"scripts.js\" value=\"${dir.js}/${scripts.sha}.js\" />\n            </else>\n        </if>\n        <copy file=\"${dir.intermediate}/${dir.js}/scripts-concat.min.js\" tofile=\"${dir.publish}/${dir.js}/${scripts.sha}.js\" />\n    </target>\n    \n    \n    <target name=\"-js.all.minify\" depends=\"-mkdirs\" description=\"(PRIVATE) Minifies the scripts.js files created by js.scripts.concat\">\n        <echo message=\"Minifying scripts\"/>\n        <copy todir=\"${dir.intermediate}/\">\n            <fileset dir=\"${dir.source}/\" includes=\"${dir.js}/**/*.min.js\"  />\n        </copy>\n        <apply executable=\"java\" parallel=\"false\">\n            <fileset dir=\"${dir.source}/\" >\n                <include name=\"${dir.js}/**/*.js\"/>\n                <exclude name=\"${dir.js}/**/*.min.js\"/>\n            </fileset>\n            <arg line=\"-jar\"/>\n            <arg path=\"./${dir.build.tools}/${tool.yuicompressor}\"/>\n            <srcfile/>\n            <arg line=\"--line-break\"/>\n            <arg line=\"4000\"/>\n            <arg line=\"-o\"/>\n            <mapper type=\"glob\" from=\"*.js\" to=\"${basedir}/${dir.intermediate}/*.js\"/>\n            <targetfile/>\n        </apply>\n\n        <!-- at this point all js files are minified with their original names -->\n\n        <copy todir=\"${dir.publish}/\">\n          <fileset dir=\"${dir.intermediate}/\">\n              <include name=\"${dir.js}/**/*.js\"/>\n              <exclude name=\"${dir.js.mylibs}/**/*.js\"/>\n              <exclude name=\"${dir.js}/scripts-concat.js\"/>\n              <exclude name=\"${dir.js}/mylibs-concat.js\"/>\n              <exclude name=\"${dir.js}/scripts-concat.min.js\"/>\n              <exclude name=\"${dir.js}/plugins.js\"/>\n              <exclude name=\"${dir.js}/script.js\"/>\n          </fileset>                                   \n        </copy>\n        <copy todir=\"${dir.publish}/${dir.js.mylibs}/\">\n            <fileset dir=\"${dir.source}/${dir.js.mylibs}/\"\n            includes=\"${file.js.bypass}\"/>           \n        </copy>\n    </target>\n    \n    \n    <!-- HTML -->\n    <target name=\"-usemin\" depends=\"-js.scripts.concat,-css\" description=\"(PRIVATE) Replaces references to non-minified scripts\">\n        <echo message=\"Switching to minified js files...\"/>\n\n        <!-- Changes to style.css or scripts.js mean that the html must be updated, and it will be.\n             Unfortunately, the html we want to update may not have the tags we want to replace(because it was updated before).\n             This outofdate check ensures that the html files have the markers for us to replace. -->\n        <outofdate property=\"needhtmlrefresh\">\n            <sourcefiles>\n                <fileset dir=\"${dir.publish}\" includes=\"${style.css}, ${scripts.js}\"/>\n            </sourcefiles>\n            <targetfiles>\n                <fileset dir=\"${dir.intermediate}\" includes=\"${page-files}\"/>\n            </targetfiles>\n        </outofdate>\n\n        <!-- force the files to be overwritten with older copies from source if needhtmlrefresh is set -->\n        <copy todir=\"${dir.intermediate}\" overwrite=\"${needhtmlrefresh}\">\n            <fileset dir=\"${dir.source}\" includes=\"${page-files}\"/>\n        </copy>\n\n        <!-- switch from a regular jquery to minified -->\n        <replaceregexp match=\"jquery-(\\d|\\d(\\.\\d)+)\\.js\" replace=\"jquery-\\1.min.js\" flags=\"g\">\n            <fileset dir=\"./${dir.intermediate}\" includes=\"${page-files}\"/>\n        </replaceregexp>\n        <!-- switch any google CDN reference to minified -->\n        <replaceregexp match=\"(\\d|\\d(\\.\\d)+)\\/jquery\\.js\" replace=\"\\1/jquery.min.js\" flags=\"g\">\n            <fileset dir=\"./${dir.intermediate}\" includes=\"${page-files}\"/>\n        </replaceregexp>    \n\n        <echo>Kill off those versioning flags: ?v=2</echo>\n        <replaceregexp match='\\?v=\\d+\">' replace='\">' flags=\"g\">\n            <fileset dir=\"./${dir.intermediate}\" includes=\"${page-files}\"/>\n        </replaceregexp>\n        \n        <echo>Remove favicon.ico reference if it is pointing to the root</echo>\n        <replaceregexp match=\"&lt;link rel=[&quot;']shortcut icon[&quot;'] href=[&quot;']/favicon\\.ico[&quot;']&gt;\" replace=\"\">\n            <fileset dir=\"${dir.intermediate}\" includes=\"${page-files}\"/>\n        </replaceregexp>\n        <!-- we maintain the apple-touch-icon reference for Android 2.2   www.ravelrumba.com/blog/android-apple-touch-icon\n        <replace token=\"&lt;link rel=&quot;apple-touch-icon&quot; href=&quot;/apple-touch-icon.png&quot;>\" value=\"\">\n            <fileset dir=\"${dir.intermediate}\" includes=\"${page-files}\"/>\n        </replace>\n        -->\n\n        <echo message=\"Update the HTML to reference our concatenated script file: ${scripts.js}\"/>\n        <!-- style.css replacement handled as a replacetoken above -->\n        <replaceregexp match=\"&lt;!-- scripts concatenated [\\d\\w\\s\\W]*?!-- end ((scripts)|(concatenated and minified scripts))--&gt;\" replace=\"&lt;script defer src='/${scripts.js}\\'&gt;&lt;/script&gt;\" flags=\"m\">\n            <fileset dir=\"${dir.intermediate}\" includes=\"${page-files}\"/>\n        </replaceregexp>\n        <!--[! use comments like this one to avoid having them get minified -->\n\n        <echo message=\"Updating the HTML with the new css filename: ${style.css}\"/>\n\n        <replaceregexp match=\"&lt;!-- CSS concatenated [\\d\\w\\s\\W]*?!-- end CSS--&gt;\" replace=\"&lt;link rel='stylesheet' href='/${style.css}'&gt;\" flags=\"m\">\n            <fileset dir=\"${dir.intermediate}\" includes=\"${page-files}\"/>\n        </replaceregexp>\n\n    </target>\n    \n    \n    <target name=\"-manifest\" depends=\"-usemin\">\n        <if>\n            <isset property=\"file.manifest\" />\n            <then>\n                <echo message=\"copying a fresh ${dir.build}/config/${file.manifest} to /${dir.intermediate}\"/>\n\n                <delete file=\"${dir.intermediate}/${file.manifest}\"/>\n                <copy file=\"${dir.build}/config/${file.manifest}\" tofile=\"${dir.intermediate}/${file.manifest}\" />\n                \n                <echo message=\"manifest creation\" />\n\n                <!-- update version -->\n                <echo message=\"Updating the site.manifest version date to today, current time\"/>\n                <tstamp>\n                    <format property=\"TODAY\" pattern=\"yyyy-MM-dd HH:mm:ss\"/>\n                </tstamp>\n                <replaceregexp match=\"# version .+\" replace=\"# version ${TODAY}\" file=\"${dir.intermediate}/${file.manifest}\"/>\n\n                <!-- add html files -->\n                <echo message=\"Updating the site.manifest with html files: ${page-files}\"/>\n                <for list=\"${page-files}\" param=\"file\" delimiter=\",\" trim=\"true\">\n                    <sequential>\n                        <replaceregexp match=\"# html files\" replace=\"# html files${line.separator}@{file}\" file=\"${dir.intermediate}/${file.manifest}\" />\n                    </sequential>\n                </for>\n                \n                <!-- add stylesheet files -->\n                <echo message=\"Updating the site.manifest with the new css filename: ${style.css}\"/>\n                <replace token=\"# css files\" value=\"# css files${line.separator}${style.css}\" file=\"${dir.intermediate}/${file.manifest}\" />\n\n                <!-- add javascript files -->\n                <echo message=\"Updating the site.manifest with the new js filename: ${scripts.js}\"/>\n                <for param=\"file\">\n                    <path>\n                        <fileset dir=\"./${dir.intermediate}/${dir.js.mylibs}/\"\n                            includes=\"${file.js.bypass}\" />\n                    </path>\n                    <sequential>\n                        <basename property=\"filename.@{file}\" file=\"@{file}\" />\n                        <replaceregexp match=\"# js files\" replace=\"# js files${line.separator}${dir.js.mylibs}/${filename.@{file}}\" file=\"${dir.intermediate}/${file.manifest}\" />\n                    </sequential>\n                </for>\n                <for param=\"file\">\n                    <path>\n                        <fileset dir=\"./${dir.intermediate}/${dir.js.libs}/\"\n                            includes=\"*.min.js\"/>\n                    </path>\n                    <sequential>\n                        <basename property=\"filename.@{file}\" file=\"@{file}\" />\n                        <replaceregexp match=\"# js files\" replace=\"# js files${line.separator}${dir.js.libs}/${filename.@{file}}\" file=\"${dir.intermediate}/${file.manifest}\" />\n                    </sequential>\n                </for>\n                <replace token=\"# js files\" value=\"# js files${line.separator}${scripts.js}\" file=\"${dir.intermediate}/${file.manifest}\" />\n                \n                <echo message=\"copying ${file.manifest} to /${dir.publish}\"/>\n                <copy file=\"${dir.intermediate}/${file.manifest}\" tofile=\"${dir.publish}/${file.manifest}\" />\n                \n                <echo>Add manifest attribute to HTML: </echo>\n                <replaceregexp match=\"&lt;html (.*?)>\\s*?&lt;!--&lt;!\\[endif\" replace='&lt;html \\1 manifest=\"${file.manifest}\"> &lt;!--&lt;![endif' flags=\"g\">\n                    <fileset dir=\"./${dir.intermediate}\" includes=\"${page-files}\"/>\n                </replaceregexp>\n                \n            </then>\n            <else>\n                <echo message=\"no manifest.appcache generated!\" />\n            </else>\n        </if>\n    </target>\n    \n    <target name=\"-htmlclean\" depends=\"-usemin\">\n        <echo message=\"Run htmlcompressor on the HTML\"/>\n        <echo message=\" - maintaining whitespace\"/>\n        <echo message=\" - removing html comments\"/>\n        <echo message=\" - compressing inline style/script tag contents\"/>\n        <apply executable=\"java\" parallel=\"false\" dest=\"./${dir.publish}/\" >\n            <fileset dir=\"./${dir.intermediate}/\" includes=\"${page-files}\"/>\n            <arg value=\"-jar\"/>\n            <arg path=\"./${dir.build.tools}/${tool.htmlcompressor}\"/>\n            <arg line=\"--preserve-multi-spaces\"/>\n            <arg line=\"--remove-quotes\"/>\n            <arg line=\"--compress-js\"/>\n            <arg line=\"--compress-css\"/>\n            <arg line=\"--preserve-php\"/>\n            <arg line=\"--preserve-ssi\"/>\n            <srcfile/>\n            <arg value=\"-o\"/>\n            <mapper type=\"glob\" from=\"*\" to=\"../${dir.publish}/*\"/>\n            <targetfile/>\n        </apply>\n    </target>\n    \n    \n    <target name=\"-htmlbuildkit\" depends=\"-usemin\">\n        <echo message=\"Run htmlcompressor on the HTML\"/>\n        <echo message=\" - maintaining whitespace\"/>\n        <echo message=\" - retain html comments\"/>\n        <echo message=\" - compressing inline style/script tag contents\"/>\n        <apply executable=\"java\" parallel=\"false\" dest=\"./${dir.publish}/\" >\n            <fileset dir=\"./${dir.intermediate}/\" includes=\"${page-files}\"/>\n            <arg value=\"-jar\"/>\n            <arg path=\"./${dir.build.tools}/${tool.htmlcompressor}\"/>\n            <arg value=\"--preserve-comments\"/>\n            <arg line=\"--preserve-multi-spaces\"/>\n            <arg line=\"--compress-js\"/>\n            <arg line=\"--compress-css\"/>\n            <arg line=\"--preserve-php\"/>\n            <arg line=\"--preserve-ssi\"/>\n            <srcfile/>\n            <arg value=\"-o\"/>\n            <mapper type=\"glob\" from=\"*\" to=\"../${dir.publish}/*\"/>\n            <targetfile/>\n        </apply>\n    </target>\n    \n    \n    <target name=\"-htmlcompress\" depends=\"-usemin\">\n        <echo message=\"Run htmlcompressor on the HTML\"/>\n        <echo message=\" - removing unnecessary whitespace\"/>\n        <echo message=\" - removing html comments\"/>\n        <echo message=\" - compressing inline style/script tag contents\"/>\n        <apply executable=\"java\" parallel=\"false\" dest=\"./${dir.publish}/\" >\n            <fileset dir=\"./${dir.intermediate}/\" includes=\"${page-files}\"/>\n            <arg value=\"-jar\"/>\n            <arg path=\"./${dir.build.tools}/${tool.htmlcompressor}\"/>\n            <arg line=\"--remove-quotes\"/>\n            <arg line=\"--compress-js\"/>\n            <arg line=\"--compress-css\"/>\n            <arg line=\"--preserve-php\"/>\n            <arg line=\"--preserve-ssi\"/>\n            <srcfile/>\n            <arg value=\"-o\"/>\n            <mapper type=\"glob\" from=\"*\" to=\"../${dir.publish}/*\"/>\n            <targetfile/>\n        </apply>\n    </target>\n\n\n    <!-- CSS -->\n\n    <target name=\"-css-remove-concatenated-stylesheets\">\n            <echo>Removing ${css_file} from html</echo>\n            <replaceregexp match=\"&lt;link.+href=&quot;.*${css_file}&quot;.*&gt;\" replace=\"  \">\n                <fileset dir=\"${dir.intermediate}\" includes=\"${page-files}\"/>\n            </replaceregexp>       \n    </target>\n        \n\n    <target name=\"css-split\" description=\"turns style.css into multiple files @imported together\">\n        <copy file=\"${dir.source}/${dir.css}/${file.root.stylesheet}\" tofile=\"${dir.source}/${dir.css}/${file.root.stylesheet}.temp\"/>\n        \n        <replaceregexp file=\"${dir.source}/${dir.css}/${file.root.stylesheet}.temp\" \n               match=\".*\" \n               replace=\"/* remove me */\" flags=\"s\" />\n    \n        <loadfile property=\"root\" srcfile=\"${dir.source}/${dir.css}/${file.root.stylesheet}\"/>\n        <var name=\"curr.buffer\" value=\"\"/>\n    \n        <for delimiter=\"${line.separator}\" param=\"currline\" list=\"${root}\">\n            <sequential>\n                <!-- does this line contain an h5bp-import? -->\n                <propertyregex property=\"export.name\" input=\"@{currline}\" regexp=\"^.*==\\|== +(.*) +==+$\" select=\"\\1\" casesensitive=\"true\" override=\"true\" />\n                <if>\n                    <isset property=\"export.name\"/>\n                    <then>\n                        <propertyregex property=\"export.name\" input=\"${export.name}\" regexp=\" \" replace=\".\" global=\"true\" override=\"true\" />\n                        <var name=\"export.name\" value=\"${export.name}.css\"/>           \n                    \n                        <if>\n                            <isset property=\"curr.file\"/>\n                            <then>\n                                <!-- create curr.file -->\n                                <copy file=\"${dir.source}/${dir.css}/${file.root.stylesheet}\" tofile=\"${dir.source}/${dir.css}/${curr.file}\" overwrite=\"true\"/>\n                                <!-- write the curr.buffer into the curr.file -->\n                                <replaceregexp file=\"${dir.source}/${dir.css}/${curr.file}\" \n                                       match=\".*\" \n                                       replace=\"${curr.buffer}\" flags=\"s\" />\n                                \n                                <var name=\"curr.buffer\" value=\"\"/>\n                                <var name=\"curr.file\" unset=\"true\"/>\n                            </then>\n                        </if>\n                        <var name=\"curr.file\" value=\"${export.name}\"/>\n                        <var name=\"export.name\" unset=\"true\"/>\n\n                        <!-- insert import line into new root -->\n                        <replace file=\"${dir.source}/${dir.css}/${file.root.stylesheet}.temp\" token=\"/* remove me */\" value=\"@import url(${curr.file});${line.separator}/* remove me */\"/>\n                    </then>\n                </if>\n                <var name=\"curr.buffer\" value=\"${curr.buffer}@{currline}${line.separator}\" />                                        \n            </sequential>\n        </for>\n        <!-- one more time to write out the last file -->\n        <if>\n            <isset property=\"curr.file\"/>\n            <then>\n                <!-- create curr.file -->\n                <copy file=\"${dir.source}/${dir.css}/${file.root.stylesheet}\" tofile=\"${dir.source}/${dir.css}/${curr.file}\" overwrite=\"true\"/>\n                <!-- write the curr.buffer into the curr.file -->\n                <replaceregexp file=\"${dir.source}/${dir.css}/${curr.file}\" \n                       match=\".*\" \n                       replace=\"${curr.buffer}\" flags=\"s\" />\n                \n                <var name=\"curr.buffer\" value=\"\"/>\n                <var name=\"curr.file\" unset=\"true\"/>\n            </then>\n        </if>\n        <replace file=\"${dir.source}/${dir.css}/${file.root.stylesheet}.temp\" token=\"/* remove me */\" value=\"${curr.buffer}\"/>\n        <copy file=\"${dir.source}/${dir.css}/${file.root.stylesheet}\" tofile=\"${dir.source}/${dir.css}/${file.root.stylesheet}.orig\" overwrite=\"false\"/>\n        <move file=\"${dir.source}/${dir.css}/${file.root.stylesheet}.temp\" tofile=\"${dir.source}/${dir.css}/${file.root.stylesheet}\" overwrite=\"false\"/>\n    </target>\n    \n    <target name=\"-css\" depends=\"-mkdirs\" description=\"Concatenates and Minifies any stylesheets listed in the file.stylesheets property\">\n        <echo message=\"Concatenating any @imports...\"/>\n\n        <!-- copy source file to intermediate directory -->\n        <copy file=\"${dir.source}/${dir.css}/${file.root.stylesheet}\" tofile=\"${dir.intermediate}/${dir.css}/${file.root.stylesheet}\"/>\n\n        <!-- replace imports with h5bp-import tags (part 1) this one wraps @media types -->\n        <replaceregexp file=\"${dir.intermediate}/${dir.css}/${file.root.stylesheet}\" \n                        match=\"^@import\\s+(?:url\\s*\\(\\s*['&quot;]?|['&quot;])((?!http:|https:|ftp:)[^&quot;^'^\\s]+)(?:['&quot;]?\\s*\\)|['&quot;])\\s*([\\w\\s,\\-]*);.*$\"\n                       replace=\"@media \\2{ /* h5bp-import: \\1 */ }\" byline=\"true\" />\n        \n        <!-- replace imports with h5bp-import tags (part 2) -->\n        <replaceregexp file=\"${dir.intermediate}/${dir.css}/${file.root.stylesheet}\" \n                       match=\"^@media \\{ (/\\* .* \\*/) \\}\" replace=\"\\1\" byline=\"true\" />\n\n        <!-- copy skeleton to concat file -->\n        <copy file=\"${dir.intermediate}/${dir.css}/${file.root.stylesheet}\"\n              tofile=\"${dir.intermediate}/${dir.css}/style-concat.css\" overwrite=\"true\"/>\n\n        <!-- load the file into a property -->\n        <loadfile property=\"imports\" srcfile=\"${dir.intermediate}/${dir.css}/${file.root.stylesheet}\"/>\n\n        <var name=\"concat-files\" value=\"${file.root.stylesheet}\"/>\n\n        <!-- go over the file line by line -->\n        <for delimiter=\"${line.separator}\" param=\"import\" list=\"${imports}\">\n            <sequential>\n                <!-- does this line contain an h5bp-import? -->\n                <propertyregex property=\"file.name\" input=\"@{import}\" regexp=\"/\\* h5bp-import: (.*) \\*/\" select=\"\\1\" casesensitive=\"true\" override=\"true\" />\n\n                <if>\n                    <isset property=\"file.name\"/>\n                    <then>\n                        <var name=\"concat-files\" value=\"${file.name},${concat-files}\"/>\n\n                        <!-- load the file into a variable -->\n                        <loadfile property=\"file.contents\" srcFile=\"${dir.source}/${dir.css}/${file.name}\"/>\n\n                        <!-- pop that file into the concatenated output file -->\n                        <replace file=\"${dir.intermediate}/${dir.css}/style-concat.css\" token=\"/* h5bp-import: ${file.name} */\" value=\"${file.contents}\"/>\n\n                        <var name=\"file.contents\" unset=\"true\"/>\n                    </then>\n                </if>\n            </sequential>\n        </for>\n        <echo message=\"Minifying css...\"/>\n        \n        <apply executable=\"java\" parallel=\"false\">\n            <fileset dir=\"${dir.intermediate}/${dir.css}/\" includes=\"style-concat.css\"/>\n            <arg line=\"-jar\"/>\n            <arg path=\"${dir.build.tools}/${tool.yuicompressor}\"/>\n            <srcfile/>\n            <arg line=\"-o\"/>\n            <mapper type=\"merge\" to=\"${basedir}/${dir.intermediate}/${dir.css}/style-concat.min.css\"/>\n            <targetfile/>\n        </apply>\n\n        <checksum file=\"${dir.intermediate}/${dir.css}/style-concat.min.css\" algorithm=\"sha\" property=\"css.sha\" />\n        <if>\n            <isset property=\"gae.css_dir\" />\n            <then>\n                <property name=\"style.css\" value=\"${gae.css_dir}/${css.sha}.css\" />\n            </then>\n            <else>\n                <property name=\"style.css\" value=\"${dir.css}/${css.sha}.css\" />\n            </else>\n        </if>\n        <copy file=\"${dir.intermediate}/${dir.css}/style-concat.min.css\" tofile=\"${dir.publish}/${dir.css}/${css.sha}.css\" />\n\n        <echo message=\"Minifying any unconcatenated css files...\"/>\n\n        <apply executable=\"java\" parallel=\"false\">\n            <fileset dir=\"${dir.source}/${dir.css}/\" excludes=\"${concat-files}\" includes=\"**/*.css\"/>\n            <arg line=\"-jar\"/>\n            <arg path=\"${dir.build.tools}/${tool.yuicompressor}\"/>\n            <srcfile/>\n            <arg line=\"-o\"/>\n            <mapper type=\"glob\" from=\"*.css\" to=\"${basedir}/${dir.publish}/${dir.css}/*.css\"/>\n            <targetfile/>\n        </apply>\n        <foreach list=\"${file.stylesheets}\" param=\"css_file\" target=\"-css-remove-concatenated-stylesheets\" />        \n    </target>\n    \n    \n    <!-- IMAGES -->\n    <target name=\"-imagespng\" depends=\"-mkdirs\" description=\"(PRIVATE) Optimizes .png images using optipng\">\n        <echo message=\"Optimizing images...\"/>\n        <echo message=\"This part might take a while. But everything else is already done.\"/>\n        <echo message=\" \"/>\n        \n        \n        <echo message=\"First, we run optipng on the .png files...\"/>\n        \n        <!-- osfamily=unix is actually true on OS X as well -->\n        <!-- On *nix's and OS X, check for optipng and give a helpful message if it's not installed -->\n        <if>\n            <and>\n                <os family=\"unix\" />\n                <available file=\"optipng\" filepath=\"${ENV.PATH}\" />\n            </and>\n            <then>\n                <!-- work around https://sourceforge.net/tracker/?func=detail&aid=2671422&group_id=151404&atid=780916 -->\n                <delete>\n                    <fileset dir=\"./${dir.publish}/${dir.images}/\">\n                        <include name=\"**/*.png\"/>\n                    </fileset>\n                </delete>\n                <apply executable=\"optipng\" dest=\"./${dir.publish}/${dir.images}/\" osfamily=\"unix\">\n                    <fileset dir=\"./${dir.source}/${dir.images}/\" includes=\"**/*.png\"  excludes=\"${images.bypass}, ${images.default.bypass}\"/>\n                    <arg value=\"-quiet\"/>\n                    <arg value=\"-o7\"/>\n                    <arg value=\"-out\"/>\n                    <targetfile/>\n                    <srcfile/>\n                    <mapper type=\"identity\"/>\n                </apply>\n            </then>\n            <elseif>\n                <os family=\"unix\" />\n                <then>\n                    <echo message=\"*** optipng NOT INSTALLED. SKIPPING OPTIMIZATION OF PNGs.\" />\n                    <echo message=\"*** Install optipng to enable png optimization.\" />\n                    <echo message=\"*** For instructions see 'Dependencies' at: http://html5boilerplate.com/docs/#Build-script#dependencies\" />\n                </then>\n            </elseif>\n        </if>\n\n        <!-- work around https://sourceforge.net/tracker/?func=detail&aid=2671422&group_id=151404&atid=780916 -->\n        <delete>\n            <fileset dir=\"./${dir.publish}/${dir.images}/\">\n                <include name=\"**/*.png\"/>\n            </fileset>\n        </delete>\n        <apply executable=\"${basedir}/${dir.build.tools}/optipng-0.6.4-exe/optipng.exe\" dest=\"./${dir.publish}/${dir.images}/\" osfamily=\"windows\">\n            <fileset dir=\"./${dir.source}/${dir.images}/\" includes=\"**/*.png\"  excludes=\"${images.bypass}, ${images.default.bypass}\"/>\n            <arg value=\"-quiet\"/>\n            <arg value=\"-o7\"/>\n            <arg value=\"-out\"/>\n            <targetfile/>\n            <srcfile/>\n            <mapper type=\"identity\"/>\n        </apply>\n    </target>\n\n\n    <target name=\"-imagesjpg\" depends=\"-mkdirs\" description=\"(PRIVATE) Optimizes .jpg images using jpegtan\">\n        <echo message=\"Now, we clean up those jpgs...\"/>\n\n        <if>\n            <equals arg1=\"${images.strip.metadata}\" arg2=\"true\"/>\n            <then>\n                <var name=\"strip-meta-tags\" value=\"none\"/>\n            </then>\n            <else>\n                <var name=\"strip-meta-tags\" value=\"all\"/>\n            </else>\n        </if>\n\n        <!-- On *nix's and OS X, check for jpegtran and give a helpful message if it's not installed -->\n        <if>\n            <and>\n                <os family=\"unix\" />\n                <available file=\"jpegtran\" filepath=\"${ENV.PATH}\" />\n            </and>\n            <then>\n                <apply executable=\"jpegtran\" dest=\"./${dir.publish}/${dir.images}\" osfamily=\"unix\">\n                    <fileset dir=\"${dir.source}/${dir.images}\" includes=\"**/*.jpg\" excludes=\"${images.bypass}, ${images.default.bypass}\"/>\n                    <arg value=\"-copy\"/>\n                    <arg value=\"${strip-meta-tags}\"/>\n                    <arg value=\"-optimize\"/>\n                    <arg value=\"-outfile\"/>\n                    <targetfile/>\n                    <srcfile/>\n                    <mapper type=\"identity\"/>\n                    <!-- you may want to flag optimized images. If so, do it here. Otherwise change this to type=\"identity\" -->\n                    <!--<mapper type=\"glob\" from=\"*.jpg\" to=\"*.jpg\"/>-->\n                </apply>\n            </then>\n            <elseif>\n                <os family=\"unix\" />\n                <then>\n                    <echo message=\"*** jpegtran NOT INSTALLED. SKIPPING OPTIMIZATION OF JPEGs.\" />\n                    <echo message=\"*** Install jpegtran to enable jpeg optimization.\" />\n                    <echo message=\"*** For instructions see 'Dependencies' at: http://html5boilerplate.com/docs/#Build-script#dependencies\" />\n                </then>\n            </elseif>\n        </if>\n\n        <apply executable=\"${basedir}/${dir.build.tools}/jpegtran.exe\" dest=\"./${dir.publish}/${dir.images}\" osfamily=\"windows\">\n            <fileset dir=\"${dir.source}/${dir.images}\" includes=\"**/*.jpg\"  excludes=\"${images.bypass}, ${images.default.bypass}\"/>\n            <arg value=\"-copy\"/>\n            <arg value=\"${strip-meta-tags}\"/>\n            <arg value=\"-optimize\"/>\n            <arg value=\"-outfile\"/>\n            <targetfile/>\n            <srcfile/>\n            <mapper type=\"identity\"/>\n            <!-- you may want to flag optimized images. If so, do it here. Otherwise change this to type=\"identity\" -->\n            <!--<mapper type=\"glob\" from=\"*.jpg\" to=\"*.jpg\"/>-->\n        </apply>\n    </target>\n\n\n    <target name=\"-imgcopy\" depends=\"-mkdirs\">\n        <echo message=\"Copying over the unmodified images.\"/>\n\n        <copy todir=\"./${dir.publish}/${dir.images}\">\n            <fileset dir=\"${dir.source}/${dir.images}\"  includes=\"**/*.jpg, **/*.png\"/>\n        </copy> \n    </target>\n    \n</project>\n"
  },
  {
    "path": "app/static_dev/build/config/default.properties",
    "content": "#\n# Default Build Settings\n# you can override these settings on a project basis in a project.properties file\n# so probably best not to touch these as they could be overwritten in later versions!\n#\n\n\n#\n# Directory Paths\n#\ndir.source          = .\ndir.intermediate    = intermediate\ndir.publish         = publish\ndir.build           = build\ndir.build.tools     = ${dir.build}/tools\ndir.test            = test\ndir.demo            = demo\ndir.js              = js\ndir.js.main         = ${dir.js}\n# scripts in the lib directory will only be minified, not concatenated together\ndir.js.libs         = ${dir.js}/libs\ndir.js.mylibs       = ${dir.js}/mylibs\ndir.css             = css\ndir.images          = img\n\n\n#\n# HTML, PHP, etc files to clean and update script/css references\n#\nfile.pages.default.include  = index.html, 404.html\n\n# You will need to include the property file.pages.include in your project.properties file\n# and add any extra pages you want to be updated by the scripts in a comma separated list\n\n\n# the server configuration you're going with. If you don't use apache,\n#   get a different one here:  github.com/paulirish/html5-boilerplate-server-configs\n\nfile.serverconfig           = .htaccess\n\n#\n# Files not to be copied over by the script to the publish directory\n#\nfile.default.exclude        = .gitignore, .project, .settings, README.markdown, README.md, **/.git/**, **/.svn/**, ${dir.test}/**, ${dir.demo}/**, ${dir.intermediate}/**, ${dir.publish}/**, ${dir.build}/**, **/nbproject/**, *.komodoproject, **/.komodotools/**, **/dwsync.xml, **_notes, **/.hg/**, **/.idea/**\n# Declare the file.exclude property in your project.properties file if you want to exclude files / folders you have added\n# Note: you cannot declare an empty file.exclude property\n\n#\n# Bypass Optimization for these files\n#\n# file.default.js.bypass\n# If set, these files will not be optimized (minifications, concatinations, image optimizations will not be applied)\n# Note: you cannot declare an empty file.default.bypass property\n\n\n#\n# Root Stylesheet\n# this is the file that contains the @import directives\n#\nfile.root.stylesheet    = style.css\n\n#\n# Default Stylesheet\n#\nfile.default.stylesheets    = \n\n#\n# Script Optimisation\n#\n# If set, concat libraries with main scripts file, producing single script file\nbuild.concat.scripts        = true\n\n\n#\n# Image Optimisation\n#\nimages.strip.metadata       = true\n# Seting this to true will strip the metadata from all jpeg files.\n# YOU SHOULD ONLY DO THIS IF YOU OWN THE COPYRIGHT TO ALL THE IMAGES IN THE BUILD\n\n#\n# Bypass Optimization for these image files or folders\n#\n# images.default.bypass\n# If set, these images will not be optimized\n# Note: you cannot declare an empty images.default.bypass property\n\n\n# Build Info\nbuild.version.info          = buildinfo.properties\nbuild.scripts.dir           = ${dir.build}/build-scripts\n\n# Tools\ntool.yuicompressor          = yuicompressor-2.4.5.jar\ntool.htmlcompressor         = htmlcompressor-1.4.3.jar\ntool.csscompressor          = css-compressor/cli.php\ntool.rhino                  = rhino.jar\ntool.jslint                 = fulljslint.js\ntool.jshint                 = fulljshint.js\ntool.csslint                = csslint-rhino.js\n\n# Default Lint Utils Options\ntool.jshint.opts            = maxerr=25,eqeqeq=true\ntool.jslint.opts            = maxerr=25,evil=true,browser=true,eqeqeq=true,immed=true,newcap=true,nomen=true,es5=true,rhino=true,undef=true,white=false,devel=true\ntool.csslint.opts           = \n"
  },
  {
    "path": "app/static_dev/build/config/manifest.appcache",
    "content": "CACHE MANIFEST\n\n# version xxxxxxxxx\n\nCACHE:\n# html files\n\n\n# css files\n\n\n\n# js files\n\n\n\nFALLBACK:\n\nNETWORK:\n*"
  },
  {
    "path": "app/static_dev/build/config/project.properties",
    "content": "# project.properties file defines overrides for default.properties\n\n# Explanation: This file should be created by each user as and when he or she needs to override particular values.\n# Consequently, it should not be placed under version control.\n\n\n# Stylesheets\n#\n# Note: Stylesheets will be concatenated in the order they are listed in the file.stylesheets property (i.e. the last\n# file listed will be at the end of the concatenated file), so it probably makes sense to have the main style.css file\n# as the first entry\n# Example:\n# file.stylesheets  = style.css, lightbox.css, plugin.css\n#\nfile.stylesheets  =\n\n\n# Web Pages\n#\n# These are the pages (files) that will be served to users (.html, .php, .asp, etc). Files in this property will\n# be minified / optimised and have any stylesheet or javascript references updated to the minified examples\n#\n# The paths need to be relative\n#\n# Files can be added in a comma separated form\nfile.pages        =\n\n\n# site manifest for offline\n# this is the name of the manifest file you declared in the <html> tag\n# Uncomment this line to enable appcache generation:\n# file.manifest    = manifest.appcache\n\n# Excluded files and dirs\n#\n# Add any files or directories you add to the project and do not want to be copied to the publish directory as a\n# comma separated list\n# These files are ignored in addition to the default ones specified in default.properties.\nfile.exclude      =\n\n# Bypassed JavaScript files and dirs\n#\n# Add any files or folders within the mylibs directory that you want to be copied to the publish directory as a\n# comma separated list\n# These files will not be concatenated or minimized and will simply be copied over as is.\n# Note: you cannot declare an empty file.bypass property, it would exclude the entire mylibs folder\n# Example:\n# file.js.bypass = widgets.js, gadgets.js, gidgets.js\n# file.js.bypass = \n\n\n# Specify an environment to build\n#\n# By Default, it builds a production environment\n# Set to dev if building a development environment\n# Set to test if building a test environment\nenv               =\n\n#\n# Bypass Optimization for these image files or folders\n#\n# images.bypass\n# If set, these images will not be optimized\n# Note: you cannot declare an empty images.bypass property, it would exclude the entire img folder from being optimized\n\n# Directory Structure\n#\n# Override any directory paths specific to this project\n#\n# dir.publish\n# dir.js\n# dir.js.libs\n# dir.js.mylibs\n# dir.css\n# dir.images\n\n# Google App Engine Directory Structure\n#\n# Prevent \"static/\" being included in concated file paths.\n#\n# gae.css_dir = /css\n# gae.js_dir = /js\n\n# Override default JSHint Options (see http://jshint.com/ for description of options)\n#tool.jshint.opts = \n\n# Override default JSLint Options (see http://www.jslint.com/lint.html for description of options)\n#tool.jslint.opts = \n\n# Override default CSSLint Options (see http://csslint.net/about.html#settings for description of options)\n#tool.csslint.opts = \n"
  },
  {
    "path": "app/static_dev/build/createproject.sh",
    "content": "#!/usr/bin/env bash\n\n#Generate a new project from your HTML5 Boilerplate repo clone\n#by: Rick Waldron & Michael Cetrulo\n\n\n##first run\n# $ cd  html5-boilerplate/build\n# $ chmod +x createproject.sh && ./createproject.sh\n\n##usage\n# $ cd  html5-boilerplate/build\n# $ ./createproject.sh\n\n# find project root (also ensure script is ran from within repo)\nsrc=$(git rev-parse --show-toplevel) || {\n  echo \"try running the script from within html5-boilerplate directories.\" >&2\n  exit 1\n}\n[[ -d $src ]] || {\n  echo \"fatal: could not determine html5-boilerplate's root directory.\" >&2\n  echo \"try updating git.\" >&2\n  exit 1\n}\n\n# get a name for new project\nwhile [[ -z $name ]]\ndo\n    echo \"To create a new html5-boilerplate project, enter a new directory name:\"\n    read name || exit\ndone\ndst=$src/../$name\n\nif [[ -d $dst ]]\nthen\n    echo \"$dst exists\"\nelse\n    #create new project\n    mkdir -- \"$dst\" || exit 1\n\n    #sucess message\n    echo \"Created Directory: $dst\"\n\n    cd -- \"$src\"\n    cp -vr -- css js img build test *.html *.xml *.txt *.png *.ico .htaccess \"$dst\"\n\n    #sucess message\n    echo \"Created Project: $dst\"\nfi\n\n"
  },
  {
    "path": "app/static_dev/build/runbuildscript.bat",
    "content": "# This is for windows users only.\n# If you're on a mac or linux, just run `ant build` from this folder in Terminal\n\nset MYDIR=%~dp0\nant build"
  },
  {
    "path": "app/static_dev/build/tools/csslint-rhino.js",
    "content": "/*! \nCSSLint\nCopyright (c) 2011 Nicole Sullivan and Nicholas C. Zakas. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n/* Build time: 5-July-2011 03:16:53 */\nvar CSSLint = (function(){\n/*!\nParser-Lib\nCopyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n/* Build time: 5-July-2011 03:12:40 */\nvar parserlib = {};\n(function(){\n\n/**\n * A generic base to inherit from for any object\n * that needs event handling.\n * @class EventTarget\n * @constructor\n */\nfunction EventTarget(){\n\n    /**\n     * The array of listeners for various events.\n     * @type Object\n     * @property _listeners\n     * @private\n     */\n    this._listeners = {};    \n}\n\nEventTarget.prototype = {\n\n    //restore constructor\n    constructor: EventTarget,\n\n    /**\n     * Adds a listener for a given event type.\n     * @param {String} type The type of event to add a listener for.\n     * @param {Function} listener The function to call when the event occurs.\n     * @return {void}\n     * @method addListener\n     */\n    addListener: function(type, listener){\n        if (!this._listeners[type]){\n            this._listeners[type] = [];\n        }\n\n        this._listeners[type].push(listener);\n    },\n    \n    /**\n     * Fires an event based on the passed-in object.\n     * @param {Object|String} event An object with at least a 'type' attribute\n     *      or a string indicating the event name.\n     * @return {void}\n     * @method fire\n     */    \n    fire: function(event){\n        if (typeof event == \"string\"){\n            event = { type: event };\n        }\n        if (!event.target){\n            event.target = this;\n        }\n        \n        if (!event.type){\n            throw new Error(\"Event object missing 'type' property.\");\n        }\n        \n        if (this._listeners[event.type]){\n        \n            //create a copy of the array and use that so listeners can't chane\n            var listeners = this._listeners[event.type].concat();\n            for (var i=0, len=listeners.length; i < len; i++){\n                listeners[i].call(this, event);\n            }\n        }            \n    },\n\n    /**\n     * Removes a listener for a given event type.\n     * @param {String} type The type of event to remove a listener from.\n     * @param {Function} listener The function to remove from the event.\n     * @return {void}\n     * @method removeListener\n     */\n    removeListener: function(type, listener){\n        if (this._listeners[type]){\n            var listeners = this._listeners[type];\n            for (var i=0, len=listeners.length; i < len; i++){\n                if (listeners[i] === listener){\n                    listeners.splice(i, 1);\n                    break;\n                }\n            }\n            \n            \n        }            \n    }\n};\n/**\n * Convenient way to read through strings.\n * @namespace parserlib.util\n * @class StringReader\n * @constructor\n * @param {String} text The text to read.\n */\nfunction StringReader(text){\n    \n    /**\n     * The input text with line endings normalized.\n     * @property _input\n     * @type String\n     * @private\n     */\n    this._input = text.replace(/\\n\\r?/g, \"\\n\");\n    \n    \n    /**\n     * The row for the character to be read next.\n     * @property _line\n     * @type int\n     * @private\n     */\n    this._line = 1;\n    \n    \n    /**\n     * The column for the character to be read next.\n     * @property _col\n     * @type int\n     * @private\n     */\n    this._col = 1;\n    \n    /**\n     * The index of the character in the input to be read next.\n     * @property _cursor\n     * @type int\n     * @private\n     */    \n    this._cursor = 0;\n}\n\nStringReader.prototype = {\n\n    //restore constructor\n    constructor: StringReader,\n        \n    //-------------------------------------------------------------------------\n    // Position info\n    //-------------------------------------------------------------------------\n    \n    /**\n     * Returns the column of the character to be read next.\n     * @return {int} The column of the character to be read next.\n     * @method getCol\n     */\n    getCol: function(){\n        return this._col;\n    },\n    \n    /**\n     * Returns the row of the character to be read next.\n     * @return {int} The row of the character to be read next.\n     * @method getLine\n     */    \n    getLine: function(){\n        return this._line ;\n    },\n    \n    /**\n     * Determines if you're at the end of the input.\n     * @return {Boolean} True if there's no more input, false otherwise.\n     * @method eof\n     */    \n    eof: function(){\n        return (this._cursor == this._input.length)\n    },\n    \n    //-------------------------------------------------------------------------\n    // Basic reading\n    //-------------------------------------------------------------------------\n    \n    /**\n     * Reads the next character without advancing the cursor.\n     * @param {int} count How many characters to look ahead (default is 1).\n     * @return {String} The next character or null if there is no next character.\n     * @method peek\n     */\n    peek: function(count){\n        var c = null;\n        count = (typeof count == \"undefined\" ? 1 : count);\n        \n        //if we're not at the end of the input...\n        if (this._cursor < this._input.length){        \n        \n            //get character and increment cursor and column\n            c = this._input.charAt(this._cursor + count - 1);\n        }\n        \n        return c;\n    },        \n       \n    /**\n     * Reads the next character from the input and adjusts the row and column\n     * accordingly.\n     * @return {String} The next character or null if there is no next character.\n     * @method read\n     */\n    read: function(){\n        var c = null;\n        \n        //if we're not at the end of the input...\n        if (this._cursor < this._input.length){\n        \n            //if the last character was a newline, increment row count\n            //and reset column count\n            if (this._input.charAt(this._cursor) == \"\\n\"){\n                this._line++;\n                this._col=1;\n            } else {\n                this._col++;\n            }\n        \n            //get character and increment cursor and column\n            c = this._input.charAt(this._cursor++);\n        }\n        \n        return c;\n    },        \n       \n    //-------------------------------------------------------------------------\n    // Misc\n    //-------------------------------------------------------------------------\n    \n    /**\n     * Saves the current location so it can be returned to later.\n     * @method mark\n     * @return {void}\n     */\n    mark: function(){\n        this._bookmark = {\n            cursor: this._cursor,\n            line:   this._line,\n            col:    this._col\n        };\n    },\n    \n    reset: function(){\n        if (this._bookmark){\n            this._cursor = this._bookmark.cursor;\n            this._line = this._bookmark.line;\n            this._col = this._bookmark.col;\n            delete this._bookmark;\n        }\n    },\n    \n    //-------------------------------------------------------------------------\n    // Advanced reading\n    //-------------------------------------------------------------------------\n    \n    /**\n     * Reads up to and including the given string. Throws an error if that\n     * string is not found.\n     * @param {String} pattern The string to read.\n     * @return {String} The string when it is found.\n     * @throws Error when the string pattern is not found.\n     * @method readTo\n     */       \n    readTo: function(pattern){\n    \n        var buffer = \"\",\n            c;\n\n        /*\n         * First, buffer must be the same length as the pattern.\n         * Then, buffer must end with the pattern or else reach the\n         * end of the input.\n         */\n        while (buffer.length < pattern.length || buffer.lastIndexOf(pattern) != buffer.length - pattern.length){\n            c = this.read();\n            if (c){\n                buffer += c;\n            } else {\n                throw new Error(\"Expected \\\"\" + pattern + \"\\\" at line \" + this._line  + \", col \" + this._col + \".\");\n            }\n        }\n        \n        return buffer;\n    \n    },\n    \n    /**\n     * Reads characters while each character causes the given\n     * filter function to return true. The function is passed\n     * in each character and either returns true to continue\n     * reading or false to stop.\n     * @param {Function} filter The function to read on each character.\n     * @return {String} The string made up of all characters that passed the\n     *      filter check.\n     * @method readWhile\n     */           \n    readWhile: function(filter){\n        \n        var buffer = \"\",\n            c = this.read();\n        \n        while(c !== null && filter(c)){\n            buffer += c;\n            c = this.read();\n        }\n        \n        return buffer;\n    \n    },\n    \n    /**\n     * Reads characters that match either text or a regular expression and\n     * returns those characters. If a match is found, the row and column\n     * are adjusted; if no match is found, the reader's state is unchanged.\n     * reading or false to stop.\n     * @param {String|RegExp} matchter If a string, then the literal string\n     *      value is searched for. If a regular expression, then any string\n     *      matching the pattern is search for.\n     * @return {String} The string made up of all characters that matched or\n     *      null if there was no match.\n     * @method readMatch\n     */               \n    readMatch: function(matcher){\n    \n        var source = this._input.substring(this._cursor),\n            value = null;\n        \n        //if it's a string, just do a straight match\n        if (typeof matcher == \"string\"){\n            if (source.indexOf(matcher) === 0){\n                value = this.readCount(matcher.length); \n            }\n        } else if (matcher instanceof RegExp){\n            if (matcher.test(source)){\n                value = this.readCount(RegExp.lastMatch.length);\n            }\n        }\n        \n        return value;        \n    },\n    \n    \n    /**\n     * Reads a given number of characters. If the end of the input is reached,\n     * it reads only the remaining characters and does not throw an error.\n     * @param {int} count The number of characters to read.\n     * @return {String} The string made up the read characters.\n     * @method readCount\n     */                   \n    readCount: function(count){\n        var buffer = \"\";\n        \n        while(count--){\n            buffer += this.read();\n        }\n        \n        return buffer;\n    }\n\n};\n/**\n * Type to use when a syntax error occurs.\n * @class SyntaxError\n * @namespace parserlib.util\n * @constructor\n * @param {String} message The error message.\n * @param {int} line The line at which the error occurred.\n * @param {int} col The column at which the error occurred.\n */\nfunction SyntaxError(message, line, col){\n\n    /**\n     * The column at which the error occurred.\n     * @type int\n     * @property col\n     */\n    this.col = col;\n\n    /**\n     * The line at which the error occurred.\n     * @type int\n     * @property line\n     */\n    this.line = line;\n\n    /**\n     * The text representation of the unit.\n     * @type String\n     * @property text\n     */\n    this.message = message;\n\n}\n\n//inherit from Error\nSyntaxError.prototype = new Error();\n/**\n * Base type to represent a single syntactic unit.\n * @class SyntaxUnit\n * @namespace parserlib.util\n * @constructor\n * @param {String} text The text of the unit.\n * @param {int} line The line of text on which the unit resides.\n * @param {int} col The column of text on which the unit resides.\n */\nfunction SyntaxUnit(text, line, col){\n\n\n    /**\n     * The column of text on which the unit resides.\n     * @type int\n     * @property col\n     */\n    this.col = col;\n\n    /**\n     * The line of text on which the unit resides.\n     * @type int\n     * @property line\n     */\n    this.line = line;\n\n    /**\n     * The text representation of the unit.\n     * @type String\n     * @property text\n     */\n    this.text = text;\n\n}\n\n/**\n * Create a new syntax unit based solely on the given token.\n * Convenience method for creating a new syntax unit when\n * it represents a single token instead of multiple.\n * @param {Object} token The token object to represent.\n * @return {parserlib.util.SyntaxUnit} The object representing the token.\n * @static\n * @method fromToken\n */\nSyntaxUnit.fromToken = function(token){\n    return new SyntaxUnit(token.value, token.startLine, token.startCol);\n};\n\nSyntaxUnit.prototype = {\n\n    //restore constructor\n    constructor: SyntaxUnit,\n    \n    /**\n     * Returns the text representation of the unit.\n     * @return {String} The text representation of the unit.\n     * @method valueOf\n     */\n    valueOf: function(){\n        return this.toString();\n    },\n    \n    /**\n     * Returns the text representation of the unit.\n     * @return {String} The text representation of the unit.\n     * @method toString\n     */\n    toString: function(){\n        return this.text;\n    }\n\n};\n/**\n * Generic TokenStream providing base functionality.\n * @class TokenStreamBase\n * @namespace parserlib.util\n * @constructor\n * @param {String|StringReader} input The text to tokenize or a reader from \n *      which to read the input.\n */\nfunction TokenStreamBase(input, tokenData){\n\n    /**\n     * The string reader for easy access to the text.\n     * @type StringReader\n     * @property _reader\n     * @private\n     */\n    //this._reader = (typeof input == \"string\") ? new StringReader(input) : input;\n    this._reader = input ? new StringReader(input.toString()) : null;\n    \n    /**\n     * Token object for the last consumed token.\n     * @type Token\n     * @property _token\n     * @private\n     */\n    this._token = null;    \n    \n    /**\n     * The array of token information.\n     * @type Array\n     * @property _tokenData\n     * @private\n     */\n    this._tokenData = tokenData;\n    \n    /**\n     * Lookahead token buffer.\n     * @type Array\n     * @property _lt\n     * @private\n     */\n    this._lt = [];\n    \n    /**\n     * Lookahead token buffer index.\n     * @type int\n     * @property _ltIndex\n     * @private\n     */\n    this._ltIndex = 0;\n    \n    this._ltIndexCache = [];\n}\n\n/**\n * Accepts an array of token information and outputs\n * an array of token data containing key-value mappings\n * and matching functions that the TokenStream needs.\n * @param {Array} tokens An array of token descriptors.\n * @return {Array} An array of processed token data.\n * @method createTokenData\n * @static\n */\nTokenStreamBase.createTokenData = function(tokens){\n\n    var nameMap \t= [],\n        typeMap \t= {},\n\t\ttokenData \t= tokens.concat([]),\n\t\ti\t\t\t= 0,\n\t\tlen\t\t\t= tokenData.length+1;\n    \n    tokenData.UNKNOWN = -1;\n\ttokenData.unshift({name:\"EOF\"});\n\n    for (; i < len; i++){\n        nameMap.push(tokenData[i].name);\n        tokenData[tokenData[i].name] = i;\n        if (tokenData[i].text){\n            typeMap[tokenData[i].text] = i;\n        }\n    }\n    \n    tokenData.name = function(tt){\n        return nameMap[tt];\n    };\n    \n    tokenData.type = function(c){\n        return typeMap[c];\n    };\n\t\n\treturn tokenData;\n};\n\nTokenStreamBase.prototype = {\n\n    //restore constructor\n    constructor: TokenStreamBase,    \n    \n    //-------------------------------------------------------------------------\n    // Matching methods\n    //-------------------------------------------------------------------------\n    \n    /**\n     * Determines if the next token matches the given token type.\n     * If so, that token is consumed; if not, the token is placed\n     * back onto the token stream. You can pass in any number of\n     * token types and this will return true if any of the token\n     * types is found.\n     * @param {int|int[]} tokenTypes Either a single token type or an array of\n     *      token types that the next token might be. If an array is passed,\n     *      it's assumed that the token can be any of these.\n     * @param {variant} channel (Optional) The channel to read from. If not\n     *      provided, reads from the default (unnamed) channel.\n     * @return {Boolean} True if the token type matches, false if not.\n     * @method match\n     */\n    match: function(tokenTypes, channel){\n    \n        //always convert to an array, makes things easier\n        if (!(tokenTypes instanceof Array)){\n            tokenTypes = [tokenTypes];\n        }\n                \n        var tt  = this.get(channel),\n            i   = 0,\n            len = tokenTypes.length;\n            \n        while(i < len){\n            if (tt == tokenTypes[i++]){\n                return true;\n            }\n        }\n        \n        //no match found, put the token back\n        this.unget();\n        return false;\n    },    \n    \n    /**\n     * Determines if the next token matches the given token type.\n     * If so, that token is consumed; if not, an error is thrown.\n     * @param {int|int[]} tokenTypes Either a single token type or an array of\n     *      token types that the next token should be. If an array is passed,\n     *      it's assumed that the token must be one of these.\n     * @param {variant} channel (Optional) The channel to read from. If not\n     *      provided, reads from the default (unnamed) channel.\n     * @return {void}\n     * @method mustMatch\n     */    \n    mustMatch: function(tokenTypes, channel){\n\n        //always convert to an array, makes things easier\n        if (!(tokenTypes instanceof Array)){\n            tokenTypes = [tokenTypes];\n        }\n\n        if (!this.match.apply(this, arguments)){    \n            token = this.LT(1);\n            throw new SyntaxError(\"Expected \" + this._tokenData[tokenTypes[0]].name + \n                \" at line \" + token.startLine + \", character \" + token.startCol + \".\", token.startLine, token.startCol);\n        }\n    },\n    \n    //-------------------------------------------------------------------------\n    // Consuming methods\n    //-------------------------------------------------------------------------\n    \n    /**\n     * Keeps reading from the token stream until either one of the specified\n     * token types is found or until the end of the input is reached.\n     * @param {int|int[]} tokenTypes Either a single token type or an array of\n     *      token types that the next token should be. If an array is passed,\n     *      it's assumed that the token must be one of these.\n     * @param {variant} channel (Optional) The channel to read from. If not\n     *      provided, reads from the default (unnamed) channel.\n     * @return {void}\n     * @method advance\n     */\n    advance: function(tokenTypes, channel){\n        \n        while(this.LA(0) != 0 && !this.match(tokenTypes, channel)){\n            this.get();\n        }\n\n        return this.LA(0);    \n    },\n    \n    /**\n     * Consumes the next token from the token stream. \n     * @return {int} The token type of the token that was just consumed.\n     * @method get\n     */      \n    get: function(channel){\n    \n        var tokenInfo   = this._tokenData,\n            reader      = this._reader,\n            value,\n            i           =0,\n            len         = tokenInfo.length,\n            found       = false,\n            token,\n            info;\n            \n        //check the lookahead buffer first\n        if (this._lt.length && this._ltIndex >= 0 && this._ltIndex < this._lt.length){  \n                           \n            i++;\n            this._token = this._lt[this._ltIndex++];\n            info = tokenInfo[this._token.type];\n            \n            //obey channels logic\n            while((info.channel !== undefined && channel !== info.channel) &&\n                    this._ltIndex < this._lt.length){\n                this._token = this._lt[this._ltIndex++];\n                info = tokenInfo[this._token.type];\n                i++;\n            }\n            \n            //here be dragons\n            if ((info.channel === undefined || channel === info.channel) &&\n                    this._ltIndex <= this._lt.length){\n                this._ltIndexCache.push(i);\n                return this._token.type;\n            }\n        }\n        \n        //call token retriever method\n\t\ttoken = this._getToken();\n\n        //if it should be hidden, don't save a token\n        if (token.type > -1 && !tokenInfo[token.type].hide){\n                     \n            //apply token channel\n            token.channel = tokenInfo[token.type].channel;\n         \n            //save for later\n            this._token = token;\n            this._lt.push(token);\n\n            //save space that will be moved (must be done before array is truncated)\n            this._ltIndexCache.push(this._lt.length - this._ltIndex + i);  \n        \n            //keep the buffer under 5 items\n            if (this._lt.length > 5){\n                this._lt.shift();                \n            }\n            \n            //also keep the shift buffer under 5 items\n            if (this._ltIndexCache.length > 5){\n                this._ltIndexCache.shift();\n            }\n                \n            //update lookahead index\n            this._ltIndex = this._lt.length;\n        }\n            \n        /*\n         * Skip to the next token if:\n         * 1. The token type is marked as hidden.\n         * 2. The token type has a channel specified and it isn't the current channel.\n         */\n        info = tokenInfo[token.type];\n        if (info && \n                (info.hide || \n                (info.channel !== undefined && channel !== info.channel))){\n            return this.get(channel);\n        } else {\n            //return just the type\n            return token.type;\n        }\n    },\n    \n    /**\n     * Looks ahead a certain number of tokens and returns the token type at\n     * that position. This will throw an error if you lookahead past the\n     * end of input, past the size of the lookahead buffer, or back past\n     * the first token in the lookahead buffer.\n     * @param {int} The index of the token type to retrieve. 0 for the\n     *      current token, 1 for the next, -1 for the previous, etc.\n     * @return {int} The token type of the token in the given position.\n     * @method LA\n     */\n    LA: function(index){\n        var total = index,\n            tt;\n        if (index > 0){\n            //TODO: Store 5 somewhere\n            if (index > 5){\n                throw new Error(\"Too much lookahead.\");\n            }\n        \n            //get all those tokens\n            while(total){\n                tt = this.get();   \n                total--;                            \n            }\n            \n            //unget all those tokens\n            while(total < index){\n                this.unget();\n                total++;\n            }\n        } else if (index < 0){\n        \n            if(this._lt[this._ltIndex+index]){\n                tt = this._lt[this._ltIndex+index].type;\n            } else {\n                throw new Error(\"Too much lookbehind.\");\n            }\n        \n        } else {\n            tt = this._token.type;\n        }\n        \n        return tt;\n    \n    },\n    \n    /**\n     * Looks ahead a certain number of tokens and returns the token at\n     * that position. This will throw an error if you lookahead past the\n     * end of input, past the size of the lookahead buffer, or back past\n     * the first token in the lookahead buffer.\n     * @param {int} The index of the token type to retrieve. 0 for the\n     *      current token, 1 for the next, -1 for the previous, etc.\n     * @return {Object} The token of the token in the given position.\n     * @method LA\n     */    \n    LT: function(index){\n    \n        //lookahead first to prime the token buffer\n        this.LA(index);\n        \n        //now find the token, subtract one because _ltIndex is already at the next index\n        return this._lt[this._ltIndex+index-1];    \n    },\n    \n    /**\n     * Returns the token type for the next token in the stream without \n     * consuming it.\n     * @return {int} The token type of the next token in the stream.\n     * @method peek\n     */\n    peek: function(){\n        return this.LA(1);\n    },\n    \n    /**\n     * Returns the actual token object for the last consumed token.\n     * @return {Token} The token object for the last consumed token.\n     * @method token\n     */\n    token: function(){\n        return this._token;\n    },\n    \n    /**\n     * Returns the name of the token for the given token type.\n     * @param {int} tokenType The type of token to get the name of.\n     * @return {String} The name of the token or \"UNKNOWN_TOKEN\" for any\n     *      invalid token type.\n     * @method tokenName\n     */\n    tokenName: function(tokenType){\n        if (tokenType < 0 || tokenType > this._tokenData.length){\n            return \"UNKNOWN_TOKEN\";\n        } else {\n            return this._tokenData[tokenType].name;\n        }\n    },\n    \n    /**\n     * Returns the token type value for the given token name.\n     * @param {String} tokenName The name of the token whose value should be returned.\n     * @return {int} The token type value for the given token name or -1\n     *      for an unknown token.\n     * @method tokenName\n     */    \n    tokenType: function(tokenName){\n        return this._tokenData[tokenName] || -1;\n    },\n    \n    /**\n     * Returns the last consumed token to the token stream.\n     * @method unget\n     */      \n    unget: function(){\n        //if (this._ltIndex > -1){\n        if (this._ltIndexCache.length){\n            this._ltIndex -= this._ltIndexCache.pop();//--;\n            this._token = this._lt[this._ltIndex - 1];\n        } else {\n            throw new Error(\"Too much lookahead.\");\n        }\n    }\n\n};\n\n\nparserlib.util = {\nStringReader: StringReader,\nSyntaxError : SyntaxError,\nSyntaxUnit  : SyntaxUnit,\nEventTarget : EventTarget,\nTokenStreamBase : TokenStreamBase\n};\n})();\n/* \nParser-Lib\nCopyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n*/\n/* Build time: 5-July-2011 03:12:40 */\n(function(){\nvar EventTarget = parserlib.util.EventTarget,\nTokenStreamBase = parserlib.util.TokenStreamBase,\nStringReader = parserlib.util.StringReader,\nSyntaxError = parserlib.util.SyntaxError,\nSyntaxUnit  = parserlib.util.SyntaxUnit;\n\nvar Colors = {\n    aliceblue       :\"#f0f8ff\",\n    antiquewhite    :\"#faebd7\",\n    aqua            :\"#00ffff\",\n    aquamarine      :\"#7fffd4\",\n    azure           :\"#f0ffff\",\n    beige           :\"#f5f5dc\",\n    bisque          :\"#ffe4c4\",\n    black           :\"#000000\",\n    blanchedalmond  :\"#ffebcd\",\n    blue            :\"#0000ff\",\n    blueviolet      :\"#8a2be2\",\n    brown           :\"#a52a2a\",\n    burlywood       :\"#deb887\",\n    cadetblue       :\"#5f9ea0\",\n    chartreuse      :\"#7fff00\",\n    chocolate       :\"#d2691e\",\n    coral           :\"#ff7f50\",\n    cornflowerblue  :\"#6495ed\",\n    cornsilk        :\"#fff8dc\",\n    crimson         :\"#dc143c\",\n    cyan            :\"#00ffff\",\n    darkblue        :\"#00008b\",\n    darkcyan        :\"#008b8b\",\n    darkgoldenrod   :\"#b8860b\",\n    darkgray        :\"#a9a9a9\",\n    darkgreen       :\"#006400\",\n    darkkhaki       :\"#bdb76b\",\n    darkmagenta     :\"#8b008b\",\n    darkolivegreen  :\"#556b2f\",\n    darkorange      :\"#ff8c00\",\n    darkorchid      :\"#9932cc\",\n    darkred         :\"#8b0000\",\n    darksalmon      :\"#e9967a\",\n    darkseagreen    :\"#8fbc8f\",\n    darkslateblue   :\"#483d8b\",\n    darkslategray   :\"#2f4f4f\",\n    darkturquoise   :\"#00ced1\",\n    darkviolet      :\"#9400d3\",\n    deeppink        :\"#ff1493\",\n    deepskyblue     :\"#00bfff\",\n    dimgray         :\"#696969\",\n    dodgerblue      :\"#1e90ff\",\n    firebrick       :\"#b22222\",\n    floralwhite     :\"#fffaf0\",\n    forestgreen     :\"#228b22\",\n    fuchsia         :\"#ff00ff\",\n    gainsboro       :\"#dcdcdc\",\n    ghostwhite      :\"#f8f8ff\",\n    gold            :\"#ffd700\",\n    goldenrod       :\"#daa520\",\n    gray            :\"#808080\",\n    green           :\"#008000\",\n    greenyellow     :\"#adff2f\",\n    honeydew        :\"#f0fff0\",\n    hotpink         :\"#ff69b4\",\n    indianred       :\"#cd5c5c\",\n    indigo          :\"#4b0082\",\n    ivory           :\"#fffff0\",\n    khaki           :\"#f0e68c\",\n    lavender        :\"#e6e6fa\",\n    lavenderblush   :\"#fff0f5\",\n    lawngreen       :\"#7cfc00\",\n    lemonchiffon    :\"#fffacd\",\n    lightblue       :\"#add8e6\",\n    lightcoral      :\"#f08080\",\n    lightcyan       :\"#e0ffff\",\n    lightgoldenrodyellow  :\"#fafad2\",\n    lightgrey       :\"#d3d3d3\",\n    lightgreen      :\"#90ee90\",\n    lightpink       :\"#ffb6c1\",\n    lightsalmon     :\"#ffa07a\",\n    lightseagreen   :\"#20b2aa\",\n    lightskyblue    :\"#87cefa\",\n    lightslategray  :\"#778899\",\n    lightsteelblue  :\"#b0c4de\",\n    lightyellow     :\"#ffffe0\",\n    lime            :\"#00ff00\",\n    limegreen       :\"#32cd32\",\n    linen           :\"#faf0e6\",\n    magenta         :\"#ff00ff\",\n    maroon          :\"#800000\",\n    mediumaquamarine:\"#66cdaa\",\n    mediumblue      :\"#0000cd\",\n    mediumorchid    :\"#ba55d3\",\n    mediumpurple    :\"#9370d8\",\n    mediumseagreen  :\"#3cb371\",\n    mediumslateblue :\"#7b68ee\",\n    mediumspringgreen   :\"#00fa9a\",\n    mediumturquoise :\"#48d1cc\",\n    mediumvioletred :\"#c71585\",\n    midnightblue    :\"#191970\",\n    mintcream       :\"#f5fffa\",\n    mistyrose       :\"#ffe4e1\",\n    moccasin        :\"#ffe4b5\",\n    navajowhite     :\"#ffdead\",\n    navy            :\"#000080\",\n    oldlace         :\"#fdf5e6\",\n    olive           :\"#808000\",\n    olivedrab       :\"#6b8e23\",\n    orange          :\"#ffa500\",\n    orangered       :\"#ff4500\",\n    orchid          :\"#da70d6\",\n    palegoldenrod   :\"#eee8aa\",\n    palegreen       :\"#98fb98\",\n    paleturquoise   :\"#afeeee\",\n    palevioletred   :\"#d87093\",\n    papayawhip      :\"#ffefd5\",\n    peachpuff       :\"#ffdab9\",\n    peru            :\"#cd853f\",\n    pink            :\"#ffc0cb\",\n    plum            :\"#dda0dd\",\n    powderblue      :\"#b0e0e6\",\n    purple          :\"#800080\",\n    red             :\"#ff0000\",\n    rosybrown       :\"#bc8f8f\",\n    royalblue       :\"#4169e1\",\n    saddlebrown     :\"#8b4513\",\n    salmon          :\"#fa8072\",\n    sandybrown      :\"#f4a460\",\n    seagreen        :\"#2e8b57\",\n    seashell        :\"#fff5ee\",\n    sienna          :\"#a0522d\",\n    silver          :\"#c0c0c0\",\n    skyblue         :\"#87ceeb\",\n    slateblue       :\"#6a5acd\",\n    slategray       :\"#708090\",\n    snow            :\"#fffafa\",\n    springgreen     :\"#00ff7f\",\n    steelblue       :\"#4682b4\",\n    tan             :\"#d2b48c\",\n    teal            :\"#008080\",\n    thistle         :\"#d8bfd8\",\n    tomato          :\"#ff6347\",\n    turquoise       :\"#40e0d0\",\n    violet          :\"#ee82ee\",\n    wheat           :\"#f5deb3\",\n    white           :\"#ffffff\",\n    whitesmoke      :\"#f5f5f5\",\n    yellow          :\"#ffff00\",\n    yellowgreen     :\"#9acd32\"\n};\n/**\n * Represents a selector combinator (whitespace, +, >).\n * @namespace parserlib.css\n * @class Combinator\n * @extends parserlib.util.SyntaxUnit\n * @constructor\n * @param {String} text The text representation of the unit. \n * @param {int} line The line of text on which the unit resides.\n * @param {int} col The column of text on which the unit resides.\n */\nfunction Combinator(text, line, col){\n    \n    SyntaxUnit.call(this, text, line, col);\n\n    /**\n     * The type of modifier.\n     * @type String\n     * @property type\n     */\n    this.type = \"unknown\";\n    \n    //pretty simple\n    if (/^\\s+$/.test(text)){\n        this.type = \"descendant\";\n    } else if (text == \">\"){\n        this.type = \"child\";\n    } else if (text == \"+\"){\n        this.type = \"adjacent-sibling\";\n    } else if (text == \"~\"){\n        this.type = \"sibling\";\n    }\n\n}\n\nCombinator.prototype = new SyntaxUnit();\nCombinator.prototype.constructor = Combinator;\n\n\nvar Level1Properties = {\n\n    \"background\": 1,\n    \"background-attachment\": 1,\n    \"background-color\": 1,\n    \"background-image\": 1,\n    \"background-position\": 1,\n    \"background-repeat\": 1,\n \n    \"border\": 1,\n    \"border-bottom\": 1,\n    \"border-bottom-width\": 1,\n    \"border-color\": 1,\n    \"border-left\": 1,\n    \"border-left-width\": 1,\n    \"border-right\": 1,\n    \"border-right-width\": 1,\n    \"border-style\": 1,\n    \"border-top\": 1,\n    \"border-top-width\": 1,\n    \"border-width\": 1,\n \n    \"clear\": 1,\n    \"color\": 1,\n    \"display\": 1,\n    \"float\": 1,\n \n    \"font\": 1,\n    \"font-family\": 1,\n    \"font-size\": 1,\n    \"font-style\": 1,\n    \"font-variant\": 1,\n    \"font-weight\": 1,\n \n    \"height\": 1,\n    \"letter-spacing\": 1,\n    \"line-height\": 1,\n \n    \"list-style\": 1,\n    \"list-style-image\": 1,\n    \"list-style-position\": 1,\n    \"list-style-type\": 1,\n \n    \"margin\": 1,\n    \"margin-bottom\": 1,\n    \"margin-left\": 1,\n    \"margin-right\": 1,\n    \"margin-top\": 1,\n \n    \"padding\": 1,\n    \"padding-bottom\": 1,\n    \"padding-left\": 1,\n    \"padding-right\": 1,\n    \"padding-top\": 1,\n \n    \"text-align\": 1,\n    \"text-decoration\": 1,\n    \"text-indent\": 1,\n    \"text-transform\": 1,\n \n    \"vertical-align\": 1,\n    \"white-space\": 1,\n    \"width\": 1,\n    \"word-spacing\": 1\n    \n};\n\nvar Level2Properties = {\n\n    //Aural\n    \"azimuth\": 1,\n    \"cue-after\": 1,\n    \"cue-before\": 1,\n    \"cue\": 1,\n    \"elevation\": 1,\n    \"pause-after\": 1,\n    \"pause-before\": 1,\n    \"pause\": 1,\n    \"pitch-range\": 1,\n    \"pitch\": 1,\n    \"play-during\": 1,\n    \"richness\": 1,\n    \"speak-header\": 1,\n    \"speak-numeral\": 1,\n    \"speak-punctuation\": 1,\n    \"speak\": 1,\n    \"speech-rate\": 1,\n    \"stress\": 1,\n    \"voice-family\": 1,\n    \"volume\": 1,\n    \n    //Paged\n    \"orphans\": 1,\n    \"page-break-after\": 1,\n    \"page-break-before\": 1,\n    \"page-break-inside\": 1,\n    \"widows\": 1,\n\n    //Interactive\n    \"cursor\": 1,\n    \"outline-color\": 1,\n    \"outline-style\": 1,\n    \"outline-width\": 1,\n    \"outline\": 1,    \n    \n    //Visual\n    \"background-attachment\": 1,\n    \"background-color\": 1,\n    \"background-image\": 1,\n    \"background-position\": 1,\n    \"background-repeat\": 1,\n    \"background\": 1,    \n    \"border-collapse\": 1,\n    \"border-color\": 1,\n    \"border-spacing\": 1,\n    \"border-style\": 1,\n    \"border-top\": 1,\n    \"border-top-color\": 1,\n    \"border-top-style\": 1,\n    \"border-top-width\": 1,\n    \"border-width\": 1,\n    \"border\": 1,\n    \"bottom\": 1,    \n    \"caption-side\": 1,\n    \"clear\": 1,\n    \"clip\": 1,\n    \"color\": 1,\n    \"content\": 1,\n    \"counter-increment\": 1,\n    \"counter-reset\": 1,\n    \"direction\": 1,\n    \"display\": 1,\n    \"empty-cells\": 1,\n    \"float\": 1,\n    \"font-family\": 1,\n    \"font-size\": 1,\n    \"font-style\": 1,\n    \"font-variant\": 1,\n    \"font-weight\": 1,\n    \"font\": 1,\n    \"height\": 1,\n    \"left\": 1,\n    \"letter-spacing\": 1,\n    \"line-height\": 1,\n    \"list-style-image\": 1,\n    \"list-style-position\": 1,\n    \"list-style-type\": 1,\n    \"list-style\": 1,\n    \"margin-right\": 1,\n    \"margin-top\": 1,\n    \"margin\": 1,\n    \"max-height\": 1,\n    \"max-width\": 1,\n    \"min-height\": 1,\n    \"min-width\": 1,\n    \"overflow\": 1,\n    \"padding-top\": 1,\n    \"padding\": 1,\n    \"position\": 1,\n    \"quotes\": 1,\n    \"right\": 1,\n    \"table-layout\": 1,\n    \"text-align\": 1,\n    \"text-decoration\": 1,\n    \"text-indent\": 1,\n    \"text-transform\": 1,\n    \"top\": 1,\n    \"unicode-bidi\": 1,\n    \"vertical-align\": 1,\n    \"visibility\": 1,\n    \"white-space\": 1,\n    \"width\": 1,\n    \"word-spacing\": 1,\n    \"z-index\": 1\n};\n/**\n * Represents a media feature, such as max-width:500.\n * @namespace parserlib.css\n * @class MediaFeature\n * @extends parserlib.util.SyntaxUnit\n * @constructor\n * @param {SyntaxUnit} name The name of the feature.\n * @param {SyntaxUnit} value The value of the feature or null if none.\n */\nfunction MediaFeature(name, value){\n    \n    SyntaxUnit.call(this, \"(\" + name + (value !== null ? \":\" + value : \"\") + \")\", name.startLine, name.startCol);\n\n    /**\n     * The name of the media feature\n     * @type String\n     * @property name\n     */\n    this.name = name;\n\n    /**\n     * The value for the feature or null if there is none.\n     * @type SyntaxUnit\n     * @property value\n     */\n    this.value = value;\n}\n\nMediaFeature.prototype = new SyntaxUnit();\nMediaFeature.prototype.constructor = MediaFeature;\n\n/**\n * Represents an individual media query.\n * @namespace parserlib.css\n * @class MediaQuery\n * @extends parserlib.util.SyntaxUnit\n * @constructor\n * @param {String} modifier The modifier \"not\" or \"only\" (or null).\n * @param {String} mediaType The type of media (i.e., \"print\").\n * @param {Array} parts Array of selectors parts making up this selector.\n * @param {int} line The line of text on which the unit resides.\n * @param {int} col The column of text on which the unit resides.\n */\nfunction MediaQuery(modifier, mediaType, features, line, col){\n    \n    SyntaxUnit.call(this, (modifier ? modifier + \" \": \"\") + (mediaType ? mediaType + \" \" : \"\") + features.join(\" and \"), line, col);\n\n    /**\n     * The media modifier (\"not\" or \"only\")\n     * @type String\n     * @property modifier\n     */\n    this.modifier = modifier;\n\n    /**\n     * The mediaType (i.e., \"print\")\n     * @type String\n     * @property mediaType\n     */\n    this.mediaType = mediaType;    \n    \n    /**\n     * The parts that make up the selector.\n     * @type Array\n     * @property features\n     */\n    this.features = features;\n\n}\n\nMediaQuery.prototype = new SyntaxUnit();\nMediaQuery.prototype.constructor = MediaQuery;\n\n/**\n * A CSS3 parser.\n * @namespace parserlib.css\n * @class Parser\n * @constructor\n * @param {Object} options (Optional) Various options for the parser:\n *      starHack (true|false) to allow IE6 star hack as valid,\n *      underscoreHack (true|false) to interpret leading underscores\n *      as IE6-7 targeting for known properties, ieFilters (true|false)\n *      to indicate that IE < 8 filters should be accepted and not throw\n *      syntax errors.\n */\nfunction Parser(options){\n\n    //inherit event functionality\n    EventTarget.call(this);\n\n\n    this.options = options || {};\n\n    this._tokenStream = null;\n}\n\nParser.prototype = function(){\n\n    var proto = new EventTarget(),  //new prototype\n        prop,\n        additions =  {\n        \n            //restore constructor\n            constructor: Parser,\n        \n            //-----------------------------------------------------------------\n            // Grammar\n            //-----------------------------------------------------------------\n        \n            _stylesheet: function(){\n            \n                /*\n                 * stylesheet\n                 *  : [ CHARSET_SYM S* STRING S* ';' ]?\n                 *    [S|CDO|CDC]* [ import [S|CDO|CDC]* ]*\n                 *    [ namespace [S|CDO|CDC]* ]*\n                 *    [ [ ruleset | media | page | font_face ] [S|CDO|CDC]* ]*\n                 *  ;\n                 */ \n               \n                var tokenStream = this._tokenStream,\n                    charset     = null,\n                    token,\n                    tt;\n                    \n                this.fire(\"startstylesheet\");\n            \n                //try to read character set\n                this._charset();\n                \n                this._skipCruft();\n\n                //try to read imports - may be more than one\n                while (tokenStream.peek() == Tokens.IMPORT_SYM){\n                    this._import();\n                    this._skipCruft();\n                }\n                \n                //try to read namespaces - may be more than one\n                while (tokenStream.peek() == Tokens.NAMESPACE_SYM){\n                    this._namespace();\n                    this._skipCruft();\n                }\n                \n                //get the next token\n                tt = tokenStream.peek();\n                \n                //try to read the rest\n                while(tt > Tokens.EOF){\n                \n                    try {\n                \n                        switch(tt){\n                            case Tokens.MEDIA_SYM:\n                                this._media();\n                                this._skipCruft();\n                                break;\n                            case Tokens.PAGE_SYM:\n                                this._page(); \n                                this._skipCruft();\n                                break;                   \n                            case Tokens.FONT_FACE_SYM:\n                                this._font_face(); \n                                this._skipCruft();\n                                break;  \n                            case Tokens.S:\n                                this._readWhitespace();\n                                break;\n                            default:                            \n                                if(!this._ruleset()){\n                                \n                                    //error handling for known issues\n                                    switch(tt){\n                                        case Tokens.CHARSET_SYM:\n                                            token = tokenStream.LT(1);\n                                            this._charset(false);\n                                            throw new SyntaxError(\"@charset not allowed here.\", token.startLine, token.startCol);\n                                        case Tokens.IMPORT_SYM:\n                                            token = tokenStream.LT(1);\n                                            this._import(false);\n                                            throw new SyntaxError(\"@import not allowed here.\", token.startLine, token.startCol);\n                                        case Tokens.NAMESPACE_SYM:\n                                            token = tokenStream.LT(1);\n                                            this._namespace(false);\n                                            throw new SyntaxError(\"@namespace not allowed here.\", token.startLine, token.startCol);\n                                        default:\n                                            tokenStream.get();  //get the last token\n                                            this._unexpectedToken(tokenStream.token());\n                                    }\n                                \n                                }\n                        }\n                    } catch(ex) {\n                        if (ex instanceof SyntaxError && !this.options.strict){\n                            this.fire({\n                                type:       \"error\",\n                                error:      ex,\n                                message:    ex.message,\n                                line:       ex.line,\n                                col:        ex.col\n                            });                     \n                        } else {\n                            throw ex;\n                        }\n                    }\n                    \n                    tt = tokenStream.peek();\n                }\n                \n                if (tt != Tokens.EOF){\n                    this._unexpectedToken(tokenStream.token());\n                }\n            \n                this.fire(\"endstylesheet\");\n            },\n            \n            _charset: function(emit){\n                var tokenStream = this._tokenStream,\n                    charset,\n                    token,\n                    line,\n                    col;\n                    \n                if (tokenStream.match(Tokens.CHARSET_SYM)){\n                    line = tokenStream.token().startLine;\n                    col = tokenStream.token().startCol;\n                \n                    this._readWhitespace();\n                    tokenStream.mustMatch(Tokens.STRING);\n                    \n                    token = tokenStream.token();\n                    charset = token.value;\n                    \n                    this._readWhitespace();\n                    tokenStream.mustMatch(Tokens.SEMICOLON);\n                    \n                    if (emit !== false){\n                        this.fire({ \n                            type:   \"charset\",\n                            charset:charset,\n                            line:   line,\n                            col:    col\n                        });\n                    }\n                }            \n            },\n            \n            _import: function(emit){\n                /*\n                 * import\n                 *   : IMPORT_SYM S*\n                 *    [STRING|URI] S* media_query_list? ';' S*\n                 */    \n            \n                var tokenStream = this._tokenStream,\n                    tt,\n                    uri,\n                    importToken,\n                    mediaList   = [];\n                \n                //read import symbol\n                tokenStream.mustMatch(Tokens.IMPORT_SYM);\n                importToken = tokenStream.token();\n                this._readWhitespace();\n                \n                tokenStream.mustMatch([Tokens.STRING, Tokens.URI]);\n                \n                //grab the URI value\n                uri = tokenStream.token().value.replace(/(?:url\\()?[\"']([^\"']+)[\"']\\)?/, \"$1\");                \n\n                this._readWhitespace();\n                \n                mediaList = this._media_query_list();\n                \n                //must end with a semicolon\n                tokenStream.mustMatch(Tokens.SEMICOLON);\n                this._readWhitespace();\n                \n                if (emit !== false){\n                    this.fire({\n                        type:   \"import\",\n                        uri:    uri,\n                        media:  mediaList,\n                        line:   importToken.startLine,\n                        col:    importToken.startCol\n                    });\n                }\n        \n            },\n            \n            _namespace: function(emit){\n                /*\n                 * namespace\n                 *   : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*\n                 */    \n            \n                var tokenStream = this._tokenStream,\n                    line,\n                    col,\n                    prefix,\n                    uri;\n                \n                //read import symbol\n                tokenStream.mustMatch(Tokens.NAMESPACE_SYM);\n                line = tokenStream.token().startLine;\n                col = tokenStream.token().startCol;\n                this._readWhitespace();\n                \n                //it's a namespace prefix - no _namespace_prefix() method because it's just an IDENT\n                if (tokenStream.match(Tokens.IDENT)){\n                    prefix = tokenStream.token().value;\n                    this._readWhitespace();\n                }\n                \n                tokenStream.mustMatch([Tokens.STRING, Tokens.URI]);\n                /*if (!tokenStream.match(Tokens.STRING)){\n                    tokenStream.mustMatch(Tokens.URI);\n                }*/\n                \n                //grab the URI value\n                uri = tokenStream.token().value.replace(/(?:url\\()?[\"']([^\"']+)[\"']\\)?/, \"$1\");                \n\n                this._readWhitespace();\n\n                //must end with a semicolon\n                tokenStream.mustMatch(Tokens.SEMICOLON);\n                this._readWhitespace();\n                \n                if (emit !== false){\n                    this.fire({\n                        type:   \"namespace\",\n                        prefix: prefix,\n                        uri:    uri,\n                        line:   line,\n                        col:    col\n                    });\n                }\n        \n            },            \n                       \n            _media: function(){\n                /*\n                 * media\n                 *   : MEDIA_SYM S* media_query_list S* '{' S* ruleset* '}' S*\n                 *   ;\n                 */\n                var tokenStream     = this._tokenStream,\n                    line,\n                    col,\n                    mediaList;//       = [];\n                \n                //look for @media\n                tokenStream.mustMatch(Tokens.MEDIA_SYM);\n                line = tokenStream.token().startLine;\n                col = tokenStream.token().startCol;\n                \n                this._readWhitespace();               \n\n                mediaList = this._media_query_list();\n\n                tokenStream.mustMatch(Tokens.LBRACE);\n                this._readWhitespace();\n                \n                this.fire({\n                    type:   \"startmedia\",\n                    media:  mediaList,\n                    line:   line,\n                    col:    col\n                });\n                \n                while(true) {\n                    if (tokenStream.peek() == Tokens.PAGE_SYM){\n                        this._page();\n                    } else if (!this._ruleset()){\n                        break;\n                    }                \n                }\n                \n                tokenStream.mustMatch(Tokens.RBRACE);\n                this._readWhitespace();\n        \n                this.fire({\n                    type:   \"endmedia\",\n                    media:  mediaList,\n                    line:   line,\n                    col:    col\n                });\n            },                           \n        \n\n            //CSS3 Media Queries\n            _media_query_list: function(){\n                /*\n                 * media_query_list\n                 *   : S* [media_query [ ',' S* media_query ]* ]?\n                 *   ;\n                 */\n                var tokenStream = this._tokenStream,\n                    mediaList   = [];\n                \n                \n                this._readWhitespace();\n                \n                if (tokenStream.peek() == Tokens.IDENT || tokenStream.peek() == Tokens.LPAREN){\n                    mediaList.push(this._media_query());\n                }\n                \n                while(tokenStream.match(Tokens.COMMA)){\n                    this._readWhitespace();\n                    mediaList.push(this._media_query());\n                }\n                \n                return mediaList;\n            },\n            \n            /*\n             * Note: \"expression\" in the grammar maps to the _media_expression\n             * method.\n             \n             */\n            _media_query: function(){\n                /*\n                 * media_query\n                 *   : [ONLY | NOT]? S* media_type S* [ AND S* expression ]*\n                 *   | expression [ AND S* expression ]*\n                 *   ;\n                 */\n                var tokenStream = this._tokenStream,\n                    type        = null,\n                    ident       = null,\n                    token       = null,\n                    expressions = [];\n                    \n                if (tokenStream.match(Tokens.IDENT)){\n                    ident = tokenStream.token().value.toLowerCase();\n                    \n                    //since there's no custom tokens for these, need to manually check\n                    if (ident != \"only\" && ident != \"not\"){\n                        tokenStream.unget();\n                        ident = null;\n                    } else {\n                        token = tokenStream.token();\n                    }\n                }\n                                \n                this._readWhitespace();\n                \n                if (tokenStream.peek() == Tokens.IDENT){\n                    type = this._media_type();\n                    if (token === null){\n                        token = tokenStream.token();\n                    }\n                } else if (tokenStream.peek() == Tokens.LPAREN){\n                    if (token === null){\n                        token = tokenStream.LT(1);\n                    }\n                    expressions.push(this._media_expression());\n                }                               \n                \n                if (type === null && expressions.length === 0){\n                    return null;\n                } else {                \n                    this._readWhitespace();\n                    while (tokenStream.match(Tokens.IDENT)){\n                        if (tokenStream.token().value.toLowerCase() != \"and\"){\n                            this._unexpectedToken(tokenStream.token());\n                        }\n                        \n                        this._readWhitespace();\n                        expressions.push(this._media_expression());\n                    }\n                }\n\n                return new MediaQuery(ident, type, expressions, token.startLine, token.startCol);\n            },\n\n            //CSS3 Media Queries\n            _media_type: function(){\n                /*\n                 * media_type\n                 *   : IDENT\n                 *   ;\n                 */\n                return this._media_feature();           \n            },\n\n            /**\n             * Note: in CSS3 Media Queries, this is called \"expression\".\n             * Renamed here to avoid conflict with CSS3 Selectors\n             * definition of \"expression\". Also note that \"expr\" in the\n             * grammar now maps to \"expression\" from CSS3 selectors.\n             * @method _media_expression\n             * @private\n             */\n            _media_expression: function(){\n                /*\n                 * expression\n                 *  : '(' S* media_feature S* [ ':' S* expr ]? ')' S*\n                 *  ;\n                 */\n                var tokenStream = this._tokenStream,\n                    feature     = null,\n                    token,\n                    expression  = null;\n                \n                tokenStream.mustMatch(Tokens.LPAREN);\n                \n                feature = this._media_feature();\n                this._readWhitespace();\n                \n                if (tokenStream.match(Tokens.COLON)){\n                    this._readWhitespace();\n                    token = tokenStream.LT(1);\n                    expression = this._expression();\n                }\n                \n                tokenStream.mustMatch(Tokens.RPAREN);\n                this._readWhitespace();\n\n                return new MediaFeature(feature, (expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null));            \n            },\n\n            //CSS3 Media Queries\n            _media_feature: function(){\n                /*\n                 * media_feature\n                 *   : IDENT\n                 *   ;\n                 */\n                var tokenStream = this._tokenStream;\n                    \n                tokenStream.mustMatch(Tokens.IDENT);\n                \n                return SyntaxUnit.fromToken(tokenStream.token());            \n            },\n            \n            //CSS3 Paged Media\n            _page: function(){\n                /*\n                 * page:\n                 *    PAGE_SYM S* IDENT? pseudo_page? S* \n                 *    '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S*\n                 *    ;\n                 */            \n                var tokenStream = this._tokenStream,\n                    line,\n                    col,\n                    identifier  = null,\n                    pseudoPage  = null;\n                \n                //look for @page\n                tokenStream.mustMatch(Tokens.PAGE_SYM);\n                line = tokenStream.token().startLine;\n                col = tokenStream.token().startCol;\n                \n                this._readWhitespace();\n                \n                if (tokenStream.match(Tokens.IDENT)){\n                    identifier = tokenStream.token().value;\n\n                    //The value 'auto' may not be used as a page name and MUST be treated as a syntax error.\n                    if (identifier.toLowerCase() === \"auto\"){\n                        this._unexpectedToken(tokenStream.token());\n                    }\n                }                \n                \n                //see if there's a colon upcoming\n                if (tokenStream.peek() == Tokens.COLON){\n                    pseudoPage = this._pseudo_page();\n                }\n            \n                this._readWhitespace();\n                \n                this.fire({\n                    type:   \"startpage\",\n                    id:     identifier,\n                    pseudo: pseudoPage,\n                    line:   line,\n                    col:    col\n                });                   \n\n                this._readDeclarations(true, true);                \n                \n                this.fire({\n                    type:   \"endpage\",\n                    id:     identifier,\n                    pseudo: pseudoPage,\n                    line:   line,\n                    col:    col\n                });             \n            \n            },\n            \n            //CSS3 Paged Media\n            _margin: function(){\n                /*\n                 * margin :\n                 *    margin_sym S* '{' declaration [ ';' S* declaration? ]* '}' S*\n                 *    ;\n                 */\n                var tokenStream = this._tokenStream,\n                    line,\n                    col,\n                    marginSym   = this._margin_sym();\n\n                if (marginSym){\n                    line = tokenStream.token().startLine;\n                    col = tokenStream.token().startCol;\n                \n                    this.fire({\n                        type: \"startpagemargin\",\n                        margin: marginSym,\n                        line:   line,\n                        col:    col\n                    });    \n                    \n                    this._readDeclarations(true);\n\n                    this.fire({\n                        type: \"endpagemargin\",\n                        margin: marginSym,\n                        line:   line,\n                        col:    col\n                    });    \n                    return true;\n                } else {\n                    return false;\n                }\n            },\n\n            //CSS3 Paged Media\n            _margin_sym: function(){\n            \n                /*\n                 * margin_sym :\n                 *    TOPLEFTCORNER_SYM | \n                 *    TOPLEFT_SYM | \n                 *    TOPCENTER_SYM | \n                 *    TOPRIGHT_SYM | \n                 *    TOPRIGHTCORNER_SYM |\n                 *    BOTTOMLEFTCORNER_SYM | \n                 *    BOTTOMLEFT_SYM | \n                 *    BOTTOMCENTER_SYM | \n                 *    BOTTOMRIGHT_SYM |\n                 *    BOTTOMRIGHTCORNER_SYM |\n                 *    LEFTTOP_SYM |\n                 *    LEFTMIDDLE_SYM |\n                 *    LEFTBOTTOM_SYM |\n                 *    RIGHTTOP_SYM |\n                 *    RIGHTMIDDLE_SYM |\n                 *    RIGHTBOTTOM_SYM \n                 *    ;\n                 */\n            \n                var tokenStream = this._tokenStream;\n            \n                if(tokenStream.match([Tokens.TOPLEFTCORNER_SYM, Tokens.TOPLEFT_SYM,\n                        Tokens.TOPCENTER_SYM, Tokens.TOPRIGHT_SYM, Tokens.TOPRIGHTCORNER_SYM,\n                        Tokens.BOTTOMLEFTCORNER_SYM, Tokens.BOTTOMLEFT_SYM, \n                        Tokens.BOTTOMCENTER_SYM, Tokens.BOTTOMRIGHT_SYM,\n                        Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_SYM, \n                        Tokens.LEFTMIDDLE_SYM, Tokens.LEFTBOTTOM_SYM, Tokens.RIGHTTOP_SYM,\n                        Tokens.RIGHTMIDDLE_SYM, Tokens.RIGHTBOTTOM_SYM]))\n                {\n                    return SyntaxUnit.fromToken(tokenStream.token());                \n                } else {\n                    return null;\n                }\n            \n            },\n            \n            _pseudo_page: function(){\n                /*\n                 * pseudo_page\n                 *   : ':' IDENT\n                 *   ;    \n                 */\n        \n                var tokenStream = this._tokenStream;\n                \n                tokenStream.mustMatch(Tokens.COLON);\n                tokenStream.mustMatch(Tokens.IDENT);\n                \n                //TODO: CSS3 Paged Media says only \"left\", \"center\", and \"right\" are allowed\n                \n                return tokenStream.token().value;\n            },\n            \n            _font_face: function(){\n                /*\n                 * font_face\n                 *   : FONT_FACE_SYM S* \n                 *     '{' S* declaration [ ';' S* declaration ]* '}' S*\n                 *   ;\n                 */     \n                var tokenStream = this._tokenStream,\n                    line,\n                    col;\n                \n                //look for @page\n                tokenStream.mustMatch(Tokens.FONT_FACE_SYM);\n                line = tokenStream.token().startLine;\n                col = tokenStream.token().startCol;\n                \n                this._readWhitespace();\n\n                this.fire({\n                    type:   \"startfontface\",\n                    line:   line,\n                    col:    col\n                });                    \n                \n                this._readDeclarations(true);\n                \n                this.fire({\n                    type:   \"endfontface\",\n                    line:   line,\n                    col:    col\n                });              \n            },\n\n            _operator: function(){\n            \n                /*\n                 * operator\n                 *  : '/' S* | ',' S* | /( empty )/\n                 *  ;\n                 */    \n                 \n                var tokenStream = this._tokenStream,\n                    token       = null;\n                \n                if (tokenStream.match([Tokens.SLASH, Tokens.COMMA])){\n                    token =  tokenStream.token();\n                    this._readWhitespace();\n                } \n                return token ? PropertyValuePart.fromToken(token) : null;\n                \n            },\n            \n            _combinator: function(){\n            \n                /*\n                 * combinator\n                 *  : PLUS S* | GREATER S* | TILDE S* | S+\n                 *  ;\n                 */    \n                 \n                var tokenStream = this._tokenStream,\n                    value       = null,\n                    token;\n                \n                if(tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])){                \n                    token = tokenStream.token();\n                    value = new Combinator(token.value, token.startLine, token.startCol);\n                    this._readWhitespace();\n                }\n                \n                return value;\n            },\n            \n            _unary_operator: function(){\n            \n                /*\n                 * unary_operator\n                 *  : '-' | '+'\n                 *  ;\n                 */\n                 \n                var tokenStream = this._tokenStream;\n                \n                if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])){\n                    return tokenStream.token().value;\n                } else {\n                    return null;\n                }         \n            },\n            \n            _property: function(){\n            \n                /*\n                 * property\n                 *   : IDENT S*\n                 *   ;        \n                 */\n                 \n                var tokenStream = this._tokenStream,\n                    value       = null,\n                    hack        = null,\n                    tokenValue,\n                    token,\n                    line,\n                    col;\n                    \n                //check for star hack - throws error if not allowed\n                if (tokenStream.peek() == Tokens.STAR && this.options.starHack){\n                    tokenStream.get();\n                    token = tokenStream.token();\n                    hack = token.value;\n                    line = token.startLine;\n                    col = token.startCol;\n                }\n                \n                if(tokenStream.match(Tokens.IDENT)){\n                    token = tokenStream.token();\n                    tokenValue = token.value;\n                    \n                    //check for underscore hack - no error if not allowed because it's valid CSS syntax\n                    if (tokenValue.charAt(0) == \"_\" && this.options.underscoreHack){\n                        hack = \"_\";\n                        tokenValue = tokenValue.substring(1);\n                    }\n                    \n                    value = new PropertyName(tokenValue, hack, (line||token.startLine), (col||token.startCol));\n                    this._readWhitespace();\n                }\n                \n                return value;\n            },\n        \n            //Augmented with CSS3 Selectors\n            _ruleset: function(){\n                /*\n                 * ruleset\n                 *   : selectors_group\n                 *     '{' S* declaration? [ ';' S* declaration? ]* '}' S*\n                 *   ;    \n                 */    \n                 \n                var tokenStream = this._tokenStream,\n                tt,\n                    selectors;\n\n\n                /*\n                 * Error Recovery: If even a single selector fails to parse,\n                 * then the entire ruleset should be thrown away.\n                 */\n                try {\n                    selectors = this._selectors_group();\n                } catch (ex){\n                    if (ex instanceof SyntaxError && !this.options.strict){\n                    \n                        //fire error event\n                        this.fire({\n                            type:       \"error\",\n                            error:      ex,\n                            message:    ex.message,\n                            line:       ex.line,\n                            col:        ex.col\n                        });                          \n                        \n                        //skip over everything until closing brace\n                        tt = tokenStream.advance([Tokens.RBRACE]);\n                        if (tt == Tokens.RBRACE){\n                            //if there's a right brace, the rule is finished so don't do anything\n                        } else {\n                            //otherwise, rethrow the error because it wasn't handled properly\n                            throw ex;\n                        }                        \n                        \n                    } else {\n                        //not a syntax error, rethrow it\n                        throw ex;\n                    }                \n                \n                    //trigger parser to continue\n                    return true;\n                }\n                \n                //if it got here, all selectors parsed\n                if (selectors){ \n                                    \n                    this.fire({\n                        type:       \"startrule\",\n                        selectors:  selectors,\n                        line:       selectors[0].line,\n                        col:        selectors[0].col\n                    });                \n                    \n                    this._readDeclarations(true);                \n                    \n                    this.fire({\n                        type:       \"endrule\",\n                        selectors:  selectors,\n                        line:       selectors[0].line,\n                        col:        selectors[0].col\n                    });  \n                    \n                }\n                \n                return selectors;\n                \n            },\n\n            //CSS3 Selectors\n            _selectors_group: function(){\n            \n                /*            \n                 * selectors_group\n                 *   : selector [ COMMA S* selector ]*\n                 *   ;\n                 */           \n                var tokenStream = this._tokenStream,\n                    selectors   = [],\n                    selector;\n                    \n                selector = this._selector();\n                if (selector !== null){\n                \n                    selectors.push(selector);\n                    while(tokenStream.match(Tokens.COMMA)){\n                        this._readWhitespace();\n                        selector = this._selector();\n                        if (selector !== null){\n                            selectors.push(selector);\n                        } else {\n                            this._unexpectedToken(tokenStream.LT(1));\n                        }\n                    }\n                }\n\n                return selectors.length ? selectors : null;\n            },\n                \n            //CSS3 Selectors\n            _selector: function(){\n                /*\n                 * selector\n                 *   : simple_selector_sequence [ combinator simple_selector_sequence ]*\n                 *   ;    \n                 */\n                 \n                var tokenStream = this._tokenStream,\n                    selector    = [],\n                    nextSelector = null,\n                    combinator  = null,\n                    ws          = null;\n                \n                //if there's no simple selector, then there's no selector\n                nextSelector = this._simple_selector_sequence();\n                if (nextSelector === null){\n                    return null;\n                }\n                \n                selector.push(nextSelector);\n                \n                do {\n                    \n                    //look for a combinator\n                    combinator = this._combinator();\n                    \n                    if (combinator !== null){\n                        selector.push(combinator);\n                        nextSelector = this._simple_selector_sequence();\n                        \n                        //there must be a next selector\n                        if (nextSelector === null){\n                            this._unexpectedToken(this.LT(1));\n                        } else {\n                        \n                            //nextSelector is an instance of SelectorPart\n                            selector.push(nextSelector);\n                        }\n                    } else {\n                        \n                        //if there's not whitespace, we're done\n                        if (this._readWhitespace()){           \n        \n                            //add whitespace separator\n                            ws = new Combinator(tokenStream.token().value, tokenStream.token().startLine, tokenStream.token().startCol);\n                            \n                            //combinator is not required\n                            combinator = this._combinator();\n                            \n                            //selector is required if there's a combinator\n                            nextSelector = this._simple_selector_sequence();\n                            if (nextSelector === null){                        \n                                if (combinator !== null){\n                                    this._unexpectedToken(tokenStream.LT(1));\n                                }\n                            } else {\n                                \n                                if (combinator !== null){\n                                    selector.push(combinator);\n                                } else {\n                                    selector.push(ws);\n                                }\n                                \n                                selector.push(nextSelector);\n                            }     \n                        } else {\n                            break;\n                        }               \n                    \n                    }\n                } while(true);\n                \n                return new Selector(selector, selector[0].line, selector[0].col);\n            },\n            \n            //CSS3 Selectors\n            _simple_selector_sequence: function(){\n                /*\n                 * simple_selector_sequence\n                 *   : [ type_selector | universal ]\n                 *     [ HASH | class | attrib | pseudo | negation ]*\n                 *   | [ HASH | class | attrib | pseudo | negation ]+\n                 *   ;\n                 */\n                 \n                var tokenStream = this._tokenStream,\n                \n                    //parts of a simple selector\n                    elementName = null,\n                    modifiers   = [],\n                    \n                    //complete selector text\n                    selectorText= \"\",\n\n                    //the different parts after the element name to search for\n                    components  = [\n                        //HASH\n                        function(){\n                            return tokenStream.match(Tokens.HASH) ?\n                                    new SelectorSubPart(tokenStream.token().value, \"id\", tokenStream.token().startLine, tokenStream.token().startCol) :\n                                    null;\n                        },\n                        this._class,\n                        this._attrib,\n                        this._pseudo,\n                        this._negation\n                    ],\n                    i           = 0,\n                    len         = components.length,\n                    component   = null,\n                    found       = false,\n                    line,\n                    col;\n                    \n                    \n                //get starting line and column for the selector\n                line = tokenStream.LT(1).startLine;\n                col = tokenStream.LT(1).startCol;\n                                        \n                elementName = this._type_selector();\n                if (!elementName){\n                    elementName = this._universal();\n                }\n                \n                if (elementName !== null){\n                    selectorText += elementName;\n                }                \n                \n                while(true){\n\n                    //whitespace means we're done\n                    if (tokenStream.peek() === Tokens.S){\n                        break;\n                    }\n                \n                    //check for each component\n                    while(i < len && component === null){\n                        component = components[i++].call(this);\n                    }\n        \n                    if (component === null){\n                    \n                        //we don't have a selector\n                        if (selectorText === \"\"){\n                            return null;\n                        } else {\n                            break;\n                        }\n                    } else {\n                        i = 0;\n                        modifiers.push(component);\n                        selectorText += component.toString(); \n                        component = null;\n                    }\n                }\n\n                 \n                return selectorText !== \"\" ?\n                        new SelectorPart(elementName, modifiers, selectorText, line, col) :\n                        null;\n            },            \n            \n            //CSS3 Selectors\n            _type_selector: function(){\n                /*\n                 * type_selector\n                 *   : [ namespace_prefix ]? element_name\n                 *   ;\n                 */\n                 \n                var tokenStream = this._tokenStream,\n                    ns          = this._namespace_prefix(),\n                    elementName = this._element_name();\n                    \n                if (!elementName){                    \n                    /*\n                     * Need to back out the namespace that was read due to both\n                     * type_selector and universal reading namespace_prefix\n                     * first. Kind of hacky, but only way I can figure out\n                     * right now how to not change the grammar.\n                     */\n                    if (ns){\n                        tokenStream.unget();\n                        if (ns.length > 1){\n                            tokenStream.unget();\n                        }\n                    }\n                \n                    return null;\n                } else {     \n                    if (ns){\n                        elementName.text = ns + elementName.text;\n                        elementName.col -= ns.length;\n                    }\n                    return elementName;\n                }\n            },\n            \n            //CSS3 Selectors\n            _class: function(){\n                /*\n                 * class\n                 *   : '.' IDENT\n                 *   ;\n                 */    \n                 \n                var tokenStream = this._tokenStream,\n                    token;\n                \n                if (tokenStream.match(Tokens.DOT)){\n                    tokenStream.mustMatch(Tokens.IDENT);    \n                    token = tokenStream.token();\n                    return new SelectorSubPart(\".\" + token.value, \"class\", token.startLine, token.startCol - 1);        \n                } else {\n                    return null;\n                }\n        \n            },\n            \n            //CSS3 Selectors\n            _element_name: function(){\n                /*\n                 * element_name\n                 *   : IDENT\n                 *   ;\n                 */    \n                \n                var tokenStream = this._tokenStream,\n                    token;\n                \n                if (tokenStream.match(Tokens.IDENT)){\n                    token = tokenStream.token();\n                    return new SelectorSubPart(token.value, \"elementName\", token.startLine, token.startCol);        \n                \n                } else {\n                    return null;\n                }\n            },\n            \n            //CSS3 Selectors\n            _namespace_prefix: function(){\n                /*            \n                 * namespace_prefix\n                 *   : [ IDENT | '*' ]? '|'\n                 *   ;\n                 */\n                var tokenStream = this._tokenStream,\n                    value       = \"\";\n                    \n                //verify that this is a namespace prefix\n                if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE){\n                        \n                    if(tokenStream.match([Tokens.IDENT, Tokens.STAR])){\n                        value += tokenStream.token().value;\n                    }\n                    \n                    tokenStream.mustMatch(Tokens.PIPE);\n                    value += \"|\";\n                    \n                }\n                \n                return value.length ? value : null;                \n            },\n            \n            //CSS3 Selectors\n            _universal: function(){\n                /*\n                 * universal\n                 *   : [ namespace_prefix ]? '*'\n                 *   ;            \n                 */\n                var tokenStream = this._tokenStream,\n                    value       = \"\",\n                    ns;\n                    \n                ns = this._namespace_prefix();\n                if(ns){\n                    value += ns;\n                }\n                \n                if(tokenStream.match(Tokens.STAR)){\n                    value += \"*\";\n                }\n                \n                return value.length ? value : null;\n                \n           },\n            \n            //CSS3 Selectors\n            _attrib: function(){\n                /*\n                 * attrib\n                 *   : '[' S* [ namespace_prefix ]? IDENT S*\n                 *         [ [ PREFIXMATCH |\n                 *             SUFFIXMATCH |\n                 *             SUBSTRINGMATCH |\n                 *             '=' |\n                 *             INCLUDES |\n                 *             DASHMATCH ] S* [ IDENT | STRING ] S*\n                 *         ]? ']'\n                 *   ;    \n                 */\n                 \n                var tokenStream = this._tokenStream,\n                    value       = null,\n                    ns,\n                    token;\n                \n                if (tokenStream.match(Tokens.LBRACKET)){\n                    token = tokenStream.token();\n                    value = token.value;\n                    value += this._readWhitespace();\n                    \n                    ns = this._namespace_prefix();\n                    \n                    if (ns){\n                        value += ns;\n                    }\n                                        \n                    tokenStream.mustMatch(Tokens.IDENT);\n                    value += tokenStream.token().value;                    \n                    value += this._readWhitespace();\n                    \n                    if(tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH,\n                            Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])){\n                    \n                        value += tokenStream.token().value;                    \n                        value += this._readWhitespace();\n                        \n                        tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]);\n                        value += tokenStream.token().value;                    \n                        value += this._readWhitespace();\n                    }\n                    \n                    tokenStream.mustMatch(Tokens.RBRACKET);\n                                        \n                    return new SelectorSubPart(value + \"]\", \"attribute\", token.startLine, token.startCol);\n                } else {\n                    return null;\n                }\n            },\n            \n            //CSS3 Selectors\n            _pseudo: function(){\n            \n                /*\n                 * pseudo\n                 *   : ':' ':'? [ IDENT | functional_pseudo ]\n                 *   ;    \n                 */   \n            \n                var tokenStream = this._tokenStream,\n                    pseudo      = null,\n                    colons      = \":\",\n                    line,\n                    col;\n                \n                if (tokenStream.match(Tokens.COLON)){\n                \n                    if (tokenStream.match(Tokens.COLON)){\n                        colons += \":\";\n                    }\n                \n                    if (tokenStream.match(Tokens.IDENT)){\n                        pseudo = tokenStream.token().value;\n                        line = tokenStream.token().startLine;\n                        col = tokenStream.token().startCol - colons.length;\n                    } else if (tokenStream.peek() == Tokens.FUNCTION){\n                        line = tokenStream.LT(1).startLine;\n                        col = tokenStream.LT(1).startCol - colons.length;\n                        pseudo = this._functional_pseudo();\n                    }\n                    \n                    if (pseudo){\n                        pseudo = new SelectorSubPart(colons + pseudo, \"pseudo\", line, col);\n                    }\n                }\n        \n                return pseudo;\n            },\n            \n            //CSS3 Selectors\n            _functional_pseudo: function(){\n                /*\n                 * functional_pseudo\n                 *   : FUNCTION S* expression ')'\n                 *   ;\n                */            \n                \n                var tokenStream = this._tokenStream,\n                    value = null;\n                \n                if(tokenStream.match(Tokens.FUNCTION)){\n                    value = tokenStream.token().value;\n                    value += this._readWhitespace();\n                    value += this._expression();\n                    tokenStream.mustMatch(Tokens.RPAREN);\n                    value += \")\";\n                }\n                \n                return value;\n            },\n            \n            //CSS3 Selectors\n            _expression: function(){\n                /*\n                 * expression\n                 *   : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+\n                 *   ;\n                 */\n                 \n                var tokenStream = this._tokenStream,\n                    value       = \"\";\n                    \n                while(tokenStream.match([Tokens.PLUS, Tokens.MINUS, Tokens.DIMENSION,\n                        Tokens.NUMBER, Tokens.STRING, Tokens.IDENT, Tokens.LENGTH,\n                        Tokens.FREQ, Tokens.EMS, Tokens.EXS, Tokens.ANGLE, Tokens.TIME,\n                        Tokens.RESOLUTION])){\n                    \n                    value += tokenStream.token().value;\n                    value += this._readWhitespace();                        \n                }\n                \n                return value.length ? value : null;\n                \n            },\n\n            //CSS3 Selectors\n            _negation: function(){\n                /*            \n                 * negation\n                 *   : NOT S* negation_arg S* ')'\n                 *   ;\n                 */\n\n                var tokenStream = this._tokenStream,\n                    line,\n                    col,\n                    value       = \"\",\n                    arg,\n                    subpart     = null;\n                    \n                if (tokenStream.match(Tokens.NOT)){\n                    value = tokenStream.token().value;\n                    line = tokenStream.token().startLine;\n                    col = tokenStream.token().startCol;\n                    value += this._readWhitespace();\n                    arg = this._negation_arg();\n                    value += arg;\n                    value += this._readWhitespace();\n                    tokenStream.match(Tokens.RPAREN);\n                    value += tokenStream.token().value;\n                    \n                    subpart = new SelectorSubPart(value, \"not\", line, col);\n                    subpart.args.push(arg);\n                }\n                \n                return subpart;\n            },\n            \n            //CSS3 Selectors\n            _negation_arg: function(){            \n                /*\n                 * negation_arg\n                 *   : type_selector | universal | HASH | class | attrib | pseudo\n                 *   ;            \n                 */           \n                 \n                var tokenStream = this._tokenStream,\n                    args        = [\n                        this._type_selector,\n                        this._universal,\n                        function(){\n                            return tokenStream.match(Tokens.HASH) ?\n                                    new SelectorSubPart(tokenStream.token().value, \"id\", tokenStream.token().startLine, tokenStream.token().startCol) :\n                                    null;                        \n                        },\n                        this._class,\n                        this._attrib,\n                        this._pseudo                    \n                    ],\n                    arg         = null,\n                    i           = 0,\n                    len         = args.length,\n                    elementName,\n                    line,\n                    col,\n                    part;\n                    \n                line = tokenStream.LT(1).startLine;\n                col = tokenStream.LT(1).startCol;\n                \n                while(i < len && arg === null){\n                    \n                    arg = args[i].call(this);\n                    i++;\n                }\n                \n                //must be a negation arg\n                if (arg === null){\n                    this._unexpectedToken(tokenStream.LT(1));\n                }\n \n                //it's an element name\n                if (arg.type == \"elementName\"){\n                    part = new SelectorPart(arg, [], arg.toString(), line, col);\n                } else {\n                    part = new SelectorPart(null, [arg], arg.toString(), line, col);\n                }\n                \n                return part;                \n            },\n            \n            _declaration: function(){\n            \n                /*\n                 * declaration\n                 *   : property ':' S* expr prio?\n                 *   | /( empty )/\n                 *   ;     \n                 */    \n            \n                var tokenStream = this._tokenStream,\n                    property    = null,\n                    expr        = null,\n                    prio        = null;\n                \n                property = this._property();\n                if (property !== null){\n\n                    tokenStream.mustMatch(Tokens.COLON);\n                    this._readWhitespace();\n                    \n                    expr = this._expr();\n                    \n                    //if there's no parts for the value, it's an error\n                    if (!expr || expr.length === 0){\n                        this._unexpectedToken(tokenStream.LT(1));\n                    }\n                    \n                    prio = this._prio();\n                    \n                    this.fire({\n                        type:       \"property\",\n                        property:   property,\n                        value:      expr,\n                        important:  prio,\n                        line:       property.line,\n                        col:        property.col\n                    });                      \n                    \n                    return true;\n                } else {\n                    return false;\n                }\n            },\n            \n            _prio: function(){\n                /*\n                 * prio\n                 *   : IMPORTANT_SYM S*\n                 *   ;    \n                 */\n                 \n                var tokenStream = this._tokenStream,\n                    result      = tokenStream.match(Tokens.IMPORTANT_SYM);\n                    \n                this._readWhitespace();\n                return result;\n            },\n            \n            _expr: function(){\n                /*\n                 * expr\n                 *   : term [ operator term ]*\n                 *   ;\n                 */\n        \n                var tokenStream = this._tokenStream,\n                    values      = [],\n\t\t\t\t\t//valueParts\t= [],\n                    value       = null,\n                    operator    = null;\n                    \n                value = this._term();\n                if (value !== null){\n                \n                    values.push(value);\n                    \n                    do {\n                        operator = this._operator();\n        \n                        //if there's an operator, keep building up the value parts\n                        if (operator){\n                            values.push(operator);\n                        } /*else {\n                            //if there's not an operator, you have a full value\n\t\t\t\t\t\t\tvalues.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col));\n\t\t\t\t\t\t\tvalueParts = [];\n\t\t\t\t\t\t}*/\n                        \n                        value = this._term();\n                        \n                        if (value === null){\n                            break;\n                        } else {\n                            values.push(value);\n                        }\n                    } while(true);\n                }\n\t\t\t\t\n\t\t\t\t//cleanup\n                /*if (valueParts.length){\n                    values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col));\n                }*/\n        \n                return values.length > 0 ? new PropertyValue(values, values[0].startLine, values[0].startCol) : null;\n            },\n            \n            _term: function(){                       \n            \n                /*\n                 * term\n                 *   : unary_operator?\n                 *     [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* |\n                 *       TIME S* | FREQ S* | function | ie_function ]\n                 *   | STRING S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor\n                 *   ;\n                 */    \n        \n                var tokenStream = this._tokenStream,\n                    unary       = null,\n                    value       = null,\n                    line,\n                    col;\n                    \n                //returns the operator or null\n                unary = this._unary_operator();\n                if (unary !== null){\n                    line = tokenStream.token().startLine;\n                    col = tokenStream.token().startCol;\n                }                \n               \n                //exception for IE filters\n                if (tokenStream.peek() == Tokens.IE_FUNCTION && this.options.ieFilters){\n                \n                    value = this._ie_function();\n                    if (unary === null){\n                        line = tokenStream.token().startLine;\n                        col = tokenStream.token().startCol;\n                    }\n                \n                //see if there's a simple match\n                } else if (tokenStream.match([Tokens.NUMBER, Tokens.PERCENTAGE, Tokens.LENGTH,\n                        Tokens.EMS, Tokens.EXS, Tokens.ANGLE, Tokens.TIME,\n                        Tokens.FREQ, Tokens.STRING, Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])){\n                 \n                    value = tokenStream.token().value;\n                    if (unary === null){\n                        line = tokenStream.token().startLine;\n                        col = tokenStream.token().startCol;\n                    }\n                    this._readWhitespace();\n                } else {\n                \n                    //see if it's a color\n                    value = this._hexcolor();\n                    if (value === null){\n                    \n                        //if there's no unary, get the start of the next token for line/col info\n                        if (unary === null){\n                            line = tokenStream.LT(1).startLine;\n                            col = tokenStream.LT(1).startCol;\n                        }                    \n                    \n                        //has to be a function\n                        if (value === null){\n                            \n                            /*\n                             * This checks for alpha(opacity=0) style of IE\n                             * functions. IE_FUNCTION only presents progid: style.\n                             */\n                            if (tokenStream.LA(3) == Tokens.EQUALS && this.options.ieFilters){\n                                value = this._ie_function();\n                            } else {\n                                value = this._function();\n                            }\n                        }\n\n                        /*if (value === null){\n                            return null;\n                            //throw new Error(\"Expected identifier at line \" + tokenStream.token().startLine + \", character \" +  tokenStream.token().startCol + \".\");\n                        }*/\n                    \n                    } else {\n                        if (unary === null){\n                            line = tokenStream.token().startLine;\n                            col = tokenStream.token().startCol;\n                        }                    \n                    }\n                \n                }                \n                \n                return value !== null ?\n                        new PropertyValuePart(unary !== null ? unary + value : value, line, col) :\n                        null;\n        \n            },\n            \n            _function: function(){\n            \n                /*\n                 * function\n                 *   : FUNCTION S* expr ')' S*\n                 *   ;\n                 */\n                 \n                var tokenStream = this._tokenStream,\n                    functionText = null,\n                    expr        = null;\n                    \n                if (tokenStream.match(Tokens.FUNCTION)){\n                    functionText = tokenStream.token().value;\n                    this._readWhitespace();\n                    expr = this._expr();\n                    \n                    tokenStream.match(Tokens.RPAREN);    \n                    functionText += expr + \")\";\n                    this._readWhitespace();\n                }                \n                \n                return functionText;\n            }, \n            \n            _ie_function: function(){\n            \n                /* (My own extension)\n                 * ie_function\n                 *   : IE_FUNCTION S* IDENT '=' term [S* ','? IDENT '=' term]+ ')' S*\n                 *   ;\n                 */\n                 \n                var tokenStream = this._tokenStream,\n                    functionText = null,\n                    expr        = null,\n                    lt;\n                    \n                //IE function can begin like a regular function, too\n                if (tokenStream.match([Tokens.IE_FUNCTION, Tokens.FUNCTION])){\n                    functionText = tokenStream.token().value;\n                    \n                    do {\n                    \n                        if (this._readWhitespace()){\n                            functionText += tokenStream.token().value;\n                        }\n                        \n                        //might be second time in the loop\n                        if (tokenStream.LA(0) == Tokens.COMMA){\n                            functionText += tokenStream.token().value;\n                        }\n                    \n                        tokenStream.match(Tokens.IDENT);\n                        functionText += tokenStream.token().value;\n                        \n                        tokenStream.match(Tokens.EQUALS);\n                        functionText += tokenStream.token().value;\n                        \n                        //functionText += this._term();\n                        lt = tokenStream.peek();\n                        while(lt != Tokens.COMMA && lt != Tokens.S && lt != Tokens.RPAREN){\n                            tokenStream.get();\n                            functionText += tokenStream.token().value;\n                            lt = tokenStream.peek();\n                        }\n                    } while(tokenStream.match([Tokens.COMMA, Tokens.S]));                    \n                    \n                    tokenStream.match(Tokens.RPAREN);    \n                    functionText += \")\";\n                    this._readWhitespace();\n                }                \n                \n                return functionText;\n            }, \n            \n            _hexcolor: function(){\n                /*\n                 * There is a constraint on the color that it must\n                 * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])\n                 * after the \"#\"; e.g., \"#000\" is OK, but \"#abcd\" is not.\n                 *\n                 * hexcolor\n                 *   : HASH S*\n                 *   ;\n                 */\n                 \n                var tokenStream = this._tokenStream,\n                    token,\n                    color = null;\n                \n                if(tokenStream.match(Tokens.HASH)){\n                \n                    //need to do some validation here\n                    \n                    token = tokenStream.token();\n                    color = token.value;\n                    if (!/#[a-f0-9]{3,6}/i.test(color)){\n                        throw new SyntaxError(\"Expected a hex color but found '\" + color + \"' at line \" + token.startLine + \", character \" + token.startCol + \".\", token.startLine, token.startCol);\n                    }\n                    this._readWhitespace();\n                }\n                \n                return color;\n            },\n            \n            //-----------------------------------------------------------------\n            // Helper methods\n            //-----------------------------------------------------------------\n            \n            /**\n             * Not part of CSS grammar, but useful for skipping over\n             * combination of white space and HTML-style comments.\n             * @return {void}\n             * @method _skipCruft\n             * @private\n             */\n            _skipCruft: function(){\n                while(this._tokenStream.match([Tokens.S, Tokens.CDO, Tokens.CDC])){\n                    //noop\n                }\n            },\n\n            /**\n             * Not part of CSS grammar, but this pattern occurs frequently\n             * in the official CSS grammar. Split out here to eliminate\n             * duplicate code.\n             * @param {Boolean} checkStart Indicates if the rule should check\n             *      for the left brace at the beginning.\n             * @param {Boolean} readMargins Indicates if the rule should check\n             *      for margin patterns.\n             * @return {void}\n             * @method _readDeclarations\n             * @private\n             */\n            _readDeclarations: function(checkStart, readMargins){\n                /*\n                 * Reads the pattern\n                 * S* '{' S* declaration [ ';' S* declaration ]* '}' S*\n                 * or\n                 * S* '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S*\n                 * Note that this is how it is described in CSS3 Paged Media, but is actually incorrect.\n                 * A semicolon is only necessary following a delcaration is there's another declaration\n                 * or margin afterwards. \n                 */\n                var tokenStream = this._tokenStream,\n                    tt;\n                       \n\n                this._readWhitespace();\n                \n                if (checkStart){\n                    tokenStream.mustMatch(Tokens.LBRACE);            \n                }\n                \n                this._readWhitespace();\n\n                try {\n                    \n                    while(true){\n                    \n                        if (readMargins && this._margin()){\n                            //noop\n                        } else if (this._declaration()){\n                            if (!tokenStream.match(Tokens.SEMICOLON)){\n                                break;\n                            }\n                        } else {\n                            break;\n                        }\n                    \n                        //if ((!this._margin() && !this._declaration()) || !tokenStream.match(Tokens.SEMICOLON)){\n                        //    break;\n                        //}\n                        this._readWhitespace();\n                    }\n                    \n                    tokenStream.mustMatch(Tokens.RBRACE);\n                    this._readWhitespace();\n                    \n                } catch (ex) {\n                    if (ex instanceof SyntaxError && !this.options.strict){\n                    \n                        //fire error event\n                        this.fire({\n                            type:       \"error\",\n                            error:      ex,\n                            message:    ex.message,\n                            line:       ex.line,\n                            col:        ex.col\n                        });                          \n                        \n                        //see if there's another declaration\n                        tt = tokenStream.advance([Tokens.SEMICOLON, Tokens.RBRACE]);\n                        if (tt == Tokens.SEMICOLON){\n                            //if there's a semicolon, then there might be another declaration\n                            this._readDeclarations(false, readMargins);\n                        } else if (tt == Tokens.RBRACE){\n                            //if there's a right brace, the rule is finished so don't do anything\n                        } else {\n                            //otherwise, rethrow the error because it wasn't handled properly\n                            throw ex;\n                        }                        \n                        \n                    } else {\n                        //not a syntax error, rethrow it\n                        throw ex;\n                    }\n                }    \n            \n            },      \n            \n            /**\n             * In some cases, you can end up with two white space tokens in a\n             * row. Instead of making a change in every function that looks for\n             * white space, this function is used to match as much white space\n             * as necessary.\n             * @method _readWhitespace\n             * @return {String} The white space if found, empty string if not.\n             * @private\n             */\n            _readWhitespace: function(){\n            \n                var tokenStream = this._tokenStream,\n                    ws = \"\";\n                    \n                while(tokenStream.match(Tokens.S)){\n                    ws += tokenStream.token().value;\n                }\n                \n                return ws;\n            },\n          \n\n            /**\n             * Throws an error when an unexpected token is found.\n             * @param {Object} token The token that was found.\n             * @method _unexpectedToken\n             * @return {void}\n             * @private\n             */\n            _unexpectedToken: function(token){\n                throw new SyntaxError(\"Unexpected token '\" + token.value + \"' at line \" + token.startLine + \", char \" + token.startCol + \".\", token.startLine, token.startCol);\n            },\n            \n            /**\n             * Helper method used for parsing subparts of a style sheet.\n             * @return {void}\n             * @method _verifyEnd\n             * @private\n             */\n            _verifyEnd: function(){\n                if (this._tokenStream.LA(1) != Tokens.EOF){\n                    this._unexpectedToken(this._tokenStream.LT(1));\n                }            \n            },\n            \n            //-----------------------------------------------------------------\n            // Parsing methods\n            //-----------------------------------------------------------------\n            \n            parse: function(input){    \n                this._tokenStream = new TokenStream(input, Tokens);\n                this._stylesheet();\n            },\n            \n            parseStyleSheet: function(input){\n                //just passthrough\n                return this.parse(input);\n            },\n            \n            parseMediaQuery: function(input){\n                this._tokenStream = new TokenStream(input, Tokens);\n                var result = this._media_query();\n                \n                //if there's anything more, then it's an invalid selector\n                this._verifyEnd();\n                \n                //otherwise return result\n                return result;            \n            },\n            \n            /**\n             * Parses a property value (everything after the semicolon).\n             * @return {parserlib.css.PropertyValue} The property value.\n             * @throws parserlib.util.SyntaxError If an unexpected token is found.\n             * @method parserPropertyValue\n             */             \n            parsePropertyValue: function(input){\n            \n                this._tokenStream = new TokenStream(input, Tokens);\n                this._readWhitespace();\n                \n                var result = this._expr();\n                \n                //okay to have a trailing white space\n                this._readWhitespace();\n                \n                //if there's anything more, then it's an invalid selector\n                this._verifyEnd();\n                \n                //otherwise return result\n                return result;\n            },\n            \n            /**\n             * Parses a complete CSS rule, including selectors and\n             * properties.\n             * @param {String} input The text to parser.\n             * @return {Boolean} True if the parse completed successfully, false if not.\n             * @method parseRule\n             */\n            parseRule: function(input){\n                this._tokenStream = new TokenStream(input, Tokens);\n                \n                //skip any leading white space\n                this._readWhitespace();\n                \n                var result = this._ruleset();\n                \n                //skip any trailing white space\n                this._readWhitespace();\n\n                //if there's anything more, then it's an invalid selector\n                this._verifyEnd();\n                \n                //otherwise return result\n                return result;            \n            },\n            \n            /**\n             * Parses a single CSS selector (no comma)\n             * @param {String} input The text to parse as a CSS selector.\n             * @return {Selector} An object representing the selector.\n             * @throws parserlib.util.SyntaxError If an unexpected token is found.\n             * @method parseSelector\n             */\n            parseSelector: function(input){\n            \n                this._tokenStream = new TokenStream(input, Tokens);\n                \n                //skip any leading white space\n                this._readWhitespace();\n                \n                var result = this._selector();\n                \n                //skip any trailing white space\n                this._readWhitespace();\n\n                //if there's anything more, then it's an invalid selector\n                this._verifyEnd();\n                \n                //otherwise return result\n                return result;\n            }\n            \n        };\n        \n    //copy over onto prototype\n    for (prop in additions){\n        proto[prop] = additions[prop];\n    }   \n    \n    return proto;\n}();\n\n\n/*\nnth\n  : S* [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? |\n         ['-'|'+']? INTEGER | {O}{D}{D} | {E}{V}{E}{N} ] S*\n  ;\n*/\n/**\n * Represents a selector combinator (whitespace, +, >).\n * @namespace parserlib.css\n * @class PropertyName\n * @extends parserlib.util.SyntaxUnit\n * @constructor\n * @param {String} text The text representation of the unit. \n * @param {String} hack The type of IE hack applied (\"*\", \"_\", or null).\n * @param {int} line The line of text on which the unit resides.\n * @param {int} col The column of text on which the unit resides.\n */\nfunction PropertyName(text, hack, line, col){\n    \n    SyntaxUnit.call(this, (hack||\"\") + text, line, col);\n\n    /**\n     * The type of IE hack applied (\"*\", \"_\", or null).\n     * @type String\n     * @property hack\n     */\n    this.hack = hack;\n\n}\n\nPropertyName.prototype = new SyntaxUnit();\nPropertyName.prototype.constructor = PropertyName;\n\n/**\n * Represents a single part of a CSS property value, meaning that it represents\n * just everything single part between \":\" and \";\". If there are multiple values\n * separated by commas, this type represents just one of the values.\n * @param {String[]} parts An array of value parts making up this value.\n * @param {int} line The line of text on which the unit resides.\n * @param {int} col The column of text on which the unit resides.\n * @namespace parserlib.css\n * @class PropertyValue\n * @extends parserlib.util.SyntaxUnit\n * @constructor\n */\nfunction PropertyValue(parts, line, col){\n\n    SyntaxUnit.call(this, parts.join(\" \"), line, col);\n    \n    /**\n     * The parts that make up the selector.\n     * @type Array\n     * @property parts\n     */\n    this.parts = parts;\n    \n}\n\nPropertyValue.prototype = new SyntaxUnit();\nPropertyValue.prototype.constructor = PropertyValue;\n\n/**\n * Represents a single part of a CSS property value, meaning that it represents\n * just one part of the data between \":\" and \";\".\n * @param {String} text The text representation of the unit.\n * @param {int} line The line of text on which the unit resides.\n * @param {int} col The column of text on which the unit resides.\n * @namespace parserlib.css\n * @class PropertyValuePart\n * @extends parserlib.util.SyntaxUnit\n * @constructor\n */\nfunction PropertyValuePart(text, line, col){\n\n    SyntaxUnit.apply(this,arguments);\n    \n    /**\n     * Indicates the type of value unit.\n     * @type String\n     * @property type\n     */\n    this.type = \"unknown\";\n\n    //figure out what type of data it is\n    \n    var temp;\n    \n    //it is a measurement?\n    if (/^([+\\-]?[\\d\\.]+)([a-z]+)$/i.test(text)){  //dimension\n        this.type = \"dimension\";\n        this.value = +RegExp.$1;\n        this.units = RegExp.$2;\n        \n        //try to narrow down\n        switch(this.units.toLowerCase()){\n        \n            case \"em\":\n            case \"rem\":\n            case \"ex\":\n            case \"px\":\n            case \"cm\":\n            case \"mm\":\n            case \"in\":\n            case \"pt\":\n            case \"pc\":\n                this.type = \"length\";\n                break;\n                \n            case \"deg\":\n            case \"rad\":\n            case \"grad\":\n                this.type = \"angle\";\n                break;\n            \n            case \"ms\":\n            case \"s\":\n                this.type = \"time\";\n                break;\n            \n            case \"hz\":\n            case \"khz\":\n                this.type = \"frequency\";\n                break;\n            \n            case \"dpi\":\n            case \"dpcm\":\n                this.type = \"resolution\";\n                break;\n                \n            //default\n                \n        }\n        \n    } else if (/^([+\\-]?[\\d\\.]+)%$/i.test(text)){  //percentage\n        this.type = \"percentage\";\n        this.value = +RegExp.$1;\n    } else if (/^([+\\-]?[\\d\\.]+)%$/i.test(text)){  //percentage\n        this.type = \"percentage\";\n        this.value = +RegExp.$1;\n    } else if (/^([+\\-]?\\d+)$/i.test(text)){  //integer\n        this.type = \"integer\";\n        this.value = +RegExp.$1;\n    } else if (/^([+\\-]?[\\d\\.]+)$/i.test(text)){  //number\n        this.type = \"number\";\n        this.value = +RegExp.$1;\n    \n    } else if (/^#([a-f0-9]{3,6})/i.test(text)){  //hexcolor\n        this.type = \"color\";\n        temp = RegExp.$1;\n        if (temp.length == 3){\n            this.red    = parseInt(temp.charAt(0)+temp.charAt(0),16);\n            this.green  = parseInt(temp.charAt(1)+temp.charAt(1),16);\n            this.blue   = parseInt(temp.charAt(2)+temp.charAt(2),16);            \n        } else {\n            this.red    = parseInt(temp.substring(0,2),16);\n            this.green  = parseInt(temp.substring(2,4),16);\n            this.blue   = parseInt(temp.substring(4,6),16);            \n        }\n    } else if (/^rgb\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)/i.test(text)){ //rgb() color with absolute numbers\n        this.type   = \"color\";\n        this.red    = +RegExp.$1;\n        this.green  = +RegExp.$2;\n        this.blue   = +RegExp.$3;\n    } else if (/^rgb\\(\\s*(\\d+)%\\s*,\\s*(\\d+)%\\s*,\\s*(\\d+)%\\s*\\)/i.test(text)){ //rgb() color with percentages\n        this.type   = \"color\";\n        this.red    = +RegExp.$1 * 255 / 100;\n        this.green  = +RegExp.$2 * 255 / 100;\n        this.blue   = +RegExp.$3 * 255 / 100;\n    } else if (/^url\\([\"']?([^\\)\"']+)[\"']?\\)/i.test(text)){ //URI\n        this.type   = \"uri\";\n        this.uri    = RegExp.$1;\n    } else if (/^[\"'][^\"']*[\"']/.test(text)){    //string\n        this.type   = \"string\";\n        this.value  = eval(text);\n    } else if (Colors[text.toLowerCase()]){  //named color\n        this.type   = \"color\";\n        temp        = Colors[text.toLowerCase()].substring(1);\n        this.red    = parseInt(temp.substring(0,2),16);\n        this.green  = parseInt(temp.substring(2,4),16);\n        this.blue   = parseInt(temp.substring(4,6),16);         \n    } else if (/^[\\,\\/]$/.test(text)){\n        this.type   = \"operator\";\n        this.value  = text;\n    } else if (/^[a-z\\-\\u0080-\\uFFFF][a-z0-9\\-\\u0080-\\uFFFF]*$/i.test(text)){\n        this.type   = \"identifier\";\n        this.value  = text;\n    }\n\n}\n\nPropertyValuePart.prototype = new SyntaxUnit();\nPropertyValuePart.prototype.constructor = PropertyValue;\n\n/**\n * Create a new syntax unit based solely on the given token.\n * Convenience method for creating a new syntax unit when\n * it represents a single token instead of multiple.\n * @param {Object} token The token object to represent.\n * @return {parserlib.css.PropertyValuePart} The object representing the token.\n * @static\n * @method fromToken\n */\nPropertyValuePart.fromToken = function(token){\n    return new PropertyValuePart(token.value, token.startLine, token.startCol);\n};\n/**\n * Represents an entire single selector, including all parts but not\n * including multiple selectors (those separated by commas).\n * @namespace parserlib.css\n * @class Selector\n * @extends parserlib.util.SyntaxUnit\n * @constructor\n * @param {Array} parts Array of selectors parts making up this selector.\n * @param {int} line The line of text on which the unit resides.\n * @param {int} col The column of text on which the unit resides.\n */\nfunction Selector(parts, line, col){\n    \n    SyntaxUnit.call(this, parts.join(\" \"), line, col);\n    \n    /**\n     * The parts that make up the selector.\n     * @type Array\n     * @property parts\n     */\n    this.parts = parts;\n\n}\n\nSelector.prototype = new SyntaxUnit();\nSelector.prototype.constructor = Selector;\n\n/**\n * Represents a single part of a selector string, meaning a single set of\n * element name and modifiers. This does not include combinators such as\n * spaces, +, >, etc.\n * @namespace parserlib.css\n * @class SelectorPart\n * @extends parserlib.util.SyntaxUnit\n * @constructor\n * @param {String} elementName The element name in the selector or null\n *      if there is no element name.\n * @param {Array} modifiers Array of individual modifiers for the element.\n *      May be empty if there are none.\n * @param {String} text The text representation of the unit. \n * @param {int} line The line of text on which the unit resides.\n * @param {int} col The column of text on which the unit resides.\n */\nfunction SelectorPart(elementName, modifiers, text, line, col){\n    \n    SyntaxUnit.call(this, text, line, col);\n\n    /**\n     * The tag name of the element to which this part\n     * of the selector affects.\n     * @type String\n     * @property elementName\n     */\n    this.elementName = elementName;\n    \n    /**\n     * The parts that come after the element name, such as class names, IDs,\n     * pseudo classes/elements, etc.\n     * @type Array\n     * @property modifiers\n     */\n    this.modifiers = modifiers;\n\n}\n\nSelectorPart.prototype = new SyntaxUnit();\nSelectorPart.prototype.constructor = SelectorPart;\n\n/**\n * Represents a selector modifier string, meaning a class name, element name,\n * element ID, pseudo rule, etc.\n * @namespace parserlib.css\n * @class SelectorSubPart\n * @extends parserlib.util.SyntaxUnit\n * @constructor\n * @param {String} text The text representation of the unit. \n * @param {String} type The type of selector modifier.\n * @param {int} line The line of text on which the unit resides.\n * @param {int} col The column of text on which the unit resides.\n */\nfunction SelectorSubPart(text, type, line, col){\n    \n    SyntaxUnit.call(this, text, line, col);\n\n    /**\n     * The type of modifier.\n     * @type String\n     * @property type\n     */\n    this.type = type;\n    \n    /**\n     * Some subparts have arguments, this represents them.\n     * @type Array\n     * @property args\n     */\n    this.args = [];\n\n}\n\nSelectorSubPart.prototype = new SyntaxUnit();\nSelectorSubPart.prototype.constructor = SelectorSubPart;\n\n\n \nvar h = /^[0-9a-fA-F]$/,\n    nonascii = /^[\\u0080-\\uFFFF]$/,\n    nl = /\\n|\\r\\n|\\r|\\f/;\n\n//-----------------------------------------------------------------------------\n// Helper functions\n//-----------------------------------------------------------------------------\n    \n \nfunction isHexDigit(c){\n    return c != null && h.test(c);\n}\n\nfunction isDigit(c){\n    return c != null && /\\d/.test(c);\n}\n\nfunction isWhitespace(c){\n    return c != null && /\\s/.test(c);\n}\n\nfunction isNewLine(c){\n    return c != null && nl.test(c);\n}\n\nfunction isNameStart(c){\n    return c != null && (/[a-z_\\u0080-\\uFFFF\\\\]/i.test(c));\n}\n\nfunction isNameChar(c){\n    return c != null && (isNameStart(c) || /[0-9\\-]/.test(c));\n}\n\nfunction isIdentStart(c){\n    return c != null && (isNameStart(c) || c == \"-\");\n}\n\nfunction mix(receiver, supplier){\n\tfor (var prop in supplier){\n\t\tif (supplier.hasOwnProperty(prop)){\n\t\t\treceiver[prop] = supplier[prop];\n\t\t}\n\t}\n\treturn receiver;\n}\n\n//-----------------------------------------------------------------------------\n// CSS Token Stream\n//-----------------------------------------------------------------------------\n\n\n/**\n * A token stream that produces CSS tokens.\n * @param {String|Reader} input The source of text to tokenize.\n * @constructor\n * @class TokenStream\n * @namespace parserlib.css\n */\nfunction TokenStream(input){\n\tTokenStreamBase.call(this, input, Tokens);\n}\n\nTokenStream.prototype = mix(new TokenStreamBase(), {\n\n    /**\n     * Overrides the TokenStreamBase method of the same name\n     * to produce CSS tokens.\n     * @param {variant} channel The name of the channel to use\n     *      for the next token.\n     * @return {Object} A token object representing the next token.\n     * @method _getToken\n     * @private\n     */\n    _getToken: function(channel){\n    \n        var c,\n            reader = this._reader,\n            token   = null,\n            startLine   = reader.getLine(),\n            startCol    = reader.getCol();\n        \n        c = reader.read();\n        \n\n        while(c){\n            switch(c){\n            \n                /*\n                 * Potential tokens:\n                 * - COMMENT\n                 * - SLASH\n                 * - CHAR\n                 */\n                case \"/\":\n\n                    if(reader.peek() == \"*\"){\n                        token = this.commentToken(c, startLine, startCol);\n                    } else {\n                        token = this.charToken(c, startLine, startCol);\n                    }\n                    break;                    \n                \n                /*\n                 * Potential tokens:\n                 * - DASHMATCH\n                 * - INCLUDES\n                 * - PREFIXMATCH\n                 * - SUFFIXMATCH\n                 * - SUBSTRINGMATCH\n                 * - CHAR\n                 */\n                case \"|\":\n                case \"~\":\n                case \"^\":\n                case \"$\":\n                case \"*\":\n                    if(reader.peek() == \"=\"){\n                        token = this.comparisonToken(c, startLine, startCol);\n                    } else {\n                        token = this.charToken(c, startLine, startCol);\n                    }\n                    break;                    \n                \n                /*\n                 * Potential tokens:\n                 * - STRING\n                 * - INVALID\n                 */\n                case \"\\\"\":\n                case \"'\":\n                    token = this.stringToken(c, startLine, startCol);                \n                    break;\n                    \n                /*\n                 * Potential tokens:\n                 * - HASH\n                 * - CHAR\n                 */\n                case \"#\":\n                    if (isNameChar(reader.peek())){\n                        token = this.hashToken(c, startLine, startCol);                        \n                    } else {\n                        token = this.charToken(c, startLine, startCol);\n                    }                \n                    break;\n                    \n                /*\n                 * Potential tokens:\n                 * - DOT\n                 * - NUMBER\n                 * - DIMENSION\n                 * - PERCENTAGE\n                 */\n                case \".\":\n                    if (isDigit(reader.peek())){\n                        token = this.numberToken(c, startLine, startCol);                        \n                    } else {\n                        token = this.charToken(c, startLine, startCol);\n                    }\n                    break;                    \n                    \n                /*\n                 * Potential tokens:\n                 * - CDC\n                 * - MINUS\n                 * - NUMBER\n                 * - DIMENSION\n                 * - PERCENTAGE\n                 */\n                case \"-\":\n                    if (reader.peek() == \"-\"){  //could be closing HTML-style comment\n                        token = this.htmlCommentEndToken(c, startLine, startCol);\n                    } else if (isNameStart(reader.peek())){\n                        token = this.identOrFunctionToken(c, startLine, startCol);\n                    } else {\n                        token = this.charToken(c, startLine, startCol);\n                    }\n                    break;\n                \n                /*\n                 * Potential tokens:\n                 * - IMPORTANT_SYM\n                 * - CHAR\n                 */\n                case \"!\":\n                    token = this.importantToken(c, startLine, startCol);\n                    break;\n                    \n                /*\n                 * Any at-keyword or CHAR\n                 */\n                case \"@\":\n                    token = this.atRuleToken(c, startLine, startCol);\n                    break;\n                    \n                /*\n                 * Potential tokens:\n                 * - NOT\n                 * - CHAR\n                 */\n                case \":\":\n                    token = this.notToken(c, startLine, startCol);\n                    break;         \n           \n                /*\n                 * Potential tokens:\n                 * - CDO\n                 * - CHAR\n                 */\n                case \"<\":\n                    token = this.htmlCommentStartToken(c, startLine, startCol);\n                    break;     \n\n                /*\n                 * Potential tokens:\n                 * - UNICODE_RANGE\n                 * - URL\n                 * - CHAR\n                 */\n                case \"U\":\n                case \"u\":\n                    if (reader.peek() == \"+\"){\n                        token = this.unicodeRangeToken(c, startLine, startCol);\n                        break;\n                    } \n                    /*falls through*/\n                    \n                default:\n                    \n                    /*\n                     * Potential tokens:\n                     * - NUMBER\n                     * - DIMENSION\n                     * - LENGTH\n                     * - FREQ\n                     * - TIME\n                     * - EMS\n                     * - EXS\n                     * - ANGLE\n                     */\n                    if (isDigit(c)){\n                        token = this.numberToken(c, startLine, startCol);\n                    } else \n                \n                    /*\n                     * Potential tokens:\n                     * - S\n                     */\n                    if (isWhitespace(c)){\n                        token = this.whitespaceToken(c, startLine, startCol);\n                    } else \n                    \n                    /*\n                     * Potential tokens:\n                     * - IDENT\n                     */                    \n                    if (isIdentStart(c)){\n                        token = this.identOrFunctionToken(c, startLine, startCol);\n                    } else \n                    \n                    /*\n                     * Potential tokens:\n                     * - CHAR\n                     * - PLUS\n                     */\n                    {\n                        token = this.charToken(c, startLine, startCol);                    \n                    }\n        \n        \n        \n        \n        \n        \n            }\n            \n            //make sure this token is wanted\n            //TODO: check channel\n            break;\n            \n            c = reader.read();\n        }\n        \n        if (!token && c == null){\n            token = this.createToken(Tokens.EOF,null,startLine,startCol);\n        }\n        \n        return token;\n    },\n    \n    //-------------------------------------------------------------------------\n    // Methods to create tokens\n    //-------------------------------------------------------------------------\n    \n    /**\n     * Produces a token based on available data and the current\n     * reader position information. This method is called by other\n     * private methods to create tokens and is never called directly.\n     * @param {int} tt The token type.\n     * @param {String} value The text value of the token.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @param {Object} options (Optional) Specifies a channel property\n     *      to indicate that a different channel should be scanned\n     *      and/or a hide property indicating that the token should\n     *      be hidden.\n     * @return {Object} A token object.\n     * @method createToken\n     */    \n    createToken: function(tt, value, startLine, startCol, options){\n        var reader = this._reader;\n        options = options || {};\n        \n        return {\n            value:      value,\n            type:       tt,\n            channel:    options.channel,\n            hide:       options.hide || false,\n            startLine:  startLine,\n            startCol:   startCol,\n            endLine:    reader.getLine(),\n            endCol:     reader.getCol()            \n        };    \n    }, \n    \n    //-------------------------------------------------------------------------\n    // Methods to create specific tokens\n    //-------------------------------------------------------------------------    \n    \n    /**\n     * Produces a token for any at-rule. If the at-rule is unknown, then\n     * the token is for a single \"@\" character.\n     * @param {String} first The first character for the token.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @return {Object} A token object.\n     * @method atRuleToken\n     */    \n    atRuleToken: function(first, startLine, startCol){\n        var rule    = first,\n            reader  = this._reader,\n            tt      = Tokens.CHAR,\n            valid   = false,\n            ident,\n            c;            \n                    \n        /*\n         * First, mark where we are. There are only four @ rules,\n         * so anything else is really just an invalid token.\n         * Basically, if this doesn't match one of the known @\n         * rules, just return '@' as an unknown token and allow\n         * parsing to continue after that point.\n         */\n        reader.mark();\n        \n        //try to find the at-keyword        \n        ident = this.readName();\n        rule = first + ident;\n        tt = Tokens.type(rule.toLowerCase());\n        \n        //if it's not valid, use the first character only and reset the reader\n        if (tt == Tokens.CHAR || tt == Tokens.UNKNOWN){\n            tt = Tokens.CHAR;\n            rule = first;\n            reader.reset();\n        }            \n            \n        return this.createToken(tt, rule, startLine, startCol);        \n    },         \n    \n    /**\n     * Produces a character token based on the given character\n     * and location in the stream. If there's a special (non-standard)\n     * token name, this is used; otherwise CHAR is used.\n     * @param {String} c The character for the token.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @return {Object} A token object.\n     * @method charToken\n     */\n    charToken: function(c, startLine, startCol){\n        var tt = Tokens.type(c);\n\n        if (tt == -1){\n            tt = Tokens.CHAR;\n        }\n        \n        return this.createToken(tt, c, startLine, startCol);\n    },    \n    \n    /**\n     * Produces a character token based on the given character\n     * and location in the stream. If there's a special (non-standard)\n     * token name, this is used; otherwise CHAR is used.\n     * @param {String} first The first character for the token.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @return {Object} A token object.\n     * @method commentToken\n     */    \n    commentToken: function(first, startLine, startCol){\n        var reader  = this._reader,\n            comment = this.readComment(first);\n\n        return this.createToken(Tokens.COMMENT, comment, startLine, startCol);    \n    },    \n    \n    /**\n     * Produces a comparison token based on the given character\n     * and location in the stream. The next character must be\n     * read and is already known to be an equals sign.\n     * @param {String} c The character for the token.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @return {Object} A token object.\n     * @method comparisonToken\n     */\n    comparisonToken: function(c, startLine, startCol){\n        var reader  = this._reader,\n            comparison  = c + reader.read(),\n            tt      = Tokens.type(comparison) || Tokens.CHAR;\n            \n        return this.createToken(tt, comparison, startLine, startCol);\n    },\n    \n    /**\n     * Produces a hash token based on the specified information. The\n     * first character provided is the pound sign (#) and then this\n     * method reads a name afterward.\n     * @param {String} first The first character (#) in the hash name.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @return {Object} A token object.\n     * @method hashToken\n     */\n    hashToken: function(first, startLine, startCol){\n        var reader  = this._reader,\n            name    = this.readName(first);\n\n        return this.createToken(Tokens.HASH, name, startLine, startCol);    \n    },\n    \n    /**\n     * Produces a CDO or CHAR token based on the specified information. The\n     * first character is provided and the rest is read by the function to determine\n     * the correct token to create.\n     * @param {String} first The first character in the token.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @return {Object} A token object.\n     * @method htmlCommentStartToken\n     */      \n    htmlCommentStartToken: function(first, startLine, startCol){\n        var reader      = this._reader,\n            text        = first;\n\n        reader.mark();        \n        text += reader.readCount(3);\n            \n        if (text == \"<!--\"){\n            return this.createToken(Tokens.CDO, text, startLine, startCol);\n        } else {\n            reader.reset();\n            return this.charToken(first, startLine, startCol);\n        }        \n    },    \n    \n    /**\n     * Produces a CDC or CHAR token based on the specified information. The\n     * first character is provided and the rest is read by the function to determine\n     * the correct token to create.\n     * @param {String} first The first character in the token.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @return {Object} A token object.\n     * @method htmlCommentEndToken\n     */      \n    htmlCommentEndToken: function(first, startLine, startCol){\n        var reader      = this._reader,\n            text        = first;\n\n        reader.mark();        \n        text += reader.readCount(2);\n            \n        if (text == \"-->\"){\n            return this.createToken(Tokens.CDC, text, startLine, startCol);\n        } else {\n            reader.reset();\n            return this.charToken(first, startLine, startCol);\n        }        \n    },    \n    \n    /**\n     * Produces an IDENT or FUNCTION token based on the specified information. The\n     * first character is provided and the rest is read by the function to determine\n     * the correct token to create.\n     * @param {String} first The first character in the identifier.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @return {Object} A token object.\n     * @method identOrFunctionToken\n     */    \n    identOrFunctionToken: function(first, startLine, startCol){\n        var reader  = this._reader,\n            ident   = this.readName(first),\n            tt      = Tokens.IDENT;\n\n        //if there's a left paren immediately after, it's a URI or function\n        if (reader.peek() == \"(\"){\n            ident += reader.read();\n            if (ident.toLowerCase() == \"url(\"){\n                tt = Tokens.URI;\n                ident = this.readURI(ident);\n                \n                //didn't find a valid URL or there's no closing paren\n                if (ident.toLowerCase() == \"url(\"){\n                    tt = Tokens.FUNCTION;\n                }\n            } else {\n                tt = Tokens.FUNCTION;\n            }\n        } else if (reader.peek() == \":\"){  //might be an IE function\n            \n            //IE-specific functions always being with progid:\n            if (ident.toLowerCase() == \"progid\"){\n                ident += reader.readTo(\"(\");\n                tt = Tokens.IE_FUNCTION;\n            }\n        }\n\n        return this.createToken(tt, ident, startLine, startCol);    \n    },\n    \n    /**\n     * Produces an IMPORTANT_SYM or CHAR token based on the specified information. The\n     * first character is provided and the rest is read by the function to determine\n     * the correct token to create.\n     * @param {String} first The first character in the token.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @return {Object} A token object.\n     * @method importantToken\n     */      \n    importantToken: function(first, startLine, startCol){\n        var reader      = this._reader,\n            important   = first,\n            tt          = Tokens.CHAR,\n            temp,\n            c;\n\n        reader.mark();\n        c = reader.read();\n            \n        while(c){\n        \n            //there can be a comment in here\n            if (c == \"/\"){\n            \n                //if the next character isn't a star, then this isn't a valid !important token\n                if (reader.peek() != \"*\"){\n                    break;\n                } else {\n                    temp = this.readComment(c);\n                    if (temp == \"\"){    //broken!\n                        break;\n                    }\n                }\n            } else if (isWhitespace(c)){\n                important += c + this.readWhitespace();\n            } else if (/i/i.test(c)){\n                temp = reader.readCount(8);\n                if (/mportant/i.test(temp)){\n                    important += c + temp;\n                    tt = Tokens.IMPORTANT_SYM;\n                    \n                }\n                break;  //we're done\n            } else {\n                break;\n            }\n        \n            c = reader.read();\n        }\n        \n        if (tt == Tokens.CHAR){\n            reader.reset();\n            return this.charToken(first, startLine, startCol);\n        } else {\n            return this.createToken(tt, important, startLine, startCol);\n        }\n        \n        \n    },\n\n    /**\n     * Produces a NOT or CHAR token based on the specified information. The\n     * first character is provided and the rest is read by the function to determine\n     * the correct token to create.\n     * @param {String} first The first character in the token.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @return {Object} A token object.\n     * @method notToken\n     */      \n    notToken: function(first, startLine, startCol){\n        var reader      = this._reader,\n            text        = first;\n\n        reader.mark();        \n        text += reader.readCount(4);\n            \n        if (text.toLowerCase() == \":not(\"){\n            return this.createToken(Tokens.NOT, text, startLine, startCol);\n        } else {\n            reader.reset();\n            return this.charToken(first, startLine, startCol);\n        }\n    },\n\n    /**\n     * Produces a number token based on the given character\n     * and location in the stream. This may return a token of\n     * NUMBER, EMS, EXS, LENGTH, ANGLE, TIME, FREQ, DIMENSION,\n     * or PERCENTAGE.\n     * @param {String} first The first character for the token.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @return {Object} A token object.\n     * @method numberToken\n     */    \n    numberToken: function(first, startLine, startCol){\n        var reader  = this._reader,\n            value   = this.readNumber(first),\n            ident,\n            tt      = Tokens.NUMBER,\n            c       = reader.peek();\n            \n        if (isIdentStart(c)){\n            ident = this.readName(reader.read());\n            value += ident;            \n\n            if (/em|ex|px|gd|rem|vw|vh|vm|ch|cm|mm|in|pt|pc/i.test(ident)){\n                tt = Tokens.LENGTH;\n            } else if (/deg|rad|grad/i.test(ident)){\n                tt = Tokens.ANGLE;\n            } else if (/ms|s/i.test(ident)){\n                tt = Tokens.TIME;\n            } else if (/hz|khz/i.test(ident)){\n                tt = Tokens.FREQ;\n            } else if (/dpi|dpcm/i.test(ident)){\n                tt = Tokens.RESOLUTION;\n            } else {\n                tt = Tokens.DIMENSION;\n            }\n\n        } else if (c == \"%\"){\n            value += reader.read();\n            tt = Tokens.PERCENTAGE;\n        }\n            \n        return this.createToken(tt, value, startLine, startCol);            \n    },    \n    \n    /**\n     * Produces a string token based on the given character\n     * and location in the stream. Since strings may be indicated\n     * by single or double quotes, a failure to match starting\n     * and ending quotes results in an INVALID token being generated.\n     * The first character in the string is passed in and then\n     * the rest are read up to and including the final quotation mark.\n     * @param {String} first The first character in the string.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @return {Object} A token object.\n     * @method stringToken\n     */    \n    stringToken: function(first, startLine, startCol){\n        var delim   = first,\n            string  = first,\n            reader  = this._reader,\n            prev    = first,\n            tt      = Tokens.STRING,\n            c       = reader.read();\n            \n        while(c){\n            string += c;\n            \n            //if the delimiter is found with an escapement, we're done.\n            if (c == delim && prev != \"\\\\\"){\n                break;\n            }\n\n            //if there's a newline without an escapement, it's an invalid string\n            if (isNewLine(reader.peek()) && c != \"\\\\\"){\n                tt = Tokens.INVALID;\n                break;\n            }\n        \n            //save previous and get next\n            prev = c;\n            c = reader.read();\n        }\n        \n        //if c is null, that means we're out of input and the string was never closed\n        if (c == null){\n            tt = Tokens.INVALID;\n        }\n            \n        return this.createToken(tt, string, startLine, startCol);        \n    },    \n    \n    unicodeRangeToken: function(first, startLine, startCol){\n        var reader  = this._reader,\n            value   = first,\n            temp,\n            tt      = Tokens.CHAR;\n         \n        //then it should be a unicode range\n        if (reader.peek() == \"+\"){\n            reader.mark();\n            value += reader.read();\n            value += this.readUnicodeRangePart(true);\n            \n            //ensure there's an actual unicode range here\n            if (value.length == 2){\n                reader.reset();\n            } else {\n                \n                tt = Tokens.UNICODE_RANGE;\n            \n                //if there's a ? in the first part, there can't be a second part\n                if (value.indexOf(\"?\") == -1){\n                            \n                    if (reader.peek() == \"-\"){\n                        reader.mark();\n                        temp = reader.read();\n                        temp += this.readUnicodeRangePart(false);\n                        \n                        //if there's not another value, back up and just take the first\n                        if (temp.length == 1){\n                            reader.reset();\n                        } else {\n                            value += temp;\n                        }\n                    }\n\n                }\n            }\n        }\n    \n        return this.createToken(tt, value, startLine, startCol);\n    },\n    \n    /**\n     * Produces a S token based on the specified information. Since whitespace\n     * may have multiple characters, this consumes all whitespace characters\n     * into a single token.\n     * @param {String} first The first character in the token.\n     * @param {int} startLine The beginning line for the character.\n     * @param {int} startCol The beginning column for the character.\n     * @return {Object} A token object.\n     * @method whitespaceToken\n     */          \n    whitespaceToken: function(first, startLine, startCol){\n        var reader  = this._reader,\n            value   = first + this.readWhitespace();\n        return this.createToken(Tokens.S, value, startLine, startCol);            \n    },    \n   \n\n\n\n    //-------------------------------------------------------------------------\n    // Methods to read values from the string stream\n    //-------------------------------------------------------------------------\n    \n    readUnicodeRangePart: function(allowQuestionMark){\n        var reader  = this._reader,\n            part = \"\",            \n            c       = reader.peek();\n        \n        //first read hex digits\n        while(isHexDigit(c) && part.length < 6){\n            reader.read();\n            part += c;\n            c = reader.peek();            \n        }\n        \n        //then read question marks if allowed\n        if (allowQuestionMark){\n            while(c == \"?\" && part.length < 6){\n                reader.read();\n                part += c;\n                c = reader.peek();            \n            }\n        }\n\n        //there can't be any other characters after this point\n        \n        return part;    \n    },\n    \n    readWhitespace: function(){\n        var reader  = this._reader,\n            whitespace = \"\",\n            c       = reader.peek();\n        \n        while(isWhitespace(c)){\n            reader.read();\n            whitespace += c;\n            c = reader.peek();            \n        }\n        \n        return whitespace;\n    },\n    readNumber: function(first){\n        var reader  = this._reader,\n            number  = first,\n            hasDot  = (first == \".\"),\n            c       = reader.peek();\n        \n\n        while(c){\n            if (isDigit(c)){\n                number += reader.read();\n            } else if (c == \".\"){\n                if (hasDot){\n                    break;\n                } else {\n                    hasDot = true;\n                    number += reader.read();\n                }\n            } else {\n                break;\n            }\n            \n            c = reader.peek();\n        }        \n        \n        return number;\n    },\n    readString: function(){\n        var reader  = this._reader,\n            delim   = reader.read(),\n            string  = delim,            \n            prev    = delim,\n            c       = reader.peek();\n            \n        while(c){\n            c = reader.read();\n            string += c;\n            \n            //if the delimiter is found with an escapement, we're done.\n            if (c == delim && prev != \"\\\\\"){\n                break;\n            }\n\n            //if there's a newline without an escapement, it's an invalid string\n            if (isNewLine(reader.peek()) && c != \"\\\\\"){\n                string = \"\";\n                break;\n            }\n        \n            //save previous and get next\n            prev = c;\n            c = reader.peek();\n        }\n        \n        //if c is null, that means we're out of input and the string was never closed\n        if (c == null){\n            string = \"\";\n        }\n                \n        return string;\n    },\n    readURI: function(first){\n        var reader  = this._reader,\n            uri     = first,\n            inner   = \"\",\n            c       = reader.peek();\n            \n        reader.mark();\n        \n        //skip whitespace before\n        while(c && isWhitespace(c)){\n            reader.read();\n            c = reader.peek();\n        }\n            \n        //it's a string\n        if (c == \"'\" || c == \"\\\"\"){\n            inner = this.readString();\n        } else {\n            inner = this.readURL();\n        }\n        \n        c = reader.peek();\n\n        //skip whitespace after\n        while(c && isWhitespace(c)){\n            reader.read();\n            c = reader.peek();\n        }\n            \n        //if there was no inner value or the next character isn't closing paren, it's not a URI\n        if (inner == \"\" || c != \")\"){\n            uri = first;\n            reader.reset();\n        } else {\n            uri += inner + reader.read();\n        }\n                \n        return uri;\n    },\n    readURL: function(){\n        var reader  = this._reader,\n            url     = \"\",\n            c       = reader.peek();\n    \n        //TODO: Check for escape and nonascii\n        while (/^[!#$%&\\\\*-~]$/.test(c)){\n            url += reader.read();\n            c = reader.peek();\n        }\n    \n        return url;\n    \n    },\n    readName: function(first){\n        var reader  = this._reader,\n            ident   = first || \"\",\n            c       = reader.peek();\n        \n\n        while(c && isNameChar(c)){\n            ident += reader.read();\n            c = reader.peek();\n        }\n        \n        return ident;\n    },    \n    readComment: function(first){\n        var reader  = this._reader,\n            comment = first || \"\",\n            c       = reader.read();\n        \n        if (c == \"*\"){\n            while(c){\n                comment += c;\n                \n                //look for end of comment\n                if (c == \"*\" && reader.peek() == \"/\"){\n                    comment += reader.read();\n                    break;\n                }\n                \n                c = reader.read();\n            }\n            \n            return comment;\n        } else {\n            return \"\";\n        }\n    \n    },\n    \n\n\n\n});\n\nvar Tokens  = [\n\n    /*\n     * The following token names are defined in CSS3 Grammar: http://www.w3.org/TR/css3-syntax/#lexical\n     */\n     \n    //HTML-style comments\n    { name: \"CDO\"},\n    { name: \"CDC\"},\n\n    //ignorables\n    { name: \"S\", whitespace: true/*, channel: \"ws\"*/},\n    { name: \"COMMENT\", comment: true, hide: true, channel: \"comment\" },\n        \n    //attribute equality\n    { name: \"INCLUDES\", text: \"~=\"},\n    { name: \"DASHMATCH\", text: \"|=\"},\n    { name: \"PREFIXMATCH\", text: \"^=\"},\n    { name: \"SUFFIXMATCH\", text: \"$=\"},\n    { name: \"SUBSTRINGMATCH\", text: \"*=\"},\n        \n    //identifier types\n    { name: \"STRING\"},     \n    { name: \"IDENT\"},\n    { name: \"HASH\"},\n\n    //at-keywords\n    { name: \"IMPORT_SYM\", text: \"@import\"},\n    { name: \"PAGE_SYM\", text: \"@page\"},\n    { name: \"MEDIA_SYM\", text: \"@media\"},\n    { name: \"FONT_FACE_SYM\", text: \"@font-face\"},\n    { name: \"CHARSET_SYM\", text: \"@charset\"},\n    { name: \"NAMESPACE_SYM\", text: \"@namespace\"},\n    //{ name: \"ATKEYWORD\"},\n\n    //important symbol\n    { name: \"IMPORTANT_SYM\"},\n\n    //measurements\n    { name: \"EMS\"},\n    { name: \"EXS\"},\n    { name: \"LENGTH\"},\n    { name: \"ANGLE\"},\n    { name: \"TIME\"},\n    { name: \"FREQ\"},\n    { name: \"DIMENSION\"},\n    { name: \"PERCENTAGE\"},\n    { name: \"NUMBER\"},\n    \n    //functions\n    { name: \"URI\"},\n    { name: \"FUNCTION\"},\n    \n    //Unicode ranges\n    { name: \"UNICODE_RANGE\"},\n    \n    /*\n     * The following token names are defined in CSS3 Selectors: http://www.w3.org/TR/css3-selectors/#selector-syntax\n     */    \n    \n    //invalid string\n    { name: \"INVALID\"},\n    \n    //combinators\n    { name: \"PLUS\", text: \"+\" },\n    { name: \"GREATER\", text: \">\"},\n    { name: \"COMMA\", text: \",\"},\n    { name: \"TILDE\", text: \"~\"},\n    \n    //modifier\n    { name: \"NOT\"},        \n    \n    /*\n     * Defined in CSS3 Paged Media\n     */\n    { name: \"TOPLEFTCORNER_SYM\", text: \"@top-left-corner\"},\n    { name: \"TOPLEFT_SYM\", text: \"@top-left\"},\n    { name: \"TOPCENTER_SYM\", text: \"@top-center\"},\n    { name: \"TOPRIGHT_SYM\", text: \"@top-right\"},\n    { name: \"TOPRIGHTCORNER_SYM\", text: \"@top-right-corner\"},\n    { name: \"BOTTOMLEFTCORNER_SYM\", text: \"@bottom-left-corner\"},\n    { name: \"BOTTOMLEFT_SYM\", text: \"@bottom-left\"},\n    { name: \"BOTTOMCENTER_SYM\", text: \"@bottom-center\"},\n    { name: \"BOTTOMRIGHT_SYM\", text: \"@bottom-right\"},\n    { name: \"BOTTOMRIGHTCORNER_SYM\", text: \"@bottom-right-corner\"},\n    { name: \"LEFTTOP_SYM\", text: \"@left-top\"},\n    { name: \"LEFTMIDDLE_SYM\", text: \"@left-middle\"},\n    { name: \"LEFTBOTTOM_SYM\", text: \"@left-bottom\"},\n    { name: \"RIGHTTOP_SYM\", text: \"@right-top\"},\n    { name: \"RIGHTMIDDLE_SYM\", text: \"@right-middle\"},\n    { name: \"RIGHTBOTTOM_SYM\", text: \"@right-bottom\"},\n\n    /*\n     * The following token names are defined in CSS3 Media Queries: http://www.w3.org/TR/css3-mediaqueries/#syntax\n     */\n    /*{ name: \"MEDIA_ONLY\", state: \"media\"},\n    { name: \"MEDIA_NOT\", state: \"media\"},\n    { name: \"MEDIA_AND\", state: \"media\"},*/\n    { name: \"RESOLUTION\", state: \"media\"},\n\n    /*\n     * The following token names are not defined in any CSS specification but are used by the lexer.\n     */\n    \n    //not a real token, but useful for stupid IE filters\n    { name: \"IE_FUNCTION\" },\n\n    //part of CSS3 grammar but not the Flex code\n    { name: \"CHAR\" },\n    \n    //TODO: Needed?\n    //Not defined as tokens, but might as well be\n    {\n        name: \"PIPE\",\n        text: \"|\"\n    },\n    {\n        name: \"SLASH\",\n        text: \"/\"\n    },\n    {\n        name: \"MINUS\",\n        text: \"-\"\n    },\n    {\n        name: \"STAR\",\n        text: \"*\"\n    },\n\n    {\n        name: \"LBRACE\",\n        text: \"{\"\n    },   \n    {\n        name: \"RBRACE\",\n        text: \"}\"\n    },      \n    {\n        name: \"LBRACKET\",\n        text: \"[\"\n    },   \n    {\n        name: \"RBRACKET\",\n        text: \"]\"\n    },    \n    {\n        name: \"EQUALS\",\n        text: \"=\"\n    },\n    {\n        name: \"COLON\",\n        text: \":\"\n    },    \n    {\n        name: \"SEMICOLON\",\n        text: \";\"\n    },    \n \n    {\n        name: \"LPAREN\",\n        text: \"(\"\n    },   \n    {\n        name: \"RPAREN\",\n        text: \")\"\n    },     \n    {\n        name: \"DOT\",\n        text: \".\"\n    }\n];\n\n(function(){\n\n    var nameMap = [],\n        typeMap = {};\n    \n    Tokens.UNKNOWN = -1;\n    Tokens.unshift({name:\"EOF\"});\n    for (var i=0, len = Tokens.length; i < len; i++){\n        nameMap.push(Tokens[i].name);\n        Tokens[Tokens[i].name] = i;\n        if (Tokens[i].text){\n            typeMap[Tokens[i].text] = i;\n        }\n    }\n    \n    Tokens.name = function(tt){\n        return nameMap[tt];\n    };\n    \n    Tokens.type = function(c){\n        return typeMap[c] || -1;\n    };\n\n})();\n\n\n\n\nparserlib.css = {\nColors              :Colors,    \nCombinator          :Combinator,                \nParser              :Parser,\nPropertyName        :PropertyName,\nPropertyValue       :PropertyValue,\nPropertyValuePart   :PropertyValuePart,\nMediaFeature        :MediaFeature,\nMediaQuery          :MediaQuery,\nSelector            :Selector,\nSelectorPart        :SelectorPart,\nSelectorSubPart     :SelectorSubPart,\nTokenStream         :TokenStream,\nTokens              :Tokens\n};\n})();\n/**\n * YUI Test Framework\n * @module yuitest\n */\n\n/**\n * The root namespace for YUI Test.\n * @class YUITest\n * @static\n */\n\nvar YUITest = {\n    version: \"@VERSION@\"\n};\n\n\n/**\n * Simple custom event implementation.\n * @namespace YUITest\n * @class EventTarget\n * @constructor\n */\nYUITest.EventTarget = function(){\n\n    /**\n     * Event handlers for the various events.\n     * @type Object\n     * @private\n     * @property _handlers\n     * @static\n     */\n    this._handlers = {};\n\n};\n\nYUITest.EventTarget.prototype = {\n\n    //restore prototype\n    constructor: YUITest.EventTarget,\n\n    //-------------------------------------------------------------------------\n    // Event Handling\n    //-------------------------------------------------------------------------\n\n    /**\n     * Adds a listener for a given event type.\n     * @param {String} type The type of event to add a listener for.\n     * @param {Function} listener The function to call when the event occurs.\n     * @return {void}\n     * @method attach\n     */\n    attach: function(type, listener){\n        if (typeof this._handlers[type] == \"undefined\"){\n            this._handlers[type] = [];\n        }\n\n        this._handlers[type].push(listener);\n    },\n\n    /**\n     * Adds a listener for a given event type.\n     * @param {String} type The type of event to add a listener for.\n     * @param {Function} listener The function to call when the event occurs.\n     * @return {void}\n     * @method subscribe\n     * @deprecated\n     */\n    subscribe: function(type, listener){\n        this.attach.apply(this, arguments);\n    },\n\n    /**\n     * Fires an event based on the passed-in object.\n     * @param {Object|String} event An object with at least a 'type' attribute\n     *      or a string indicating the event name.\n     * @return {void}\n     * @method fire\n     */\n    fire: function(event){\n        if (typeof event == \"string\"){\n            event = { type: event };\n        }\n        if (!event.target){\n            event.target = this;\n        }\n\n        if (!event.type){\n            throw new Error(\"Event object missing 'type' property.\");\n        }\n\n        if (this._handlers[event.type] instanceof Array){\n            var handlers = this._handlers[event.type];\n            for (var i=0, len=handlers.length; i < len; i++){\n                handlers[i].call(this, event);\n            }\n        }\n    },\n\n    /**\n     * Removes a listener for a given event type.\n     * @param {String} type The type of event to remove a listener from.\n     * @param {Function} listener The function to remove from the event.\n     * @return {void}\n     * @method detach\n     */\n    detach: function(type, listener){\n        if (this._handlers[type] instanceof Array){\n            var handlers = this._handlers[type];\n            for (var i=0, len=handlers.length; i < len; i++){\n                if (handlers[i] === listener){\n                    handlers.splice(i, 1);\n                    break;\n                }\n            }\n        }\n    },\n\n    /**\n     * Removes a listener for a given event type.\n     * @param {String} type The type of event to remove a listener from.\n     * @param {Function} listener The function to remove from the event.\n     * @return {void}\n     * @method unsubscribe\n     * @deprecated\n     */\n    unsubscribe: function(type, listener){\n        this.detach.apply(this, arguments);\n    }\n\n};\n\n\n/**\n * Object containing helper methods.\n * @namespace YUITest\n * @class Util\n * @static\n */\nYUITest.Util = {\n\n    /**\n     * Mixes the own properties from the supplier onto the\n     * receiver.\n     * @param {Object} receiver The object to receive the properties.\n     * @param {Object} supplier The object to supply the properties.\n     * @return {Object} The receiver that was passed in.\n     * @method mix\n     * @static\n     */\n    mix: function(receiver, supplier){\n\n        for (var prop in supplier){\n            if (supplier.hasOwnProperty(prop)){\n                receiver[prop] = supplier[prop];\n            }\n        }\n\n        return receiver;\n    },\n\n    /**\n     * Stub for JSON functionality. When the native JSON utility\n     * is available, it will be used. Otherwise, a stub object\n     * is created. Developers should override YUITest.Util.JSON\n     * when attempting to use it in environments where a native\n     * JSON utility is unavailable.\n     * @property JSON\n     * @type JSON\n     * @static\n     */\n    JSON: typeof JSON != \"undefined\" ? JSON : {\n        stringify: function(){\n            //TODO: Should include code to do this?\n            throw new Error(\"No JSON utility specified.\");\n        }\n    }\n\n};\n\n\n/**\n * Error is thrown whenever an assertion fails. It provides methods\n * to more easily get at error information and also provides a base class\n * from which more specific assertion errors can be derived.\n *\n * @param {String} message The message to display when the error occurs.\n * @namespace YUITest\n * @class AssertionError\n * @constructor\n */\nYUITest.AssertionError = function (message){\n\n    /**\n     * Error message. Must be duplicated to ensure browser receives it.\n     * @type String\n     * @property message\n     */\n    this.message = message;\n\n    /**\n     * The name of the error that occurred.\n     * @type String\n     * @property name\n     */\n    this.name = \"Assert Error\";\n};\n\nYUITest.AssertionError.prototype = {\n\n    //restore constructor\n    constructor: YUITest.AssertionError,\n\n    /**\n     * Returns a fully formatted error for an assertion failure. This should\n     * be overridden by all subclasses to provide specific information.\n     * @method getMessage\n     * @return {String} A string describing the error.\n     */\n    getMessage : function () {\n        return this.message;\n    },\n\n    /**\n     * Returns a string representation of the error.\n     * @method toString\n     * @return {String} A string representation of the error.\n     */\n    toString : function () {\n        return this.name + \": \" + this.getMessage();\n    }\n\n};\n\n/**\n * ComparisonFailure is subclass of Error that is thrown whenever\n * a comparison between two values fails. It provides mechanisms to retrieve\n * both the expected and actual value.\n *\n * @param {String} message The message to display when the error occurs.\n * @param {Object} expected The expected value.\n * @param {Object} actual The actual value that caused the assertion to fail.\n * @namespace YUITest\n * @extends AssertionError\n * @class ComparisonFailure\n * @constructor\n */\nYUITest.ComparisonFailure = function (message, expected, actual){\n\n    //call superclass\n    YUITest.AssertionError.call(this, message);\n\n    /**\n     * The expected value.\n     * @type Object\n     * @property expected\n     */\n    this.expected = expected;\n\n    /**\n     * The actual value.\n     * @type Object\n     * @property actual\n     */\n    this.actual = actual;\n\n    /**\n     * The name of the error that occurred.\n     * @type String\n     * @property name\n     */\n    this.name = \"ComparisonFailure\";\n\n};\n\n//inherit from YUITest.AssertionError\nYUITest.ComparisonFailure.prototype = new YUITest.AssertionError;\n\n//restore constructor\nYUITest.ComparisonFailure.prototype.constructor = YUITest.ComparisonFailure;\n\n/**\n * Returns a fully formatted error for an assertion failure. This message\n * provides information about the expected and actual values.\n * @method getMessage\n * @return {String} A string describing the error.\n */\nYUITest.ComparisonFailure.prototype.getMessage = function(){\n    return this.message + \"\\nExpected: \" + this.expected + \" (\" + (typeof this.expected) + \")\"  +\n            \"\\nActual: \" + this.actual + \" (\" + (typeof this.actual) + \")\";\n};\n\n/**\n * ShouldError is subclass of Error that is thrown whenever\n * a test is expected to throw an error but doesn't.\n *\n * @param {String} message The message to display when the error occurs.\n * @namespace YUITest\n * @extends AssertionError\n * @class ShouldError\n * @constructor\n */\nYUITest.ShouldError = function (message){\n\n    //call superclass\n    YUITest.AssertionError.call(this, message || \"This test should have thrown an error but didn't.\");\n\n    /**\n     * The name of the error that occurred.\n     * @type String\n     * @property name\n     */\n    this.name = \"ShouldError\";\n\n};\n\n//inherit from YUITest.AssertionError\nYUITest.ShouldError.prototype = new YUITest.AssertionError();\n\n//restore constructor\nYUITest.ShouldError.prototype.constructor = YUITest.ShouldError;\n\n/**\n * ShouldFail is subclass of AssertionError that is thrown whenever\n * a test was expected to fail but did not.\n *\n * @param {String} message The message to display when the error occurs.\n * @namespace YUITest\n * @extends YUITest.AssertionError\n * @class ShouldFail\n * @constructor\n */\nYUITest.ShouldFail = function (message){\n\n    //call superclass\n    YUITest.AssertionError.call(this, message || \"This test should fail but didn't.\");\n\n    /**\n     * The name of the error that occurred.\n     * @type String\n     * @property name\n     */\n    this.name = \"ShouldFail\";\n\n};\n\n//inherit from YUITest.AssertionError\nYUITest.ShouldFail.prototype = new YUITest.AssertionError();\n\n//restore constructor\nYUITest.ShouldFail.prototype.constructor = YUITest.ShouldFail;\n\n/**\n * UnexpectedError is subclass of AssertionError that is thrown whenever\n * an error occurs within the course of a test and the test was not expected\n * to throw an error.\n *\n * @param {Error} cause The unexpected error that caused this error to be\n *                      thrown.\n * @namespace YUITest\n * @extends YUITest.AssertionError\n * @class UnexpectedError\n * @constructor\n */\nYUITest.UnexpectedError = function (cause){\n\n    //call superclass\n    YUITest.AssertionError.call(this, \"Unexpected error: \" + cause.message);\n\n    /**\n     * The unexpected error that occurred.\n     * @type Error\n     * @property cause\n     */\n    this.cause = cause;\n\n    /**\n     * The name of the error that occurred.\n     * @type String\n     * @property name\n     */\n    this.name = \"UnexpectedError\";\n\n    /**\n     * Stack information for the error (if provided).\n     * @type String\n     * @property stack\n     */\n    this.stack = cause.stack;\n\n};\n\n//inherit from YUITest.AssertionError\nYUITest.UnexpectedError.prototype = new YUITest.AssertionError();\n\n//restore constructor\nYUITest.UnexpectedError.prototype.constructor = YUITest.UnexpectedError;\n\n/**\n * UnexpectedValue is subclass of Error that is thrown whenever\n * a value was unexpected in its scope. This typically means that a test\n * was performed to determine that a value was *not* equal to a certain\n * value.\n *\n * @param {String} message The message to display when the error occurs.\n * @param {Object} unexpected The unexpected value.\n * @namespace YUITest\n * @extends AssertionError\n * @class UnexpectedValue\n * @constructor\n */\nYUITest.UnexpectedValue = function (message, unexpected){\n\n    //call superclass\n    YUITest.AssertionError.call(this, message);\n\n    /**\n     * The unexpected value.\n     * @type Object\n     * @property unexpected\n     */\n    this.unexpected = unexpected;\n\n    /**\n     * The name of the error that occurred.\n     * @type String\n     * @property name\n     */\n    this.name = \"UnexpectedValue\";\n\n};\n\n//inherit from YUITest.AssertionError\nYUITest.UnexpectedValue.prototype = new YUITest.AssertionError();\n\n//restore constructor\nYUITest.UnexpectedValue.prototype.constructor = YUITest.UnexpectedValue;\n\n/**\n * Returns a fully formatted error for an assertion failure. This message\n * provides information about the expected and actual values.\n * @method getMessage\n * @return {String} A string describing the error.\n */\nYUITest.UnexpectedValue.prototype.getMessage = function(){\n    return this.message + \"\\nUnexpected: \" + this.unexpected + \" (\" + (typeof this.unexpected) + \") \";\n};\n\n\n/**\n * Represents a stoppage in test execution to wait for an amount of time before\n * continuing.\n * @param {Function} segment A function to run when the wait is over.\n * @param {int} delay The number of milliseconds to wait before running the code.\n * @class Wait\n * @namespace Test\n * @constructor\n *\n */\nYUITest.Wait = function (segment, delay) {\n\n    /**\n     * The segment of code to run when the wait is over.\n     * @type Function\n     * @property segment\n     */\n    this.segment = (typeof segment == \"function\" ? segment : null);\n\n    /**\n     * The delay before running the segment of code.\n     * @type int\n     * @property delay\n     */\n    this.delay = (typeof delay == \"number\" ? delay : 0);\n};\n\n\n/**\n * The Assert object provides functions to test JavaScript values against\n * known and expected results. Whenever a comparison (assertion) fails,\n * an error is thrown.\n * @namespace YUITest\n * @class Assert\n * @static\n */\nYUITest.Assert = {\n\n    /**\n     * The number of assertions performed.\n     * @property _asserts\n     * @type int\n     * @private\n     */\n    _asserts: 0,\n\n    //-------------------------------------------------------------------------\n    // Helper Methods\n    //-------------------------------------------------------------------------\n\n    /**\n     * Formats a message so that it can contain the original assertion message\n     * in addition to the custom message.\n     * @param {String} customMessage The message passed in by the developer.\n     * @param {String} defaultMessage The message created by the error by default.\n     * @return {String} The final error message, containing either or both.\n     * @protected\n     * @static\n     * @method _formatMessage\n     */\n    _formatMessage : function (customMessage, defaultMessage) {\n        if (typeof customMessage == \"string\" && customMessage.length > 0){\n            return customMessage.replace(\"{message}\", defaultMessage);\n        } else {\n            return defaultMessage;\n        }\n    },\n\n    /**\n     * Returns the number of assertions that have been performed.\n     * @method _getCount\n     * @protected\n     * @static\n     */\n    _getCount: function(){\n        return this._asserts;\n    },\n\n    /**\n     * Increments the number of assertions that have been performed.\n     * @method _increment\n     * @protected\n     * @static\n     */\n    _increment: function(){\n        this._asserts++;\n    },\n\n    /**\n     * Resets the number of assertions that have been performed to 0.\n     * @method _reset\n     * @protected\n     * @static\n     */\n    _reset: function(){\n        this._asserts = 0;\n    },\n\n    //-------------------------------------------------------------------------\n    // Generic Assertion Methods\n    //-------------------------------------------------------------------------\n\n    /**\n     * Forces an assertion error to occur.\n     * @param {String} message (Optional) The message to display with the failure.\n     * @method fail\n     * @static\n     */\n    fail : function (message) {\n        throw new YUITest.AssertionError(YUITest.Assert._formatMessage(message, \"Test force-failed.\"));\n    },\n\n    //-------------------------------------------------------------------------\n    // Equality Assertion Methods\n    //-------------------------------------------------------------------------\n\n    /**\n     * Asserts that a value is equal to another. This uses the double equals sign\n     * so type cohersion may occur.\n     * @param {Object} expected The expected value.\n     * @param {Object} actual The actual value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method areEqual\n     * @static\n     */\n    areEqual : function (expected, actual, message) {\n        YUITest.Assert._increment();\n        if (expected != actual) {\n            throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(message, \"Values should be equal.\"), expected, actual);\n        }\n    },\n\n    /**\n     * Asserts that a value is not equal to another. This uses the double equals sign\n     * so type cohersion may occur.\n     * @param {Object} unexpected The unexpected value.\n     * @param {Object} actual The actual value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method areNotEqual\n     * @static\n     */\n    areNotEqual : function (unexpected, actual,\n                         message) {\n        YUITest.Assert._increment();\n        if (unexpected == actual) {\n            throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(message, \"Values should not be equal.\"), unexpected);\n        }\n    },\n\n    /**\n     * Asserts that a value is not the same as another. This uses the triple equals sign\n     * so no type cohersion may occur.\n     * @param {Object} unexpected The unexpected value.\n     * @param {Object} actual The actual value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method areNotSame\n     * @static\n     */\n    areNotSame : function (unexpected, actual, message) {\n        YUITest.Assert._increment();\n        if (unexpected === actual) {\n            throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(message, \"Values should not be the same.\"), unexpected);\n        }\n    },\n\n    /**\n     * Asserts that a value is the same as another. This uses the triple equals sign\n     * so no type cohersion may occur.\n     * @param {Object} expected The expected value.\n     * @param {Object} actual The actual value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method areSame\n     * @static\n     */\n    areSame : function (expected, actual, message) {\n        YUITest.Assert._increment();\n        if (expected !== actual) {\n            throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(message, \"Values should be the same.\"), expected, actual);\n        }\n    },\n\n    //-------------------------------------------------------------------------\n    // Boolean Assertion Methods\n    //-------------------------------------------------------------------------\n\n    /**\n     * Asserts that a value is false. This uses the triple equals sign\n     * so no type cohersion may occur.\n     * @param {Object} actual The actual value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isFalse\n     * @static\n     */\n    isFalse : function (actual, message) {\n        YUITest.Assert._increment();\n        if (false !== actual) {\n            throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(message, \"Value should be false.\"), false, actual);\n        }\n    },\n\n    /**\n     * Asserts that a value is true. This uses the triple equals sign\n     * so no type cohersion may occur.\n     * @param {Object} actual The actual value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isTrue\n     * @static\n     */\n    isTrue : function (actual, message) {\n        YUITest.Assert._increment();\n        if (true !== actual) {\n            throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(message, \"Value should be true.\"), true, actual);\n        }\n\n    },\n\n    //-------------------------------------------------------------------------\n    // Special Value Assertion Methods\n    //-------------------------------------------------------------------------\n\n    /**\n     * Asserts that a value is not a number.\n     * @param {Object} actual The value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isNaN\n     * @static\n     */\n    isNaN : function (actual, message){\n        YUITest.Assert._increment();\n        if (!isNaN(actual)){\n            throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(message, \"Value should be NaN.\"), NaN, actual);\n        }\n    },\n\n    /**\n     * Asserts that a value is not the special NaN value.\n     * @param {Object} actual The value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isNotNaN\n     * @static\n     */\n    isNotNaN : function (actual, message){\n        YUITest.Assert._increment();\n        if (isNaN(actual)){\n            throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(message, \"Values should not be NaN.\"), NaN);\n        }\n    },\n\n    /**\n     * Asserts that a value is not null. This uses the triple equals sign\n     * so no type cohersion may occur.\n     * @param {Object} actual The actual value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isNotNull\n     * @static\n     */\n    isNotNull : function (actual, message) {\n        YUITest.Assert._increment();\n        if (actual === null) {\n            throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(message, \"Values should not be null.\"), null);\n        }\n    },\n\n    /**\n     * Asserts that a value is not undefined. This uses the triple equals sign\n     * so no type cohersion may occur.\n     * @param {Object} actual The actual value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isNotUndefined\n     * @static\n     */\n    isNotUndefined : function (actual, message) {\n        YUITest.Assert._increment();\n        if (typeof actual == \"undefined\") {\n            throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(message, \"Value should not be undefined.\"), undefined);\n        }\n    },\n\n    /**\n     * Asserts that a value is null. This uses the triple equals sign\n     * so no type cohersion may occur.\n     * @param {Object} actual The actual value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isNull\n     * @static\n     */\n    isNull : function (actual, message) {\n        YUITest.Assert._increment();\n        if (actual !== null) {\n            throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(message, \"Value should be null.\"), null, actual);\n        }\n    },\n\n    /**\n     * Asserts that a value is undefined. This uses the triple equals sign\n     * so no type cohersion may occur.\n     * @param {Object} actual The actual value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isUndefined\n     * @static\n     */\n    isUndefined : function (actual, message) {\n        YUITest.Assert._increment();\n        if (typeof actual != \"undefined\") {\n            throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(message, \"Value should be undefined.\"), undefined, actual);\n        }\n    },\n\n    //--------------------------------------------------------------------------\n    // Instance Assertion Methods\n    //--------------------------------------------------------------------------\n\n    /**\n     * Asserts that a value is an array.\n     * @param {Object} actual The value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isArray\n     * @static\n     */\n    isArray : function (actual, message) {\n        YUITest.Assert._increment();\n        var shouldFail = false;\n        if (Array.isArray){\n            shouldFail = !Array.isArray(actual);\n        } else {\n            shouldFail = Object.prototype.toString.call(actual) != \"[object Array]\";\n        }\n        if (shouldFail){\n            throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(message, \"Value should be an array.\"), actual);\n        }\n    },\n\n    /**\n     * Asserts that a value is a Boolean.\n     * @param {Object} actual The value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isBoolean\n     * @static\n     */\n    isBoolean : function (actual, message) {\n        YUITest.Assert._increment();\n        if (typeof actual != \"boolean\"){\n            throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(message, \"Value should be a Boolean.\"), actual);\n        }\n    },\n\n    /**\n     * Asserts that a value is a function.\n     * @param {Object} actual The value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isFunction\n     * @static\n     */\n    isFunction : function (actual, message) {\n        YUITest.Assert._increment();\n        if (!(actual instanceof Function)){\n            throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(message, \"Value should be a function.\"), actual);\n        }\n    },\n\n    /**\n     * Asserts that a value is an instance of a particular object. This may return\n     * incorrect results when comparing objects from one frame to constructors in\n     * another frame. For best results, don't use in a cross-frame manner.\n     * @param {Function} expected The function that the object should be an instance of.\n     * @param {Object} actual The object to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isInstanceOf\n     * @static\n     */\n    isInstanceOf : function (expected, actual, message) {\n        YUITest.Assert._increment();\n        if (!(actual instanceof expected)){\n            throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(message, \"Value isn't an instance of expected type.\"), expected, actual);\n        }\n    },\n\n    /**\n     * Asserts that a value is a number.\n     * @param {Object} actual The value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isNumber\n     * @static\n     */\n    isNumber : function (actual, message) {\n        YUITest.Assert._increment();\n        if (typeof actual != \"number\"){\n            throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(message, \"Value should be a number.\"), actual);\n        }\n    },\n\n    /**\n     * Asserts that a value is an object.\n     * @param {Object} actual The value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isObject\n     * @static\n     */\n    isObject : function (actual, message) {\n        YUITest.Assert._increment();\n        if (!actual || (typeof actual != \"object\" && typeof actual != \"function\")){\n            throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(message, \"Value should be an object.\"), actual);\n        }\n    },\n\n    /**\n     * Asserts that a value is a string.\n     * @param {Object} actual The value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isString\n     * @static\n     */\n    isString : function (actual, message) {\n        YUITest.Assert._increment();\n        if (typeof actual != \"string\"){\n            throw new YUITest.UnexpectedValue(YUITest.Assert._formatMessage(message, \"Value should be a string.\"), actual);\n        }\n    },\n\n    /**\n     * Asserts that a value is of a particular type.\n     * @param {String} expectedType The expected type of the variable.\n     * @param {Object} actualValue The actual value to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isTypeOf\n     * @static\n     */\n    isTypeOf : function (expectedType, actualValue, message){\n        YUITest.Assert._increment();\n        if (typeof actualValue != expectedType){\n            throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(message, \"Value should be of type \" + expectedType + \".\"), expectedType, typeof actualValue);\n        }\n    },\n\n    //--------------------------------------------------------------------------\n    // Error Detection Methods\n    //--------------------------------------------------------------------------\n\n    /**\n     * Asserts that executing a particular method should throw an error of\n     * a specific type. This is a replacement for _should.error.\n     * @param {String|Function|Object} expectedError If a string, this\n     *      is the error message that the error must have; if a function, this\n     *      is the constructor that should have been used to create the thrown\n     *      error; if an object, this is an instance of a particular error type\n     *      with a specific error message (both must match).\n     * @param {Function} method The method to execute that should throw the error.\n     * @param {String} message (Optional) The message to display if the assertion\n     *      fails.\n     * @method throwsError\n     * @return {void}\n     * @static\n     */\n    throwsError: function(expectedError, method, message){\n        YUITest.Assert._increment();\n        var error = false;\n\n        try {\n            method();\n        } catch (thrown) {\n\n            //check to see what type of data we have\n            if (typeof expectedError == \"string\"){\n\n                //if it's a string, check the error message\n                if (thrown.message != expectedError){\n                    error = true;\n                }\n            } else if (typeof expectedError == \"function\"){\n\n                //if it's a function, see if the error is an instance of it\n                if (!(thrown instanceof expectedError)){\n                    error = true;\n                }\n\n            } else if (typeof expectedError == \"object\" && expectedError !== null){\n\n                //if it's an object, check the instance and message\n                if (!(thrown instanceof expectedError.constructor) ||\n                        thrown.message != expectedError.message){\n                    error = true;\n                }\n\n            } else { //if it gets here, the argument could be wrong\n                error = true;\n            }\n\n            if (error){\n                throw new YUITest.UnexpectedError(thrown);\n            } else {\n                return;\n            }\n        }\n\n        //if it reaches here, the error wasn't thrown, which is a bad thing\n        throw new YUITest.AssertionError(YUITest.Assert._formatMessage(message, \"Error should have been thrown.\"));\n    }\n\n};\n\n\n/**\n * The ArrayAssert object provides functions to test JavaScript array objects\n * for a variety of cases.\n * @namespace YUITest\n * @class ArrayAssert\n * @static\n */\n\nYUITest.ArrayAssert = {\n\n    //=========================================================================\n    // Private methods\n    //=========================================================================\n\n    /**\n     * Simple indexOf() implementation for an array. Defers to native\n     * if available.\n     * @param {Array} haystack The array to search.\n     * @param {Variant} needle The value to locate.\n     * @return {int} The index of the needle if found or -1 if not.\n     * @method _indexOf\n     * @private\n     */\n    _indexOf: function(haystack, needle){\n        if (haystack.indexOf){\n            return haystack.indexOf(needle);\n        } else {\n            for (var i=0; i < haystack.length; i++){\n                if (haystack[i] === needle){\n                    return i;\n                }\n            }\n            return -1;\n        }\n    },\n\n    /**\n     * Simple some() implementation for an array. Defers to native\n     * if available.\n     * @param {Array} haystack The array to search.\n     * @param {Function} matcher The function to run on each value.\n     * @return {Boolean} True if any value, when run through the matcher,\n     *      returns true.\n     * @method _some\n     * @private\n     */\n    _some: function(haystack, matcher){\n        if (haystack.some){\n            return haystack.some(matcher);\n        } else {\n            for (var i=0; i < haystack.length; i++){\n                if (matcher(haystack[i])){\n                    return true;\n                }\n            }\n            return false;\n        }\n    },\n\n    /**\n     * Asserts that a value is present in an array. This uses the triple equals\n     * sign so no type cohersion may occur.\n     * @param {Object} needle The value that is expected in the array.\n     * @param {Array} haystack An array of values.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method contains\n     * @static\n     */\n    contains : function (needle, haystack,\n                           message) {\n\n        YUITest.Assert._increment();\n\n        if (this._indexOf(haystack, needle) == -1){\n            YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Value \" + needle + \" (\" + (typeof needle) + \") not found in array [\" + haystack + \"].\"));\n        }\n    },\n\n    /**\n     * Asserts that a set of values are present in an array. This uses the triple equals\n     * sign so no type cohersion may occur. For this assertion to pass, all values must\n     * be found.\n     * @param {Object[]} needles An array of values that are expected in the array.\n     * @param {Array} haystack An array of values to check.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method containsItems\n     * @static\n     */\n    containsItems : function (needles, haystack,\n                           message) {\n        YUITest.Assert._increment();\n\n        //begin checking values\n        for (var i=0; i < needles.length; i++){\n            if (this._indexOf(haystack, needles[i]) == -1){\n                YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Value \" + needles[i] + \" (\" + (typeof needles[i]) + \") not found in array [\" + haystack + \"].\"));\n            }\n        }\n    },\n\n    /**\n     * Asserts that a value matching some condition is present in an array. This uses\n     * a function to determine a match.\n     * @param {Function} matcher A function that returns true if the items matches or false if not.\n     * @param {Array} haystack An array of values.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method containsMatch\n     * @static\n     */\n    containsMatch : function (matcher, haystack,\n                           message) {\n\n        YUITest.Assert._increment();\n        //check for valid matcher\n        if (typeof matcher != \"function\"){\n            throw new TypeError(\"ArrayAssert.containsMatch(): First argument must be a function.\");\n        }\n\n        if (!this._some(haystack, matcher)){\n            YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"No match found in array [\" + haystack + \"].\"));\n        }\n    },\n\n    /**\n     * Asserts that a value is not present in an array. This uses the triple equals\n     * Asserts that a value is not present in an array. This uses the triple equals\n     * sign so no type cohersion may occur.\n     * @param {Object} needle The value that is expected in the array.\n     * @param {Array} haystack An array of values.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method doesNotContain\n     * @static\n     */\n    doesNotContain : function (needle, haystack,\n                           message) {\n\n        YUITest.Assert._increment();\n\n        if (this._indexOf(haystack, needle) > -1){\n            YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Value found in array [\" + haystack + \"].\"));\n        }\n    },\n\n    /**\n     * Asserts that a set of values are not present in an array. This uses the triple equals\n     * sign so no type cohersion may occur. For this assertion to pass, all values must\n     * not be found.\n     * @param {Object[]} needles An array of values that are not expected in the array.\n     * @param {Array} haystack An array of values to check.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method doesNotContainItems\n     * @static\n     */\n    doesNotContainItems : function (needles, haystack,\n                           message) {\n\n        YUITest.Assert._increment();\n\n        for (var i=0; i < needles.length; i++){\n            if (this._indexOf(haystack, needles[i]) > -1){\n                YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Value found in array [\" + haystack + \"].\"));\n            }\n        }\n\n    },\n\n    /**\n     * Asserts that no values matching a condition are present in an array. This uses\n     * a function to determine a match.\n     * @param {Function} matcher A function that returns true if the item matches or false if not.\n     * @param {Array} haystack An array of values.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method doesNotContainMatch\n     * @static\n     */\n    doesNotContainMatch : function (matcher, haystack,\n                           message) {\n\n        YUITest.Assert._increment();\n\n        //check for valid matcher\n        if (typeof matcher != \"function\"){\n            throw new TypeError(\"ArrayAssert.doesNotContainMatch(): First argument must be a function.\");\n        }\n\n        if (this._some(haystack, matcher)){\n            YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Value found in array [\" + haystack + \"].\"));\n        }\n    },\n\n    /**\n     * Asserts that the given value is contained in an array at the specified index.\n     * This uses the triple equals sign so no type cohersion will occur.\n     * @param {Object} needle The value to look for.\n     * @param {Array} haystack The array to search in.\n     * @param {int} index The index at which the value should exist.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method indexOf\n     * @static\n     */\n    indexOf : function (needle, haystack, index, message) {\n\n        YUITest.Assert._increment();\n\n        //try to find the value in the array\n        for (var i=0; i < haystack.length; i++){\n            if (haystack[i] === needle){\n                if (index != i){\n                    YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Value exists at index \" + i + \" but should be at index \" + index + \".\"));\n                }\n                return;\n            }\n        }\n\n        //if it makes it here, it wasn't found at all\n        YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Value doesn't exist in array [\" + haystack + \"].\"));\n    },\n\n    /**\n     * Asserts that the values in an array are equal, and in the same position,\n     * as values in another array. This uses the double equals sign\n     * so type cohersion may occur. Note that the array objects themselves\n     * need not be the same for this test to pass.\n     * @param {Array} expected An array of the expected values.\n     * @param {Array} actual Any array of the actual values.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method itemsAreEqual\n     * @static\n     */\n    itemsAreEqual : function (expected, actual,\n                           message) {\n\n        YUITest.Assert._increment();\n\n        //first check array length\n        if (expected.length != actual.length){\n            YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Array should have a length of \" + expected.length + \" but has a length of \" + actual.length));\n        }\n\n        //begin checking values\n        for (var i=0; i < expected.length; i++){\n            if (expected[i] != actual[i]){\n                throw new YUITest.Assert.ComparisonFailure(YUITest.Assert._formatMessage(message, \"Values in position \" + i + \" are not equal.\"), expected[i], actual[i]);\n            }\n        }\n    },\n\n    /**\n     * Asserts that the values in an array are equivalent, and in the same position,\n     * as values in another array. This uses a function to determine if the values\n     * are equivalent. Note that the array objects themselves\n     * need not be the same for this test to pass.\n     * @param {Array} expected An array of the expected values.\n     * @param {Array} actual Any array of the actual values.\n     * @param {Function} comparator A function that returns true if the values are equivalent\n     *      or false if not.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @return {Void}\n     * @method itemsAreEquivalent\n     * @static\n     */\n    itemsAreEquivalent : function (expected, actual,\n                           comparator, message) {\n\n        YUITest.Assert._increment();\n\n        //make sure the comparator is valid\n        if (typeof comparator != \"function\"){\n            throw new TypeError(\"ArrayAssert.itemsAreEquivalent(): Third argument must be a function.\");\n        }\n\n        //first check array length\n        if (expected.length != actual.length){\n            YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Array should have a length of \" + expected.length + \" but has a length of \" + actual.length));\n        }\n\n        //begin checking values\n        for (var i=0; i < expected.length; i++){\n            if (!comparator(expected[i], actual[i])){\n                throw new YUITest.Assert.ComparisonFailure(YUITest.Assert._formatMessage(message, \"Values in position \" + i + \" are not equivalent.\"), expected[i], actual[i]);\n            }\n        }\n    },\n\n    /**\n     * Asserts that an array is empty.\n     * @param {Array} actual The array to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isEmpty\n     * @static\n     */\n    isEmpty : function (actual, message) {\n        YUITest.Assert._increment();\n        if (actual.length > 0){\n            YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Array should be empty.\"));\n        }\n    },\n\n    /**\n     * Asserts that an array is not empty.\n     * @param {Array} actual The array to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method isNotEmpty\n     * @static\n     */\n    isNotEmpty : function (actual, message) {\n        YUITest.Assert._increment();\n        if (actual.length === 0){\n            YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Array should not be empty.\"));\n        }\n    },\n\n    /**\n     * Asserts that the values in an array are the same, and in the same position,\n     * as values in another array. This uses the triple equals sign\n     * so no type cohersion will occur. Note that the array objects themselves\n     * need not be the same for this test to pass.\n     * @param {Array} expected An array of the expected values.\n     * @param {Array} actual Any array of the actual values.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method itemsAreSame\n     * @static\n     */\n    itemsAreSame : function (expected, actual,\n                          message) {\n\n        YUITest.Assert._increment();\n\n        //first check array length\n        if (expected.length != actual.length){\n            YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Array should have a length of \" + expected.length + \" but has a length of \" + actual.length));\n        }\n\n        //begin checking values\n        for (var i=0; i < expected.length; i++){\n            if (expected[i] !== actual[i]){\n                throw new YUITest.Assert.ComparisonFailure(YUITest.Assert._formatMessage(message, \"Values in position \" + i + \" are not the same.\"), expected[i], actual[i]);\n            }\n        }\n    },\n\n    /**\n     * Asserts that the given value is contained in an array at the specified index,\n     * starting from the back of the array.\n     * This uses the triple equals sign so no type cohersion will occur.\n     * @param {Object} needle The value to look for.\n     * @param {Array} haystack The array to search in.\n     * @param {int} index The index at which the value should exist.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method lastIndexOf\n     * @static\n     */\n    lastIndexOf : function (needle, haystack, index, message) {\n\n        //try to find the value in the array\n        for (var i=haystack.length; i >= 0; i--){\n            if (haystack[i] === needle){\n                if (index != i){\n                    YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Value exists at index \" + i + \" but should be at index \" + index + \".\"));\n                }\n                return;\n            }\n        }\n\n        //if it makes it here, it wasn't found at all\n        YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Value doesn't exist in array.\"));\n    }\n\n};\n\n\n/**\n * The ObjectAssert object provides functions to test JavaScript objects\n * for a variety of cases.\n * @namespace YUITest\n * @class ObjectAssert\n * @static\n */\nYUITest.ObjectAssert = {\n\n    /**\n     * Asserts that an object has all of the same properties\n     * and property values as the other.\n     * @param {Object} expected The object with all expected properties and values.\n     * @param {Object} actual The object to inspect.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method areEqual\n     * @static\n     * @deprecated\n     */\n    areEqual: function(expected, actual, message) {\n        YUITest.Assert._increment();\n\n        for (var name in expected){\n            if (expected.hasOwnProperty(name)){\n                if (expected[name] != actual[name]){\n                    throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(message, \"Values should be equal for property \" + name), expected[name], actual[name]);\n                }\n            }\n        }\n    },\n\n    /**\n     * Asserts that an object has a property with the given name.\n     * @param {String} propertyName The name of the property to test.\n     * @param {Object} object The object to search.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method hasKey\n     * @static\n     * @deprecated Use ownsOrInheritsKey() instead\n     */\n    hasKey: function (propertyName, object, message) {\n        YUITest.ObjectAssert.ownsOrInheritsKey(propertyName, object, message);\n    },\n\n    /**\n     * Asserts that an object has all properties of a reference object.\n     * @param {Array} properties An array of property names that should be on the object.\n     * @param {Object} object The object to search.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method hasKeys\n     * @static\n     * @deprecated Use ownsOrInheritsKeys() instead\n     */\n    hasKeys: function (properties, object, message) {\n        YUITest.ObjectAssert.ownsOrInheritsKeys(properties, objects, message);\n    },\n\n    /**\n     * Asserts that a property with the given name exists on an object's prototype.\n     * @param {String} propertyName The name of the property to test.\n     * @param {Object} object The object to search.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method inheritsKey\n     * @static\n     */\n    inheritsKey: function (propertyName, object, message) {\n        YUITest.Assert._increment();\n        if (!(propertyName in object && !object.hasOwnProperty(propertyName))){\n            YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Property '\" + propertyName + \"' not found on object instance.\"));\n        }\n    },\n\n    /**\n     * Asserts that all properties exist on an object prototype.\n     * @param {Array} properties An array of property names that should be on the object.\n     * @param {Object} object The object to search.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method inheritsKeys\n     * @static\n     */\n    inheritsKeys: function (properties, object, message) {\n        YUITest.Assert._increment();\n        for (var i=0; i < properties.length; i++){\n            if (!(propertyName in object && !object.hasOwnProperty(properties[i]))){\n                YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Property '\" + properties[i] + \"' not found on object instance.\"));\n            }\n        }\n    },\n\n    /**\n     * Asserts that a property with the given name exists on an object instance (not on its prototype).\n     * @param {String} propertyName The name of the property to test.\n     * @param {Object} object The object to search.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method ownsKey\n     * @static\n     */\n    ownsKey: function (propertyName, object, message) {\n        YUITest.Assert._increment();\n        if (!object.hasOwnProperty(propertyName)){\n            YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Property '\" + propertyName + \"' not found on object instance.\"));\n        }\n    },\n\n    /**\n     * Asserts that all properties exist on an object instance (not on its prototype).\n     * @param {Array} properties An array of property names that should be on the object.\n     * @param {Object} object The object to search.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method ownsKeys\n     * @static\n     */\n    ownsKeys: function (properties, object, message) {\n        YUITest.Assert._increment();\n        for (var i=0; i < properties.length; i++){\n            if (!object.hasOwnProperty(properties[i])){\n                YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Property '\" + properties[i] + \"' not found on object instance.\"));\n            }\n        }\n    },\n\n    /**\n     * Asserts that an object owns no properties.\n     * @param {Object} object The object to check.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method ownsNoKeys\n     * @static\n     */\n    ownsNoKeys : function (object, message) {\n        YUITest.Assert._increment();\n        var count = 0,\n            name;\n        for (name in object){\n            if (object.hasOwnProperty(name)){\n                count++;\n            }\n        }\n\n        if (count !== 0){\n            YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Object owns \" + count + \" properties but should own none.\"));\n        }\n\n    },\n\n    /**\n     * Asserts that an object has a property with the given name.\n     * @param {String} propertyName The name of the property to test.\n     * @param {Object} object The object to search.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method ownsOrInheritsKey\n     * @static\n     */\n    ownsOrInheritsKey: function (propertyName, object, message) {\n        YUITest.Assert._increment();\n        if (!(propertyName in object)){\n            YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Property '\" + propertyName + \"' not found on object.\"));\n        }\n    },\n\n    /**\n     * Asserts that an object has all properties of a reference object.\n     * @param {Array} properties An array of property names that should be on the object.\n     * @param {Object} object The object to search.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method ownsOrInheritsKeys\n     * @static\n     */\n    ownsOrInheritsKeys: function (properties, object, message) {\n        YUITest.Assert._increment();\n        for (var i=0; i < properties.length; i++){\n            if (!(properties[i] in object)){\n                YUITest.Assert.fail(YUITest.Assert._formatMessage(message, \"Property '\" + properties[i] + \"' not found on object.\"));\n            }\n        }\n    }\n};\n\n\n\n/**\n * The DateAssert object provides functions to test JavaScript Date objects\n * for a variety of cases.\n * @namespace  YUITest\n * @class DateAssert\n * @static\n */\n\nYUITest.DateAssert = {\n\n    /**\n     * Asserts that a date's month, day, and year are equal to another date's.\n     * @param {Date} expected The expected date.\n     * @param {Date} actual The actual date to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method datesAreEqual\n     * @static\n     */\n    datesAreEqual : function (expected, actual, message){\n        YUITest.Assert._increment();\n        if (expected instanceof Date && actual instanceof Date){\n            var msg = \"\";\n\n            //check years first\n            if (expected.getFullYear() != actual.getFullYear()){\n                msg = \"Years should be equal.\";\n            }\n\n            //now check months\n            if (expected.getMonth() != actual.getMonth()){\n                msg = \"Months should be equal.\";\n            }\n\n            //last, check the day of the month\n            if (expected.getDate() != actual.getDate()){\n                msg = \"Days of month should be equal.\";\n            }\n\n            if (msg.length){\n                throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(message, msg), expected, actual);\n            }\n        } else {\n            throw new TypeError(\"YUITest.DateAssert.datesAreEqual(): Expected and actual values must be Date objects.\");\n        }\n    },\n\n    /**\n     * Asserts that a date's hour, minutes, and seconds are equal to another date's.\n     * @param {Date} expected The expected date.\n     * @param {Date} actual The actual date to test.\n     * @param {String} message (Optional) The message to display if the assertion fails.\n     * @method timesAreEqual\n     * @static\n     */\n    timesAreEqual : function (expected, actual, message){\n        YUITest.Assert._increment();\n        if (expected instanceof Date && actual instanceof Date){\n            var msg = \"\";\n\n            //check hours first\n            if (expected.getHours() != actual.getHours()){\n                msg = \"Hours should be equal.\";\n            }\n\n            //now check minutes\n            if (expected.getMinutes() != actual.getMinutes()){\n                msg = \"Minutes should be equal.\";\n            }\n\n            //last, check the seconds\n            if (expected.getSeconds() != actual.getSeconds()){\n                msg = \"Seconds should be equal.\";\n            }\n\n            if (msg.length){\n                throw new YUITest.ComparisonFailure(YUITest.Assert._formatMessage(message, msg), expected, actual);\n            }\n        } else {\n            throw new TypeError(\"YUITest.DateAssert.timesAreEqual(): Expected and actual values must be Date objects.\");\n        }\n    }\n\n};\n\n/**\n * Creates a new mock object.\n * @namespace YUITest\n * @class Mock\n * @constructor\n * @param {Object} template (Optional) An object whose methods\n *      should be stubbed out on the mock object.\n */\nYUITest.Mock = function(template){\n\n    //use blank object is nothing is passed in\n    template = template || {};\n\n    var mock,\n        name;\n\n    //try to create mock that keeps prototype chain intact\n    //fails in the case of ActiveX objects\n    try {\n        function f(){}\n        f.prototype = template;\n        mock = new f();\n    } catch (ex) {\n        mock = {};\n    }\n\n    //create stubs for all methods\n    for (name in template){\n        if (template.hasOwnProperty(name)){\n            if (typeof template[name] == \"function\"){\n                mock[name] = function(name){\n                    return function(){\n                        YUITest.Assert.fail(\"Method \" + name + \"() was called but was not expected to be.\");\n                    };\n                }(name);\n            }\n        }\n    }\n\n    //return it\n    return mock;\n};\n\n/**\n * Assigns an expectation to a mock object. This is used to create\n * methods and properties on the mock object that are monitored for\n * calls and changes, respectively.\n * @param {Object} mock The object to add the expectation to.\n * @param {Object} expectation An object defining the expectation. For\n *      a method, the keys \"method\" and \"args\" are required with\n *      an optional \"returns\" key available. For properties, the keys\n *      \"property\" and \"value\" are required.\n * @return {void}\n * @method expect\n * @static\n */\nYUITest.Mock.expect = function(mock /*:Object*/, expectation /*:Object*/){\n\n    //make sure there's a place to store the expectations\n    if (!mock.__expectations) {\n        mock.__expectations = {};\n    }\n\n    //method expectation\n    if (expectation.method){\n        var name = expectation.method,\n            args = expectation.args || [],\n            result = expectation.returns,\n            callCount = (typeof expectation.callCount == \"number\") ? expectation.callCount : 1,\n            error = expectation.error,\n            run = expectation.run || function(){},\n            i;\n\n        //save expectations\n        mock.__expectations[name] = expectation;\n        expectation.callCount = callCount;\n        expectation.actualCallCount = 0;\n\n        //process arguments\n        for (i=0; i < args.length; i++){\n             if (!(args[i] instanceof YUITest.Mock.Value)){\n                args[i] = YUITest.Mock.Value(YUITest.Assert.areSame, [args[i]], \"Argument \" + i + \" of \" + name + \"() is incorrect.\");\n            }\n        }\n\n        //if the method is expected to be called\n        if (callCount > 0){\n            mock[name] = function(){\n                try {\n                    expectation.actualCallCount++;\n                    YUITest.Assert.areEqual(args.length, arguments.length, \"Method \" + name + \"() passed incorrect number of arguments.\");\n                    for (var i=0, len=args.length; i < len; i++){\n                        args[i].verify(arguments[i]);\n                    }\n\n                    run.apply(this, arguments);\n\n                    if (error){\n                        throw error;\n                    }\n                } catch (ex){\n                    //route through TestRunner for proper handling\n                    YUITest.TestRunner._handleError(ex);\n                }\n\n                return result;\n            };\n        } else {\n\n            //method should fail if called when not expected\n            mock[name] = function(){\n                try {\n                    YUITest.Assert.fail(\"Method \" + name + \"() should not have been called.\");\n                } catch (ex){\n                    //route through TestRunner for proper handling\n                    YUITest.TestRunner._handleError(ex);\n                }\n            };\n        }\n    } else if (expectation.property){\n        //save expectations\n        mock.__expectations[name] = expectation;\n    }\n};\n\n/**\n * Verifies that all expectations of a mock object have been met and\n * throws an assertion error if not.\n * @param {Object} mock The object to verify..\n * @return {void}\n * @method verify\n * @static\n */\nYUITest.Mock.verify = function(mock){\n    try {\n\n        for (var name in mock.__expectations){\n            if (mock.__expectations.hasOwnProperty(name)){\n                var expectation = mock.__expectations[name];\n                if (expectation.method) {\n                    YUITest.Assert.areEqual(expectation.callCount, expectation.actualCallCount, \"Method \" + expectation.method + \"() wasn't called the expected number of times.\");\n                } else if (expectation.property){\n                    YUITest.Assert.areEqual(expectation.value, mock[expectation.property], \"Property \" + expectation.property + \" wasn't set to the correct value.\");\n                }\n            }\n        }\n\n    } catch (ex){\n        //route through TestRunner for proper handling\n        YUITest.TestRunner._handleError(ex);\n    }\n};\n\n/**\n * Creates a new value matcher.\n * @param {Function} method The function to call on the value.\n * @param {Array} originalArgs (Optional) Array of arguments to pass to the method.\n * @param {String} message (Optional) Message to display in case of failure.\n * @namespace YUITest.Mock\n * @class Value\n * @constructor\n */\nYUITest.Mock.Value = function(method, originalArgs, message){\n    if (this instanceof YUITest.Mock.Value){\n        this.verify = function(value){\n            var args = [].concat(originalArgs || []);\n            args.push(value);\n            args.push(message);\n            method.apply(null, args);\n        };\n    } else {\n        return new YUITest.Mock.Value(method, originalArgs, message);\n    }\n};\n\n/**\n * Predefined matcher to match any value.\n * @property Any\n * @static\n * @type Function\n */\nYUITest.Mock.Value.Any        = YUITest.Mock.Value(function(){});\n\n/**\n * Predefined matcher to match boolean values.\n * @property Boolean\n * @static\n * @type Function\n */\nYUITest.Mock.Value.Boolean    = YUITest.Mock.Value(YUITest.Assert.isBoolean);\n\n/**\n * Predefined matcher to match number values.\n * @property Number\n * @static\n * @type Function\n */\nYUITest.Mock.Value.Number     = YUITest.Mock.Value(YUITest.Assert.isNumber);\n\n/**\n * Predefined matcher to match string values.\n * @property String\n * @static\n * @type Function\n */\nYUITest.Mock.Value.String     = YUITest.Mock.Value(YUITest.Assert.isString);\n\n/**\n * Predefined matcher to match object values.\n * @property Object\n * @static\n * @type Function\n */\nYUITest.Mock.Value.Object     = YUITest.Mock.Value(YUITest.Assert.isObject);\n\n/**\n * Predefined matcher to match function values.\n * @property Function\n * @static\n * @type Function\n */\nYUITest.Mock.Value.Function   = YUITest.Mock.Value(YUITest.Assert.isFunction);\n\n/**\n * Convenience type for storing and aggregating\n * test result information.\n * @private\n * @namespace YUITest\n * @class Results\n * @constructor\n * @param {String} name The name of the test.\n */\nYUITest.Results = function(name){\n\n    /**\n     * Name of the test, test case, or test suite.\n     * @type String\n     * @property name\n     */\n    this.name = name;\n\n    /**\n     * Number of passed tests.\n     * @type int\n     * @property passed\n     */\n    this.passed = 0;\n\n    /**\n     * Number of failed tests.\n     * @type int\n     * @property failed\n     */\n    this.failed = 0;\n\n    /**\n     * Number of errors that occur in non-test methods.\n     * @type int\n     * @property errors\n     */\n    this.errors = 0;\n\n    /**\n     * Number of ignored tests.\n     * @type int\n     * @property ignored\n     */\n    this.ignored = 0;\n\n    /**\n     * Number of total tests.\n     * @type int\n     * @property total\n     */\n    this.total = 0;\n\n    /**\n     * Amount of time (ms) it took to complete testing.\n     * @type int\n     * @property duration\n     */\n    this.duration = 0;\n};\n\n/**\n * Includes results from another results object into this one.\n * @param {YUITest.Results} result The results object to include.\n * @method include\n * @return {void}\n */\nYUITest.Results.prototype.include = function(results){\n    this.passed += results.passed;\n    this.failed += results.failed;\n    this.ignored += results.ignored;\n    this.total += results.total;\n    this.errors += results.errors;\n};\n\n/**\n * Test case containing various tests to run.\n * @param template An object containing any number of test methods, other methods,\n *                 an optional name, and anything else the test case needs.\n * @class TestCase\n * @namespace YUITest\n * @constructor\n */\nYUITest.TestCase = function (template) {\n\n    /**\n     * Special rules for the test case. Possible subobjects\n     * are fail, for tests that should fail, and error, for\n     * tests that should throw an error.\n     */\n    this._should = {};\n\n    //copy over all properties from the template to this object\n    for (var prop in template) {\n        this[prop] = template[prop];\n    }\n\n    //check for a valid name\n    if (typeof this.name != \"string\"){\n        this.name = \"testCase\" + (+new Date());\n    }\n\n};\n\nYUITest.TestCase.prototype = {\n\n    //restore constructor\n    constructor: YUITest.TestCase,\n\n    /**\n     * Method to call from an async init method to\n     * restart the test case. When called, returns a function\n     * that should be called when tests are ready to continue.\n     * @method callback\n     * @return {Function} The function to call as a callback.\n     */\n    callback: function(){\n        return YUITest.TestRunner.callback.apply(YUITest.TestRunner,arguments);\n    },\n\n    /**\n     * Resumes a paused test and runs the given function.\n     * @param {Function} segment (Optional) The function to run.\n     *      If omitted, the test automatically passes.\n     * @return {Void}\n     * @method resume\n     */\n    resume : function (segment) {\n        YUITest.TestRunner.resume(segment);\n    },\n\n    /**\n     * Causes the test case to wait a specified amount of time and then\n     * continue executing the given code.\n     * @param {Function} segment (Optional) The function to run after the delay.\n     *      If omitted, the TestRunner will wait until resume() is called.\n     * @param {int} delay (Optional) The number of milliseconds to wait before running\n     *      the function. If omitted, defaults to zero.\n     * @return {Void}\n     * @method wait\n     */\n    wait : function (segment, delay){\n\n        var actualDelay = (typeof segment == \"number\" ? segment : delay);\n        actualDelay = (typeof actualDelay == \"number\" ? actualDelay : 10000);\n\n\t\tif (typeof segment == \"function\"){\n            throw new YUITest.Wait(segment, actualDelay);\n        } else {\n            throw new YUITest.Wait(function(){\n                YUITest.Assert.fail(\"Timeout: wait() called but resume() never called.\");\n            }, actualDelay);\n        }\n    },\n\n    //-------------------------------------------------------------------------\n    // Assertion Methods\n    //-------------------------------------------------------------------------\n\n    /**\n     * Asserts that a given condition is true. If not, then a YUITest.AssertionError object is thrown\n     * and the test fails.\n     * @method assert\n     * @param {Boolean} condition The condition to test.\n     * @param {String} message The message to display if the assertion fails.\n     */\n    assert : function (condition, message){\n        YUITest.Assert._increment();\n        if (!condition){\n            throw new YUITest.AssertionError(YUITest.Assert._formatMessage(message, \"Assertion failed.\"));\n        }\n    },\n\n    /**\n     * Forces an assertion error to occur. Shortcut for YUITest.Assert.fail().\n     * @method fail\n     * @param {String} message (Optional) The message to display with the failure.\n     */\n    fail: function (message) {\n        YUITest.Assert.fail(message);\n    },\n\n    //-------------------------------------------------------------------------\n    // Stub Methods\n    //-------------------------------------------------------------------------\n\n    /**\n     * Function to run once before tests start to run.\n     * This executes before the first call to setUp().\n     */\n    init: function(){\n        //noop\n    },\n\n    /**\n     * Function to run once after tests finish running.\n     * This executes after the last call to tearDown().\n     */\n    destroy: function(){\n        //noop\n    },\n\n    /**\n     * Function to run before each test is executed.\n     * @return {Void}\n     * @method setUp\n     */\n    setUp : function () {\n        //noop\n    },\n\n    /**\n     * Function to run after each test is executed.\n     * @return {Void}\n     * @method tearDown\n     */\n    tearDown: function () {\n        //noop\n    }\n};\n\n\n\n/**\n * A test suite that can contain a collection of TestCase and TestSuite objects.\n * @param {String||Object} data The name of the test suite or an object containing\n *      a name property as well as setUp and tearDown methods.\n * @namespace YUITest\n * @class TestSuite\n * @constructor\n */\nYUITest.TestSuite = function (data) {\n\n    /**\n     * The name of the test suite.\n     * @type String\n     * @property name\n     */\n    this.name = \"\";\n\n    /**\n     * Array of test suites and test cases.\n     * @type Array\n     * @property items\n     * @private\n     */\n    this.items = [];\n\n    //initialize the properties\n    if (typeof data == \"string\"){\n        this.name = data;\n    } else if (data instanceof Object){\n        for (var prop in data){\n            if (data.hasOwnProperty(prop)){\n                this[prop] = data[prop];\n            }\n        }\n    }\n\n    //double-check name\n    if (this.name === \"\"){\n        this.name = \"testSuite\" + (+new Date());\n    }\n\n};\n\nYUITest.TestSuite.prototype = {\n\n    //restore constructor\n    constructor: YUITest.TestSuite,\n\n    /**\n     * Adds a test suite or test case to the test suite.\n     * @param {YUITest.TestSuite||YUITest.TestCase} testObject The test suite or test case to add.\n     * @return {Void}\n     * @method add\n     */\n    add : function (testObject) {\n        if (testObject instanceof YUITest.TestSuite || testObject instanceof YUITest.TestCase) {\n            this.items.push(testObject);\n        }\n        return this;\n    },\n\n    //-------------------------------------------------------------------------\n    // Stub Methods\n    //-------------------------------------------------------------------------\n\n    /**\n     * Function to run before each test is executed.\n     * @return {Void}\n     * @method setUp\n     */\n    setUp : function () {\n    },\n\n    /**\n     * Function to run after each test is executed.\n     * @return {Void}\n     * @method tearDown\n     */\n    tearDown: function () {\n    }\n\n};\n\n/**\n * An object object containing test result formatting methods.\n * @namespace YUITest\n * @class TestFormat\n * @static\n */\nYUITest.TestFormat = function(){\n\n    /* (intentionally not documented)\n     * Basic XML escaping method. Replaces quotes, less-than, greater-than,\n     * apostrophe, and ampersand characters with their corresponding entities.\n     * @param {String} text The text to encode.\n     * @return {String} The XML-escaped text.\n     */\n    function xmlEscape(text){\n\n        return text.replace(/[<>\"'&]/g, function(value){\n            switch(value){\n                case \"<\":   return \"&lt;\";\n                case \">\":   return \"&gt;\";\n                case \"\\\"\":  return \"&quot;\";\n                case \"'\":   return \"&apos;\";\n                case \"&\":   return \"&amp;\";\n            }\n        });\n\n    }\n\n\n    return {\n\n        /**\n         * Returns test results formatted as a JSON string. Requires JSON utility.\n         * @param {Object} result The results object created by TestRunner.\n         * @return {String} A JSON-formatted string of results.\n         * @method JSON\n         * @static\n         */\n        JSON: function(results) {\n            return YUITest.Util.JSON.stringify(results);\n        },\n\n        /**\n         * Returns test results formatted as an XML string.\n         * @param {Object} result The results object created by TestRunner.\n         * @return {String} An XML-formatted string of results.\n         * @method XML\n         * @static\n         */\n        XML: function(results) {\n\n            function serializeToXML(results){\n                var xml = \"<\" + results.type + \" name=\\\"\" + xmlEscape(results.name) + \"\\\"\";\n\n                if (typeof(results.duration)==\"number\"){\n                    xml += \" duration=\\\"\" + results.duration + \"\\\"\";\n                }\n\n                if (results.type == \"test\"){\n                    xml += \" result=\\\"\" + results.result + \"\\\" message=\\\"\" + xmlEscape(results.message) + \"\\\">\";\n                } else {\n                    xml += \" passed=\\\"\" + results.passed + \"\\\" failed=\\\"\" + results.failed + \"\\\" ignored=\\\"\" + results.ignored + \"\\\" total=\\\"\" + results.total + \"\\\">\";\n                    for (var prop in results){\n                        if (results.hasOwnProperty(prop)){\n                            if (results[prop] && typeof results[prop] == \"object\" && !(results[prop] instanceof Array)){\n                                xml += serializeToXML(results[prop]);\n                            }\n                        }\n                    }\n                }\n\n                xml += \"</\" + results.type + \">\";\n\n                return xml;\n            }\n\n            return \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" + serializeToXML(results);\n\n        },\n\n\n        /**\n         * Returns test results formatted in JUnit XML format.\n         * @param {Object} result The results object created by TestRunner.\n         * @return {String} An XML-formatted string of results.\n         * @method JUnitXML\n         * @static\n         */\n        JUnitXML: function(results) {\n\n            function serializeToJUnitXML(results){\n                var xml = \"\";\n\n                switch (results.type){\n                    //equivalent to testcase in JUnit\n                    case \"test\":\n                        if (results.result != \"ignore\"){\n                            xml = \"<testcase name=\\\"\" + xmlEscape(results.name) + \"\\\" time=\\\"\" + (results.duration/1000) + \"\\\">\";\n                            if (results.result == \"fail\"){\n                                xml += \"<failure message=\\\"\" + xmlEscape(results.message) + \"\\\"><![CDATA[\" + results.message + \"]]></failure>\";\n                            }\n                            xml+= \"</testcase>\";\n                        }\n                        break;\n\n                    //equivalent to testsuite in JUnit\n                    case \"testcase\":\n\n                        xml = \"<testsuite name=\\\"\" + xmlEscape(results.name) + \"\\\" tests=\\\"\" + results.total + \"\\\" failures=\\\"\" + results.failed + \"\\\" time=\\\"\" + (results.duration/1000) + \"\\\">\";\n\n                        for (var prop in results){\n                            if (results.hasOwnProperty(prop)){\n                                if (results[prop] && typeof results[prop] == \"object\" && !(results[prop] instanceof Array)){\n                                    xml += serializeToJUnitXML(results[prop]);\n                                }\n                            }\n                        }\n\n                        xml += \"</testsuite>\";\n                        break;\n\n                    //no JUnit equivalent, don't output anything\n                    case \"testsuite\":\n                        for (var prop in results){\n                            if (results.hasOwnProperty(prop)){\n                                if (results[prop] && typeof results[prop] == \"object\" && !(results[prop] instanceof Array)){\n                                    xml += serializeToJUnitXML(results[prop]);\n                                }\n                            }\n                        }\n                        break;\n\n                    //top-level, equivalent to testsuites in JUnit\n                    case \"report\":\n\n                        xml = \"<testsuites>\";\n\n                        for (var prop in results){\n                            if (results.hasOwnProperty(prop)){\n                                if (results[prop] && typeof results[prop] == \"object\" && !(results[prop] instanceof Array)){\n                                    xml += serializeToJUnitXML(results[prop]);\n                                }\n                            }\n                        }\n\n                        xml += \"</testsuites>\";\n\n                    //no default\n                }\n\n                return xml;\n\n            }\n\n            return \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\" + serializeToJUnitXML(results);\n        },\n\n        /**\n         * Returns test results formatted in TAP format.\n         * For more information, see <a href=\"http://testanything.org/\">Test Anything Protocol</a>.\n         * @param {Object} result The results object created by TestRunner.\n         * @return {String} A TAP-formatted string of results.\n         * @method TAP\n         * @static\n         */\n        TAP: function(results) {\n\n            var currentTestNum = 1;\n\n            function serializeToTAP(results){\n                var text = \"\";\n\n                switch (results.type){\n\n                    case \"test\":\n                        if (results.result != \"ignore\"){\n\n                            text = \"ok \" + (currentTestNum++) + \" - \" + results.name;\n\n                            if (results.result == \"fail\"){\n                                text = \"not \" + text + \" - \" + results.message;\n                            }\n\n                            text += \"\\n\";\n                        } else {\n                            text = \"#Ignored test \" + results.name + \"\\n\";\n                        }\n                        break;\n\n                    case \"testcase\":\n\n                        text = \"#Begin testcase \" + results.name + \"(\" + results.failed + \" failed of \" + results.total + \")\\n\";\n\n                        for (var prop in results){\n                            if (results.hasOwnProperty(prop)){\n                                if (results[prop] && typeof results[prop] == \"object\" && !(results[prop] instanceof Array)){\n                                    text += serializeToTAP(results[prop]);\n                                }\n                            }\n                        }\n\n                        text += \"#End testcase \" + results.name + \"\\n\";\n\n\n                        break;\n\n                    case \"testsuite\":\n\n                        text = \"#Begin testsuite \" + results.name + \"(\" + results.failed + \" failed of \" + results.total + \")\\n\";\n\n                        for (var prop in results){\n                            if (results.hasOwnProperty(prop)){\n                                if (results[prop] && typeof results[prop] == \"object\" && !(results[prop] instanceof Array)){\n                                    text += serializeToTAP(results[prop]);\n                                }\n                            }\n                        }\n\n                        text += \"#End testsuite \" + results.name + \"\\n\";\n                        break;\n\n                    case \"report\":\n\n                        for (var prop in results){\n                            if (results.hasOwnProperty(prop)){\n                                if (results[prop] && typeof results[prop] == \"object\" && !(results[prop] instanceof Array)){\n                                    text += serializeToTAP(results[prop]);\n                                }\n                            }\n                        }\n\n                    //no default\n                }\n\n                return text;\n\n            }\n\n            return \"1..\" + results.total + \"\\n\" + serializeToTAP(results);\n        }\n\n    };\n}();\n\n/**\n * An object object containing coverage result formatting methods.\n * @namespace YUITest\n * @class CoverageFormat\n * @static\n */\nYUITest.CoverageFormat = {\n\n    /**\n     * Returns the coverage report in JSON format. This is the straight\n     * JSON representation of the native coverage report.\n     * @param {Object} coverage The coverage report object.\n     * @return {String} A JSON-formatted string of coverage data.\n     * @method JSON\n     * @namespace YUITest.CoverageFormat\n     */\n    JSON: function(coverage){\n        return YUITest.Util.JSON.stringify(coverage);\n    },\n\n    /**\n     * Returns the coverage report in a JSON format compatible with\n     * Xdebug. See <a href=\"http://www.xdebug.com/docs/code_coverage\">Xdebug Documentation</a>\n     * for more information. Note: function coverage is not available\n     * in this format.\n     * @param {Object} coverage The coverage report object.\n     * @return {String} A JSON-formatted string of coverage data.\n     * @method XdebugJSON\n     * @namespace YUITest.CoverageFormat\n     */\n    XdebugJSON: function(coverage){\n\n        var report = {};\n        for (var prop in coverage){\n            if (coverage.hasOwnProperty(prop)){\n                report[prop] = coverage[prop].lines;\n            }\n        }\n\n        return YUITest.Util.JSON.stringify(coverage);\n    }\n\n};\n\n\n/**\n * An object object containing methods to simulate browser events.\n * @namespace YUITest\n * @class Event\n * @static\n */\nYUITest.Event = (function() {\n\n    var\n\n    //mouse events supported\n    mouseEvents = {\n        click:      1,\n        dblclick:   1,\n        mouseover:  1,\n        mouseout:   1,\n        mousedown:  1,\n        mouseup:    1,\n        mousemove:  1\n    },\n\n    //key events supported\n    keyEvents   = {\n        keydown:    1,\n        keyup:      1,\n        keypress:   1\n    },\n\n    //HTML events supported\n    uiEvents  = {\n        blur:       1,\n        change:     1,\n        focus:      1,\n        resize:     1,\n        scroll:     1,\n        select:     1\n    },\n\n    //events that bubble by default\n    bubbleEvents = {\n        scroll:     1,\n        resize:     1,\n        reset:      1,\n        submit:     1,\n        change:     1,\n        select:     1,\n        error:      1,\n        abort:      1,\n\n        //also mouse events\n        click:      1,\n        dblclick:   1,\n        mouseover:  1,\n        mouseout:   1,\n        mousedown:  1,\n        mouseup:    1,\n        mousemove:  1,\n\n        //and keyboard events\n        keydown:    1,\n        keyup:      1,\n        keypress:   1\n\n    },\n\n    //the object to return\n    object,\n\n    //used for property name iteration\n    prop;\n\n    /*\n     * Note: Intentionally not for YUIDoc generation.\n     * Simulates a key event using the given event information to populate\n     * the generated event object. This method does browser-equalizing\n     * calculations to account for differences in the DOM and IE event models\n     * as well as different browser quirks. Note: keydown causes Safari 2.x to\n     * crash.\n     * @method simulateKeyEvent\n     * @private\n     * @static\n     * @param {HTMLElement} target The target of the given event.\n     * @param {String} type The type of event to fire. This can be any one of\n     *      the following: keyup, keydown, and keypress.\n     * @param {Boolean} bubbles (Optional) Indicates if the event can be\n     *      bubbled up. DOM Level 3 specifies that all key events bubble by\n     *      default. The default is true.\n     * @param {Boolean} cancelable (Optional) Indicates if the event can be\n     *      canceled using preventDefault(). DOM Level 3 specifies that all\n     *      key events can be cancelled. The default\n     *      is true.\n     * @param {Window} view (Optional) The view containing the target. This is\n     *      typically the window object. The default is window.\n     * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys\n     *      is pressed while the event is firing. The default is false.\n     * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys\n     *      is pressed while the event is firing. The default is false.\n     * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys\n     *      is pressed while the event is firing. The default is false.\n     * @param {Boolean} metaKey (Optional) Indicates if one of the META keys\n     *      is pressed while the event is firing. The default is false.\n     * @param {int} keyCode (Optional) The code for the key that is in use.\n     *      The default is 0.\n     * @param {int} charCode (Optional) The Unicode code for the character\n     *      associated with the key being used. The default is 0.\n     */\n    function simulateKeyEvent(target /*:HTMLElement*/, type /*:String*/,\n                                 bubbles /*:Boolean*/,  cancelable /*:Boolean*/,\n                                 view /*:Window*/,\n                                 ctrlKey /*:Boolean*/,    altKey /*:Boolean*/,\n                                 shiftKey /*:Boolean*/,   metaKey /*:Boolean*/,\n                                 keyCode /*:int*/,        charCode /*:int*/) /*:Void*/\n    {\n        //check target\n        if (!target){\n            throw new Error(\"simulateKeyEvent(): Invalid target.\");\n        }\n\n        //check event type\n        if (typeof type == \"string\"){\n            type = type.toLowerCase();\n            switch(type){\n                case \"textevent\": //DOM Level 3\n                    type = \"keypress\";\n                    break;\n                case \"keyup\":\n                case \"keydown\":\n                case \"keypress\":\n                    break;\n                default:\n                    throw new Error(\"simulateKeyEvent(): Event type '\" + type + \"' not supported.\");\n            }\n        } else {\n            throw new Error(\"simulateKeyEvent(): Event type must be a string.\");\n        }\n\n        //setup default values\n        if (typeof bubbles != \"boolean\"){\n            bubbles = true; //all key events bubble\n        }\n        if (typeof cancelable != \"boolean\"){\n            cancelable = true; //all key events can be cancelled\n        }\n        if (typeof view != \"object\" || view == null){\n            view = window; //view is typically window\n        }\n        if (typeof ctrlKey != \"boolean\"){\n            ctrlKey = false;\n        }\n        if (typeof altKey != \"boolean\"){\n            altKey = false;\n        }\n        if (typeof shiftKey != \"boolean\"){\n            shiftKey = false;\n        }\n        if (typeof metaKey != \"boolean\"){\n            metaKey = false;\n        }\n        if (typeof keyCode != \"number\"){\n            keyCode = 0;\n        }\n        if (typeof charCode != \"number\"){\n            charCode = 0;\n        }\n\n        //try to create a mouse event\n        var customEvent = null;\n\n        //check for DOM-compliant browsers first\n        if (typeof document.createEvent == \"function\"){\n\n            try {\n\n                //try to create key event\n                customEvent = document.createEvent(\"KeyEvents\");\n\n                /*\n                 * Interesting problem: Firefox implemented a non-standard\n                 * version of initKeyEvent() based on DOM Level 2 specs.\n                 * Key event was removed from DOM Level 2 and re-introduced\n                 * in DOM Level 3 with a different interface. Firefox is the\n                 * only browser with any implementation of Key Events, so for\n                 * now, assume it's Firefox if the above line doesn't error.\n                 */\n                // @TODO: Decipher between Firefox's implementation and a correct one.\n                customEvent.initKeyEvent(type, bubbles, cancelable, view, ctrlKey,\n                    altKey, shiftKey, metaKey, keyCode, charCode);\n\n            } catch (ex){\n\n                /*\n                 * If it got here, that means key events aren't officially supported.\n                 * Safari/WebKit is a real problem now. WebKit 522 won't let you\n                 * set keyCode, charCode, or other properties if you use a\n                 * UIEvent, so we first must try to create a generic event. The\n                 * fun part is that this will throw an error on Safari 2.x. The\n                 * end result is that we need another try...catch statement just to\n                 * deal with this mess.\n                 */\n                try {\n\n                    //try to create generic event - will fail in Safari 2.x\n                    customEvent = document.createEvent(\"Events\");\n\n                } catch (uierror /*:Error*/){\n\n                    //the above failed, so create a UIEvent for Safari 2.x\n                    customEvent = document.createEvent(\"UIEvents\");\n\n                } finally {\n\n                    customEvent.initEvent(type, bubbles, cancelable);\n\n                    //initialize\n                    customEvent.view = view;\n                    customEvent.altKey = altKey;\n                    customEvent.ctrlKey = ctrlKey;\n                    customEvent.shiftKey = shiftKey;\n                    customEvent.metaKey = metaKey;\n                    customEvent.keyCode = keyCode;\n                    customEvent.charCode = charCode;\n\n                }\n\n            }\n\n            //fire the event\n            target.dispatchEvent(customEvent);\n\n        } else if (typeof document.createEventObject != \"undefined\"){ //IE\n\n            //create an IE event object\n            customEvent = document.createEventObject();\n\n            //assign available properties\n            customEvent.bubbles = bubbles;\n            customEvent.cancelable = cancelable;\n            customEvent.view = view;\n            customEvent.ctrlKey = ctrlKey;\n            customEvent.altKey = altKey;\n            customEvent.shiftKey = shiftKey;\n            customEvent.metaKey = metaKey;\n\n            /*\n             * IE doesn't support charCode explicitly. CharCode should\n             * take precedence over any keyCode value for accurate\n             * representation.\n             */\n            customEvent.keyCode = (charCode > 0) ? charCode : keyCode;\n\n            //fire the event\n            target.fireEvent(\"on\" + type, customEvent);\n\n        } else {\n            throw new Error(\"simulateKeyEvent(): No event simulation framework present.\");\n        }\n    }\n\n    /*\n     * Note: Intentionally not for YUIDoc generation.\n     * Simulates a mouse event using the given event information to populate\n     * the generated event object. This method does browser-equalizing\n     * calculations to account for differences in the DOM and IE event models\n     * as well as different browser quirks.\n     * @method simulateMouseEvent\n     * @private\n     * @static\n     * @param {HTMLElement} target The target of the given event.\n     * @param {String} type The type of event to fire. This can be any one of\n     *      the following: click, dblclick, mousedown, mouseup, mouseout,\n     *      mouseover, and mousemove.\n     * @param {Boolean} bubbles (Optional) Indicates if the event can be\n     *      bubbled up. DOM Level 2 specifies that all mouse events bubble by\n     *      default. The default is true.\n     * @param {Boolean} cancelable (Optional) Indicates if the event can be\n     *      canceled using preventDefault(). DOM Level 2 specifies that all\n     *      mouse events except mousemove can be cancelled. The default\n     *      is true for all events except mousemove, for which the default\n     *      is false.\n     * @param {Window} view (Optional) The view containing the target. This is\n     *      typically the window object. The default is window.\n     * @param {int} detail (Optional) The number of times the mouse button has\n     *      been used. The default value is 1.\n     * @param {int} screenX (Optional) The x-coordinate on the screen at which\n     *      point the event occured. The default is 0.\n     * @param {int} screenY (Optional) The y-coordinate on the screen at which\n     *      point the event occured. The default is 0.\n     * @param {int} clientX (Optional) The x-coordinate on the client at which\n     *      point the event occured. The default is 0.\n     * @param {int} clientY (Optional) The y-coordinate on the client at which\n     *      point the event occured. The default is 0.\n     * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys\n     *      is pressed while the event is firing. The default is false.\n     * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys\n     *      is pressed while the event is firing. The default is false.\n     * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys\n     *      is pressed while the event is firing. The default is false.\n     * @param {Boolean} metaKey (Optional) Indicates if one of the META keys\n     *      is pressed while the event is firing. The default is false.\n     * @param {int} button (Optional) The button being pressed while the event\n     *      is executing. The value should be 0 for the primary mouse button\n     *      (typically the left button), 1 for the terciary mouse button\n     *      (typically the middle button), and 2 for the secondary mouse button\n     *      (typically the right button). The default is 0.\n     * @param {HTMLElement} relatedTarget (Optional) For mouseout events,\n     *      this is the element that the mouse has moved to. For mouseover\n     *      events, this is the element that the mouse has moved from. This\n     *      argument is ignored for all other events. The default is null.\n     */\n    function simulateMouseEvent(target /*:HTMLElement*/, type /*:String*/,\n                                   bubbles /*:Boolean*/,  cancelable /*:Boolean*/,\n                                   view /*:Window*/,        detail /*:int*/,\n                                   screenX /*:int*/,        screenY /*:int*/,\n                                   clientX /*:int*/,        clientY /*:int*/,\n                                   ctrlKey /*:Boolean*/,    altKey /*:Boolean*/,\n                                   shiftKey /*:Boolean*/,   metaKey /*:Boolean*/,\n                                   button /*:int*/,         relatedTarget /*:HTMLElement*/) /*:Void*/\n    {\n\n        //check target\n        if (!target){\n            throw new Error(\"simulateMouseEvent(): Invalid target.\");\n        }\n\n        //check event type\n        if (typeof type == \"string\"){\n            type = type.toLowerCase();\n\n            //make sure it's a supported mouse event\n            if (!mouseEvents[type]){\n                throw new Error(\"simulateMouseEvent(): Event type '\" + type + \"' not supported.\");\n            }\n        } else {\n            throw new Error(\"simulateMouseEvent(): Event type must be a string.\");\n        }\n\n        //setup default values\n        if (typeof bubbles != \"boolean\"){\n            bubbles = true; //all mouse events bubble\n        }\n        if (typeof cancelable != \"boolean\"){\n            cancelable = (type != \"mousemove\"); //mousemove is the only one that can't be cancelled\n        }\n        if (typeof view != \"object\" || view != null){\n            view = window; //view is typically window\n        }\n        if (typeof detail != \"number\"){\n            detail = 1;  //number of mouse clicks must be at least one\n        }\n        if (typeof screenX != \"number\"){\n            screenX = 0;\n        }\n        if (typeof screenY != \"number\"){\n            screenY = 0;\n        }\n        if (typeof clientX != \"number\"){\n            clientX = 0;\n        }\n        if (typeof clientY != \"number\"){\n            clientY = 0;\n        }\n        if (typeof ctrlKey != \"boolean\"){\n            ctrlKey = false;\n        }\n        if (typeof altKey != \"boolean\"){\n            altKey = false;\n        }\n        if (typeof shiftKey != \"boolean\"){\n            shiftKey = false;\n        }\n        if (typeof metaKey != \"boolean\"){\n            metaKey = false;\n        }\n        if (typeof button != \"number\"){\n            button = 0;\n        }\n\n        if (!relatedTarget){\n            relatedTarget = null;\n        }\n\n        //try to create a mouse event\n        var customEvent /*:MouseEvent*/ = null;\n\n        //check for DOM-compliant browsers first\n        if (typeof document.createEvent == \"function\"){\n\n            customEvent = document.createEvent(\"MouseEvents\");\n\n            //Safari 2.x (WebKit 418) still doesn't implement initMouseEvent()\n            if (customEvent.initMouseEvent){\n                customEvent.initMouseEvent(type, bubbles, cancelable, view, detail,\n                                     screenX, screenY, clientX, clientY,\n                                     ctrlKey, altKey, shiftKey, metaKey,\n                                     button, relatedTarget);\n            } else { //Safari\n\n                //the closest thing available in Safari 2.x is UIEvents\n                customEvent = document.createEvent(\"UIEvents\");\n                customEvent.initEvent(type, bubbles, cancelable);\n                customEvent.view = view;\n                customEvent.detail = detail;\n                customEvent.screenX = screenX;\n                customEvent.screenY = screenY;\n                customEvent.clientX = clientX;\n                customEvent.clientY = clientY;\n                customEvent.ctrlKey = ctrlKey;\n                customEvent.altKey = altKey;\n                customEvent.metaKey = metaKey;\n                customEvent.shiftKey = shiftKey;\n                customEvent.button = button;\n                customEvent.relatedTarget = relatedTarget;\n            }\n\n            /*\n             * Check to see if relatedTarget has been assigned. Firefox\n             * versions less than 2.0 don't allow it to be assigned via\n             * initMouseEvent() and the property is readonly after event\n             * creation, so in order to keep YAHOO.util.getRelatedTarget()\n             * working, assign to the IE proprietary toElement property\n             * for mouseout event and fromElement property for mouseover\n             * event.\n             */\n            if (relatedTarget && !customEvent.relatedTarget){\n                if (type == \"mouseout\"){\n                    customEvent.toElement = relatedTarget;\n                } else if (type == \"mouseover\"){\n                    customEvent.fromElement = relatedTarget;\n                }\n            }\n\n            //fire the event\n            target.dispatchEvent(customEvent);\n\n        } else if (typeof document.createEventObject != \"undefined\"){ //IE\n\n            //create an IE event object\n            customEvent = document.createEventObject();\n\n            //assign available properties\n            customEvent.bubbles = bubbles;\n            customEvent.cancelable = cancelable;\n            customEvent.view = view;\n            customEvent.detail = detail;\n            customEvent.screenX = screenX;\n            customEvent.screenY = screenY;\n            customEvent.clientX = clientX;\n            customEvent.clientY = clientY;\n            customEvent.ctrlKey = ctrlKey;\n            customEvent.altKey = altKey;\n            customEvent.metaKey = metaKey;\n            customEvent.shiftKey = shiftKey;\n\n            //fix button property for IE's wacky implementation\n            switch(button){\n                case 0:\n                    customEvent.button = 1;\n                    break;\n                case 1:\n                    customEvent.button = 4;\n                    break;\n                case 2:\n                    //leave as is\n                    break;\n                default:\n                    customEvent.button = 0;\n            }\n\n            /*\n             * Have to use relatedTarget because IE won't allow assignment\n             * to toElement or fromElement on generic events. This keeps\n             * YAHOO.util.customEvent.getRelatedTarget() functional.\n             */\n            customEvent.relatedTarget = relatedTarget;\n\n            //fire the event\n            target.fireEvent(\"on\" + type, customEvent);\n\n        } else {\n            throw new Error(\"simulateMouseEvent(): No event simulation framework present.\");\n        }\n    }\n\n    /*\n     * Note: Intentionally not for YUIDoc generation.\n     * Simulates a UI event using the given event information to populate\n     * the generated event object. This method does browser-equalizing\n     * calculations to account for differences in the DOM and IE event models\n     * as well as different browser quirks.\n     * @method simulateHTMLEvent\n     * @private\n     * @static\n     * @param {HTMLElement} target The target of the given event.\n     * @param {String} type The type of event to fire. This can be any one of\n     *      the following: click, dblclick, mousedown, mouseup, mouseout,\n     *      mouseover, and mousemove.\n     * @param {Boolean} bubbles (Optional) Indicates if the event can be\n     *      bubbled up. DOM Level 2 specifies that all mouse events bubble by\n     *      default. The default is true.\n     * @param {Boolean} cancelable (Optional) Indicates if the event can be\n     *      canceled using preventDefault(). DOM Level 2 specifies that all\n     *      mouse events except mousemove can be cancelled. The default\n     *      is true for all events except mousemove, for which the default\n     *      is false.\n     * @param {Window} view (Optional) The view containing the target. This is\n     *      typically the window object. The default is window.\n     * @param {int} detail (Optional) The number of times the mouse button has\n     *      been used. The default value is 1.\n     */\n    function simulateUIEvent(target /*:HTMLElement*/, type /*:String*/,\n                                   bubbles /*:Boolean*/,  cancelable /*:Boolean*/,\n                                   view /*:Window*/,        detail /*:int*/) /*:Void*/\n    {\n\n        //check target\n        if (!target){\n            throw new Error(\"simulateUIEvent(): Invalid target.\");\n        }\n\n        //check event type\n        if (typeof type == \"string\"){\n            type = type.toLowerCase();\n\n            //make sure it's a supported mouse event\n            if (!uiEvents[type]){\n                throw new Error(\"simulateUIEvent(): Event type '\" + type + \"' not supported.\");\n            }\n        } else {\n            throw new Error(\"simulateUIEvent(): Event type must be a string.\");\n        }\n\n        //try to create a mouse event\n        var customEvent = null;\n\n\n        //setup default values\n        if (typeof bubbles != \"boolean\"){\n            bubbles = (type in bubbleEvents);  //not all events bubble\n        }\n        if (typeof cancelable != \"boolean\"){\n            cancelable = (type == \"submit\"); //submit is the only one that can be cancelled\n        }\n        if (typeof view != \"object\" || view != null){\n            view = window; //view is typically window\n        }\n        if (typeof detail != \"number\"){\n            detail = 1;  //usually not used but defaulted to this\n        }\n\n        //check for DOM-compliant browsers first\n        if (typeof document.createEvent == \"function\"){\n\n            //just a generic UI Event object is needed\n            customEvent = document.createEvent(\"UIEvents\");\n            customEvent.initUIEvent(type, bubbles, cancelable, view, detail);\n\n            //fire the event\n            target.dispatchEvent(customEvent);\n\n        } else if (typeof document.createEventObject != \"undefined\"){ //IE\n\n            //create an IE event object\n            customEvent = document.createEventObject();\n\n            //assign available properties\n            customEvent.bubbles = bubbles;\n            customEvent.cancelable = cancelable;\n            customEvent.view = view;\n            customEvent.detail = detail;\n\n            //fire the event\n            target.fireEvent(\"on\" + type, customEvent);\n\n        } else {\n            throw new Error(\"simulateUIEvent(): No event simulation framework present.\");\n        }\n    }\n\n\n    /**\n     * Allows event simulation for browser-based events.\n     * @namespace YUITest\n     * @class Event\n     * @static\n     */\n    object = {\n\n        /**\n         * Simulates the event with the given name on a target.\n         * @param {HTMLElement} target The DOM element that's the target of the event.\n         * @param {String} type The type of event to simulate (i.e., \"click\").\n         * @param {Object} options (Optional) Extra options to copy onto the event object.\n         * @return {void}\n         * @method simulate\n         * @static\n         * @deprecated\n         */\n        simulate: function(target, type, options){\n\n            options = options || {};\n\n            if (mouseEvents[type]){\n                simulateMouseEvent(target, type, options.bubbles,\n                    options.cancelable, options.view, options.detail, options.screenX,\n                    options.screenY, options.clientX, options.clientY, options.ctrlKey,\n                    options.altKey, options.shiftKey, options.metaKey, options.button,\n                    options.relatedTarget);\n            } else if (keyEvents[type]){\n                simulateKeyEvent(target, type, options.bubbles,\n                    options.cancelable, options.view, options.ctrlKey,\n                    options.altKey, options.shiftKey, options.metaKey,\n                    options.keyCode, options.charCode);\n            } else if (uiEvents[type]){\n                simulateUIEvent(target, type, options.bubbles,\n                    options.cancelable, options.view, options.detail);\n             } else {\n                throw new Error(\"simulate(): Event '\" + type + \"' can't be simulated.\");\n            }\n        }\n    };\n\n    //create the convenience methods for mouse events\n    for (prop in mouseEvents){\n        if (mouseEvents.hasOwnProperty(prop)){\n            object[prop] = (function(type){\n                return function(target, options){\n                    options = options || {};\n                    simulateMouseEvent(target, type, options.bubbles,\n                        options.cancelable, options.view, options.detail, options.screenX,\n                        options.screenY, options.clientX, options.clientY, options.ctrlKey,\n                        options.altKey, options.shiftKey, options.metaKey, options.button,\n                        options.relatedTarget);\n                };\n            })(prop);\n        }\n    }\n\n    //create the convenience methods for key events\n    for (prop in keyEvents){\n        if (keyEvents.hasOwnProperty(prop)){\n            object[prop] = (function(type){\n                return function(target, options){\n                    options = options || {};\n                    simulateKeyEvent(target, type, options.bubbles,\n                        options.cancelable, options.view, options.ctrlKey,\n                        options.altKey, options.shiftKey, options.metaKey,\n                        options.keyCode, options.charCode);\n                };\n            })(prop);\n        }\n    }\n\n    //create the convenience methods for key events\n    for (prop in uiEvents){\n        if (uiEvents.hasOwnProperty(prop)){\n            object[prop] = (function(type){\n                return function(target, options){\n                    options = options || {};\n                    simulateUIEvent(target, type, options.bubbles,\n                        options.cancelable, options.view, options.detail);\n                };\n            })(prop);\n        }\n    }\n\n    return object;\n\n})();\n\n\n    /**\n     * An object capable of sending test results to a server.\n     * @param {String} url The URL to submit the results to.\n     * @param {Function} format (Optiona) A function that outputs the results in a specific format.\n     *      Default is YUITest.TestFormat.XML.\n     * @constructor\n     * @namespace YUITest\n     * @class Reporter\n     */\n    YUITest.Reporter = function(url, format) {\n\n        /**\n         * The URL to submit the data to.\n         * @type String\n         * @property url\n         */\n        this.url = url;\n\n        /**\n         * The formatting function to call when submitting the data.\n         * @type Function\n         * @property format\n         */\n        this.format = format || YUITest.TestFormat.XML;\n\n        /**\n         * Extra fields to submit with the request.\n         * @type Object\n         * @property _fields\n         * @private\n         */\n        this._fields = new Object();\n\n        /**\n         * The form element used to submit the results.\n         * @type HTMLFormElement\n         * @property _form\n         * @private\n         */\n        this._form = null;\n\n        /**\n         * Iframe used as a target for form submission.\n         * @type HTMLIFrameElement\n         * @property _iframe\n         * @private\n         */\n        this._iframe = null;\n    };\n\n    YUITest.Reporter.prototype = {\n\n        //restore missing constructor\n        constructor: YUITest.Reporter,\n\n        /**\n         * Adds a field to the form that submits the results.\n         * @param {String} name The name of the field.\n         * @param {Variant} value The value of the field.\n         * @return {Void}\n         * @method addField\n         */\n        addField : function (name, value){\n            this._fields[name] = value;\n        },\n\n        /**\n         * Removes all previous defined fields.\n         * @return {Void}\n         * @method addField\n         */\n        clearFields : function(){\n            this._fields = new Object();\n        },\n\n        /**\n         * Cleans up the memory associated with the TestReporter, removing DOM elements\n         * that were created.\n         * @return {Void}\n         * @method destroy\n         */\n        destroy : function() {\n            if (this._form){\n                this._form.parentNode.removeChild(this._form);\n                this._form = null;\n            }\n            if (this._iframe){\n                this._iframe.parentNode.removeChild(this._iframe);\n                this._iframe = null;\n            }\n            this._fields = null;\n        },\n\n        /**\n         * Sends the report to the server.\n         * @param {Object} results The results object created by TestRunner.\n         * @return {Void}\n         * @method report\n         */\n        report : function(results){\n\n            //if the form hasn't been created yet, create it\n            if (!this._form){\n                this._form = document.createElement(\"form\");\n                this._form.method = \"post\";\n                this._form.style.visibility = \"hidden\";\n                this._form.style.position = \"absolute\";\n                this._form.style.top = 0;\n                document.body.appendChild(this._form);\n\n                //IE won't let you assign a name using the DOM, must do it the hacky way\n                try {\n                    this._iframe = document.createElement(\"<iframe name=\\\"yuiTestTarget\\\" />\");\n                } catch (ex){\n                    this._iframe = document.createElement(\"iframe\");\n                    this._iframe.name = \"yuiTestTarget\";\n                }\n\n                this._iframe.src = \"javascript:false\";\n                this._iframe.style.visibility = \"hidden\";\n                this._iframe.style.position = \"absolute\";\n                this._iframe.style.top = 0;\n                document.body.appendChild(this._iframe);\n\n                this._form.target = \"yuiTestTarget\";\n            }\n\n            //set the form's action\n            this._form.action = this.url;\n\n            //remove any existing fields\n            while(this._form.hasChildNodes()){\n                this._form.removeChild(this._form.lastChild);\n            }\n\n            //create default fields\n            this._fields.results = this.format(results);\n            this._fields.useragent = navigator.userAgent;\n            this._fields.timestamp = (new Date()).toLocaleString();\n\n            //add fields to the form\n            for (var prop in this._fields){\n                var value = this._fields[prop];\n                if (this._fields.hasOwnProperty(prop) && (typeof value != \"function\")){\n                    var input = document.createElement(\"input\");\n                    input.type = \"hidden\";\n                    input.name = prop;\n                    input.value = value;\n                    this._form.appendChild(input);\n                }\n            }\n\n            //remove default fields\n            delete this._fields.results;\n            delete this._fields.useragent;\n            delete this._fields.timestamp;\n\n            if (arguments[1] !== false){\n                this._form.submit();\n            }\n\n        }\n\n    };\n\n\n/**\n * Runs pages containing test suite definitions.\n * @namespace YUITest\n * @class PageManager\n * @static\n */\nYUITest.PageManager = YUITest.Util.mix(new YUITest.EventTarget(), {\n\n    /**\n     * Constant for the testpagebegin custom event\n     * @property TEST_PAGE_BEGIN_EVENT\n     * @static\n     * @type string\n     * @final\n     */\n    TEST_PAGE_BEGIN_EVENT /*:String*/ : \"testpagebegin\",\n\n    /**\n     * Constant for the testpagecomplete custom event\n     * @property TEST_PAGE_COMPLETE_EVENT\n     * @static\n     * @type string\n     * @final\n     */\n    TEST_PAGE_COMPLETE_EVENT /*:String*/ : \"testpagecomplete\",\n\n    /**\n     * Constant for the testmanagerbegin custom event\n     * @property TEST_MANAGER_BEGIN_EVENT\n     * @static\n     * @type string\n     * @final\n     */\n    TEST_MANAGER_BEGIN_EVENT /*:String*/ : \"testmanagerbegin\",\n\n    /**\n     * Constant for the testmanagercomplete custom event\n     * @property TEST_MANAGER_COMPLETE_EVENT\n     * @static\n     * @type string\n     * @final\n     */\n    TEST_MANAGER_COMPLETE_EVENT /*:String*/ : \"testmanagercomplete\",\n\n    //-------------------------------------------------------------------------\n    // Private Properties\n    //-------------------------------------------------------------------------\n\n\n    /**\n     * The URL of the page currently being executed.\n     * @type String\n     * @private\n     * @property _curPage\n     * @static\n     */\n    _curPage: null,\n\n    /**\n     * The frame used to load and run tests.\n     * @type Window\n     * @private\n     * @property _frame\n     * @static\n     */\n    _frame: null,\n\n    /**\n     * The timeout ID for the next iteration through the tests.\n     * @type int\n     * @private\n     * @property _timeoutId\n     * @static\n     */\n    _timeoutId: 0,\n\n    /**\n     * Array of pages to load.\n     * @type String[]\n     * @private\n     * @property _pages\n     * @static\n     */\n    _pages: [],\n\n    /**\n     * Aggregated results\n     * @type Object\n     * @private\n     * @property _results\n     * @static\n     */\n    _results: null,\n\n    //-------------------------------------------------------------------------\n    // Private Methods\n    //-------------------------------------------------------------------------\n\n    /**\n     * Handles TestRunner.COMPLETE_EVENT, storing the results and beginning\n     * the loop again.\n     * @param {Object} data Data about the event.\n     * @return {Void}\n     * @method _handleTestRunnerComplete\n     * @private\n     * @static\n     */\n    _handleTestRunnerComplete : function (data /*:Object*/) /*:Void*/ {\n\n        this.fire(this.TEST_PAGE_COMPLETE_EVENT, {\n            page: this._curPage,\n            results: data.results\n        });\n\n        //save results\n        //this._results[this.curPage] = data.results;\n\n        //process 'em\n        this._processResults(this._curPage, data.results);\n\n\n        //if there's more to do, set a timeout to begin again\n        if (this._pages.length){\n            this._timeoutId = setTimeout(function(){\n                YUITest.TestManager._run();\n            }, 1000);\n        } else {\n            this.fire(this.TEST_MANAGER_COMPLETE_EVENT, this._results);\n        }\n    },\n\n    /**\n     * Processes the results of a test page run, outputting log messages\n     * for failed tests.\n     * @return {Void}\n     * @method _processResults\n     * @private\n     * @static\n     */\n    _processResults : function (page, results){\n\n        var r = this._results;\n\n        r.passed += results.passed;\n        r.failed += results.failed;\n        r.ignored += results.ignored;\n        r.total += results.total;\n        r.duration += results.duration;\n\n        if (results.failed){\n            r.failedPages.push(page);\n        } else {\n            r.passedPages.push(page);\n        }\n\n        results.name = page;\n        results.type = \"page\";\n\n        r[page] = results;\n    },\n\n    /**\n     * Loads the next test page into the iframe.\n     * @return {Void}\n     * @method _run\n     * @static\n     * @private\n     */\n    _run : function () /*:Void*/ {\n\n        //set the current page\n        this._curPage = this._pages.shift();\n\n        this.fire(this.TEST_PAGE_BEGIN_EVENT, this._curPage);\n\n        //load the frame - destroy history in case there are other iframes that\n        //need testing\n        this._frame.location.replace(this._curPage);\n\n    },\n\n    //-------------------------------------------------------------------------\n    // Public Methods\n    //-------------------------------------------------------------------------\n\n    /**\n     * Signals that a test page has been loaded. This should be called from\n     * within the test page itself to notify the TestManager that it is ready.\n     * @return {Void}\n     * @method load\n     * @static\n     */\n    load : function () /*:Void*/ {\n        if (parent.YUITest.PageManager !== this){\n            parent.YUITest.PageManager.load();\n        } else {\n\n            if (this._frame) {\n                //assign event handling\n                var TestRunner = this._frame.YUITest.TestRunner;\n\n                TestRunner.subscribe(TestRunner.COMPLETE_EVENT, this._handleTestRunnerComplete, this, true);\n\n                //run it\n                TestRunner.run();\n            }\n        }\n    },\n\n    /**\n     * Sets the pages to be loaded.\n     * @param {String[]} pages An array of URLs to load.\n     * @return {Void}\n     * @method setPages\n     * @static\n     */\n    setPages : function (pages /*:String[]*/) /*:Void*/ {\n        this._pages = pages;\n    },\n\n    /**\n     * Begins the process of running the tests.\n     * @return {Void}\n     * @method start\n     * @static\n     */\n    start : function () /*:Void*/ {\n\n        if (!this._initialized) {\n\n            /**\n             * Fires when loading a test page\n             * @event testpagebegin\n             * @param curPage {string} the page being loaded\n             * @static\n             */\n\n            /**\n             * Fires when a test page is complete\n             * @event testpagecomplete\n             * @param obj {page: string, results: object} the name of the\n             * page that was loaded, and the test suite results\n             * @static\n             */\n\n            /**\n             * Fires when the test manager starts running all test pages\n             * @event testmanagerbegin\n             * @static\n             */\n\n            /**\n             * Fires when the test manager finishes running all test pages.  External\n             * test runners should subscribe to this event in order to get the\n             * aggregated test results.\n             * @event testmanagercomplete\n             * @param obj { pages_passed: int, pages_failed: int, tests_passed: int\n             *              tests_failed: int, passed: string[], failed: string[],\n             *              page_results: {} }\n             * @static\n             */\n\n            //create iframe if not already available\n            if (!this._frame){\n                var frame /*:HTMLElement*/ = document.createElement(\"iframe\");\n                frame.style.visibility = \"hidden\";\n                frame.style.position = \"absolute\";\n                document.body.appendChild(frame);\n                this._frame = frame.contentWindow || frame.contentDocument.parentWindow;\n            }\n\n            this._initialized = true;\n        }\n\n\n        // reset the results cache\n        this._results = {\n\n            passed: 0,\n            failed: 0,\n            ignored: 0,\n            total: 0,\n            type: \"report\",\n            name: \"YUI Test Results\",\n            duration: 0,\n            failedPages:[],\n            passedPages:[]\n            /*\n            // number of pages that pass\n            pages_passed: 0,\n            // number of pages that fail\n            pages_failed: 0,\n            // total number of tests passed\n            tests_passed: 0,\n            // total number of tests failed\n            tests_failed: 0,\n            // array of pages that passed\n            passed: [],\n            // array of pages that failed\n            failed: [],\n            // map of full results for each page\n            page_results: {}*/\n        };\n\n        this.fire(this.TEST_MANAGER_BEGIN_EVENT, null);\n        this._run();\n\n    },\n\n    /**\n     * Stops the execution of tests.\n     * @return {Void}\n     * @method stop\n     * @static\n     */\n    stop : function () /*:Void*/ {\n        clearTimeout(this._timeoutId);\n    }\n\n});\n\n\n    /**\n     * Runs test suites and test cases, providing events to allowing for the\n     * interpretation of test results.\n     * @namespace YUITest\n     * @class TestRunner\n     * @static\n     */\n    YUITest.TestRunner = function(){\n\n        /*(intentionally not documented)\n         * Determines if any of the array of test groups appears\n         * in the given TestRunner filter.\n         * @param {Array} testGroups The array of test groups to\n         *      search for.\n         * @param {String} filter The TestRunner groups filter.\n         */\n        function inGroups(testGroups, filter){\n            if (!filter.length){\n                return true;\n            } else {\n                if (testGroups){\n                    for (var i=0, len=testGroups.length; i < len; i++){\n                        if (filter.indexOf(\",\" + testGroups[i] + \",\") > -1){\n                            return true;\n                        }\n                    }\n                }\n                return false;\n            }\n        }\n\n        /**\n         * A node in the test tree structure. May represent a TestSuite, TestCase, or\n         * test function.\n         * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.\n         * @class TestNode\n         * @constructor\n         * @private\n         */\n        function TestNode(testObject){\n\n            /**\n             * The TestSuite, TestCase, or test function represented by this node.\n             * @type Variant\n             * @property testObject\n             */\n            this.testObject = testObject;\n\n            /**\n             * Pointer to this node's first child.\n             * @type TestNode\n             * @property firstChild\n             */\n            this.firstChild = null;\n\n            /**\n             * Pointer to this node's last child.\n             * @type TestNode\n             * @property lastChild\n             */\n            this.lastChild = null;\n\n            /**\n             * Pointer to this node's parent.\n             * @type TestNode\n             * @property parent\n             */\n            this.parent = null;\n\n            /**\n             * Pointer to this node's next sibling.\n             * @type TestNode\n             * @property next\n             */\n            this.next = null;\n\n            /**\n             * Test results for this test object.\n             * @type object\n             * @property results\n             */\n            this.results = new YUITest.Results();\n\n            //initialize results\n            if (testObject instanceof YUITest.TestSuite){\n                this.results.type = \"testsuite\";\n                this.results.name = testObject.name;\n            } else if (testObject instanceof YUITest.TestCase){\n                this.results.type = \"testcase\";\n                this.results.name = testObject.name;\n            }\n\n        }\n\n        TestNode.prototype = {\n\n            /**\n             * Appends a new test object (TestSuite, TestCase, or test function name) as a child\n             * of this node.\n             * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.\n             * @return {Void}\n             */\n            appendChild : function (testObject){\n                var node = new TestNode(testObject);\n                if (this.firstChild === null){\n                    this.firstChild = this.lastChild = node;\n                } else {\n                    this.lastChild.next = node;\n                    this.lastChild = node;\n                }\n                node.parent = this;\n                return node;\n            }\n        };\n\n        /**\n         * Runs test suites and test cases, providing events to allowing for the\n         * interpretation of test results.\n         * @namespace Test\n         * @class Runner\n         * @static\n         */\n        function TestRunner(){\n\n            //inherit from EventTarget\n            YUITest.EventTarget.call(this);\n\n            /**\n             * Suite on which to attach all TestSuites and TestCases to be run.\n             * @type YUITest.TestSuite\n             * @property masterSuite\n             * @static\n             * @private\n             */\n            this.masterSuite = new YUITest.TestSuite(\"yuitests\" + (new Date()).getTime());\n\n            /**\n             * Pointer to the current node in the test tree.\n             * @type TestNode\n             * @private\n             * @property _cur\n             * @static\n             */\n            this._cur = null;\n\n            /**\n             * Pointer to the root node in the test tree.\n             * @type TestNode\n             * @private\n             * @property _root\n             * @static\n             */\n            this._root = null;\n\n            /**\n             * Indicates if the TestRunner will log events or not.\n             * @type Boolean\n             * @property _log\n             * @private\n             * @static\n             */\n            this._log = true;\n\n            /**\n             * Indicates if the TestRunner is waiting as a result of\n             * wait() being called.\n             * @type Boolean\n             * @property _waiting\n             * @private\n             * @static\n             */\n            this._waiting = false;\n\n            /**\n             * Indicates if the TestRunner is currently running tests.\n             * @type Boolean\n             * @private\n             * @property _running\n             * @static\n             */\n            this._running = false;\n\n            /**\n             * Holds copy of the results object generated when all tests are\n             * complete.\n             * @type Object\n             * @private\n             * @property _lastResults\n             * @static\n             */\n            this._lastResults = null;\n\n            /**\n             * Data object that is passed around from method to method.\n             * @type Object\n             * @private\n             * @property _data\n             * @static\n             */\n            this._context = null;\n\n            /**\n             * The list of test groups to run. The list is represented\n             * by a comma delimited string with commas at the start and\n             * end.\n             * @type String\n             * @private\n             * @property _groups\n             * @static\n             */\n            this._groups = \"\";\n        }\n\n        TestRunner.prototype = YUITest.Util.mix(new YUITest.EventTarget(), {\n\n            //restore prototype\n            constructor: YUITest.TestRunner,\n\n            //-------------------------------------------------------------------------\n            // Constants\n            //-------------------------------------------------------------------------\n\n            /**\n             * Fires when a test case is opened but before the first\n             * test is executed.\n             * @event testcasebegin\n             * @static\n             */\n            TEST_CASE_BEGIN_EVENT : \"testcasebegin\",\n\n            /**\n             * Fires when all tests in a test case have been executed.\n             * @event testcasecomplete\n             * @static\n             */\n            TEST_CASE_COMPLETE_EVENT : \"testcasecomplete\",\n\n            /**\n             * Fires when a test suite is opened but before the first\n             * test is executed.\n             * @event testsuitebegin\n             * @static\n             */\n            TEST_SUITE_BEGIN_EVENT : \"testsuitebegin\",\n\n            /**\n             * Fires when all test cases in a test suite have been\n             * completed.\n             * @event testsuitecomplete\n             * @static\n             */\n            TEST_SUITE_COMPLETE_EVENT : \"testsuitecomplete\",\n\n            /**\n             * Fires when a test has passed.\n             * @event pass\n             * @static\n             */\n            TEST_PASS_EVENT : \"pass\",\n\n            /**\n             * Fires when a test has failed.\n             * @event fail\n             * @static\n             */\n            TEST_FAIL_EVENT : \"fail\",\n\n            /**\n             * Fires when a non-test method has an error.\n             * @event error\n             * @static\n             */\n            ERROR_EVENT : \"error\",\n\n            /**\n             * Fires when a test has been ignored.\n             * @event ignore\n             * @static\n             */\n            TEST_IGNORE_EVENT : \"ignore\",\n\n            /**\n             * Fires when all test suites and test cases have been completed.\n             * @event complete\n             * @static\n             */\n            COMPLETE_EVENT : \"complete\",\n\n            /**\n             * Fires when the run() method is called.\n             * @event begin\n             * @static\n             */\n            BEGIN_EVENT : \"begin\",\n\n            //-------------------------------------------------------------------------\n            // Test Tree-Related Methods\n            //-------------------------------------------------------------------------\n\n            /**\n             * Adds a test case to the test tree as a child of the specified node.\n             * @param {TestNode} parentNode The node to add the test case to as a child.\n             * @param {YUITest.TestCase} testCase The test case to add.\n             * @return {Void}\n             * @static\n             * @private\n             * @method _addTestCaseToTestTree\n             */\n           _addTestCaseToTestTree : function (parentNode, testCase){\n\n                //add the test suite\n                var node = parentNode.appendChild(testCase),\n                    prop,\n                    testName;\n\n                //iterate over the items in the test case\n                for (prop in testCase){\n                    if ((prop.indexOf(\"test\") === 0 || prop.indexOf(\" \") > -1) && typeof testCase[prop] == \"function\"){\n                        node.appendChild(prop);\n                    }\n                }\n\n            },\n\n            /**\n             * Adds a test suite to the test tree as a child of the specified node.\n             * @param {TestNode} parentNode The node to add the test suite to as a child.\n             * @param {YUITest.TestSuite} testSuite The test suite to add.\n             * @return {Void}\n             * @static\n             * @private\n             * @method _addTestSuiteToTestTree\n             */\n            _addTestSuiteToTestTree : function (parentNode, testSuite) {\n\n                //add the test suite\n                var node = parentNode.appendChild(testSuite);\n\n                //iterate over the items in the master suite\n                for (var i=0; i < testSuite.items.length; i++){\n                    if (testSuite.items[i] instanceof YUITest.TestSuite) {\n                        this._addTestSuiteToTestTree(node, testSuite.items[i]);\n                    } else if (testSuite.items[i] instanceof YUITest.TestCase) {\n                        this._addTestCaseToTestTree(node, testSuite.items[i]);\n                    }\n                }\n            },\n\n            /**\n             * Builds the test tree based on items in the master suite. The tree is a hierarchical\n             * representation of the test suites, test cases, and test functions. The resulting tree\n             * is stored in _root and the pointer _cur is set to the root initially.\n             * @return {Void}\n             * @static\n             * @private\n             * @method _buildTestTree\n             */\n            _buildTestTree : function () {\n\n                this._root = new TestNode(this.masterSuite);\n                //this._cur = this._root;\n\n                //iterate over the items in the master suite\n                for (var i=0; i < this.masterSuite.items.length; i++){\n                    if (this.masterSuite.items[i] instanceof YUITest.TestSuite) {\n                        this._addTestSuiteToTestTree(this._root, this.masterSuite.items[i]);\n                    } else if (this.masterSuite.items[i] instanceof YUITest.TestCase) {\n                        this._addTestCaseToTestTree(this._root, this.masterSuite.items[i]);\n                    }\n                }\n\n            },\n\n            //-------------------------------------------------------------------------\n            // Private Methods\n            //-------------------------------------------------------------------------\n\n            /**\n             * Handles the completion of a test object's tests. Tallies test results\n             * from one level up to the next.\n             * @param {TestNode} node The TestNode representing the test object.\n             * @return {Void}\n             * @method _handleTestObjectComplete\n             * @private\n             */\n            _handleTestObjectComplete : function (node) {\n                var parentNode;\n\n                if (typeof node.testObject == \"object\" && node !== null){\n                    parentNode = node.parent;\n\n                    if (parentNode){\n                        parentNode.results.include(node.results);\n                        parentNode.results[node.testObject.name] = node.results;\n                    }\n\n                    if (node.testObject instanceof YUITest.TestSuite){\n                        this._execNonTestMethod(node, \"tearDown\", false);\n                        node.results.duration = (new Date()) - node._start;\n                        this.fire({ type: this.TEST_SUITE_COMPLETE_EVENT, testSuite: node.testObject, results: node.results});\n                    } else if (node.testObject instanceof YUITest.TestCase){\n                        this._execNonTestMethod(node, \"destroy\", false);\n                        node.results.duration = (new Date()) - node._start;\n                        this.fire({ type: this.TEST_CASE_COMPLETE_EVENT, testCase: node.testObject, results: node.results});\n                    }\n                }\n            },\n\n            //-------------------------------------------------------------------------\n            // Navigation Methods\n            //-------------------------------------------------------------------------\n\n            /**\n             * Retrieves the next node in the test tree.\n             * @return {TestNode} The next node in the test tree or null if the end is reached.\n             * @private\n             * @static\n             * @method _next\n             */\n            _next : function () {\n\n                if (this._cur === null){\n                    this._cur = this._root;\n                } else if (this._cur.firstChild) {\n                    this._cur = this._cur.firstChild;\n                } else if (this._cur.next) {\n                    this._cur = this._cur.next;\n                } else {\n                    while (this._cur && !this._cur.next && this._cur !== this._root){\n                        this._handleTestObjectComplete(this._cur);\n                        this._cur = this._cur.parent;\n                    }\n\n                    this._handleTestObjectComplete(this._cur);\n\n                    if (this._cur == this._root){\n                        this._cur.results.type = \"report\";\n                        this._cur.results.timestamp = (new Date()).toLocaleString();\n                        this._cur.results.duration = (new Date()) - this._cur._start;\n                        this._lastResults = this._cur.results;\n                        this._running = false;\n                        this.fire({ type: this.COMPLETE_EVENT, results: this._lastResults});\n                        this._cur = null;\n                    } else {\n                        this._cur = this._cur.next;\n                    }\n                }\n\n                return this._cur;\n            },\n\n            /**\n             * Executes a non-test method (init, setUp, tearDown, destroy)\n             * and traps an errors. If an error occurs, an error event is\n             * fired.\n             * @param {Object} node The test node in the testing tree.\n             * @param {String} methodName The name of the method to execute.\n             * @param {Boolean} allowAsync Determines if the method can be called asynchronously.\n             * @return {Boolean} True if an async method was called, false if not.\n             * @method _execNonTestMethod\n             * @private\n             */\n            _execNonTestMethod: function(node, methodName, allowAsync){\n                var testObject = node.testObject,\n                    event = { type: this.ERROR_EVENT };\n                try {\n                    if (allowAsync && testObject[\"async:\" + methodName]){\n                        testObject[\"async:\" + methodName](this._context);\n                        return true;\n                    } else {\n                        testObject[methodName](this._context);\n                    }\n                } catch (ex){\n                    node.results.errors++;\n                    event.error = ex;\n                    event.methodName = methodName;\n                    if (testObject instanceof YUITest.TestCase){\n                        event.testCase = testObject;\n                    } else {\n                        event.testSuite = testSuite;\n                    }\n\n                    this.fire(event);\n                }\n\n                return false;\n            },\n\n            /**\n             * Runs a test case or test suite, returning the results.\n             * @param {YUITest.TestCase|YUITest.TestSuite} testObject The test case or test suite to run.\n             * @return {Object} Results of the execution with properties passed, failed, and total.\n             * @private\n             * @method _run\n             * @static\n             */\n            _run : function () {\n\n                //flag to indicate if the TestRunner should wait before continuing\n                var shouldWait = false;\n\n                //get the next test node\n                var node = this._next();\n\n                if (node !== null) {\n\n                    //set flag to say the testrunner is running\n                    this._running = true;\n\n                    //eliminate last results\n                    this._lastResult = null;\n\n                    var testObject = node.testObject;\n\n                    //figure out what to do\n                    if (typeof testObject == \"object\" && testObject !== null){\n                        if (testObject instanceof YUITest.TestSuite){\n                            this.fire({ type: this.TEST_SUITE_BEGIN_EVENT, testSuite: testObject });\n                            node._start = new Date();\n                            this._execNonTestMethod(node, \"setUp\" ,false);\n                        } else if (testObject instanceof YUITest.TestCase){\n                            this.fire({ type: this.TEST_CASE_BEGIN_EVENT, testCase: testObject });\n                            node._start = new Date();\n\n                            //regular or async init\n                            /*try {\n                                if (testObject[\"async:init\"]){\n                                    testObject[\"async:init\"](this._context);\n                                    return;\n                                } else {\n                                    testObject.init(this._context);\n                                }\n                            } catch (ex){\n                                node.results.errors++;\n                                this.fire({ type: this.ERROR_EVENT, error: ex, testCase: testObject, methodName: \"init\" });\n                            }*/\n                            if(this._execNonTestMethod(node, \"init\", true)){\n                                return;\n                            }\n                        }\n\n                        //some environments don't support setTimeout\n                        if (typeof setTimeout != \"undefined\"){\n                            setTimeout(function(){\n                                YUITest.TestRunner._run();\n                            }, 0);\n                        } else {\n                            this._run();\n                        }\n                    } else {\n                        this._runTest(node);\n                    }\n\n                }\n            },\n\n            _resumeTest : function (segment) {\n\n                //get relevant information\n                var node = this._cur;\n\n                //we know there's no more waiting now\n                this._waiting = false;\n\n                //if there's no node, it probably means a wait() was called after resume()\n                if (!node){\n                    //TODO: Handle in some way?\n                    //console.log(\"wait() called after resume()\");\n                    //this.fire(\"error\", { testCase: \"(unknown)\", test: \"(unknown)\", error: new Error(\"wait() called after resume()\")} );\n                    return;\n                }\n\n                var testName = node.testObject;\n                var testCase = node.parent.testObject;\n\n                //cancel other waits if available\n                if (testCase.__yui_wait){\n                    clearTimeout(testCase.__yui_wait);\n                    delete testCase.__yui_wait;\n                }\n\n                //get the \"should\" test cases\n                var shouldFail = testName.indexOf(\"fail:\") === 0 ||\n                                    (testCase._should.fail || {})[testName];\n                var shouldError = (testCase._should.error || {})[testName];\n\n                //variable to hold whether or not the test failed\n                var failed = false;\n                var error = null;\n\n                //try the test\n                try {\n\n                    //run the test\n                    segment.call(testCase, this._context);\n\n                    //if the test hasn't already failed and doesn't have any asserts...\n                    if(YUITest.Assert._getCount() == 0){\n                        throw new YUITest.AssertionError(\"Test has no asserts.\");\n                    }\n                    //if it should fail, and it got here, then it's a fail because it didn't\n                     else if (shouldFail){\n                        error = new YUITest.ShouldFail();\n                        failed = true;\n                    } else if (shouldError){\n                        error = new YUITest.ShouldError();\n                        failed = true;\n                    }\n\n                } catch (thrown){\n\n                    //cancel any pending waits, the test already failed\n                    if (testCase.__yui_wait){\n                        clearTimeout(testCase.__yui_wait);\n                        delete testCase.__yui_wait;\n                    }\n\n                    //figure out what type of error it was\n                    if (thrown instanceof YUITest.AssertionError) {\n                        if (!shouldFail){\n                            error = thrown;\n                            failed = true;\n                        }\n                    } else if (thrown instanceof YUITest.Wait){\n\n                        if (typeof thrown.segment == \"function\"){\n                            if (typeof thrown.delay == \"number\"){\n\n                                //some environments don't support setTimeout\n                                if (typeof setTimeout != \"undefined\"){\n                                    testCase.__yui_wait = setTimeout(function(){\n                                        YUITest.TestRunner._resumeTest(thrown.segment);\n                                    }, thrown.delay);\n                                    this._waiting = true;\n                                } else {\n                                    throw new Error(\"Asynchronous tests not supported in this environment.\");\n                                }\n                            }\n                        }\n\n                        return;\n\n                    } else {\n                        //first check to see if it should error\n                        if (!shouldError) {\n                            error = new YUITest.UnexpectedError(thrown);\n                            failed = true;\n                        } else {\n                            //check to see what type of data we have\n                            if (typeof shouldError == \"string\"){\n\n                                //if it's a string, check the error message\n                                if (thrown.message != shouldError){\n                                    error = new YUITest.UnexpectedError(thrown);\n                                    failed = true;\n                                }\n                            } else if (typeof shouldError == \"function\"){\n\n                                //if it's a function, see if the error is an instance of it\n                                if (!(thrown instanceof shouldError)){\n                                    error = new YUITest.UnexpectedError(thrown);\n                                    failed = true;\n                                }\n\n                            } else if (typeof shouldError == \"object\" && shouldError !== null){\n\n                                //if it's an object, check the instance and message\n                                if (!(thrown instanceof shouldError.constructor) ||\n                                        thrown.message != shouldError.message){\n                                    error = new YUITest.UnexpectedError(thrown);\n                                    failed = true;\n                                }\n\n                            }\n\n                        }\n                    }\n\n                }\n\n                //fire appropriate event\n                if (failed) {\n                    this.fire({ type: this.TEST_FAIL_EVENT, testCase: testCase, testName: testName, error: error });\n                } else {\n                    this.fire({ type: this.TEST_PASS_EVENT, testCase: testCase, testName: testName });\n                }\n\n                //run the tear down\n                this._execNonTestMethod(node.parent, \"tearDown\", false);\n\n                //reset the assert count\n                YUITest.Assert._reset();\n\n                //calculate duration\n                var duration = (new Date()) - node._start;\n\n                //update results\n                node.parent.results[testName] = {\n                    result: failed ? \"fail\" : \"pass\",\n                    message: error ? error.getMessage() : \"Test passed\",\n                    type: \"test\",\n                    name: testName,\n                    duration: duration\n                };\n\n                if (failed){\n                    node.parent.results.failed++;\n                } else {\n                    node.parent.results.passed++;\n                }\n                node.parent.results.total++;\n\n                //set timeout not supported in all environments\n                if (typeof setTimeout != \"undefined\"){\n                    setTimeout(function(){\n                        YUITest.TestRunner._run();\n                    }, 0);\n                } else {\n                    this._run();\n                }\n\n            },\n\n            /**\n             * Handles an error as if it occurred within the currently executing\n             * test. This is for mock methods that may be called asynchronously\n             * and therefore out of the scope of the TestRunner. Previously, this\n             * error would bubble up to the browser. Now, this method is used\n             * to tell TestRunner about the error. This should never be called\n             * by anyplace other than the Mock object.\n             * @param {Error} error The error object.\n             * @return {Void}\n             * @method _handleError\n             * @private\n             * @static\n             */\n            _handleError: function(error){\n\n                if (this._waiting){\n                    this._resumeTest(function(){\n                        throw error;\n                    });\n                } else {\n                    throw error;\n                }\n\n            },\n\n            /**\n             * Runs a single test based on the data provided in the node.\n             * @param {TestNode} node The TestNode representing the test to run.\n             * @return {Void}\n             * @static\n             * @private\n             * @name _runTest\n             */\n            _runTest : function (node) {\n\n                //get relevant information\n                var testName = node.testObject,\n                    testCase = node.parent.testObject,\n                    test = testCase[testName],\n\n                    //get the \"should\" test cases\n                    shouldIgnore = testName.indexOf(\"ignore:\") === 0 ||\n                                    !inGroups(testCase.groups, this._groups) ||\n                                    (testCase._should.ignore || {})[testName];   //deprecated\n\n                //figure out if the test should be ignored or not\n                if (shouldIgnore){\n\n                    //update results\n                    node.parent.results[testName] = {\n                        result: \"ignore\",\n                        message: \"Test ignored\",\n                        type: \"test\",\n                        name: testName.indexOf(\"ignore:\") === 0 ? testName.substring(7) : testName\n                    };\n\n                    node.parent.results.ignored++;\n                    node.parent.results.total++;\n\n                    this.fire({ type: this.TEST_IGNORE_EVENT,  testCase: testCase, testName: testName });\n\n                    //some environments don't support setTimeout\n                    if (typeof setTimeout != \"undefined\"){\n                        setTimeout(function(){\n                            YUITest.TestRunner._run();\n                        }, 0);\n                    } else {\n                        this._run();\n                    }\n\n                } else {\n\n                    //mark the start time\n                    node._start = new Date();\n\n                    //run the setup\n                    this._execNonTestMethod(node.parent, \"setUp\", false);\n\n                    //now call the body of the test\n                    this._resumeTest(test);\n                }\n\n            },\n\n            //-------------------------------------------------------------------------\n            // Misc Methods\n            //-------------------------------------------------------------------------\n\n            /**\n             * Retrieves the name of the current result set.\n             * @return {String} The name of the result set.\n             * @method getName\n             */\n            getName: function(){\n                return this.masterSuite.name;\n            },\n\n            /**\n             * The name assigned to the master suite of the TestRunner. This is the name\n             * that is output as the root's name when results are retrieved.\n             * @param {String} name The name of the result set.\n             * @return {Void}\n             * @method setName\n             */\n            setName: function(name){\n                this.masterSuite.name = name;\n            },\n\n            //-------------------------------------------------------------------------\n            // Public Methods\n            //-------------------------------------------------------------------------\n\n            /**\n             * Adds a test suite or test case to the list of test objects to run.\n             * @param testObject Either a TestCase or a TestSuite that should be run.\n             * @return {Void}\n             * @method add\n             * @static\n             */\n            add : function (testObject) {\n                this.masterSuite.add(testObject);\n                return this;\n            },\n\n            /**\n             * Removes all test objects from the runner.\n             * @return {Void}\n             * @method clear\n             * @static\n             */\n            clear : function () {\n                this.masterSuite = new YUITest.TestSuite(\"yuitests\" + (new Date()).getTime());\n            },\n\n            /**\n             * Indicates if the TestRunner is waiting for a test to resume\n             * @return {Boolean} True if the TestRunner is waiting, false if not.\n             * @method isWaiting\n             * @static\n             */\n            isWaiting: function() {\n                return this._waiting;\n            },\n\n            /**\n             * Indicates that the TestRunner is busy running tests and therefore can't\n             * be stopped and results cannot be gathered.\n             * @return {Boolean} True if the TestRunner is running, false if not.\n             * @method isRunning\n             */\n            isRunning: function(){\n                return this._running;\n            },\n\n            /**\n             * Returns the last complete results set from the TestRunner. Null is returned\n             * if the TestRunner is running or no tests have been run.\n             * @param {Function} format (Optional) A test format to return the results in.\n             * @return {Object|String} Either the results object or, if a test format is\n             *      passed as the argument, a string representing the results in a specific\n             *      format.\n             * @method getResults\n             */\n            getResults: function(format){\n                if (!this._running && this._lastResults){\n                    if (typeof format == \"function\"){\n                        return format(this._lastResults);\n                    } else {\n                        return this._lastResults;\n                    }\n                } else {\n                    return null;\n                }\n            },\n\n            /**\n             * Returns the coverage report for the files that have been executed.\n             * This returns only coverage information for files that have been\n             * instrumented using YUI Test Coverage and only those that were run\n             * in the same pass.\n             * @param {Function} format (Optional) A coverage format to return results in.\n             * @return {Object|String} Either the coverage object or, if a coverage\n             *      format is specified, a string representing the results in that format.\n             * @method getCoverage\n             */\n            getCoverage: function(format){\n                if (!this._running && typeof _yuitest_coverage == \"object\"){\n                    if (typeof format == \"function\"){\n                        return format(_yuitest_coverage);\n                    } else {\n                        return _yuitest_coverage;\n                    }\n                } else {\n                    return null;\n                }\n            },\n\n            /**\n             * Used to continue processing when a method marked with\n             * \"async:\" is executed. This should not be used in test\n             * methods, only in init(). Each argument is a string, and\n             * when the returned function is executed, the arguments\n             * are assigned to the context data object using the string\n             * as the key name (value is the argument itself).\n             * @private\n             * @return {Function} A callback function.\n             */\n            callback: function(){\n                var names   = arguments,\n                    data    = this._context,\n                    that    = this;\n\n                return function(){\n                    for (var i=0; i < arguments.length; i++){\n                        data[names[i]] = arguments[i];\n                    }\n                    that._run();\n                };\n            },\n\n            /**\n             * Resumes the TestRunner after wait() was called.\n             * @param {Function} segment The function to run as the rest\n             *      of the haulted test.\n             * @return {Void}\n             * @method resume\n             * @static\n             */\n            resume : function (segment) {\n                if (this._waiting){\n                    this._resumeTest(segment || function(){});\n                } else {\n                    throw new Error(\"resume() called without wait().\");\n                }\n            },\n\n            /**\n             * Runs the test suite.\n             * @param {Object|Boolean} options (Optional) Options for the runner:\n             *      <code>oldMode</code> indicates the TestRunner should work in the YUI <= 2.8 way\n             *      of internally managing test suites. <code>groups</code> is an array\n             *      of test groups indicating which tests to run.\n             * @return {Void}\n             * @method run\n             * @static\n             */\n            run : function (options) {\n\n                options = options || {};\n\n                //pointer to runner to avoid scope issues\n                var runner  = YUITest.TestRunner,\n                    oldMode = options.oldMode;\n\n\n                //if there's only one suite on the masterSuite, move it up\n                if (!oldMode && this.masterSuite.items.length == 1 && this.masterSuite.items[0] instanceof YUITest.TestSuite){\n                    this.masterSuite = this.masterSuite.items[0];\n                }\n\n                //determine if there are any groups to filter on\n                runner._groups = (options.groups instanceof Array) ? \",\" + options.groups.join(\",\") + \",\" : \"\";\n\n                //initialize the runner\n                runner._buildTestTree();\n                runner._context = {};\n                runner._root._start = new Date();\n\n                //fire the begin event\n                runner.fire(runner.BEGIN_EVENT);\n\n                //begin the testing\n                runner._run();\n            }\n        });\n\n        return new TestRunner();\n\n    }();\n/**\n * Main CSSLint object.\n * @class CSSLint\n * @static\n * @extends parserlib.util.EventTarget\n */\nvar CSSLint = (function(){\n\n    var rules      = [],\n        formatters = [],\n        api        = new parserlib.util.EventTarget();\n        \n    api.version = \"@VERSION@\";\n\n    //-------------------------------------------------------------------------\n    // Rule Management\n    //-------------------------------------------------------------------------\n\n    /**\n     * Adds a new rule to the engine.\n     * @param {Object} rule The rule to add.\n     * @method addRule\n     */\n    api.addRule = function(rule){\n        rules.push(rule);\n        rules[rule.id] = rule;\n    };\n\n    /**\n     * Clears all rule from the engine.\n     * @method clearRules\n     */\n    api.clearRules = function(){\n        rules = [];\n    };\n\n    //-------------------------------------------------------------------------\n    // Formatters\n    //-------------------------------------------------------------------------\n\n    /**\n     * Adds a new formatter to the engine.\n     * @param {Object} formatter The formatter to add.\n     * @method addFormatter\n     */\n    api.addFormatter = function(formatter) {\n        // formatters.push(formatter);\n        formatters[formatter.id] = formatter;\n    };\n    \n    /**\n     * Retrieves a formatter for use.\n     * @param {String} formatId The name of the format to retrieve.\n     * @return {Object} The formatter or undefined.\n     * @method getFormatter\n     */\n    api.getFormatter = function(formatId){\n        return formatters[formatId];\n    };\n    \n    /**\n     * Formats the results in a particular format for a single file.\n     * @param {Object} result The results returned from CSSLint.verify().\n     * @param {String} filename The filename for which the results apply.\n     * @param {String} formatId The name of the formatter to use.\n     * @return {String} A formatted string for the results.\n     * @method format\n     */\n    api.format = function(results, filename, formatId) {\n        var formatter = this.getFormatter(formatId),\n            result = null;\n            \n        if (formatter){\n            result = formatter.startFormat();\n            result += formatter.formatResults(results, filename);\n            result += formatter.endFormat();\n        }\n        \n        return result;\n    }    \n    \n    /**\n     * Indicates if the given format is supported.\n     * @param {String} formatId The ID of the format to check.\n     * @return {Boolean} True if the format exists, false if not.\n     * @method hasFormat\n     */\n    api.hasFormat = function(formatId){\n        return formatters.hasOwnProperty(formatId);\n    };\n\n    //-------------------------------------------------------------------------\n    // Verification\n    //-------------------------------------------------------------------------\n\n    /**\n     * Starts the verification process for the given CSS text.\n     * @param {String} text The CSS text to verify.\n     * @param {Object} ruleset (Optional) List of rules to apply. If null, then\n     *      all rules are used.\n     * @return {Object} Results of the verification.\n     * @method verify\n     */\n    api.verify = function(text, ruleset){\n\n        var i       = 0,\n            len     = rules.length,\n            reporter,\n            lines,\n            parser = new parserlib.css.Parser({ starHack: true, ieFilters: true,\n                                                underscoreHack: true, strict: false });\n\n        lines = text.split(/\\n\\r?/g);\n        reporter = new Reporter(lines);\n\n        if (!ruleset){\n            while (i < len){\n                rules[i++].init(parser, reporter);\n            }\n        } else {\n            ruleset.errors = 1;       //always report parsing errors\n            for (i in ruleset){\n                if(ruleset.hasOwnProperty(i)){\n                    if (rules[i]){\n                        rules[i].init(parser, reporter);\n                    }\n                }\n            }\n        }\n\n        //capture most horrible error type\n        try {\n            parser.parse(text);\n        } catch (ex) {\n            reporter.error(\"Fatal error, cannot continue: \" + ex.message, ex.line, ex.col);\n        }\n\n        return {\n            messages    : reporter.messages,\n            stats       : reporter.stats\n        };\n    };\n\n    //-------------------------------------------------------------------------\n    // Publish the API\n    //-------------------------------------------------------------------------\n\n    return api;\n\n})();\n/**\n * An instance of Report is used to report results of the\n * verification back to the main API.\n * @class Reporter\n * @constructor\n * @param {String[]} lines The text lines of the source.\n */\nfunction Reporter(lines){\n\n    /**\n     * List of messages being reported.\n     * @property messages\n     * @type String[]\n     */\n    this.messages = [];\n\n    /**\n     * List of statistics being reported.\n     * @property stats\n     * @type String[]\n     */\n    this.stats = [];\n\n    /**\n     * Lines of code being reported on. Used to provide contextual information\n     * for messages.\n     * @property lines\n     * @type String[]\n     */\n    this.lines = lines;\n}\n\nReporter.prototype = {\n\n    //restore constructor\n    constructor: Reporter,\n\n    /**\n     * Report an error.\n     * @param {String} message The message to store.\n     * @param {int} line The line number.\n     * @param {int} col The column number.\n     * @param {Object} rule The rule this message relates to.\n     * @method error\n     */\n    error: function(message, line, col, rule){\n        this.messages.push({\n            type    : \"error\",\n            line    : line,\n            col     : col,\n            message : message,\n            evidence: this.lines[line-1],\n            rule    : rule\n        });\n    },\n\n    /**\n     * Report an warning.\n     * @param {String} message The message to store.\n     * @param {int} line The line number.\n     * @param {int} col The column number.\n     * @param {Object} rule The rule this message relates to.\n     * @method warn\n     */\n    warn: function(message, line, col, rule){\n        this.messages.push({\n            type    : \"warning\",\n            line    : line,\n            col     : col,\n            message : message,\n            evidence: this.lines[line-1],\n            rule    : rule\n        });\n    },\n\n    /**\n     * Report some informational text.\n     * @param {String} message The message to store.\n     * @param {int} line The line number.\n     * @param {int} col The column number.\n     * @param {Object} rule The rule this message relates to.\n     * @method info\n     */\n    info: function(message, line, col, rule){\n        this.messages.push({\n            type    : \"info\",\n            line    : line,\n            col     : col,\n            message : message,\n            evidence: this.lines[line-1],\n            rule    : rule\n        });\n    },\n\n    /**\n     * Report some rollup error information.\n     * @param {String} message The message to store.\n     * @param {Object} rule The rule this message relates to.\n     * @method rollupError\n     */\n    rollupError: function(message, rule){\n        this.messages.push({\n            type    : \"error\",\n            rollup  : true,\n            message : message,\n            rule    : rule\n        });\n    },\n\n    /**\n     * Report some rollup warning information.\n     * @param {String} message The message to store.\n     * @param {Object} rule The rule this message relates to.\n     * @method rollupWarn\n     */\n    rollupWarn: function(message, rule){\n        this.messages.push({\n            type    : \"warning\",\n            rollup  : true,\n            message : message,\n            rule    : rule\n        });\n    },\n\n    /**\n     * Report a statistic.\n     * @param {String} name The name of the stat to store.\n     * @param {Variant} value The value of the stat.\n     * @method stat\n     */\n    stat: function(name, value){\n        this.stats[name] = value;\n    }\n};\n/*\n * Utility functions that make life easier.\n */\n\n/*\n * Adds all properties from supplier onto receiver,\n * overwriting if the same name already exists on\n * reciever.\n * @param {Object} The object to receive the properties.\n * @param {Object} The object to provide the properties.\n * @return {Object} The receiver\n */\nfunction mix(reciever, supplier){\n    var prop;\n\n    for (prop in supplier){\n        if (supplier.hasOwnProperty(prop)){\n            receiver[prop] = supplier[prop];\n        }\n    }\n\n    return prop;\n}\n\n/*\n * Polyfill for array indexOf() method.\n * @param {Array} values The array to search.\n * @param {Variant} value The value to search for.\n * @return {int} The index of the value if found, -1 if not.\n */\nfunction indexOf(values, value){\n    if (values.indexOf){\n        return values.indexOf(value);\n    } else {\n        for (var i=0, len=values.length; i < len; i++){\n            if (values[i] === value){\n                return i;\n            }\n        }\n        return -1;\n    }\n}\n/*\n * Rule: Don't use adjoining classes (.foo.bar).\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"adjoining-classes\",\n    name: \"Adjoining Classes\",\n    desc: \"Don't use adjoining classes.\",\n    browsers: \"IE6\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this;\n        parser.addListener(\"startrule\", function(event){\n            var selectors = event.selectors,\n                selector,\n                part,\n                modifier,\n                classCount,\n                i, j, k;\n\n            for (i=0; i < selectors.length; i++){\n                selector = selectors[i];\n                for (j=0; j < selector.parts.length; j++){\n                    part = selector.parts[j];\n                    if (part instanceof parserlib.css.SelectorPart){\n                        classCount = 0;\n                        for (k=0; k < part.modifiers.length; k++){\n                            modifier = part.modifiers[k];\n                            if (modifier.type == \"class\"){\n                                classCount++;\n                            }\n                            if (classCount > 1){\n                                reporter.warn(\"Don't use adjoining classes.\", part.line, part.col, rule);\n                            }\n                        }\n                    }\n                }\n            }\n        });\n    }\n\n});\n/*\n * Rule: Don't use width or height when using padding or border. \n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"box-model\",\n    name: \"Box Model\",\n    desc: \"Don't use width or height when using padding or border.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this,\n            widthProperties = {\n                border: 1,\n                \"border-left\": 1,\n                \"border-right\": 1,\n                padding: 1,\n                \"padding-left\": 1,\n                \"padding-right\": 1\n            },\n            heightProperties = {\n                border: 1,\n                \"border-bottom\": 1,\n                \"border-top\": 1,\n                padding: 1,\n                \"padding-bottom\": 1,\n                \"padding-top\": 1\n            },\n            properties;\n\n        parser.addListener(\"startrule\", function(){\n            properties = {\n            };\n        });\n\n        parser.addListener(\"property\", function(event){\n            var name = event.property.text.toLowerCase();\n            \n            if (heightProperties[name] || widthProperties[name]){\n                if (!/^0\\S*$/.test(event.value) && !(name == \"border\" && event.value == \"none\")){\n                    properties[name] = { line: event.property.line, col: event.property.col };\n                }\n            } else {\n                if (name == \"width\" || name == \"height\"){\n                    properties[name] = 1;\n                }\n            }\n            \n        });\n\n        parser.addListener(\"endrule\", function(){\n            var prop;\n            if (properties[\"height\"]){\n                for (prop in heightProperties){\n                    if (heightProperties.hasOwnProperty(prop) && properties[prop]){\n                        reporter.warn(\"Broken box model: using height with \" + prop + \".\", properties[prop].line, properties[prop].col, rule);\n                    }\n                }\n            }\n\n            if (properties[\"width\"]){\n                for (prop in widthProperties){\n                    if (widthProperties.hasOwnProperty(prop) && properties[prop]){\n                        reporter.warn(\"Broken box model: using width with \" + prop + \".\", properties[prop].line, properties[prop].col, rule);\n                    }\n                }\n            }\n\n        });\n    }\n\n});\n/*\n * Rule: Include all compatible vendor prefixes to reach a wider\n * range of users.\n */\n/*global CSSLint*/ \nCSSLint.addRule({\n\n    //rule information\n    id: \"compatible-vendor-prefixes\",\n    name: \"Compatible Vendor Prefixes\",\n    desc: \"Include all compatible vendor prefixes to reach a wider range of users.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function (parser, reporter) {\n        var rule = this,\n            compatiblePrefixes,\n            properties,\n            prop,\n            variations,\n            prefixed,\n            i,\n            len,\n            arrayPush = Array.prototype.push,\n            applyTo = [];\n\n        // See http://peter.sh/experiments/vendor-prefixed-css-property-overview/ for details\n        compatiblePrefixes = {\n            \"animation\"                  : \"webkit moz\",\n            \"animation-delay\"            : \"webkit moz\",\n            \"animation-direction\"        : \"webkit moz\",\n            \"animation-duration\"         : \"webkit moz\",\n            \"animation-fill-mode\"        : \"webkit moz\",\n            \"animation-iteration-count\"  : \"webkit moz\",\n            \"animation-name\"             : \"webkit moz\",\n            \"animation-play-state\"       : \"webkit moz\",\n            \"animation-timing-function\"  : \"webkit moz\",\n            \"appearance\"                 : \"webkit moz\",\n            \"border-end\"                 : \"webkit moz\",\n            \"border-end-color\"           : \"webkit moz\",\n            \"border-end-style\"           : \"webkit moz\",\n            \"border-end-width\"           : \"webkit moz\",\n            \"border-image\"               : \"webkit moz o\",\n            \"border-radius\"              : \"webkit moz\",\n            \"border-start\"               : \"webkit moz\",\n            \"border-start-color\"         : \"webkit moz\",\n            \"border-start-style\"         : \"webkit moz\",\n            \"border-start-width\"         : \"webkit moz\",\n            \"box-align\"                  : \"webkit moz ms\",\n            \"box-direction\"              : \"webkit moz ms\",\n            \"box-flex\"                   : \"webkit moz ms\",\n            \"box-lines\"                  : \"webkit ms\",\n            \"box-ordinal-group\"          : \"webkit moz ms\",\n            \"box-orient\"                 : \"webkit moz ms\",\n            \"box-pack\"                   : \"webkit moz ms\",\n            \"box-sizing\"                 : \"webkit moz\",\n            \"box-shadow\"                 : \"webkit moz\",\n            \"column-count\"               : \"webkit moz\",\n            \"column-gap\"                 : \"webkit moz\",\n            \"column-rule\"                : \"webkit moz\",\n            \"column-rule-color\"          : \"webkit moz\",\n            \"column-rule-style\"          : \"webkit moz\",\n            \"column-rule-width\"          : \"webkit moz\",\n            \"column-width\"               : \"webkit moz\",\n            \"hyphens\"                    : \"epub moz\",\n            \"line-break\"                 : \"webkit ms\",\n            \"margin-end\"                 : \"webkit moz\",\n            \"margin-start\"               : \"webkit moz\",\n            \"marquee-speed\"              : \"webkit wap\",\n            \"marquee-style\"              : \"webkit wap\",\n            \"padding-end\"                : \"webkit moz\",\n            \"padding-start\"              : \"webkit moz\",\n            \"tab-size\"                   : \"moz o\",\n            \"text-size-adjust\"           : \"webkit ms\",\n            \"transform\"                  : \"webkit moz ms o\",\n            \"transform-origin\"           : \"webkit moz ms o\",\n            \"transition\"                 : \"webkit moz o\",\n            \"transition-delay\"           : \"webkit moz o\",\n            \"transition-duration\"        : \"webkit moz o\",\n            \"transition-property\"        : \"webkit moz o\",\n            \"transition-timing-function\" : \"webkit moz o\",\n            \"user-modify\"                : \"webkit moz\",\n            \"user-select\"                : \"webkit moz\",\n            \"word-break\"                 : \"epub ms\",\n            \"writing-mode\"               : \"epub ms\"\n        };\n\n        for (prop in compatiblePrefixes) {\n            if (compatiblePrefixes.hasOwnProperty(prop)) {\n                variations = [];\n                prefixed = compatiblePrefixes[prop].split(' ');\n                for (i = 0, len = prefixed.length; i < len; i++) {\n                    variations.push('-' + prefixed[i] + '-' + prop);\n                }\n                compatiblePrefixes[prop] = variations;\n                arrayPush.apply(applyTo, variations);\n            }\n        }\n        parser.addListener(\"startrule\", function () {\n            properties = [];\n        });\n\n        parser.addListener(\"property\", function (event) {\n            var name = event.property.text;\n            if (applyTo.indexOf(name) > -1) {\n                properties.push(name);\n            }\n        });\n\n        parser.addListener(\"endrule\", function (event) {\n            if (!properties.length) {\n                return;\n            }\n\n            var propertyGroups = {},\n                i,\n                len,\n                name,\n                prop,\n                variations,\n                value,\n                full,\n                actual,\n                item,\n                propertiesSpecified;\n\n            for (i = 0, len = properties.length; i < len; i++) {\n                name = properties[i];\n\n                for (prop in compatiblePrefixes) {\n                    if (compatiblePrefixes.hasOwnProperty(prop)) {\n                        variations = compatiblePrefixes[prop];\n                        if (variations.indexOf(name) > -1) {\n                            if (propertyGroups[prop] === undefined) {\n                                propertyGroups[prop] = {\n                                    full : variations.slice(0),\n                                    actual : []\n                                };\n                            }\n                            if (propertyGroups[prop].actual.indexOf(name) === -1) {\n                                propertyGroups[prop].actual.push(name);\n                            }\n                        }\n                    }\n                }\n            }\n\n            for (prop in propertyGroups) {\n                if (propertyGroups.hasOwnProperty(prop)) {\n                    value = propertyGroups[prop];\n                    full = value.full;\n                    actual = value.actual;\n\n                    if (full.length > actual.length) {\n                        for (i = 0, len = full.length; i < len; i++) {\n                            item = full[i];\n                            if (actual.indexOf(item) === -1) {\n                                propertiesSpecified = (actual.length === 1) ? actual[0] : (actual.length == 2) ? actual.join(\" and \") : actual.join(\", \");\n                                reporter.warn(\"The property \" + item + \" is compatible with \" + propertiesSpecified + \" and should be included as well.\", event.selectors[0].line, event.selectors[0].col, rule); \n                            }\n                        }\n\n                    }\n                }\n            }\n        });\n    }\n});\n/*\n * Rule: Certain properties don't play well with certain display values. \n * - float should not be used with inline-block\n * - height, width, margin-top, margin-bottom, float should not be used with inline\n * - vertical-align should not be used with block\n * - margin, float should not be used with table-*\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"display-property-grouping\",\n    name: \"Display Property Grouping\",\n    desc: \"Certain properties shouldn't be used with certain display property values.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this;\n\n        var propertiesToCheck = {\n                display: 1,\n                \"float\": \"none\",\n                height: 1,\n                width: 1,\n                margin: 1,\n                \"margin-left\": 1,\n                \"margin-right\": 1,\n                \"margin-bottom\": 1,\n                \"margin-top\": 1,\n                padding: 1,\n                \"padding-left\": 1,\n                \"padding-right\": 1,\n                \"padding-bottom\": 1,\n                \"padding-top\": 1,\n                \"vertical-align\": 1\n            },\n            properties;\n\n        parser.addListener(\"startrule\", function(){\n            properties = {};\n        });\n\n        parser.addListener(\"property\", function(event){\n            var name = event.property.text.toLowerCase();\n\n            if (propertiesToCheck[name]){\n                properties[name] = { value: event.value.text, line: event.property.line, col: event.property.col };                    \n            }\n        });\n\n        parser.addListener(\"endrule\", function(){\n\n            var display = properties.display ? properties.display.value : null;\n            if (display){\n                switch(display){\n\n                    case \"inline\":\n                        //height, width, margin-top, margin-bottom, float should not be used with inline\n                        reportProperty(\"height\", display);\n                        reportProperty(\"width\", display);\n                        reportProperty(\"margin\", display);\n                        reportProperty(\"margin-top\", display);\n                        reportProperty(\"margin-bottom\", display);              \n                        reportProperty(\"float\", display, \"display:inline has no effect on floated elements (but may be used to fix the IE6 double-margin bug).\");\n                        break;\n\n                    case \"block\":\n                        //vertical-align should not be used with block\n                        reportProperty(\"vertical-align\", display);\n                        break;\n\n                    case \"inline-block\":\n                        //float should not be used with inline-block\n                        reportProperty(\"float\", display);\n                        break;\n\n                    default:\n                        //margin, float should not be used with table\n                        if (display.indexOf(\"table-\") == 0){\n                            reportProperty(\"margin\", display);\n                            reportProperty(\"margin-left\", display);\n                            reportProperty(\"margin-right\", display);\n                            reportProperty(\"margin-top\", display);\n                            reportProperty(\"margin-bottom\", display);\n                            reportProperty(\"float\", display);\n                        }\n\n                        //otherwise do nothing\n                }\n            }\n          \n        });\n\n\n        function reportProperty(name, display, msg){\n            if (properties[name]){\n                if (!(typeof propertiesToCheck[name] == \"string\") || properties[name].value.toLowerCase() != propertiesToCheck[name]){\n                    reporter.warn(msg || name + \" can't be used with display: \" + display + \".\", properties[name].line, properties[name].col, rule);\n                }\n            }\n        }\n    }\n\n});\n/*\n * Rule: Duplicate properties must appear one after the other. If an already-defined\n * property appears somewhere else in the rule, then it's likely an error.\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"duplicate-properties\",\n    name: \"Duplicate Properties\",\n    desc: \"Duplicate properties must appear one after the other.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this,\n            properties,\n            lastProperty;            \n            \n        function startRule(event){\n            properties = {};        \n        }\n        \n        parser.addListener(\"startrule\", startRule);\n        parser.addListener(\"startfontface\", startRule);\n        parser.addListener(\"startpage\", startRule);\n        \n        parser.addListener(\"property\", function(event){\n            var property = event.property,\n                name = property.text.toLowerCase();\n            \n            if (properties[name] && (lastProperty != name || properties[name] == event.value.text)){\n                reporter.warn(\"Duplicate property '\" + event.property + \"' found.\", event.line, event.col, rule);\n            }\n            \n            properties[name] = event.value.text;\n            lastProperty = name;\n                        \n        });\n            \n        \n    }\n\n});\n/*\n * Rule: Style rules without any properties defined should be removed.\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"empty-rules\",\n    name: \"Empty Rules\",\n    desc: \"Rules without any properties specified should be removed.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this,\n            count = 0;\n\n        parser.addListener(\"startrule\", function(){\n            count=0;\n        });\n\n        parser.addListener(\"property\", function(){\n            count++;\n        });\n\n        parser.addListener(\"endrule\", function(event){\n            var selectors = event.selectors;\n            if (count == 0){\n                reporter.warn(\"Rule is empty.\", selectors[0].line, selectors[0].col, rule);\n            }\n        });\n    }\n\n});\n/*\n * Rule: There should be no syntax errors. (Duh.)\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"errors\",\n    name: \"Parsing Errors\",\n    desc: \"This rule looks for recoverable syntax errors.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this;\n\n        parser.addListener(\"error\", function(event){\n            reporter.error(event.message, event.line, event.col, rule);\n        });\n\n    }\n\n});\n/*\n * Rule: You shouldn't use more than 10 floats. If you do, there's probably\n * room for some abstraction.\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"floats\",\n    name: \"Floats\",\n    desc: \"This rule tests if the float property is used too many times\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this;\n        var count = 0;\n\n        //count how many times \"float\" is used\n        parser.addListener(\"property\", function(event){\n            if (event.property.text.toLowerCase() == \"float\" &&\n                    event.value.text.toLowerCase() != \"none\"){\n                count++;\n            }\n        });\n\n        //report the results\n        parser.addListener(\"endstylesheet\", function(){\n            reporter.stat(\"floats\", count);\n            if (count >= 10){\n                reporter.rollupWarn(\"Too many floats (\" + count + \"), you're probably using them for layout. Consider using a grid system instead.\", rule);\n            }\n        });\n    }\n\n});\n/*\n * Rule: Avoid too many @font-face declarations in the same stylesheet.\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"font-faces\",\n    name: \"Font Faces\",\n    desc: \"Too many different web fonts in the same stylesheet.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this,\n            count = 0;\n\n\n        parser.addListener(\"startfontface\", function(){\n            count++;\n        });\n\n        parser.addListener(\"endstylesheet\", function(){\n            if (count > 5){\n                reporter.rollupWarn(\"Too many @font-face declarations (\" + count + \").\", rule);\n            }\n        });\n    }\n\n});\n/*\n * Rule: You shouldn't need more than 9 font-size declarations.\n */\n\nCSSLint.addRule({\n\n    //rule information\n    id: \"font-sizes\",\n    name: \"Font Sizes\",\n    desc: \"Checks the number of font-size declarations.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this,\n            count = 0;\n\n        //check for use of \"font-size\"\n        parser.addListener(\"property\", function(event){\n            if (event.property == \"font-size\"){\n                count++;\n            }\n        });\n\n        //report the results\n        parser.addListener(\"endstylesheet\", function(){\n            reporter.stat(\"font-sizes\", count);\n            if (count >= 10){\n                reporter.rollupWarn(\"Too many font-size declarations (\" + count + \"), abstraction needed.\", rule);\n            }\n        });\n    }\n\n});\n/*\n * Rule: When using a vendor-prefixed gradient, make sure to use them all.\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"gradients\",\n    name: \"Gradients\",\n    desc: \"When using a vendor-prefixed gradient, make sure to use them all.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this,\n            gradients;\n\n        parser.addListener(\"startrule\", function(){\n            gradients = {\n                moz: 0,\n                webkit: 0,\n                ms: 0,\n                o: 0\n            };\n        });\n\n        parser.addListener(\"property\", function(event){\n\n            if (/\\-(moz|ms|o|webkit)(?:\\-(?:linear|radial))\\-gradient/.test(event.value)){\n                gradients[RegExp.$1] = 1;\n            }\n\n        });\n\n        parser.addListener(\"endrule\", function(event){\n            var missing = [];\n\n            if (!gradients.moz){\n                missing.push(\"Firefox 3.6+\");\n            }\n\n            if (!gradients.webkit){\n                missing.push(\"Webkit (Safari, Chrome)\");\n            }\n\n            if (!gradients.ms){\n                missing.push(\"Internet Explorer 10+\");\n            }\n\n            if (!gradients.o){\n                missing.push(\"Opera 11.1+\");\n            }\n\n            if (missing.length && missing.length < 4){            \n                reporter.warn(\"Missing vendor-prefixed CSS gradients for \" + missing.join(\", \") + \".\", event.selectors[0].line, event.selectors[0].col, rule); \n            }\n\n        });\n\n    }\n\n});\n/*\n * Rule: Don't use IDs for selectors.\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"ids\",\n    name: \"IDs\",\n    desc: \"Selectors should not contain IDs.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this;\n        parser.addListener(\"startrule\", function(event){\n            var selectors = event.selectors,\n                selector,\n                part,\n                modifier,\n                idCount,\n                i, j, k;\n\n            for (i=0; i < selectors.length; i++){\n                selector = selectors[i];\n                idCount = 0;\n\n                for (j=0; j < selector.parts.length; j++){\n                    part = selector.parts[j];\n                    if (part instanceof parserlib.css.SelectorPart){\n                        for (k=0; k < part.modifiers.length; k++){\n                            modifier = part.modifiers[k];\n                            if (modifier.type == \"id\"){\n                                idCount++;\n                            }\n                        }\n                    }\n                }\n\n                if (idCount == 1){\n                    reporter.warn(\"Don't use IDs in selectors.\", selector.line, selector.col, rule);\n                } else if (idCount > 1){\n                    reporter.warn(idCount + \" IDs in the selector, really?\", selector.line, selector.col, rule);\n                }\n            }\n\n        });\n    }\n\n});\n/*\n * Rule: Don't use @import, use <link> instead.\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"import\",\n    name: \"@import\",\n    desc: \"Don't use @import, use <link> instead.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this;\n        \n        parser.addListener(\"import\", function(event){        \n            reporter.warn(\"@import prevents parallel downloads, use <link> instead.\", event.line, event.col, rule);\n        });\n\n    }\n\n});\n/*\n * Rule: Make sure !important is not overused, this could lead to specificity\n * war. Display a warning on !important declarations, an error if it's\n * used more at least 10 times.\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"important\",\n    name: \"Important\",\n    desc: \"Be careful when using !important declaration\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this;\n        var count = 0;\n\n        //warn that important is used and increment the declaration counter\n        parser.addListener(\"property\", function(event){\n            var name = event.property;\n            if (event.important === true){\n                count++;\n                reporter.warn(\"Use of !important\", name.line, name.col, rule);\n            }\n        });\n\n        //report the results\n        parser.addListener(\"endstylesheet\", function(){\n            reporter.stat(\"important\", count);\n            if (count >= 10){\n                reporter.rollupError(\"Too many !important declarations (\" + count + \"), be careful with rule specificity\", rule);\n            }\n        });\n    }\n\n});\n/*\n * Rule: Don't use classes or IDs with elements (a.foo or a#foo).\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"overqualified-elements\",\n    name: \"Overqualified Elements\",\n    desc: \"Don't use classes or IDs with elements (a.foo or a#foo).\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this,\n            classes = {};\n            \n        parser.addListener(\"startrule\", function(event){\n            var selectors = event.selectors,\n                selector,\n                part,\n                modifier,\n                i, j, k;\n\n            for (i=0; i < selectors.length; i++){\n                selector = selectors[i];\n\n                for (j=0; j < selector.parts.length; j++){\n                    part = selector.parts[j];\n                    if (part instanceof parserlib.css.SelectorPart){\n                        for (k=0; k < part.modifiers.length; k++){\n                            modifier = part.modifiers[k];\n                            if (part.elementName && modifier.type == \"id\"){\n                                reporter.warn(\"Element (\" + part + \") is overqualified, just use \" + modifier + \" without element name.\", part.line, part.col, rule);\n                            } else if (modifier.type == \"class\"){\n                                \n                                if (!classes[modifier]){\n                                    classes[modifier] = [];\n                                }\n                                classes[modifier].push({ modifier: modifier, part: part });\n                            }\n                        }\n                    }\n                }\n            }\n        });\n        \n        parser.addListener(\"endstylesheet\", function(){\n        \n            var prop;\n            for (prop in classes){\n                if (classes.hasOwnProperty(prop)){\n                \n                    //one use means that this is overqualified\n                    if (classes[prop].length == 1 && classes[prop][0].part.elementName){\n                        reporter.warn(\"Element (\" + classes[prop][0].part + \") is overqualified, just use \" + classes[prop][0].modifier + \" without element name.\", classes[prop][0].part.line, classes[prop][0].part.col, rule);\n                    }\n                }\n            }        \n        });\n    }\n\n});\n/*\n * Rule: Headings (h1-h6) should not be qualified (namespaced).\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"qualified-headings\",\n    name: \"Qualified Headings\",\n    desc: \"Headings should not be qualified (namespaced).\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this;\n\n        parser.addListener(\"startrule\", function(event){\n            var selectors = event.selectors,\n                selector,\n                part,\n                i, j;\n\n            for (i=0; i < selectors.length; i++){\n                selector = selectors[i];\n\n                for (j=0; j < selector.parts.length; j++){\n                    part = selector.parts[j];\n                    if (part instanceof parserlib.css.SelectorPart){\n                        if (part.elementName && /h[1-6]/.test(part.elementName.toString()) && j > 0){\n                            reporter.warn(\"Heading (\" + part.elementName + \") should not be qualified.\", part.line, part.col, rule);\n                        }\n                    }\n                }\n            }\n        });\n    }\n\n});\n/*\n * Rule: Selectors that look like regular expressions are slow and should be avoided.\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"regex-selectors\",\n    name: \"Regex Selectors\",\n    desc: \"Selectors that look like regular expressions are slow and should be avoided.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this;\n\n        parser.addListener(\"startrule\", function(event){\n            var selectors = event.selectors,\n                selector,\n                part,\n                modifier,\n                i, j, k;\n\n            for (i=0; i < selectors.length; i++){\n                selector = selectors[i];\n                for (j=0; j < selector.parts.length; j++){\n                    part = selector.parts[j];\n                    if (part instanceof parserlib.css.SelectorPart){\n                        for (k=0; k < part.modifiers.length; k++){\n                            modifier = part.modifiers[k];\n                            if (modifier.type == \"attribute\"){\n                                if (/([\\~\\|\\^\\$\\*]=)/.test(modifier)){\n                                    reporter.warn(\"Attribute selectors with \" + RegExp.$1 + \" are slow!\", modifier.line, modifier.col, rule);\n                                }\n                            }\n\n                        }\n                    }\n                }\n            }\n        });\n    }\n\n});\n/*\n * Rule: Total number of rules should not exceed x.\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"rules-count\",\n    name: \"Rules Count\",\n    desc: \"Track how many rules there are.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this,\n            count = 0;\n\n        //count each rule\n        parser.addListener(\"startrule\", function(){\n            count++;\n        });\n\n        parser.addListener(\"endstylesheet\", function(){\n            reporter.stat(\"rule-count\", count);\n        });\n    }\n\n});\n/*\n * Rule: Don't use text-indent for image replacement if you need to support rtl. \n * \n */\n/*\n * Should we be checking for rtl/ltr?\n */\n//Commented out due to lack of tests\n/*CSSLint.addRule({\n\n    //rule information\n    id: \"text-indent\",\n    name: \"Text Indent\",\n    desc: \"Checks for text indent less than -99px\",\n    browsers: \"All\",\n    \n    //initialization\n    init: function(parser, reporter){\n        var rule = this;\n    \n        //check for use of \"font-size\"\n        parser.addListener(\"property\", function(event){\n            var name = event.property,\n                value = event.value;\n\n            if (name == \"text-indent\" && value < -99){\n                reporter.warn(\"Negative text-indent doesn't work well with RTL. If you use text-indent for image replacement explicitly set text-direction for that item to ltr.\", name.line, name.col, rule);\n            }\n        });\n    }\n\n});*/\n/*\n * Rule: Headings (h1-h6) should be defined only once.\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"unique-headings\",\n    name: \"Unique Headings\",\n    desc: \"Headings should be defined only once.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this;\n\n        var headings =  {\n                h1: 0,\n                h2: 0,\n                h3: 0,\n                h4: 0,\n                h5: 0,\n                h6: 0\n            };\n\n        parser.addListener(\"startrule\", function(event){\n            var selectors = event.selectors,\n                selector,\n                part,\n                i;\n\n            for (i=0; i < selectors.length; i++){\n                selector = selectors[i];\n                part = selector.parts[selector.parts.length-1];\n\n                if (part.elementName && /(h[1-6])/.test(part.elementName.toString())){\n                    headings[RegExp.$1]++;\n                    if (headings[RegExp.$1] > 1) {\n                        reporter.warn(\"Heading (\" + part.elementName + \") has already been defined.\", part.line, part.col, rule);\n                    }\n                }\n            }\n        });\n    }\n\n});\n/*\n * Rule: When using a vendor-prefixed property, make sure to\n * include the standard one.\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"vendor-prefix\",\n    name: \"Vendor Prefix\",\n    desc: \"When using a vendor-prefixed property, make sure to include the standard one.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this,\n            properties,\n            num,\n            propertiesToCheck = {\n                \"-moz-border-radius\": \"border-radius\",\n                \"-webkit-border-radius\": \"border-radius\",\n                \"-webkit-border-top-left-radius\": \"border-top-left-radius\",\n                \"-webkit-border-top-right-radius\": \"border-top-right-radius\",\n                \"-webkit-border-bottom-left-radius\": \"border-bottom-left-radius\",\n                \"-webkit-border-bottom-right-radius\": \"border-bottom-right-radius\",\n                \"-moz-border-radius-topleft\": \"border-top-left-radius\",\n                \"-moz-border-radius-topright\": \"border-top-right-radius\",\n                \"-moz-border-radius-bottomleft\": \"border-bottom-left-radius\",\n                \"-moz-border-radius-bottomright\": \"border-bottom-right-radius\",\n                \"-moz-box-shadow\": \"box-shadow\",\n                \"-webkit-box-shadow\": \"box-shadow\",\n                \"-moz-transform\" : \"transform\",\n                \"-webkit-transform\" : \"transform\",\n                \"-o-transform\" : \"transform\",\n                \"-ms-transform\" : \"transform\",\n                \"-moz-box-sizing\" : \"box-sizing\",\n                \"-webkit-box-sizing\" : \"box-sizing\"\n            };\n\n        //event handler for beginning of rules\n        function startRule(){\n            properties = {};\n            num=1;        \n        }\n        \n        //event handler for end of rules\n        function endRule(event){\n            var prop,\n                i, len,\n                standard,\n                needed,\n                actual,\n                needsStandard = [];\n\n            for (prop in properties){\n                if (propertiesToCheck[prop]){\n                    needsStandard.push({ actual: prop, needed: propertiesToCheck[prop]});\n                }\n            }\n\n            for (i=0, len=needsStandard.length; i < len; i++){\n                needed = needsStandard[i].needed;\n                actual = needsStandard[i].actual;\n\n                if (!properties[needed]){               \n                    reporter.warn(\"Missing standard property '\" + needed + \"' to go along with '\" + actual + \"'.\", event.line, event.col, rule);\n                } else {\n                    //make sure standard property is last\n                    if (properties[needed][0].pos < properties[actual][0].pos){\n                        reporter.warn(\"Standard property '\" + needed + \"' should come after vendor-prefixed property '\" + actual + \"'.\", event.line, event.col, rule);\n                    }\n                }\n            }\n\n        }        \n        \n        parser.addListener(\"startrule\", startRule);\n        parser.addListener(\"startfontface\", startRule);\n\n        parser.addListener(\"property\", function(event){\n            var name = event.property.text.toLowerCase();\n\n            if (!properties[name]){\n                properties[name] = [];\n            }\n\n            properties[name].push({ name: event.property, value : event.value, pos:num++ });\n        });\n\n        parser.addListener(\"endrule\", endRule);\n        parser.addListener(\"endfontface\", endRule);\n    }\n\n});\n/*\n * Rule: If an element has a width of 100%, be careful when placing within\n * an element that has padding. It may look strange.\n */\n//Commented out pending further review.\n/*CSSLint.addRule({\n\n    //rule information\n    id: \"width-100\",\n    name: \"Width 100%\",\n    desc: \"Be careful when using width: 100% on elements.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this,\n            width100,\n            boxsizing;\n\n        parser.addListener(\"startrule\", function(){\n            width100 = null;\n            boxsizing = false;\n        });\n\n        parser.addListener(\"property\", function(event){\n            var name = event.property.text.toLowerCase(),\n                value = event.value;\n\n            if (name == \"width\" && value == \"100%\"){\n                width100 = event.property;\n            } else if (name == \"box-sizing\" || /\\-(?:webkit|ms|moz)\\-box-sizing/.test(name)){  //means you know what you're doing\n                boxsizing = true;\n            }\n        });\n        \n        parser.addListener(\"endrule\", function(){\n            if (width100 && !boxsizing){\n                reporter.warn(\"Elements with a width of 100% may not appear as you expect inside of other elements.\", width100.line, width100.col, rule);\n            }\n        });\n    }\n\n});*/\n/*\n * Rule: You don't need to specify units when a value is 0.\n */\nCSSLint.addRule({\n\n    //rule information\n    id: \"zero-units\",\n    name: \"Zero Units\",\n    desc: \"You don't need to specify units when a value is 0.\",\n    browsers: \"All\",\n\n    //initialization\n    init: function(parser, reporter){\n        var rule = this;\n\n        //count how many times \"float\" is used\n        parser.addListener(\"property\", function(event){\n            var parts = event.value.parts,\n                i = 0, \n                len = parts.length;\n\n            while(i < len){\n                if ((parts[i].units || parts[i].type == \"percentage\") && parts[i].value === 0){\n                    reporter.warn(\"Values of 0 shouldn't have units specified.\", parts[i].line, parts[i].col, rule);\n                }\n                i++;\n            }\n\n        });\n\n    }\n\n});\nCSSLint.addFormatter({\n    //format information\n    id: \"lint-xml\",\n    name: \"Lint XML format\",\n    \n    startFormat: function(){\n        return \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?><lint>\";\n    },\n\n    endFormat: function(){\n        return \"</lint>\";\n    },\n    \n    formatResults: function(results, filename) {\n        var messages = results.messages,\n            output = [];\n\n        var replaceDoubleQuotes = function(str) {\n            if (!str || str.constructor !== String) {\n                return \"\";\n            }\n            return str.replace(/\\\"/g, \"'\");\n        };\n\n        if (messages.length > 0) {\n            //rollups at the bottom\n            messages.sort(function (a, b) {\n                if (a.rollup && !b.rollup) {\n                    return 1;\n                } else if (!a.rollup && b.rollup) {\n                    return -1;\n                } else {\n                    return 0;\n                }\n            });\n        \n            output.push(\"<file name=\\\"\"+filename+\"\\\">\");\n            messages.forEach(function (message, i) {\n                if (message.rollup) {\n                    output.push(\"<issue severity=\\\"\" + message.type + \"\\\" reason=\\\"\" + replaceDoubleQuotes(message.message) + \"\\\" evidence=\\\"\" + replaceDoubleQuotes(message.evidence) + \"\\\"/>\");\n                } else {\n                    output.push(\"<issue line=\\\"\" + message.line + \"\\\" char=\\\"\" + message.col + \"\\\" severity=\\\"\" + message.type + \"\\\"\" +\n                        \" reason=\\\"\" + replaceDoubleQuotes(message.message) + \"\\\" evidence=\\\"\" + replaceDoubleQuotes(message.evidence) + \"\\\"/>\");\n                }\n            });\n            output.push(\"</file>\");\n        }\n\n        return output.join(\"\");\n    }\n});\nCSSLint.addFormatter({\n    //format information\n    id: \"text\",\n    name: \"Plain Text\",\n    \n    startFormat: function(){\n        return \"\";\n    },\n    \n    endFormat: function(){\n        return \"\";\n    },\n\n    formatResults: function(results, filename) {\n        var messages = results.messages;\n        if (messages.length === 0) {\n            return \"\\n\\ncsslint: No errors in \" + filename + \".\";\n        }\n        \n        output = \"\\n\\ncsslint: There are \" + messages.length  +  \" problems in \" + filename + \".\";\n        var pos = filename.lastIndexOf(\"/\"),\n            shortFilename = filename;\n\n        if (pos == -1){\n            pos = filename.lastIndexOf(\"\\\\\");       \n        }\n        if (pos > -1){\n            shortFilename = filename.substring(pos+1);\n        }\n\n        //rollups at the bottom\n        messages.sort(function (a, b){\n            if (a.rollup && !b.rollup){\n                return 1;\n            } else if (!a.rollup && b.rollup){\n                return -1;\n            } else {\n                return 0;\n            }\n        });\n\n        messages.forEach(function (message, i) {\n            output = output + \"\\n\\n\" + shortFilename;\n            if (message.rollup) {\n                output += \"\\n\" + (i+1) + \": \" + message.type;\n                output += \"\\n\" + message.message;\n            } else {\n                output += \"\\n\" + (i+1) + \": \" + message.type + \" at line \" + message.line + \", col \" + message.col;\n                output += \"\\n\" + message.message;\n                output += \"\\n\" + message.evidence;\n            }\n        });\n    \n        return output;\n    }\n});\n\nreturn CSSLint;\n})();\n//print for rhino and nodejs\nif(typeof print == \"undefined\") {\n    var print = console.log;\n}\n\n//readFile for rhino and nodejs\nif(typeof readFile == \"undefined\") {\n    var readFile = function(filepath) {\n        var fs = require(\"fs\");\n        return fs.readFileSync(filepath, \"utf-8\");\n    }\n}\n\n//filter messages by type\nvar pluckByType = function(messages, type){\n    return messages.filter(function(message) {\n        return message.type === type;\n    });\n};\n\nfunction gatherRules(options){\n    var ruleset;\n    \n    if (options.rules){\n        ruleset = {};\n        options.rules.split(\",\").forEach(function(value){\n            ruleset[value] = 1;\n        });\n    }\n    \n    return ruleset;\n}\n\n//process a list of files, return 1 if one or more error occurred\nvar processFile = function(filename, options) {\n    var input = readFile(filename),\n        result = CSSLint.verify(input, gatherRules(options)),\n        formatId = options.format || \"text\",\n        messages = result.messages || [],\n        exitCode = 0;\n\n    if (!input) {\n        print(\"csslint: Could not read file data in \" + filename + \". Is the file empty?\");\n        exitCode = 1;\n    } else {\n        print(CSSLint.getFormatter(formatId).formatResults(result, filename, formatId));\n\n        if (messages.length > 0 && pluckByType(messages, 'error').length > 0) {\n            exitCode = 1;\n        }\n    }\n    \n    return exitCode;\n};\n\n//output CLI help screen\nfunction outputHelp(){\n    print([\n        \"\\nUsage: csslint-rhino.js [options]* [file|dir]*\",\n        \" \",\n        \"Global Options\",\n        \"  --help                 Displays this information.\",\n        \"  --rules=<rule[,rule]+> Indicate which rules to include.\",\n        \"  --format=<format>      Indicate which format to use for output.\",\n        \"  --version              Outputs the current version number.\"\n    ].join(\"\\n\") + \"\\n\\n\");\n}\n\nfunction processFiles(files, options){\n    var exitCode = 0,\n        formatId = options.format || \"text\",\n        formatter;\n    if (!files.length) {\n        print(\"No files specified.\");\n        exitCode = 1;\n    } else {\n        if (!CSSLint.hasFormat(formatId)){\n            print(\"csslint: Unknown format '\" + formatId + \"'. Cannot proceed.\");\n            exitCode = 1; \n        } else {\n            formatter = CSSLint.getFormatter(formatId);\n            print(formatter.startFormat());\n            exitCode = files.some(function(file){\n                processFile(file,options);\n            });\n            print(formatter.endFormat());\n        }\n    }\n    return exitCode;\n}\n/*\n * CSSLint Rhino Command Line Interface\n */\n\nimportPackage(java.io);\n\n//-----------------------------------------------------------------------------\n// Helper Functions\n//-----------------------------------------------------------------------------\n\nfunction getFiles(dir) {\n    var files = [];\n\n    var traverse = function (dir) {\n        var dirList = dir.listFiles();\n        dirList.forEach(function (file) {\n            if (/\\.css$/.test(file)) {\n                files.push(file);\n            } else if (file.isDirectory()) {\n                traverse(file);\n            }\n        });\n    };\n\n    traverse(dir);\n\n    return files;\n};\n\n//-----------------------------------------------------------------------------\n// Process command line\n//-----------------------------------------------------------------------------\n\nvar args     = Array.prototype.slice.call(arguments),\n    argName,\n    arg      = args.shift(),\n    options  = {},\n    files    = [];\n\nwhile(arg){\n    if (arg.indexOf(\"--\") == 0){\n        argName = arg.substring(2);\n        options[argName] = true;\n        \n        if (argName.indexOf(\"rules=\") > -1){\n            options.rules = argName.substring(argName.indexOf(\"=\") + 1);\n        } else if (argName.indexOf(\"format=\") > -1) {\n            options.format = argName.substring(argName.indexOf(\"=\") + 1);\n        }\n    } else {\n        var curFile = new File(arg);\n        \n        //see if it's a directory or a file\n        if (curFile.isDirectory()){\n            files = files.concat(getFiles(arg));\n        } else {\n            files.push(arg);\n        }\n    }\n    arg = args.shift();\n}\n\nif (options.help || arguments.length == 0){\n    outputHelp();\n    quit(0);\n}\n\nif (options.version){\n    print(\"v\" + CSSLint.version);\n    quit(0);\n}\n\n\n\nquit(processFiles(files,options));\n"
  },
  {
    "path": "app/static_dev/build/tools/fulljshint.js",
    "content": "/*\n * JSHint, by JSHint Community.\n *\n * Licensed under the same slightly modified MIT license that JSLint is.\n * It stops evil-doers everywhere.\n *\n * JSHint is a derivative work of JSLint:\n *\n *   Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)\n *\n *   Permission is hereby granted, free of charge, to any person obtaining\n *   a copy of this software and associated documentation files (the \"Software\"),\n *   to deal in the Software without restriction, including without limitation\n *   the rights to use, copy, modify, merge, publish, distribute, sublicense,\n *   and/or sell copies of the Software, and to permit persons to whom\n *   the Software is furnished to do so, subject to the following conditions:\n *\n *   The above copyright notice and this permission notice shall be included\n *   in all copies or substantial portions of the Software.\n *\n *   The Software shall be used for Good, not Evil.\n *\n *   THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n *   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n *   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n *   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n *   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n *   DEALINGS IN THE SOFTWARE.\n *\n * JSHint was forked from 2010-12-16 edition of JSLint.\n *\n */\n\n/*\n JSHINT is a global function. It takes two parameters.\n\n     var myResult = JSHINT(source, option);\n\n The first parameter is either a string or an array of strings. If it is a\n string, it will be split on '\\n' or '\\r'. If it is an array of strings, it\n is assumed that each string represents one line. The source can be a\n JavaScript text, or HTML text, or a JSON text, or a CSS text.\n\n The second parameter is an optional object of options which control the\n operation of JSHINT. Most of the options are booleans: They are all\n optional and have a default value of false. One of the options, predef,\n can be an array of names, which will be used to declare global variables,\n or an object whose keys are used as global names, with a boolean value\n that determines if they are assignable.\n\n If it checks out, JSHINT returns true. Otherwise, it returns false.\n\n If false, you can inspect JSHINT.errors to find out the problems.\n JSHINT.errors is an array of objects containing these members:\n\n {\n     line      : The line (relative to 0) at which the lint was found\n     character : The character (relative to 0) at which the lint was found\n     reason    : The problem\n     evidence  : The text line in which the problem occurred\n     raw       : The raw message before the details were inserted\n     a         : The first detail\n     b         : The second detail\n     c         : The third detail\n     d         : The fourth detail\n }\n\n If a fatal error was found, a null will be the last element of the\n JSHINT.errors array.\n\n You can request a Function Report, which shows all of the functions\n and the parameters and vars that they use. This can be used to find\n implied global variables and other problems. The report is in HTML and\n can be inserted in an HTML <body>.\n\n     var myReport = JSHINT.report(limited);\n\n If limited is true, then the report will be limited to only errors.\n\n You can request a data structure which contains JSHint's results.\n\n     var myData = JSHINT.data();\n\n It returns a structure with this form:\n\n {\n     errors: [\n         {\n             line: NUMBER,\n             character: NUMBER,\n             reason: STRING,\n             evidence: STRING\n         }\n     ],\n     functions: [\n         name: STRING,\n         line: NUMBER,\n         last: NUMBER,\n         param: [\n             STRING\n         ],\n         closure: [\n             STRING\n         ],\n         var: [\n             STRING\n         ],\n         exception: [\n             STRING\n         ],\n         outer: [\n             STRING\n         ],\n         unused: [\n             STRING\n         ],\n         global: [\n             STRING\n         ],\n         label: [\n             STRING\n         ]\n     ],\n     globals: [\n         STRING\n     ],\n     member: {\n         STRING: NUMBER\n     },\n     unuseds: [\n         {\n             name: STRING,\n             line: NUMBER\n         }\n     ],\n     implieds: [\n         {\n             name: STRING,\n             line: NUMBER\n         }\n     ],\n     urls: [\n         STRING\n     ],\n     json: BOOLEAN\n }\n\n Empty arrays will not be included.\n\n*/\n\n/*jshint\n evil: true, nomen: false, onevar: false, regexp: false, strict: true, boss: true\n*/\n\n/*members \"\\b\", \"\\t\", \"\\n\", \"\\f\", \"\\r\", \"!=\", \"!==\", \"\\\"\", \"%\",\n \"(begin)\", \"(breakage)\", \"(context)\", \"(error)\", \"(global)\",\n \"(identifier)\", \"(last)\", \"(line)\", \"(loopage)\", \"(name)\", \"(onevar)\",\n \"(params)\", \"(scope)\", \"(statement)\", \"(verb)\", \"*\", \"+\", \"++\", \"-\",\n \"--\", \"\\/\", \"<\", \"<=\", \"==\", \"===\", \">\", \">=\", ADSAFE, __filename, __dirname,\n ActiveXObject, Array, Boolean, Buffer, COM, CScript, Canvas, CustomAnimation,\n Date, Debug, E, Enumerator, Error, EvalError, FadeAnimation, Flash,\n FormField, Frame, Function, HotKey, Image, JSON, LN10, LN2, LOG10E,\n LOG2E, MAX_VALUE, MIN_VALUE, Math, MenuItem, MoveAnimation,\n NEGATIVE_INFINITY, Number, Object, Option, PI, POSITIVE_INFINITY, Point,\n RangeError, Rectangle, ReferenceError, RegExp, ResizeAnimation,\n RotateAnimation, SQRT1_2, SQRT2, ScrollBar, String, Style, SyntaxError,\n System, Text, TextArea, Timer, TypeError, URIError, URL, VBArray,\n WScript, Web, Window, XMLDOM, XMLHttpRequest, \"\\\\\", a, abbr, acronym,\n activeborder, activecaption, addEventListener, address, adsafe, alert,\n aliceblue, all, animator, antiquewhite, appleScript, applet, apply,\n approved, appworkspace, aqua, aquamarine, area, arguments, arity,\n article, aside, audio, autocomplete, azure, b, background,\n \"background-attachment\", \"background-color\", \"background-image\",\n \"background-position\", \"background-repeat\", base, bdo, beep, beige, big,\n bisque, bitwise, black, blanchedalmond, block, blockquote, blue,\n blueviolet, blur, body, border, \"border-bottom\", \"border-bottom-color\",\n \"border-bottom-style\", \"border-bottom-width\", \"border-collapse\",\n \"border-color\", \"border-left\", \"border-left-color\", \"border-left-style\",\n \"border-left-width\", \"border-right\", \"border-right-color\",\n \"border-right-style\", \"border-right-width\", \"border-spacing\",\n \"border-style\", \"border-top\", \"border-top-color\", \"border-top-style\",\n \"border-top-width\", \"border-width\", bottom, boss, br, braille, brown, browser,\n burlywood, button, buttonface, buttonhighlight, buttonshadow,\n buttontext, bytesToUIString, c, cadetblue, call, callee, caller, canvas,\n cap, caption, \"caption-side\", captiontext, cases, center, charAt,\n charCodeAt, character, chartreuse, chocolate, chooseColor, chooseFile,\n chooseFolder, cite, clear, clearInterval, clearTimeout, clip, close,\n closeWidget, closed, closure, cm, code, col, colgroup, color, command,\n comment, condition, confirm, console, constructor, content,\n convertPathToHFS, convertPathToPlatform, coral, cornflowerblue,\n cornsilk, \"counter-increment\", \"counter-reset\", create, crimson, css, curly,\n cursor, cyan, d, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen,\n darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred,\n darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise,\n darkviolet, data, datalist, dd, debug, decodeURI, decodeURIComponent,\n deeppink, deepskyblue, defaultStatus, defineClass, del, deserialize,\n details, devel, dfn, dialog, dimgray, dir, direction, display, div, dl,\n document, dodgerblue, dt, edition, else, em, embed, embossed, empty,\n \"empty-cells\", encodeURI, encodeURIComponent, entityify, eqeqeq, errors,\n es5, escape, eval, event, evidence, evil, ex, exception, exec, exps, exports,\n fieldset, figure, filesystem, firebrick, first, float, floor,\n floralwhite, focus, focusWidget, font, \"font-family\", \"font-size\",\n \"font-size-adjust\", \"font-stretch\", \"font-style\", \"font-variant\",\n \"font-weight\", footer, forestgreen, forin, form, fragment, frame,\n frames, frameset, from, fromCharCode, fuchsia, fud, funct, function,\n functions, g, gainsboro, gc, getComputedStyle, ghostwhite, GLOBAL, global,\n globals, gold, goldenrod, gray, graytext, green, greenyellow, h1, h2,\n h3, h4, h5, h6, handheld, hasOwnProperty, head, header, height, help,\n hgroup, highlight, highlighttext, history, honeydew, hotpink, hr,\n \"hta:application\", html, i, iTunes, id, identifier, iframe, img, immed,\n implieds, in, inactiveborder, inactivecaption, inactivecaptiontext,\n include, indent, indexOf, indianred, indigo, infobackground, infotext,\n init, input, ins, isAlpha, isApplicationRunning, isArray, isDigit,\n isFinite, isNaN, ivory, join, jshint, JSHINT, json, kbd, keygen, keys, khaki,\n konfabulatorVersion, label, labelled, lang, last, lavender,\n lavenderblush, lawngreen, laxbreak, lbp, led, left, legend,\n lemonchiffon, length, \"letter-spacing\", li, lib, lightblue, lightcoral,\n lightcyan, lightgoldenrodyellow, lightgreen, lightpink, lightsalmon,\n lightseagreen, lightskyblue, lightslategray, lightsteelblue,\n lightyellow, lime, limegreen, line, \"line-height\", linen, link,\n \"list-style\", \"list-style-image\", \"list-style-position\",\n \"list-style-type\", load, loadClass, location, log, m, magenta, map,\n margin, \"margin-bottom\", \"margin-left\", \"margin-right\", \"margin-top\",\n mark, \"marker-offset\", maroon, match, \"max-height\", \"max-width\", maxerr,\n maxlen, md5, mediumaquamarine, mediumblue, mediumorchid, mediumpurple,\n mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise,\n mediumvioletred, member, menu, menutext, message, meta, meter,\n midnightblue, \"min-height\", \"min-width\", mintcream, mistyrose, mm,\n moccasin, module, moveBy, moveTo, name, nav, navajowhite, navigator, navy, new,\n newcap, noarg, node, noempty, noframes, nomen, nonew, noscript, nud, object, ol,\n oldlace, olive, olivedrab, on, onbeforeunload, onblur, onerror, onevar,\n onfocus, onload, onresize, onunload, opacity, open, openURL, opener, opera,\n optgroup, option, orange, orangered, orchid, outer, outline, \"outline-color\",\n \"outline-style\", \"outline-width\", output, overflow, \"overflow-x\",\n \"overflow-y\", p, padding, \"padding-bottom\", \"padding-left\",\n \"padding-right\", \"padding-top\", \"page-break-after\", \"page-break-before\",\n palegoldenrod, palegreen, paleturquoise, palevioletred, papayawhip,\n param, parent, parseFloat, parseInt, passfail, pc, peachpuff, peru,\n pink, play, plum, plusplus, pop, popupMenu, position, powderblue, pre,\n predef, preferenceGroups, preferences, print, process, progress, projection,\n prompt, prototype, pt, purple, push, px, q, quit, quotes, random, range,\n raw, reach, readFile, readUrl, reason, red, regexp, reloadWidget,\n removeEventListener, replace, report, require, reserved, resizeBy, resizeTo,\n resolvePath, resumeUpdates, rhino, right, rosybrown, royalblue, rp, rt,\n ruby, runCommand, runCommandInBg, saddlebrown, safe, salmon, samp,\n sandybrown, saveAs, savePreferences, screen, script, scroll, scrollBy,\n scrollTo, scrollbar, seagreen, seal, search, seashell, section, select,\n serialize, setInterval, setTimeout, shift, showWidgetPreferences,\n sienna, silver, skyblue, slateblue, slategray, sleep, slice, small,\n snow, sort, source, span, spawn, speak, speech, split, springgreen, src,\n stack, status, steelblue, strict, strong, style, styleproperty, sub,\n substr, sup, supplant, suppressUpdates, sync, system, table,\n \"table-layout\", tan, tbody, td, teal, tellWidget, test, \"text-align\",\n \"text-decoration\", \"text-indent\", \"text-shadow\", \"text-transform\",\n textarea, tfoot, th, thead, thistle, threeddarkshadow, threedface,\n threedhighlight, threedlightshadow, threedshadow, time, title,\n toLowerCase, toString, toUpperCase, toint32, token, tomato, top, tr, tt,\n tty, turquoise, tv, type, u, ul, undef, unescape, \"unicode-bidi\",\n unused, unwatch, updateNow, urls, value, valueOf, var, version,\n \"vertical-align\", video, violet, visibility, watch, wheat, white,\n \"white-space\", whitesmoke, widget, width, window, windowframe, windows,\n windowtext, \"word-spacing\", \"word-wrap\", yahooCheckLogin, yahooLogin,\n yahooLogout, yellow, yellowgreen, \"z-index\"\n*/\n\n/*global exports: false */\n\n// We build the application inside a function so that we produce only a single\n// global variable. That function will be invoked immediately, and its return\n// value is the JSHINT function itself.\n\nvar JSHINT = (function () {\n    \"use strict\";\n\n    var adsafe_id,      // The widget's ADsafe id.\n        adsafe_may,     // The widget may load approved scripts.\n        adsafe_went,    // ADSAFE.go has been called.\n        anonname,       // The guessed name for anonymous functions.\n        approved,       // ADsafe approved urls.\n\n// These are operators that should not be used with the ! operator.\n\n        bang = {\n            '<'  : true,\n            '<=' : true,\n            '==' : true,\n            '===': true,\n            '!==': true,\n            '!=' : true,\n            '>'  : true,\n            '>=' : true,\n            '+'  : true,\n            '-'  : true,\n            '*'  : true,\n            '/'  : true,\n            '%'  : true\n        },\n\n// These are property names that should not be permitted in the safe subset.\n\n        banned = { // the member names that ADsafe prohibits.\n            'arguments'     : true,\n            callee          : true,\n            caller          : true,\n            constructor     : true,\n            'eval'          : true,\n            prototype       : true,\n            stack           : true,\n            unwatch         : true,\n            valueOf         : true,\n            watch           : true\n        },\n\n\n// These are the JSHint boolean options.\n\n        boolOptions = {\n            adsafe     : true, // if ADsafe should be enforced\n            bitwise    : true, // if bitwise operators should not be allowed\n            boss       : true, // if assignments inside if/for/while/do should be allowed\n            browser    : true, // if the standard browser globals should be predefined\n            cap        : true, // if upper case HTML should be allowed\n            css        : true, // if CSS workarounds should be tolerated\n            curly      : true, // if curly braces around blocks should be required (even in if/for/while)\n            debug      : true, // if debugger statements should be allowed\n            devel      : true, // if logging should be allowed (console, alert, etc.)\n            eqeqeq     : true, // if === should be required\n            es5        : true, // if ES5 syntax should be allowed\n            evil       : true, // if eval should be allowed\n            forin      : true, // if for in statements must filter\n            fragment   : true, // if HTML fragments should be allowed\n            immed      : true, // if immediate invocations must be wrapped in parens\n            laxbreak   : true, // if line breaks should not be checked\n            newcap     : true, // if constructor names must be capitalized\n            noarg      : true, // if arguments.caller and arguments.callee should be disallowed\n            node       : true, // if the Node.js environment globals should be predefined\n            noempty    : true, // if empty blocks should be disallowed\n            nonew      : true, // if using `new` for side-effects should be disallowed\n            nomen      : true, // if names should be checked\n            on         : true, // if HTML event handlers should be allowed\n            onevar     : true, // if only one var statement per function should be allowed\n            passfail   : true, // if the scan should stop on first error\n            plusplus   : true, // if increment/decrement should not be allowed\n            regexp     : true, // if the . should not be allowed in regexp literals\n            rhino      : true, // if the Rhino environment globals should be predefined\n            undef      : true, // if variables should be declared before used\n            safe       : true, // if use of some browser features should be restricted\n            windows    : true, // if MS Windows-specigic globals should be predefined\n            strict     : true, // require the \"use strict\"; pragma\n            sub        : true, // if all forms of subscript notation are tolerated\n            white      : true, // if strict whitespace rules apply\n            widget     : true  // if the Yahoo Widgets globals should be predefined\n        },\n\n// browser contains a set of global names which are commonly provided by a\n// web browser environment.\n\n        browser = {\n            addEventListener: false,\n            blur            : false,\n            clearInterval   : false,\n            clearTimeout    : false,\n            close           : false,\n            closed          : false,\n            defaultStatus   : false,\n            document        : false,\n            event           : false,\n            focus           : false,\n            frames          : false,\n            getComputedStyle: false,\n            history         : false,\n            Image           : false,\n            length          : false,\n            location        : false,\n            moveBy          : false,\n            moveTo          : false,\n            name            : false,\n            navigator       : false,\n            onbeforeunload  : true,\n            onblur          : true,\n            onerror         : true,\n            onfocus         : true,\n            onload          : true,\n            onresize        : true,\n            onunload        : true,\n            open            : false,\n            opener          : false,\n            Option          : false,\n            parent          : false,\n            print           : false,\n            removeEventListener: false,\n            resizeBy        : false,\n            resizeTo        : false,\n            screen          : false,\n            scroll          : false,\n            scrollBy        : false,\n            scrollTo        : false,\n            setInterval     : false,\n            setTimeout      : false,\n            status          : false,\n            top             : false,\n            window          : false,\n            XMLHttpRequest  : false\n        },\n\n        cssAttributeData,\n        cssAny,\n\n        cssColorData = {\n            \"aliceblue\"             : true,\n            \"antiquewhite\"          : true,\n            \"aqua\"                  : true,\n            \"aquamarine\"            : true,\n            \"azure\"                 : true,\n            \"beige\"                 : true,\n            \"bisque\"                : true,\n            \"black\"                 : true,\n            \"blanchedalmond\"        : true,\n            \"blue\"                  : true,\n            \"blueviolet\"            : true,\n            \"brown\"                 : true,\n            \"burlywood\"             : true,\n            \"cadetblue\"             : true,\n            \"chartreuse\"            : true,\n            \"chocolate\"             : true,\n            \"coral\"                 : true,\n            \"cornflowerblue\"        : true,\n            \"cornsilk\"              : true,\n            \"crimson\"               : true,\n            \"cyan\"                  : true,\n            \"darkblue\"              : true,\n            \"darkcyan\"              : true,\n            \"darkgoldenrod\"         : true,\n            \"darkgray\"              : true,\n            \"darkgreen\"             : true,\n            \"darkkhaki\"             : true,\n            \"darkmagenta\"           : true,\n            \"darkolivegreen\"        : true,\n            \"darkorange\"            : true,\n            \"darkorchid\"            : true,\n            \"darkred\"               : true,\n            \"darksalmon\"            : true,\n            \"darkseagreen\"          : true,\n            \"darkslateblue\"         : true,\n            \"darkslategray\"         : true,\n            \"darkturquoise\"         : true,\n            \"darkviolet\"            : true,\n            \"deeppink\"              : true,\n            \"deepskyblue\"           : true,\n            \"dimgray\"               : true,\n            \"dodgerblue\"            : true,\n            \"firebrick\"             : true,\n            \"floralwhite\"           : true,\n            \"forestgreen\"           : true,\n            \"fuchsia\"               : true,\n            \"gainsboro\"             : true,\n            \"ghostwhite\"            : true,\n            \"gold\"                  : true,\n            \"goldenrod\"             : true,\n            \"gray\"                  : true,\n            \"green\"                 : true,\n            \"greenyellow\"           : true,\n            \"honeydew\"              : true,\n            \"hotpink\"               : true,\n            \"indianred\"             : true,\n            \"indigo\"                : true,\n            \"ivory\"                 : true,\n            \"khaki\"                 : true,\n            \"lavender\"              : true,\n            \"lavenderblush\"         : true,\n            \"lawngreen\"             : true,\n            \"lemonchiffon\"          : true,\n            \"lightblue\"             : true,\n            \"lightcoral\"            : true,\n            \"lightcyan\"             : true,\n            \"lightgoldenrodyellow\"  : true,\n            \"lightgreen\"            : true,\n            \"lightpink\"             : true,\n            \"lightsalmon\"           : true,\n            \"lightseagreen\"         : true,\n            \"lightskyblue\"          : true,\n            \"lightslategray\"        : true,\n            \"lightsteelblue\"        : true,\n            \"lightyellow\"           : true,\n            \"lime\"                  : true,\n            \"limegreen\"             : true,\n            \"linen\"                 : true,\n            \"magenta\"               : true,\n            \"maroon\"                : true,\n            \"mediumaquamarine\"      : true,\n            \"mediumblue\"            : true,\n            \"mediumorchid\"          : true,\n            \"mediumpurple\"          : true,\n            \"mediumseagreen\"        : true,\n            \"mediumslateblue\"       : true,\n            \"mediumspringgreen\"     : true,\n            \"mediumturquoise\"       : true,\n            \"mediumvioletred\"       : true,\n            \"midnightblue\"          : true,\n            \"mintcream\"             : true,\n            \"mistyrose\"             : true,\n            \"moccasin\"              : true,\n            \"navajowhite\"           : true,\n            \"navy\"                  : true,\n            \"oldlace\"               : true,\n            \"olive\"                 : true,\n            \"olivedrab\"             : true,\n            \"orange\"                : true,\n            \"orangered\"             : true,\n            \"orchid\"                : true,\n            \"palegoldenrod\"         : true,\n            \"palegreen\"             : true,\n            \"paleturquoise\"         : true,\n            \"palevioletred\"         : true,\n            \"papayawhip\"            : true,\n            \"peachpuff\"             : true,\n            \"peru\"                  : true,\n            \"pink\"                  : true,\n            \"plum\"                  : true,\n            \"powderblue\"            : true,\n            \"purple\"                : true,\n            \"red\"                   : true,\n            \"rosybrown\"             : true,\n            \"royalblue\"             : true,\n            \"saddlebrown\"           : true,\n            \"salmon\"                : true,\n            \"sandybrown\"            : true,\n            \"seagreen\"              : true,\n            \"seashell\"              : true,\n            \"sienna\"                : true,\n            \"silver\"                : true,\n            \"skyblue\"               : true,\n            \"slateblue\"             : true,\n            \"slategray\"             : true,\n            \"snow\"                  : true,\n            \"springgreen\"           : true,\n            \"steelblue\"             : true,\n            \"tan\"                   : true,\n            \"teal\"                  : true,\n            \"thistle\"               : true,\n            \"tomato\"                : true,\n            \"turquoise\"             : true,\n            \"violet\"                : true,\n            \"wheat\"                 : true,\n            \"white\"                 : true,\n            \"whitesmoke\"            : true,\n            \"yellow\"                : true,\n            \"yellowgreen\"           : true,\n\n            \"activeborder\"          : true,\n            \"activecaption\"         : true,\n            \"appworkspace\"          : true,\n            \"background\"            : true,\n            \"buttonface\"            : true,\n            \"buttonhighlight\"       : true,\n            \"buttonshadow\"          : true,\n            \"buttontext\"            : true,\n            \"captiontext\"           : true,\n            \"graytext\"              : true,\n            \"highlight\"             : true,\n            \"highlighttext\"         : true,\n            \"inactiveborder\"        : true,\n            \"inactivecaption\"       : true,\n            \"inactivecaptiontext\"   : true,\n            \"infobackground\"        : true,\n            \"infotext\"              : true,\n            \"menu\"                  : true,\n            \"menutext\"              : true,\n            \"scrollbar\"             : true,\n            \"threeddarkshadow\"      : true,\n            \"threedface\"            : true,\n            \"threedhighlight\"       : true,\n            \"threedlightshadow\"     : true,\n            \"threedshadow\"          : true,\n            \"window\"                : true,\n            \"windowframe\"           : true,\n            \"windowtext\"            : true\n        },\n\n        cssBorderStyle,\n        cssBreak,\n\n        cssLengthData = {\n            '%': true,\n            'cm': true,\n            'em': true,\n            'ex': true,\n            'in': true,\n            'mm': true,\n            'pc': true,\n            'pt': true,\n            'px': true\n        },\n\n        cssMedia,\n        cssOverflow,\n\n        devel = {\n            alert           : false,\n            confirm         : false,\n            console         : false,\n            Debug           : false,\n            opera           : false,\n            prompt          : false\n        },\n\n        escapes = {\n            '\\b': '\\\\b',\n            '\\t': '\\\\t',\n            '\\n': '\\\\n',\n            '\\f': '\\\\f',\n            '\\r': '\\\\r',\n            '\"' : '\\\\\"',\n            '/' : '\\\\/',\n            '\\\\': '\\\\\\\\'\n        },\n\n        funct,          // The current function\n\n        functionicity = [\n            'closure', 'exception', 'global', 'label',\n            'outer', 'unused', 'var'\n        ],\n\n        functions,      // All of the functions\n\n        global,         // The global scope\n        htmltag = {\n            a:        {},\n            abbr:     {},\n            acronym:  {},\n            address:  {},\n            applet:   {},\n            area:     {empty: true, parent: ' map '},\n            article:  {},\n            aside:    {},\n            audio:    {},\n            b:        {},\n            base:     {empty: true, parent: ' head '},\n            bdo:      {},\n            big:      {},\n            blockquote: {},\n            body:     {parent: ' html noframes '},\n            br:       {empty: true},\n            button:   {},\n            canvas:   {parent: ' body p div th td '},\n            caption:  {parent: ' table '},\n            center:   {},\n            cite:     {},\n            code:     {},\n            col:      {empty: true, parent: ' table colgroup '},\n            colgroup: {parent: ' table '},\n            command:  {parent: ' menu '},\n            datalist: {},\n            dd:       {parent: ' dl '},\n            del:      {},\n            details:  {},\n            dialog:   {},\n            dfn:      {},\n            dir:      {},\n            div:      {},\n            dl:       {},\n            dt:       {parent: ' dl '},\n            em:       {},\n            embed:    {},\n            fieldset: {},\n            figure:   {},\n            font:     {},\n            footer:   {},\n            form:     {},\n            frame:    {empty: true, parent: ' frameset '},\n            frameset: {parent: ' html frameset '},\n            h1:       {},\n            h2:       {},\n            h3:       {},\n            h4:       {},\n            h5:       {},\n            h6:       {},\n            head:     {parent: ' html '},\n            header:   {},\n            hgroup:   {},\n            hr:       {empty: true},\n            'hta:application':\n                      {empty: true, parent: ' head '},\n            html:     {parent: '*'},\n            i:        {},\n            iframe:   {},\n            img:      {empty: true},\n            input:    {empty: true},\n            ins:      {},\n            kbd:      {},\n            keygen:   {},\n            label:    {},\n            legend:   {parent: ' details fieldset figure '},\n            li:       {parent: ' dir menu ol ul '},\n            link:     {empty: true, parent: ' head '},\n            map:      {},\n            mark:     {},\n            menu:     {},\n            meta:     {empty: true, parent: ' head noframes noscript '},\n            meter:    {},\n            nav:      {},\n            noframes: {parent: ' html body '},\n            noscript: {parent: ' body head noframes '},\n            object:   {},\n            ol:       {},\n            optgroup: {parent: ' select '},\n            option:   {parent: ' optgroup select '},\n            output:   {},\n            p:        {},\n            param:    {empty: true, parent: ' applet object '},\n            pre:      {},\n            progress: {},\n            q:        {},\n            rp:       {},\n            rt:       {},\n            ruby:     {},\n            samp:     {},\n            script:   {empty: true, parent: ' body div frame head iframe p pre span '},\n            section:  {},\n            select:   {},\n            small:    {},\n            span:     {},\n            source:   {},\n            strong:   {},\n            style:    {parent: ' head ', empty: true},\n            sub:      {},\n            sup:      {},\n            table:    {},\n            tbody:    {parent: ' table '},\n            td:       {parent: ' tr '},\n            textarea: {},\n            tfoot:    {parent: ' table '},\n            th:       {parent: ' tr '},\n            thead:    {parent: ' table '},\n            time:     {},\n            title:    {parent: ' head '},\n            tr:       {parent: ' table tbody thead tfoot '},\n            tt:       {},\n            u:        {},\n            ul:       {},\n            'var':    {},\n            video:    {}\n        },\n\n        ids,            // HTML ids\n        implied,        // Implied globals\n        inblock,\n        indent,\n        jsonmode,\n        lines,\n        lookahead,\n        member,\n        membersOnly,\n        nexttoken,\n\n        node = {\n            __filename  : false,\n            __dirname   : false,\n            Buffer      : false,\n            GLOBAL      : false,\n            global      : false,\n            module      : false,\n            process     : false,\n            require     : false\n        },\n\n        noreach,\n        option,\n        predefined,     // Global variables defined by option\n        prereg,\n        prevtoken,\n\n        rhino = {\n            defineClass : false,\n            deserialize : false,\n            gc          : false,\n            help        : false,\n            load        : false,\n            loadClass   : false,\n            print       : false,\n            quit        : false,\n            readFile    : false,\n            readUrl     : false,\n            runCommand  : false,\n            seal        : false,\n            serialize   : false,\n            spawn       : false,\n            sync        : false,\n            toint32     : false,\n            version     : false\n        },\n\n        scope,      // The current scope\n        src,\n        stack,\n\n// standard contains the global names that are provided by the\n// ECMAScript standard.\n\n        standard = {\n            Array               : false,\n            Boolean             : false,\n            Date                : false,\n            decodeURI           : false,\n            decodeURIComponent  : false,\n            encodeURI           : false,\n            encodeURIComponent  : false,\n            Error               : false,\n            'eval'              : false,\n            EvalError           : false,\n            Function            : false,\n            hasOwnProperty      : false,\n            isFinite            : false,\n            isNaN               : false,\n            JSON                : false,\n            Math                : false,\n            Number              : false,\n            Object              : false,\n            parseInt            : false,\n            parseFloat          : false,\n            RangeError          : false,\n            ReferenceError      : false,\n            RegExp              : false,\n            String              : false,\n            SyntaxError         : false,\n            TypeError           : false,\n            URIError            : false\n        },\n\n        standard_member = {\n            E                   : true,\n            LN2                 : true,\n            LN10                : true,\n            LOG2E               : true,\n            LOG10E              : true,\n            MAX_VALUE           : true,\n            MIN_VALUE           : true,\n            NEGATIVE_INFINITY   : true,\n            PI                  : true,\n            POSITIVE_INFINITY   : true,\n            SQRT1_2             : true,\n            SQRT2               : true\n        },\n\n        strict_mode,\n        syntax = {},\n        tab,\n        token,\n        urls,\n        warnings,\n\n// widget contains the global names which are provided to a Yahoo\n// (fna Konfabulator) widget.\n\n        widget = {\n            alert                   : true,\n            animator                : true,\n            appleScript             : true,\n            beep                    : true,\n            bytesToUIString         : true,\n            Canvas                  : true,\n            chooseColor             : true,\n            chooseFile              : true,\n            chooseFolder            : true,\n            closeWidget             : true,\n            COM                     : true,\n            convertPathToHFS        : true,\n            convertPathToPlatform   : true,\n            CustomAnimation         : true,\n            escape                  : true,\n            FadeAnimation           : true,\n            filesystem              : true,\n            Flash                   : true,\n            focusWidget             : true,\n            form                    : true,\n            FormField               : true,\n            Frame                   : true,\n            HotKey                  : true,\n            Image                   : true,\n            include                 : true,\n            isApplicationRunning    : true,\n            iTunes                  : true,\n            konfabulatorVersion     : true,\n            log                     : true,\n            md5                     : true,\n            MenuItem                : true,\n            MoveAnimation           : true,\n            openURL                 : true,\n            play                    : true,\n            Point                   : true,\n            popupMenu               : true,\n            preferenceGroups        : true,\n            preferences             : true,\n            print                   : true,\n            prompt                  : true,\n            random                  : true,\n            Rectangle               : true,\n            reloadWidget            : true,\n            ResizeAnimation         : true,\n            resolvePath             : true,\n            resumeUpdates           : true,\n            RotateAnimation         : true,\n            runCommand              : true,\n            runCommandInBg          : true,\n            saveAs                  : true,\n            savePreferences         : true,\n            screen                  : true,\n            ScrollBar               : true,\n            showWidgetPreferences   : true,\n            sleep                   : true,\n            speak                   : true,\n            Style                   : true,\n            suppressUpdates         : true,\n            system                  : true,\n            tellWidget              : true,\n            Text                    : true,\n            TextArea                : true,\n            Timer                   : true,\n            unescape                : true,\n            updateNow               : true,\n            URL                     : true,\n            Web                     : true,\n            widget                  : true,\n            Window                  : true,\n            XMLDOM                  : true,\n            XMLHttpRequest          : true,\n            yahooCheckLogin         : true,\n            yahooLogin              : true,\n            yahooLogout             : true\n        },\n\n        windows = {\n            ActiveXObject: false,\n            CScript      : false,\n            Debug        : false,\n            Enumerator   : false,\n            System       : false,\n            VBArray      : false,\n            WScript      : false\n        },\n\n//  xmode is used to adapt to the exceptions in html parsing.\n//  It can have these states:\n//      false   .js script file\n//      html\n//      outer\n//      script\n//      style\n//      scriptstring\n//      styleproperty\n\n        xmode,\n        xquote,\n\n// Regular expressions. Some of these are stupidly long.\n\n// unsafe comment or string\n        ax = /@cc|<\\/?|script|\\]\\s*\\]|<\\s*!|&lt/i,\n// unsafe characters that are silently deleted by one or more browsers\n        cx = /[\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/,\n// token\n        tx = /^\\s*([(){}\\[.,:;'\"~\\?\\]#@]|==?=?|\\/(\\*(jshint|members?|global)?|=|\\/)?|\\*[\\/=]?|\\+(?:=|\\++)?|-(?:=|-+)?|%=?|&[&=]?|\\|[|=]?|>>?>?=?|<([\\/=!]|\\!(\\[|--)?|<=?)?|\\^=?|\\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\\.[0-9]*)?([eE][+\\-]?[0-9]+)?)/,\n// html token\n        hx = /^\\s*(['\"=>\\/&#]|<(?:\\/|\\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\\-:]*|[0-9]+|--)/,\n// characters in strings that need escapement\n        nx = /[\\u0000-\\u001f&<\"\\/\\\\\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/,\n        nxg = /[\\u0000-\\u001f&<\"\\/\\\\\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n// outer html token\n        ox = /[>&]|<[\\/!]?|--/,\n// star slash\n        lx = /\\*\\/|\\/\\*/,\n// identifier\n        ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,\n// javascript url\n        jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\\s*:/i,\n// url badness\n        ux = /&|\\+|\\u00AD|\\.\\.|\\/\\*|%[^;]|base64|url|expression|data|mailto/i,\n// style\n        sx = /^\\s*([{:#%.=,>+\\[\\]@()\"';]|\\*=?|\\$=|\\|=|\\^=|~=|[a-zA-Z_][a-zA-Z0-9_\\-]*|[0-9]+|<\\/|\\/\\*)/,\n        ssx = /^\\s*([@#!\"'};:\\-%.=,+\\[\\]()*_]|[a-zA-Z][a-zA-Z0-9._\\-]*|\\/\\*?|\\d+(?:\\.\\d+)?|<\\/)/,\n// attributes characters\n        qx = /[^a-zA-Z0-9+\\-_\\/ ]/,\n// query characters for ids\n        dx = /[\\[\\]\\/\\\\\"'*<>.&:(){}+=#]/,\n\n        rx = {\n            outer: hx,\n            html: hx,\n            style: sx,\n            styleproperty: ssx\n        };\n\n\n    function F() {}     // Used by Object.create\n\n    function is_own(object, name) {\n\n// The object.hasOwnProperty method fails when the property under consideration\n// is named 'hasOwnProperty'. So we have to use this more convoluted form.\n\n        return Object.prototype.hasOwnProperty.call(object, name);\n    }\n\n// Provide critical ES5 functions to ES3.\n\n    if (typeof Array.isArray !== 'function') {\n        Array.isArray = function (o) {\n            return Object.prototype.toString.apply(o) === '[object Array]';\n        };\n    }\n\n    if (typeof Object.create !== 'function') {\n        Object.create = function (o) {\n            F.prototype = o;\n            return new F();\n        };\n    }\n\n    if (typeof Object.keys !== 'function') {\n        Object.keys = function (o) {\n            var a = [], k;\n            for (k in o) {\n                if (is_own(o, k)) {\n                    a.push(k);\n                }\n            }\n            return a;\n        };\n    }\n\n// Non standard methods\n\n    if (typeof String.prototype.entityify !== 'function') {\n        String.prototype.entityify = function () {\n            return this\n                .replace(/&/g, '&amp;')\n                .replace(/</g, '&lt;')\n                .replace(/>/g, '&gt;');\n        };\n    }\n\n    if (typeof String.prototype.isAlpha !== 'function') {\n        String.prototype.isAlpha = function () {\n            return (this >= 'a' && this <= 'z\\uffff') ||\n                (this >= 'A' && this <= 'Z\\uffff');\n        };\n    }\n\n    if (typeof String.prototype.isDigit !== 'function') {\n        String.prototype.isDigit = function () {\n            return (this >= '0' && this <= '9');\n        };\n    }\n\n    if (typeof String.prototype.supplant !== 'function') {\n        String.prototype.supplant = function (o) {\n            return this.replace(/\\{([^{}]*)\\}/g, function (a, b) {\n                var r = o[b];\n                return typeof r === 'string' || typeof r === 'number' ? r : a;\n            });\n        };\n    }\n\n    if (typeof String.prototype.name !== 'function') {\n        String.prototype.name = function () {\n\n// If the string looks like an identifier, then we can return it as is.\n// If the string contains no control characters, no quote characters, and no\n// backslash characters, then we can simply slap some quotes around it.\n// Otherwise we must also replace the offending characters with safe\n// sequences.\n\n            if (ix.test(this)) {\n                return this;\n            }\n            if (nx.test(this)) {\n                return '\"' + this.replace(nxg, function (a) {\n                    var c = escapes[a];\n                    if (c) {\n                        return c;\n                    }\n                    return '\\\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4);\n                }) + '\"';\n            }\n            return '\"' + this + '\"';\n        };\n    }\n\n\n    function combine(t, o) {\n        var n;\n        for (n in o) {\n            if (is_own(o, n)) {\n                t[n] = o[n];\n            }\n        }\n    }\n\n    function assume() {\n        if (!option.safe) {\n            if (option.rhino) {\n                combine(predefined, rhino);\n            }\n            if (option.node) {\n                combine(predefined, node);\n            }\n            if (option.devel) {\n                combine(predefined, devel);\n            }\n            if (option.browser) {\n                combine(predefined, browser);\n            }\n            if (option.windows) {\n                combine(predefined, windows);\n            }\n            if (option.widget) {\n                combine(predefined, widget);\n            }\n        }\n    }\n\n\n// Produce an error warning.\n\n    function quit(m, l, ch) {\n        throw {\n            name: 'JSHintError',\n            line: l,\n            character: ch,\n            message: m + \" (\" + Math.floor((l / lines.length) * 100) +\n                    \"% scanned).\"\n        };\n    }\n\n    function warning(m, t, a, b, c, d) {\n        var ch, l, w;\n        t = t || nexttoken;\n        if (t.id === '(end)') {  // `~\n            t = token;\n        }\n        l = t.line || 0;\n        ch = t.from || 0;\n        w = {\n            id: '(error)',\n            raw: m,\n            evidence: lines[l - 1] || '',\n            line: l,\n            character: ch,\n            a: a,\n            b: b,\n            c: c,\n            d: d\n        };\n        w.reason = m.supplant(w);\n        JSHINT.errors.push(w);\n        if (option.passfail) {\n            quit('Stopping. ', l, ch);\n        }\n        warnings += 1;\n        if (warnings >= option.maxerr) {\n            quit(\"Too many errors.\", l, ch);\n        }\n        return w;\n    }\n\n    function warningAt(m, l, ch, a, b, c, d) {\n        return warning(m, {\n            line: l,\n            from: ch\n        }, a, b, c, d);\n    }\n\n    function error(m, t, a, b, c, d) {\n        var w = warning(m, t, a, b, c, d);\n        quit(\"Stopping, unable to continue.\", w.line, w.character);\n    }\n\n    function errorAt(m, l, ch, a, b, c, d) {\n        return error(m, {\n            line: l,\n            from: ch\n        }, a, b, c, d);\n    }\n\n\n\n// lexical analysis and token construction\n\n    var lex = (function lex() {\n        var character, from, line, s;\n\n// Private lex methods\n\n        function nextLine() {\n            var at;\n            if (line >= lines.length) {\n                return false;\n            }\n            character = 1;\n            s = lines[line];\n            line += 1;\n            at = s.search(/ \\t/);\n            if (at >= 0) {\n                warningAt(\"Mixed spaces and tabs.\", line, at + 1);\n            }\n            s = s.replace(/\\t/g, tab);\n            at = s.search(cx);\n            if (at >= 0) {\n                warningAt(\"Unsafe character.\", line, at);\n            }\n            if (option.maxlen && option.maxlen < s.length) {\n                warningAt(\"Line too long.\", line, s.length);\n            }\n            return true;\n        }\n\n// Produce a token object.  The token inherits from a syntax symbol.\n\n        function it(type, value) {\n            var i, t;\n            if (type === '(color)' || type === '(range)') {\n                t = {type: type};\n            } else if (type === '(punctuator)' ||\n                    (type === '(identifier)' && is_own(syntax, value))) {\n                t = syntax[value] || syntax['(error)'];\n            } else {\n                t = syntax[type];\n            }\n            t = Object.create(t);\n            if (type === '(string)' || type === '(range)') {\n                if (jx.test(value)) {\n                    warningAt(\"Script URL.\", line, from);\n                }\n            }\n            if (type === '(identifier)') {\n                t.identifier = true;\n                if (value === '__iterator__' || value === '__proto__') {\n                    errorAt(\"Reserved name '{a}'.\",\n                        line, from, value);\n                } else if (option.nomen &&\n                        (value.charAt(0) === '_' ||\n                         value.charAt(value.length - 1) === '_')) {\n                    warningAt(\"Unexpected {a} in '{b}'.\", line, from,\n                        \"dangling '_'\", value);\n                }\n            }\n            t.value = value;\n            t.line = line;\n            t.character = character;\n            t.from = from;\n            i = t.id;\n            if (i !== '(endline)') {\n                prereg = i &&\n                    (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||\n                    i === 'return');\n            }\n            return t;\n        }\n\n// Public lex methods\n\n        return {\n            init: function (source) {\n                if (typeof source === 'string') {\n                    lines = source\n                        .replace(/\\r\\n/g, '\\n')\n                        .replace(/\\r/g, '\\n')\n                        .split('\\n');\n                } else {\n                    lines = source;\n                }\n                line = 0;\n                nextLine();\n                from = 1;\n            },\n\n            range: function (begin, end) {\n                var c, value = '';\n                from = character;\n                if (s.charAt(0) !== begin) {\n                    errorAt(\"Expected '{a}' and instead saw '{b}'.\",\n                            line, character, begin, s.charAt(0));\n                }\n                for (;;) {\n                    s = s.slice(1);\n                    character += 1;\n                    c = s.charAt(0);\n                    switch (c) {\n                    case '':\n                        errorAt(\"Missing '{a}'.\", line, character, c);\n                        break;\n                    case end:\n                        s = s.slice(1);\n                        character += 1;\n                        return it('(range)', value);\n                    case xquote:\n                    case '\\\\':\n                        warningAt(\"Unexpected '{a}'.\", line, character, c);\n                    }\n                    value += c;\n                }\n\n            },\n\n// token -- this is called by advance to get the next token.\n\n            token: function () {\n                var b, c, captures, d, depth, high, i, l, low, q, t;\n\n                function match(x) {\n                    var r = x.exec(s), r1;\n                    if (r) {\n                        l = r[0].length;\n                        r1 = r[1];\n                        c = r1.charAt(0);\n                        s = s.substr(l);\n                        from = character + l - r1.length;\n                        character += l;\n                        return r1;\n                    }\n                }\n\n                function string(x) {\n                    var c, j, r = '';\n\n                    if (jsonmode && x !== '\"') {\n                        warningAt(\"Strings must use doublequote.\",\n                                line, character);\n                    }\n\n                    if (xquote === x || (xmode === 'scriptstring' && !xquote)) {\n                        return it('(punctuator)', x);\n                    }\n\n                    function esc(n) {\n                        var i = parseInt(s.substr(j + 1, n), 16);\n                        j += n;\n                        if (i >= 32 && i <= 126 &&\n                                i !== 34 && i !== 92 && i !== 39) {\n                            warningAt(\"Unnecessary escapement.\", line, character);\n                        }\n                        character += n;\n                        c = String.fromCharCode(i);\n                    }\n                    j = 0;\n                    for (;;) {\n                        while (j >= s.length) {\n                            j = 0;\n                            if (xmode !== 'html' || !nextLine()) {\n                                errorAt(\"Unclosed string.\", line, from);\n                            }\n                        }\n                        c = s.charAt(j);\n                        if (c === x) {\n                            character += 1;\n                            s = s.substr(j + 1);\n                            return it('(string)', r, x);\n                        }\n                        if (c < ' ') {\n                            if (c === '\\n' || c === '\\r') {\n                                break;\n                            }\n                            warningAt(\"Control character in string: {a}.\",\n                                    line, character + j, s.slice(0, j));\n                        } else if (c === xquote) {\n                            warningAt(\"Bad HTML string\", line, character + j);\n                        } else if (c === '<') {\n                            if (option.safe && xmode === 'html') {\n                                warningAt(\"ADsafe string violation.\",\n                                        line, character + j);\n                            } else if (s.charAt(j + 1) === '/' && (xmode || option.safe)) {\n                                warningAt(\"Expected '<\\\\/' and instead saw '</'.\", line, character);\n                            } else if (s.charAt(j + 1) === '!' && (xmode || option.safe)) {\n                                warningAt(\"Unexpected '<!' in a string.\", line, character);\n                            }\n                        } else if (c === '\\\\') {\n                            if (xmode === 'html') {\n                                if (option.safe) {\n                                    warningAt(\"ADsafe string violation.\",\n                                            line, character + j);\n                                }\n                            } else if (xmode === 'styleproperty') {\n                                j += 1;\n                                character += 1;\n                                c = s.charAt(j);\n                                if (c !== x) {\n                                    warningAt(\"Escapement in style string.\",\n                                            line, character + j);\n                                }\n                            } else {\n                                j += 1;\n                                character += 1;\n                                c = s.charAt(j);\n                                switch (c) {\n                                case xquote:\n                                    warningAt(\"Bad HTML string\", line,\n                                        character + j);\n                                    break;\n                                case '\\\\':\n                                case '\"':\n                                case '/':\n                                    break;\n                                case '\\'':\n                                    if (jsonmode) {\n                                        warningAt(\"Avoid \\\\'.\", line, character);\n                                    }\n                                    break;\n                                case 'b':\n                                    c = '\\b';\n                                    break;\n                                case 'f':\n                                    c = '\\f';\n                                    break;\n                                case 'n':\n                                    c = '\\n';\n                                    break;\n                                case 'r':\n                                    c = '\\r';\n                                    break;\n                                case 't':\n                                    c = '\\t';\n                                    break;\n                                case 'u':\n                                    esc(4);\n                                    break;\n                                case 'v':\n                                    if (jsonmode) {\n                                        warningAt(\"Avoid \\\\v.\", line, character);\n                                    }\n                                    c = '\\v';\n                                    break;\n                                case 'x':\n                                    if (jsonmode) {\n                                        warningAt(\"Avoid \\\\x-.\", line, character);\n                                    }\n                                    esc(2);\n                                    break;\n                                default:\n                                    warningAt(\"Bad escapement.\", line, character);\n                                }\n                            }\n                        }\n                        r += c;\n                        character += 1;\n                        j += 1;\n                    }\n                }\n\n                for (;;) {\n                    if (!s) {\n                        return it(nextLine() ? '(endline)' : '(end)', '');\n                    }\n                    while (xmode === 'outer') {\n                        i = s.search(ox);\n                        if (i === 0) {\n                            break;\n                        } else if (i > 0) {\n                            character += 1;\n                            s = s.slice(i);\n                            break;\n                        } else {\n                            if (!nextLine()) {\n                                return it('(end)', '');\n                            }\n                        }\n                    }\n                    t = match(rx[xmode] || tx);\n                    if (!t) {\n                        t = '';\n                        c = '';\n                        while (s && s < '!') {\n                            s = s.substr(1);\n                        }\n                        if (s) {\n                            if (xmode === 'html') {\n                                return it('(error)', s.charAt(0));\n                            } else {\n                                errorAt(\"Unexpected '{a}'.\",\n                                        line, character, s.substr(0, 1));\n                            }\n                        }\n                    } else {\n\n    //      identifier\n\n                        if (c.isAlpha() || c === '_' || c === '$') {\n                            return it('(identifier)', t);\n                        }\n\n    //      number\n\n                        if (c.isDigit()) {\n                            if (xmode !== 'style' && !isFinite(Number(t))) {\n                                warningAt(\"Bad number '{a}'.\",\n                                    line, character, t);\n                            }\n                            if (xmode !== 'style' &&\n                                     xmode !== 'styleproperty' &&\n                                     s.substr(0, 1).isAlpha()) {\n                                warningAt(\"Missing space after '{a}'.\",\n                                        line, character, t);\n                            }\n                            if (c === '0') {\n                                d = t.substr(1, 1);\n                                if (d.isDigit()) {\n                                    if (token.id !== '.' && xmode !== 'styleproperty') {\n                                        warningAt(\"Don't use extra leading zeros '{a}'.\",\n                                            line, character, t);\n                                    }\n                                } else if (jsonmode && (d === 'x' || d === 'X')) {\n                                    warningAt(\"Avoid 0x-. '{a}'.\",\n                                            line, character, t);\n                                }\n                            }\n                            if (t.substr(t.length - 1) === '.') {\n                                warningAt(\n\"A trailing decimal point can be confused with a dot '{a}'.\", line, character, t);\n                            }\n                            return it('(number)', t);\n                        }\n                        switch (t) {\n\n    //      string\n\n                        case '\"':\n                        case \"'\":\n                            return string(t);\n\n    //      // comment\n\n                        case '//':\n                            if (src || (xmode && xmode !== 'script')) {\n                                warningAt(\"Unexpected comment.\", line, character);\n                            } else if (xmode === 'script' && /<\\s*\\//i.test(s)) {\n                                warningAt(\"Unexpected <\\/ in comment.\", line, character);\n                            } else if ((option.safe || xmode === 'script') && ax.test(s)) {\n                                warningAt(\"Dangerous comment.\", line, character);\n                            }\n                            s = '';\n                            token.comment = true;\n                            break;\n\n    //      /* comment\n\n                        case '/*':\n                            if (src || (xmode && xmode !== 'script' && xmode !== 'style' && xmode !== 'styleproperty')) {\n                                warningAt(\"Unexpected comment.\", line, character);\n                            }\n                            if (option.safe && ax.test(s)) {\n                                warningAt(\"ADsafe comment violation.\", line, character);\n                            }\n                            for (;;) {\n                                i = s.search(lx);\n                                if (i >= 0) {\n                                    break;\n                                }\n                                if (!nextLine()) {\n                                    errorAt(\"Unclosed comment.\", line, character);\n                                } else {\n                                    if (option.safe && ax.test(s)) {\n                                        warningAt(\"ADsafe comment violation.\",\n                                                line, character);\n                                    }\n                                }\n                            }\n                            character += i + 2;\n                            if (s.substr(i, 1) === '/') {\n                                errorAt(\"Nested comment.\", line, character);\n                            }\n                            s = s.substr(i + 2);\n                            token.comment = true;\n                            break;\n\n    //      /*members /*jshint /*global\n\n                        case '/*members':\n                        case '/*member':\n                        case '/*jshint':\n                        case '/*global':\n                        case '*/':\n                            return {\n                                value: t,\n                                type: 'special',\n                                line: line,\n                                character: character,\n                                from: from\n                            };\n\n                        case '':\n                            break;\n    //      /\n                        case '/':\n                            if (token.id === '/=') {\n                                errorAt(\n\"A regular expression literal can be confused with '/='.\", line, from);\n                            }\n                            if (prereg) {\n                                depth = 0;\n                                captures = 0;\n                                l = 0;\n                                for (;;) {\n                                    b = true;\n                                    c = s.charAt(l);\n                                    l += 1;\n                                    switch (c) {\n                                    case '':\n                                        errorAt(\"Unclosed regular expression.\",\n                                                line, from);\n                                        return;\n                                    case '/':\n                                        if (depth > 0) {\n                                            warningAt(\"Unescaped '{a}'.\",\n                                                    line, from + l, '/');\n                                        }\n                                        c = s.substr(0, l - 1);\n                                        q = {\n                                            g: true,\n                                            i: true,\n                                            m: true\n                                        };\n                                        while (q[s.charAt(l)] === true) {\n                                            q[s.charAt(l)] = false;\n                                            l += 1;\n                                        }\n                                        character += l;\n                                        s = s.substr(l);\n                                        q = s.charAt(0);\n                                        if (q === '/' || q === '*') {\n                                            errorAt(\"Confusing regular expression.\",\n                                                    line, from);\n                                        }\n                                        return it('(regexp)', c);\n                                    case '\\\\':\n                                        c = s.charAt(l);\n                                        if (c < ' ') {\n                                            warningAt(\n\"Unexpected control character in regular expression.\", line, from + l);\n                                        } else if (c === '<') {\n                                            warningAt(\n\"Unexpected escaped character '{a}' in regular expression.\", line, from + l, c);\n                                        }\n                                        l += 1;\n                                        break;\n                                    case '(':\n                                        depth += 1;\n                                        b = false;\n                                        if (s.charAt(l) === '?') {\n                                            l += 1;\n                                            switch (s.charAt(l)) {\n                                            case ':':\n                                            case '=':\n                                            case '!':\n                                                l += 1;\n                                                break;\n                                            default:\n                                                warningAt(\n\"Expected '{a}' and instead saw '{b}'.\", line, from + l, ':', s.charAt(l));\n                                            }\n                                        } else {\n                                            captures += 1;\n                                        }\n                                        break;\n                                    case '|':\n                                        b = false;\n                                        break;\n                                    case ')':\n                                        if (depth === 0) {\n                                            warningAt(\"Unescaped '{a}'.\",\n                                                    line, from + l, ')');\n                                        } else {\n                                            depth -= 1;\n                                        }\n                                        break;\n                                    case ' ':\n                                        q = 1;\n                                        while (s.charAt(l) === ' ') {\n                                            l += 1;\n                                            q += 1;\n                                        }\n                                        if (q > 1) {\n                                            warningAt(\n\"Spaces are hard to count. Use {{a}}.\", line, from + l, q);\n                                        }\n                                        break;\n                                    case '[':\n                                        c = s.charAt(l);\n                                        if (c === '^') {\n                                            l += 1;\n                                            if (option.regexp) {\n                                                warningAt(\"Insecure '{a}'.\",\n                                                        line, from + l, c);\n                                            } else if (s.charAt(l) === ']') {\n                                                errorAt(\"Unescaped '{a}'.\",\n                                                    line, from + l, '^');\n                                            }\n                                        }\n                                        q = false;\n                                        if (c === ']') {\n                                            warningAt(\"Empty class.\", line,\n                                                    from + l - 1);\n                                            q = true;\n                                        }\nklass:                                  do {\n                                            c = s.charAt(l);\n                                            l += 1;\n                                            switch (c) {\n                                            case '[':\n                                            case '^':\n                                                warningAt(\"Unescaped '{a}'.\",\n                                                        line, from + l, c);\n                                                q = true;\n                                                break;\n                                            case '-':\n                                                if (q) {\n                                                    q = false;\n                                                } else {\n                                                    warningAt(\"Unescaped '{a}'.\",\n                                                            line, from + l, '-');\n                                                    q = true;\n                                                }\n                                                break;\n                                            case ']':\n                                                if (!q) {\n                                                    warningAt(\"Unescaped '{a}'.\",\n                                                            line, from + l - 1, '-');\n                                                }\n                                                break klass;\n                                            case '\\\\':\n                                                c = s.charAt(l);\n                                                if (c < ' ') {\n                                                    warningAt(\n\"Unexpected control character in regular expression.\", line, from + l);\n                                                } else if (c === '<') {\n                                                    warningAt(\n\"Unexpected escaped character '{a}' in regular expression.\", line, from + l, c);\n                                                }\n                                                l += 1;\n                                                q = true;\n                                                break;\n                                            case '/':\n                                                warningAt(\"Unescaped '{a}'.\",\n                                                        line, from + l - 1, '/');\n                                                q = true;\n                                                break;\n                                            case '<':\n                                                if (xmode === 'script') {\n                                                    c = s.charAt(l);\n                                                    if (c === '!' || c === '/') {\n                                                        warningAt(\n\"HTML confusion in regular expression '<{a}'.\", line, from + l, c);\n                                                    }\n                                                }\n                                                q = true;\n                                                break;\n                                            default:\n                                                q = true;\n                                            }\n                                        } while (c);\n                                        break;\n                                    case '.':\n                                        if (option.regexp) {\n                                            warningAt(\"Insecure '{a}'.\", line,\n                                                    from + l, c);\n                                        }\n                                        break;\n                                    case ']':\n                                    case '?':\n                                    case '{':\n                                    case '}':\n                                    case '+':\n                                    case '*':\n                                        warningAt(\"Unescaped '{a}'.\", line,\n                                                from + l, c);\n                                        break;\n                                    case '<':\n                                        if (xmode === 'script') {\n                                            c = s.charAt(l);\n                                            if (c === '!' || c === '/') {\n                                                warningAt(\n\"HTML confusion in regular expression '<{a}'.\", line, from + l, c);\n                                            }\n                                        }\n                                    }\n                                    if (b) {\n                                        switch (s.charAt(l)) {\n                                        case '?':\n                                        case '+':\n                                        case '*':\n                                            l += 1;\n                                            if (s.charAt(l) === '?') {\n                                                l += 1;\n                                            }\n                                            break;\n                                        case '{':\n                                            l += 1;\n                                            c = s.charAt(l);\n                                            if (c < '0' || c > '9') {\n                                                warningAt(\n\"Expected a number and instead saw '{a}'.\", line, from + l, c);\n                                            }\n                                            l += 1;\n                                            low = +c;\n                                            for (;;) {\n                                                c = s.charAt(l);\n                                                if (c < '0' || c > '9') {\n                                                    break;\n                                                }\n                                                l += 1;\n                                                low = +c + (low * 10);\n                                            }\n                                            high = low;\n                                            if (c === ',') {\n                                                l += 1;\n                                                high = Infinity;\n                                                c = s.charAt(l);\n                                                if (c >= '0' && c <= '9') {\n                                                    l += 1;\n                                                    high = +c;\n                                                    for (;;) {\n                                                        c = s.charAt(l);\n                                                        if (c < '0' || c > '9') {\n                                                            break;\n                                                        }\n                                                        l += 1;\n                                                        high = +c + (high * 10);\n                                                    }\n                                                }\n                                            }\n                                            if (s.charAt(l) !== '}') {\n                                                warningAt(\n\"Expected '{a}' and instead saw '{b}'.\", line, from + l, '}', c);\n                                            } else {\n                                                l += 1;\n                                            }\n                                            if (s.charAt(l) === '?') {\n                                                l += 1;\n                                            }\n                                            if (low > high) {\n                                                warningAt(\n\"'{a}' should not be greater than '{b}'.\", line, from + l, low, high);\n                                            }\n                                        }\n                                    }\n                                }\n                                c = s.substr(0, l - 1);\n                                character += l;\n                                s = s.substr(l);\n                                return it('(regexp)', c);\n                            }\n                            return it('(punctuator)', t);\n\n    //      punctuator\n\n                        case '<!--':\n                            l = line;\n                            c = character;\n                            for (;;) {\n                                i = s.indexOf('--');\n                                if (i >= 0) {\n                                    break;\n                                }\n                                i = s.indexOf('<!');\n                                if (i >= 0) {\n                                    errorAt(\"Nested HTML comment.\",\n                                        line, character + i);\n                                }\n                                if (!nextLine()) {\n                                    errorAt(\"Unclosed HTML comment.\", l, c);\n                                }\n                            }\n                            l = s.indexOf('<!');\n                            if (l >= 0 && l < i) {\n                                errorAt(\"Nested HTML comment.\",\n                                    line, character + l);\n                            }\n                            character += i;\n                            if (s.charAt(i + 2) !== '>') {\n                                errorAt(\"Expected -->.\", line, character);\n                            }\n                            character += 3;\n                            s = s.slice(i + 3);\n                            break;\n                        case '#':\n                            if (xmode === 'html' || xmode === 'styleproperty') {\n                                for (;;) {\n                                    c = s.charAt(0);\n                                    if ((c < '0' || c > '9') &&\n                                            (c < 'a' || c > 'f') &&\n                                            (c < 'A' || c > 'F')) {\n                                        break;\n                                    }\n                                    character += 1;\n                                    s = s.substr(1);\n                                    t += c;\n                                }\n                                if (t.length !== 4 && t.length !== 7) {\n                                    warningAt(\"Bad hex color '{a}'.\", line,\n                                        from + l, t);\n                                }\n                                return it('(color)', t);\n                            }\n                            return it('(punctuator)', t);\n                        default:\n                            if (xmode === 'outer' && c === '&') {\n                                character += 1;\n                                s = s.substr(1);\n                                for (;;) {\n                                    c = s.charAt(0);\n                                    character += 1;\n                                    s = s.substr(1);\n                                    if (c === ';') {\n                                        break;\n                                    }\n                                    if (!((c >= '0' && c <= '9') ||\n                                            (c >= 'a' && c <= 'z') ||\n                                            c === '#')) {\n                                        errorAt(\"Bad entity\", line, from + l,\n                                        character);\n                                    }\n                                }\n                                break;\n                            }\n                            return it('(punctuator)', t);\n                        }\n                    }\n                }\n            }\n        };\n    }());\n\n\n    function addlabel(t, type) {\n\n        if (option.safe && funct['(global)'] &&\n                typeof predefined[t] !== 'boolean') {\n            warning('ADsafe global: ' + t + '.', token);\n        } else if (t === 'hasOwnProperty') {\n            warning(\"'hasOwnProperty' is a really bad name.\");\n        }\n\n// Define t in the current function in the current scope.\n\n        if (is_own(funct, t) && !funct['(global)']) {\n            warning(funct[t] === true ?\n                \"'{a}' was used before it was defined.\" :\n                \"'{a}' is already defined.\",\n                nexttoken, t);\n        }\n        funct[t] = type;\n        if (funct['(global)']) {\n            global[t] = funct;\n            if (is_own(implied, t)) {\n                warning(\"'{a}' was used before it was defined.\", nexttoken, t);\n                delete implied[t];\n            }\n        } else {\n            scope[t] = funct;\n        }\n    }\n\n\n    function doOption() {\n        var b, obj, filter, o = nexttoken.value, t, v;\n        switch (o) {\n        case '*/':\n            error(\"Unbegun comment.\");\n            break;\n        case '/*members':\n        case '/*member':\n            o = '/*members';\n            if (!membersOnly) {\n                membersOnly = {};\n            }\n            obj = membersOnly;\n            break;\n        case '/*jshint':\n            if (option.safe) {\n                warning(\"ADsafe restriction.\");\n            }\n            obj = option;\n            filter = boolOptions;\n            break;\n        case '/*global':\n            if (option.safe) {\n                warning(\"ADsafe restriction.\");\n            }\n            obj = predefined;\n            break;\n        default:\n            error(\"What?\");\n        }\n        t = lex.token();\nloop:   for (;;) {\n            for (;;) {\n                if (t.type === 'special' && t.value === '*/') {\n                    break loop;\n                }\n                if (t.id !== '(endline)' && t.id !== ',') {\n                    break;\n                }\n                t = lex.token();\n            }\n            if (t.type !== '(string)' && t.type !== '(identifier)' &&\n                    o !== '/*members') {\n                error(\"Bad option.\", t);\n            }\n            v = lex.token();\n            if (v.id === ':') {\n                v = lex.token();\n                if (obj === membersOnly) {\n                    error(\"Expected '{a}' and instead saw '{b}'.\",\n                            t, '*/', ':');\n                }\n                if (t.value === 'indent' && o === '/*jshint') {\n                    b = +v.value;\n                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||\n                            Math.floor(b) !== b) {\n                        error(\"Expected a small integer and instead saw '{a}'.\",\n                                v, v.value);\n                    }\n                    obj.white = true;\n                    obj.indent = b;\n                } else if (t.value === 'maxerr' && o === '/*jshint') {\n                    b = +v.value;\n                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||\n                            Math.floor(b) !== b) {\n                        error(\"Expected a small integer and instead saw '{a}'.\",\n                                v, v.value);\n                    }\n                    obj.maxerr = b;\n                } else if (t.value === 'maxlen' && o === '/*jshint') {\n                    b = +v.value;\n                    if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||\n                            Math.floor(b) !== b) {\n                        error(\"Expected a small integer and instead saw '{a}'.\",\n                                v, v.value);\n                    }\n                    obj.maxlen = b;\n                } else if (v.value === 'true') {\n                    obj[t.value] = true;\n                } else if (v.value === 'false') {\n                    obj[t.value] = false;\n                } else {\n                    error(\"Bad option value.\", v);\n                }\n                t = lex.token();\n            } else {\n                if (o === '/*jshint') {\n                    error(\"Missing option value.\", t);\n                }\n                obj[t.value] = false;\n                t = v;\n            }\n        }\n        if (filter) {\n            assume();\n        }\n    }\n\n\n// We need a peek function. If it has an argument, it peeks that much farther\n// ahead. It is used to distinguish\n//     for ( var i in ...\n// from\n//     for ( var i = ...\n\n    function peek(p) {\n        var i = p || 0, j = 0, t;\n\n        while (j <= i) {\n            t = lookahead[j];\n            if (!t) {\n                t = lookahead[j] = lex.token();\n            }\n            j += 1;\n        }\n        return t;\n    }\n\n\n\n// Produce the next token. It looks for programming errors.\n\n    function advance(id, t) {\n        switch (token.id) {\n        case '(number)':\n            if (nexttoken.id === '.') {\n                warning(\n\"A dot following a number can be confused with a decimal point.\", token);\n            }\n            break;\n        case '-':\n            if (nexttoken.id === '-' || nexttoken.id === '--') {\n                warning(\"Confusing minusses.\");\n            }\n            break;\n        case '+':\n            if (nexttoken.id === '+' || nexttoken.id === '++') {\n                warning(\"Confusing plusses.\");\n            }\n            break;\n        }\n        if (token.type === '(string)' || token.identifier) {\n            anonname = token.value;\n        }\n\n        if (id && nexttoken.id !== id) {\n            if (t) {\n                if (nexttoken.id === '(end)') {\n                    warning(\"Unmatched '{a}'.\", t, t.id);\n                } else {\n                    warning(\n\"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.\",\n                            nexttoken, id, t.id, t.line, nexttoken.value);\n                }\n            } else if (nexttoken.type !== '(identifier)' ||\n                            nexttoken.value !== id) {\n                warning(\"Expected '{a}' and instead saw '{b}'.\",\n                        nexttoken, id, nexttoken.value);\n            }\n        }\n        prevtoken = token;\n        token = nexttoken;\n        for (;;) {\n            nexttoken = lookahead.shift() || lex.token();\n            if (nexttoken.id === '(end)' || nexttoken.id === '(error)') {\n                return;\n            }\n            if (nexttoken.type === 'special') {\n                doOption();\n            } else {\n                if (nexttoken.id !== '(endline)') {\n                    break;\n                }\n            }\n        }\n    }\n\n\n// This is the heart of JSHINT, the Pratt parser. In addition to parsing, it\n// is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is\n// like .nud except that it is only used on the first token of a statement.\n// Having .fud makes it much easier to define statement-oriented languages like\n// JavaScript. I retained Pratt's nomenclature.\n\n// .nud     Null denotation\n// .fud     First null denotation\n// .led     Left denotation\n//  lbp     Left binding power\n//  rbp     Right binding power\n\n// They are elements of the parsing method called Top Down Operator Precedence.\n\n    function expression(rbp, initial) {\n        var left;\n        if (nexttoken.id === '(end)') {\n            error(\"Unexpected early end of program.\", token);\n        }\n        advance();\n        if (option.safe && typeof predefined[token.value] === 'boolean' &&\n                (nexttoken.id !== '(' && nexttoken.id !== '.')) {\n            warning('ADsafe violation.', token);\n        }\n        if (initial) {\n            anonname = 'anonymous';\n            funct['(verb)'] = token.value;\n        }\n        if (initial === true && token.fud) {\n            left = token.fud();\n        } else {\n            if (token.nud) {\n                left = token.nud();\n            } else {\n                if (nexttoken.type === '(number)' && token.id === '.') {\n                    warning(\n\"A leading decimal point can be confused with a dot: '.{a}'.\",\n                            token, nexttoken.value);\n                    advance();\n                    return token;\n                } else {\n                    error(\"Expected an identifier and instead saw '{a}'.\",\n                            token, token.id);\n                }\n            }\n            while (rbp < nexttoken.lbp) {\n                advance();\n                if (token.led) {\n                    left = token.led(left);\n                } else {\n                    error(\"Expected an operator and instead saw '{a}'.\",\n                        token, token.id);\n                }\n            }\n        }\n        return left;\n    }\n\n\n// Functions for conformance of style.\n\n    function adjacent(left, right) {\n        left = left || token;\n        right = right || nexttoken;\n        if (option.white || xmode === 'styleproperty' || xmode === 'style') {\n            if (left.character !== right.from && left.line === right.line) {\n                warning(\"Unexpected space after '{a}'.\", right, left.value);\n            }\n        }\n    }\n\n    function nobreak(left, right) {\n        left = left || token;\n        right = right || nexttoken;\n        if (option.white && (left.character !== right.from || left.line !== right.line)) {\n            warning(\"Unexpected space before '{a}'.\", right, right.value);\n        }\n    }\n\n    function nospace(left, right) {\n        left = left || token;\n        right = right || nexttoken;\n        if (option.white && !left.comment) {\n            if (left.line === right.line) {\n                adjacent(left, right);\n            }\n        }\n    }\n\n    function nonadjacent(left, right) {\n        if (option.white) {\n            left = left || token;\n            right = right || nexttoken;\n            if (left.line === right.line && left.character === right.from) {\n                warning(\"Missing space after '{a}'.\",\n                        nexttoken, left.value);\n            }\n        }\n    }\n\n    function nobreaknonadjacent(left, right) {\n        left = left || token;\n        right = right || nexttoken;\n        if (!option.laxbreak && left.line !== right.line) {\n            warning(\"Bad line breaking before '{a}'.\", right, right.id);\n        } else if (option.white) {\n            left = left || token;\n            right = right || nexttoken;\n            if (left.character === right.from) {\n                warning(\"Missing space after '{a}'.\",\n                        nexttoken, left.value);\n            }\n        }\n    }\n\n    function indentation(bias) {\n        var i;\n        if (option.white && nexttoken.id !== '(end)') {\n            i = indent + (bias || 0);\n            if (nexttoken.from !== i) {\n                warning(\n\"Expected '{a}' to have an indentation at {b} instead at {c}.\",\n                        nexttoken, nexttoken.value, i, nexttoken.from);\n            }\n        }\n    }\n\n    function nolinebreak(t) {\n        t = t || token;\n        if (t.line !== nexttoken.line) {\n            warning(\"Line breaking error '{a}'.\", t, t.value);\n        }\n    }\n\n\n    function comma() {\n        if (token.line !== nexttoken.line) {\n            if (!option.laxbreak) {\n                warning(\"Bad line breaking before '{a}'.\", token, nexttoken.id);\n            }\n        } else if (token.character !== nexttoken.from && option.white) {\n            warning(\"Unexpected space after '{a}'.\", nexttoken, token.value);\n        }\n        advance(',');\n        nonadjacent(token, nexttoken);\n    }\n\n\n// Functional constructors for making the symbols that will be inherited by\n// tokens.\n\n    function symbol(s, p) {\n        var x = syntax[s];\n        if (!x || typeof x !== 'object') {\n            syntax[s] = x = {\n                id: s,\n                lbp: p,\n                value: s\n            };\n        }\n        return x;\n    }\n\n\n    function delim(s) {\n        return symbol(s, 0);\n    }\n\n\n    function stmt(s, f) {\n        var x = delim(s);\n        x.identifier = x.reserved = true;\n        x.fud = f;\n        return x;\n    }\n\n\n    function blockstmt(s, f) {\n        var x = stmt(s, f);\n        x.block = true;\n        return x;\n    }\n\n\n    function reserveName(x) {\n        var c = x.id.charAt(0);\n        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {\n            x.identifier = x.reserved = true;\n        }\n        return x;\n    }\n\n\n    function prefix(s, f) {\n        var x = symbol(s, 150);\n        reserveName(x);\n        x.nud = (typeof f === 'function') ? f : function () {\n            this.right = expression(150);\n            this.arity = 'unary';\n            if (this.id === '++' || this.id === '--') {\n                if (option.plusplus) {\n                    warning(\"Unexpected use of '{a}'.\", this, this.id);\n                } else if ((!this.right.identifier || this.right.reserved) &&\n                        this.right.id !== '.' && this.right.id !== '[') {\n                    warning(\"Bad operand.\", this);\n                }\n            }\n            return this;\n        };\n        return x;\n    }\n\n\n    function type(s, f) {\n        var x = delim(s);\n        x.type = s;\n        x.nud = f;\n        return x;\n    }\n\n\n    function reserve(s, f) {\n        var x = type(s, f);\n        x.identifier = x.reserved = true;\n        return x;\n    }\n\n\n    function reservevar(s, v) {\n        return reserve(s, function () {\n            if (typeof v === 'function') {\n                v(this);\n            }\n            return this;\n        });\n    }\n\n\n    function infix(s, f, p, w) {\n        var x = symbol(s, p);\n        reserveName(x);\n        x.led = function (left) {\n            if (!w) {\n                nobreaknonadjacent(prevtoken, token);\n                nonadjacent(token, nexttoken);\n            }\n            if (typeof f === 'function') {\n                return f(left, this);\n            } else {\n                this.left = left;\n                this.right = expression(p);\n                return this;\n            }\n        };\n        return x;\n    }\n\n\n    function relation(s, f) {\n        var x = symbol(s, 100);\n        x.led = function (left) {\n            nobreaknonadjacent(prevtoken, token);\n            nonadjacent(token, nexttoken);\n            var right = expression(100);\n            if ((left && left.id === 'NaN') || (right && right.id === 'NaN')) {\n                warning(\"Use the isNaN function to compare with NaN.\", this);\n            } else if (f) {\n                f.apply(this, [left, right]);\n            }\n            if (left.id === '!') {\n                warning(\"Confusing use of '{a}'.\", left, '!');\n            }\n            if (right.id === '!') {\n                warning(\"Confusing use of '{a}'.\", left, '!');\n            }\n            this.left = left;\n            this.right = right;\n            return this;\n        };\n        return x;\n    }\n\n\n    function isPoorRelation(node) {\n        return node &&\n              ((node.type === '(number)' && +node.value === 0) ||\n               (node.type === '(string)' && node.value === '') ||\n                node.type === 'true' ||\n                node.type === 'false' ||\n                node.type === 'undefined' ||\n                node.type === 'null');\n    }\n\n\n    function assignop(s, f) {\n        symbol(s, 20).exps = true;\n        return infix(s, function (left, that) {\n            var l;\n            that.left = left;\n            if (predefined[left.value] === false &&\n                    scope[left.value]['(global)'] === true) {\n                warning(\"Read only.\", left);\n            } else if (left['function']) {\n                warning(\"'{a}' is a function.\", left, left.value);\n            }\n            if (option.safe) {\n                l = left;\n                do {\n                    if (typeof predefined[l.value] === 'boolean') {\n                        warning('ADsafe violation.', l);\n                    }\n                    l = l.left;\n                } while (l);\n            }\n            if (left) {\n                if (left.id === '.' || left.id === '[') {\n                    if (!left.left || left.left.value === 'arguments') {\n                        warning('Bad assignment.', that);\n                    }\n                    that.right = expression(19);\n                    return that;\n                } else if (left.identifier && !left.reserved) {\n                    if (funct[left.value] === 'exception') {\n                        warning(\"Do not assign to the exception parameter.\", left);\n                    }\n                    that.right = expression(19);\n                    return that;\n                }\n                if (left === syntax['function']) {\n                    warning(\n\"Expected an identifier in an assignment and instead saw a function invocation.\",\n                                token);\n                }\n            }\n            error(\"Bad assignment.\", that);\n        }, 20);\n    }\n\n\n    function bitwise(s, f, p) {\n        var x = symbol(s, p);\n        reserveName(x);\n        x.led = (typeof f === 'function') ? f : function (left) {\n            if (option.bitwise) {\n                warning(\"Unexpected use of '{a}'.\", this, this.id);\n            }\n            this.left = left;\n            this.right = expression(p);\n            return this;\n        };\n        return x;\n    }\n\n\n    function bitwiseassignop(s) {\n        symbol(s, 20).exps = true;\n        return infix(s, function (left, that) {\n            if (option.bitwise) {\n                warning(\"Unexpected use of '{a}'.\", that, that.id);\n            }\n            nonadjacent(prevtoken, token);\n            nonadjacent(token, nexttoken);\n            if (left) {\n                if (left.id === '.' || left.id === '[' ||\n                        (left.identifier && !left.reserved)) {\n                    expression(19);\n                    return that;\n                }\n                if (left === syntax['function']) {\n                    warning(\n\"Expected an identifier in an assignment, and instead saw a function invocation.\",\n                                token);\n                }\n                return that;\n            }\n            error(\"Bad assignment.\", that);\n        }, 20);\n    }\n\n\n    function suffix(s, f) {\n        var x = symbol(s, 150);\n        x.led = function (left) {\n            if (option.plusplus) {\n                warning(\"Unexpected use of '{a}'.\", this, this.id);\n            } else if ((!left.identifier || left.reserved) &&\n                    left.id !== '.' && left.id !== '[') {\n                warning(\"Bad operand.\", this);\n            }\n            this.left = left;\n            return this;\n        };\n        return x;\n    }\n\n\n    function optionalidentifier() {\n        if (nexttoken.identifier) {\n            advance();\n            if (option.safe && banned[token.value]) {\n                warning(\"ADsafe violation: '{a}'.\", token, token.value);\n            } else if (token.reserved && !option.es5) {\n                warning(\"Expected an identifier and instead saw '{a}' (a reserved word).\",\n                        token, token.id);\n            }\n            return token.value;\n        }\n    }\n\n\n    function identifier() {\n        var i = optionalidentifier();\n        if (i) {\n            return i;\n        }\n        if (token.id === 'function' && nexttoken.id === '(') {\n            warning(\"Missing name in function statement.\");\n        } else {\n            error(\"Expected an identifier and instead saw '{a}'.\",\n                    nexttoken, nexttoken.value);\n        }\n    }\n\n\n    function reachable(s) {\n        var i = 0, t;\n        if (nexttoken.id !== ';' || noreach) {\n            return;\n        }\n        for (;;) {\n            t = peek(i);\n            if (t.reach) {\n                return;\n            }\n            if (t.id !== '(endline)') {\n                if (t.id === 'function') {\n                    warning(\n\"Inner functions should be listed at the top of the outer function.\", t);\n                    break;\n                }\n                warning(\"Unreachable '{a}' after '{b}'.\", t, t.value, s);\n                break;\n            }\n            i += 1;\n        }\n    }\n\n\n    function statement(noindent) {\n        var i = indent, r, s = scope, t = nexttoken;\n\n// We don't like the empty statement.\n\n        if (t.id === ';') {\n            warning(\"Unnecessary semicolon.\", t);\n            advance(';');\n            return;\n        }\n\n// Is this a labelled statement?\n\n        if (t.identifier && !t.reserved && peek().id === ':') {\n            advance();\n            advance(':');\n            scope = Object.create(s);\n            addlabel(t.value, 'label');\n            if (!nexttoken.labelled) {\n                warning(\"Label '{a}' on {b} statement.\",\n                        nexttoken, t.value, nexttoken.value);\n            }\n            if (jx.test(t.value + ':')) {\n                warning(\"Label '{a}' looks like a javascript url.\",\n                        t, t.value);\n            }\n            nexttoken.label = t.value;\n            t = nexttoken;\n        }\n\n// Parse the statement.\n\n        if (!noindent) {\n            indentation();\n        }\n        r = expression(0, true);\n\n// Look for the final semicolon.\n\n        if (!t.block) {\n            if (!r || !r.exps) {\n                warning(\"Expected an assignment or function call and instead saw an expression.\", token);\n            } else if (option.nonew && r.id === '(' && r.left.id === 'new') {\n                warning(\"Do not use 'new' for side effects.\");\n            }\n            if (nexttoken.id !== ';') {\n                warningAt(\"Missing semicolon.\", token.line, token.from + token.value.length);\n            } else {\n                adjacent(token, nexttoken);\n                advance(';');\n                nonadjacent(token, nexttoken);\n            }\n        }\n\n// Restore the indentation.\n\n        indent = i;\n        scope = s;\n        return r;\n    }\n\n\n    function use_strict() {\n        if (nexttoken.value === 'use strict') {\n            if (strict_mode) {\n                warning(\"Unnecessary \\\"use strict\\\".\");\n            }\n            advance();\n            advance(';');\n            strict_mode = true;\n            option.newcap = true;\n            option.undef = true;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n\n    function statements(begin) {\n        var a = [], f, p;\n        if (option.adsafe) {\n            switch (begin) {\n            case 'script':\n\n// JSHint is also the static analizer for ADsafe. See www.ADsafe.org.\n\n                if (!adsafe_may) {\n                    if (nexttoken.value !== 'ADSAFE' ||\n                            peek(0).id !== '.' ||\n                            (peek(1).value !== 'id' &&\n                            peek(1).value !== 'go')) {\n                        error('ADsafe violation: Missing ADSAFE.id or ADSAFE.go.',\n                            nexttoken);\n                    }\n                }\n                if (nexttoken.value === 'ADSAFE' &&\n                        peek(0).id === '.' &&\n                        peek(1).value === 'id') {\n                    if (adsafe_may) {\n                        error('ADsafe violation.', nexttoken);\n                    }\n                    advance('ADSAFE');\n                    advance('.');\n                    advance('id');\n                    advance('(');\n                    if (nexttoken.value !== adsafe_id) {\n                        error('ADsafe violation: id does not match.', nexttoken);\n                    }\n                    advance('(string)');\n                    advance(')');\n                    advance(';');\n                    adsafe_may = true;\n                }\n                break;\n            case 'lib':\n                if (nexttoken.value === 'ADSAFE') {\n                    advance('ADSAFE');\n                    advance('.');\n                    advance('lib');\n                    advance('(');\n                    advance('(string)');\n                    comma();\n                    f = expression(0);\n                    if (f.id !== 'function') {\n                        error('The second argument to lib must be a function.', f);\n                    }\n                    p = f.funct['(params)'];\n                    p = p && p.join(', ');\n                    if (p && p !== 'lib') {\n                        error(\"Expected '{a}' and instead saw '{b}'.\",\n                            f, '(lib)', '(' + p + ')');\n                    }\n                    advance(')');\n                    advance(';');\n                    return a;\n                } else {\n                    error(\"ADsafe lib violation.\");\n                }\n            }\n        }\n        while (!nexttoken.reach && nexttoken.id !== '(end)') {\n            if (nexttoken.id === ';') {\n                warning(\"Unnecessary semicolon.\");\n                advance(';');\n            } else {\n                a.push(statement());\n            }\n        }\n        return a;\n    }\n\n\n    /*\n     * Parses a single block. A block is a sequence of statements wrapped in\n     * braces.\n     * \n     * ordinary - true for everything but function bodies and try blocks. \n     * stmt     - true if block can be a single statement (e.g. in if/for/while).     \n     */ \n    function block(ordinary, stmt) {\n        var a,\n            b = inblock,\n            old_indent = indent,\n            m = strict_mode,\n            s = scope,\n            t;\n\n        inblock = ordinary;\n        scope = Object.create(scope);\n        nonadjacent(token, nexttoken);\n        t = nexttoken;\n\n        if (nexttoken.id === '{') {\n            advance('{');\n            if (nexttoken.id !== '}' || token.line !== nexttoken.line) {\n                indent += option.indent;\n                while (!ordinary && nexttoken.from > indent) {\n                    indent += option.indent;\n                }\n                if (!ordinary && !use_strict() && !m && option.strict &&\n                        funct['(context)']['(global)']) {\n                    warning(\"Missing \\\"use strict\\\" statement.\");\n                }\n                a = statements();\n                strict_mode = m;\n                indent -= option.indent;\n                indentation();\n            }\n            advance('}', t);\n            indent = old_indent;\n        } else if (!ordinary) {\n            error(\"Expected '{a}' and instead saw '{b}'.\",\n                  nexttoken, '{', nexttoken.value);\n        } else {\n            if (!stmt || option.curly)\n                warning(\"Expected '{a}' and instead saw '{b}'.\",\n                        nexttoken, '{', nexttoken.value);\n\n            noreach = true;\n            a = [statement()];\n            noreach = false;\n        }\n        funct['(verb)'] = null;\n        scope = s;\n        inblock = b;\n        if (ordinary && option.noempty && (!a || a.length === 0)) {\n            warning(\"Empty block.\");\n        }\n        return a;\n    }\n\n\n    function countMember(m) {\n        if (membersOnly && typeof membersOnly[m] !== 'boolean') {\n            warning(\"Unexpected /*member '{a}'.\", token, m);\n        }\n        if (typeof member[m] === 'number') {\n            member[m] += 1;\n        } else {\n            member[m] = 1;\n        }\n    }\n\n\n    function note_implied(token) {\n        var name = token.value, line = token.line, a = implied[name];\n        if (typeof a === 'function') {\n            a = false;\n        }\n        if (!a) {\n            a = [line];\n            implied[name] = a;\n        } else if (a[a.length - 1] !== line) {\n            a.push(line);\n        }\n    }\n\n\n// CSS parsing.\n\n    function cssName() {\n        if (nexttoken.identifier) {\n            advance();\n            return true;\n        }\n    }\n\n\n    function cssNumber() {\n        if (nexttoken.id === '-') {\n            advance('-');\n            adjacent();\n            nolinebreak();\n        }\n        if (nexttoken.type === '(number)') {\n            advance('(number)');\n            return true;\n        }\n    }\n\n\n    function cssString() {\n        if (nexttoken.type === '(string)') {\n            advance();\n            return true;\n        }\n    }\n\n\n    function cssColor() {\n        var i, number, value;\n        if (nexttoken.identifier) {\n            value = nexttoken.value;\n            if (value === 'rgb' || value === 'rgba') {\n                advance();\n                advance('(');\n                for (i = 0; i < 3; i += 1) {\n                    if (i) {\n                        advance(',');\n                    }\n                    number = nexttoken.value;\n                    if (nexttoken.type !== '(number)' || number < 0) {\n                        warning(\"Expected a positive number and instead saw '{a}'\",\n                            nexttoken, number);\n                        advance();\n                    } else {\n                        advance();\n                        if (nexttoken.id === '%') {\n                            advance('%');\n                            if (number > 100) {\n                                warning(\"Expected a percentage and instead saw '{a}'\",\n                                    token, number);\n                            }\n                        } else {\n                            if (number > 255) {\n                                warning(\"Expected a small number and instead saw '{a}'\",\n                                    token, number);\n                            }\n                        }\n                    }\n                }\n                if (value === 'rgba') {\n                    advance(',');\n                    number = +nexttoken.value;\n                    if (nexttoken.type !== '(number)' || number < 0 || number > 1) {\n                        warning(\"Expected a number between 0 and 1 and instead saw '{a}'\",\n                            nexttoken, number);\n                    }\n                    advance();\n                    if (nexttoken.id === '%') {\n                        warning(\"Unexpected '%'.\");\n                        advance('%');\n                    }\n                }\n                advance(')');\n                return true;\n            } else if (cssColorData[nexttoken.value] === true) {\n                advance();\n                return true;\n            }\n        } else if (nexttoken.type === '(color)') {\n            advance();\n            return true;\n        }\n        return false;\n    }\n\n\n    function cssLength() {\n        if (nexttoken.id === '-') {\n            advance('-');\n            adjacent();\n            nolinebreak();\n        }\n        if (nexttoken.type === '(number)') {\n            advance();\n            if (nexttoken.type !== '(string)' &&\n                    cssLengthData[nexttoken.value] === true) {\n                adjacent();\n                advance();\n            } else if (+token.value !== 0) {\n                warning(\"Expected a linear unit and instead saw '{a}'.\",\n                    nexttoken, nexttoken.value);\n            }\n            return true;\n        }\n        return false;\n    }\n\n\n    function cssLineHeight() {\n        if (nexttoken.id === '-') {\n            advance('-');\n            adjacent();\n        }\n        if (nexttoken.type === '(number)') {\n            advance();\n            if (nexttoken.type !== '(string)' &&\n                    cssLengthData[nexttoken.value] === true) {\n                adjacent();\n                advance();\n            }\n            return true;\n        }\n        return false;\n    }\n\n\n    function cssWidth() {\n        if (nexttoken.identifier) {\n            switch (nexttoken.value) {\n            case 'thin':\n            case 'medium':\n            case 'thick':\n                advance();\n                return true;\n            }\n        } else {\n            return cssLength();\n        }\n    }\n\n\n    function cssMargin() {\n        if (nexttoken.identifier) {\n            if (nexttoken.value === 'auto') {\n                advance();\n                return true;\n            }\n        } else {\n            return cssLength();\n        }\n    }\n\n    function cssAttr() {\n        if (nexttoken.identifier && nexttoken.value === 'attr') {\n            advance();\n            advance('(');\n            if (!nexttoken.identifier) {\n                warning(\"Expected a name and instead saw '{a}'.\",\n                        nexttoken, nexttoken.value);\n            }\n            advance();\n            advance(')');\n            return true;\n        }\n        return false;\n    }\n\n\n    function cssCommaList() {\n        while (nexttoken.id !== ';') {\n            if (!cssName() && !cssString()) {\n                warning(\"Expected a name and instead saw '{a}'.\",\n                        nexttoken, nexttoken.value);\n            }\n            if (nexttoken.id !== ',') {\n                return true;\n            }\n            comma();\n        }\n    }\n\n\n    function cssCounter() {\n        if (nexttoken.identifier && nexttoken.value === 'counter') {\n            advance();\n            advance('(');\n            advance();\n            if (nexttoken.id === ',') {\n                comma();\n                if (nexttoken.type !== '(string)') {\n                    warning(\"Expected a string and instead saw '{a}'.\",\n                        nexttoken, nexttoken.value);\n                }\n                advance();\n            }\n            advance(')');\n            return true;\n        }\n        if (nexttoken.identifier && nexttoken.value === 'counters') {\n            advance();\n            advance('(');\n            if (!nexttoken.identifier) {\n                warning(\"Expected a name and instead saw '{a}'.\",\n                        nexttoken, nexttoken.value);\n            }\n            advance();\n            if (nexttoken.id === ',') {\n                comma();\n                if (nexttoken.type !== '(string)') {\n                    warning(\"Expected a string and instead saw '{a}'.\",\n                        nexttoken, nexttoken.value);\n                }\n                advance();\n            }\n            if (nexttoken.id === ',') {\n                comma();\n                if (nexttoken.type !== '(string)') {\n                    warning(\"Expected a string and instead saw '{a}'.\",\n                        nexttoken, nexttoken.value);\n                }\n                advance();\n            }\n            advance(')');\n            return true;\n        }\n        return false;\n    }\n\n\n    function cssShape() {\n        var i;\n        if (nexttoken.identifier && nexttoken.value === 'rect') {\n            advance();\n            advance('(');\n            for (i = 0; i < 4; i += 1) {\n                if (!cssLength()) {\n                    warning(\"Expected a number and instead saw '{a}'.\",\n                        nexttoken, nexttoken.value);\n                    break;\n                }\n            }\n            advance(')');\n            return true;\n        }\n        return false;\n    }\n\n\n    function cssUrl() {\n        var c, url;\n        if (nexttoken.identifier && nexttoken.value === 'url') {\n            nexttoken = lex.range('(', ')');\n            url = nexttoken.value;\n            c = url.charAt(0);\n            if (c === '\"' || c === '\\'') {\n                if (url.slice(-1) !== c) {\n                    warning(\"Bad url string.\");\n                } else {\n                    url = url.slice(1, -1);\n                    if (url.indexOf(c) >= 0) {\n                        warning(\"Bad url string.\");\n                    }\n                }\n            }\n            if (!url) {\n                warning(\"Missing url.\");\n            }\n            advance();\n            if (option.safe && ux.test(url)) {\n                error(\"ADsafe URL violation.\");\n            }\n            urls.push(url);\n            return true;\n        }\n        return false;\n    }\n\n\n    cssAny = [cssUrl, function () {\n        for (;;) {\n            if (nexttoken.identifier) {\n                switch (nexttoken.value.toLowerCase()) {\n                case 'url':\n                    cssUrl();\n                    break;\n                case 'expression':\n                    warning(\"Unexpected expression '{a}'.\",\n                        nexttoken, nexttoken.value);\n                    advance();\n                    break;\n                default:\n                    advance();\n                }\n            } else {\n                if (nexttoken.id === ';' || nexttoken.id === '!'  ||\n                        nexttoken.id === '(end)' || nexttoken.id === '}') {\n                    return true;\n                }\n                advance();\n            }\n        }\n    }];\n\n\n    cssBorderStyle = [\n        'none', 'dashed', 'dotted', 'double', 'groove',\n        'hidden', 'inset', 'outset', 'ridge', 'solid'\n    ];\n\n    cssBreak = [\n        'auto', 'always', 'avoid', 'left', 'right'\n    ];\n\n    cssMedia = {\n        'all': true,\n        'braille': true,\n        'embossed': true,\n        'handheld': true,\n        'print': true,\n        'projection': true,\n        'screen': true,\n        'speech': true,\n        'tty': true,\n        'tv': true\n    };\n\n    cssOverflow = [\n        'auto', 'hidden', 'scroll', 'visible'\n    ];\n\n    cssAttributeData = {\n        background: [\n            true, 'background-attachment', 'background-color',\n            'background-image', 'background-position', 'background-repeat'\n        ],\n        'background-attachment': ['scroll', 'fixed'],\n        'background-color': ['transparent', cssColor],\n        'background-image': ['none', cssUrl],\n        'background-position': [\n            2, [cssLength, 'top', 'bottom', 'left', 'right', 'center']\n        ],\n        'background-repeat': [\n            'repeat', 'repeat-x', 'repeat-y', 'no-repeat'\n        ],\n        'border': [true, 'border-color', 'border-style', 'border-width'],\n        'border-bottom': [\n            true, 'border-bottom-color', 'border-bottom-style',\n            'border-bottom-width'\n        ],\n        'border-bottom-color': cssColor,\n        'border-bottom-style': cssBorderStyle,\n        'border-bottom-width': cssWidth,\n        'border-collapse': ['collapse', 'separate'],\n        'border-color': ['transparent', 4, cssColor],\n        'border-left': [\n            true, 'border-left-color', 'border-left-style', 'border-left-width'\n        ],\n        'border-left-color': cssColor,\n        'border-left-style': cssBorderStyle,\n        'border-left-width': cssWidth,\n        'border-right': [\n            true, 'border-right-color', 'border-right-style',\n            'border-right-width'\n        ],\n        'border-right-color': cssColor,\n        'border-right-style': cssBorderStyle,\n        'border-right-width': cssWidth,\n        'border-spacing': [2, cssLength],\n        'border-style': [4, cssBorderStyle],\n        'border-top': [\n            true, 'border-top-color', 'border-top-style', 'border-top-width'\n        ],\n        'border-top-color': cssColor,\n        'border-top-style': cssBorderStyle,\n        'border-top-width': cssWidth,\n        'border-width': [4, cssWidth],\n        bottom: [cssLength, 'auto'],\n        'caption-side' : ['bottom', 'left', 'right', 'top'],\n        clear: ['both', 'left', 'none', 'right'],\n        clip: [cssShape, 'auto'],\n        color: cssColor,\n        content: [\n            'open-quote', 'close-quote', 'no-open-quote', 'no-close-quote',\n            cssString, cssUrl, cssCounter, cssAttr\n        ],\n        'counter-increment': [\n            cssName, 'none'\n        ],\n        'counter-reset': [\n            cssName, 'none'\n        ],\n        cursor: [\n            cssUrl, 'auto', 'crosshair', 'default', 'e-resize', 'help', 'move',\n            'n-resize', 'ne-resize', 'nw-resize', 'pointer', 's-resize',\n            'se-resize', 'sw-resize', 'w-resize', 'text', 'wait'\n        ],\n        direction: ['ltr', 'rtl'],\n        display: [\n            'block', 'compact', 'inline', 'inline-block', 'inline-table',\n            'list-item', 'marker', 'none', 'run-in', 'table', 'table-caption',\n            'table-cell', 'table-column', 'table-column-group',\n            'table-footer-group', 'table-header-group', 'table-row',\n            'table-row-group'\n        ],\n        'empty-cells': ['show', 'hide'],\n        'float': ['left', 'none', 'right'],\n        font: [\n            'caption', 'icon', 'menu', 'message-box', 'small-caption',\n            'status-bar', true, 'font-size', 'font-style', 'font-weight',\n            'font-family'\n        ],\n        'font-family': cssCommaList,\n        'font-size': [\n            'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large',\n            'xx-large', 'larger', 'smaller', cssLength\n        ],\n        'font-size-adjust': ['none', cssNumber],\n        'font-stretch': [\n            'normal', 'wider', 'narrower', 'ultra-condensed',\n            'extra-condensed', 'condensed', 'semi-condensed',\n            'semi-expanded', 'expanded', 'extra-expanded'\n        ],\n        'font-style': [\n            'normal', 'italic', 'oblique'\n        ],\n        'font-variant': [\n            'normal', 'small-caps'\n        ],\n        'font-weight': [\n            'normal', 'bold', 'bolder', 'lighter', cssNumber\n        ],\n        height: [cssLength, 'auto'],\n        left: [cssLength, 'auto'],\n        'letter-spacing': ['normal', cssLength],\n        'line-height': ['normal', cssLineHeight],\n        'list-style': [\n            true, 'list-style-image', 'list-style-position', 'list-style-type'\n        ],\n        'list-style-image': ['none', cssUrl],\n        'list-style-position': ['inside', 'outside'],\n        'list-style-type': [\n            'circle', 'disc', 'square', 'decimal', 'decimal-leading-zero',\n            'lower-roman', 'upper-roman', 'lower-greek', 'lower-alpha',\n            'lower-latin', 'upper-alpha', 'upper-latin', 'hebrew', 'katakana',\n            'hiragana-iroha', 'katakana-oroha', 'none'\n        ],\n        margin: [4, cssMargin],\n        'margin-bottom': cssMargin,\n        'margin-left': cssMargin,\n        'margin-right': cssMargin,\n        'margin-top': cssMargin,\n        'marker-offset': [cssLength, 'auto'],\n        'max-height': [cssLength, 'none'],\n        'max-width': [cssLength, 'none'],\n        'min-height': cssLength,\n        'min-width': cssLength,\n        opacity: cssNumber,\n        outline: [true, 'outline-color', 'outline-style', 'outline-width'],\n        'outline-color': ['invert', cssColor],\n        'outline-style': [\n            'dashed', 'dotted', 'double', 'groove', 'inset', 'none',\n            'outset', 'ridge', 'solid'\n        ],\n        'outline-width': cssWidth,\n        overflow: cssOverflow,\n        'overflow-x': cssOverflow,\n        'overflow-y': cssOverflow,\n        padding: [4, cssLength],\n        'padding-bottom': cssLength,\n        'padding-left': cssLength,\n        'padding-right': cssLength,\n        'padding-top': cssLength,\n        'page-break-after': cssBreak,\n        'page-break-before': cssBreak,\n        position: ['absolute', 'fixed', 'relative', 'static'],\n        quotes: [8, cssString],\n        right: [cssLength, 'auto'],\n        'table-layout': ['auto', 'fixed'],\n        'text-align': ['center', 'justify', 'left', 'right'],\n        'text-decoration': [\n            'none', 'underline', 'overline', 'line-through', 'blink'\n        ],\n        'text-indent': cssLength,\n        'text-shadow': ['none', 4, [cssColor, cssLength]],\n        'text-transform': ['capitalize', 'uppercase', 'lowercase', 'none'],\n        top: [cssLength, 'auto'],\n        'unicode-bidi': ['normal', 'embed', 'bidi-override'],\n        'vertical-align': [\n            'baseline', 'bottom', 'sub', 'super', 'top', 'text-top', 'middle',\n            'text-bottom', cssLength\n        ],\n        visibility: ['visible', 'hidden', 'collapse'],\n        'white-space': [\n            'normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'inherit'\n        ],\n        width: [cssLength, 'auto'],\n        'word-spacing': ['normal', cssLength],\n        'word-wrap': ['break-word', 'normal'],\n        'z-index': ['auto', cssNumber]\n    };\n\n    function styleAttribute() {\n        var v;\n        while (nexttoken.id === '*' || nexttoken.id === '#' ||\n                nexttoken.value === '_') {\n            if (!option.css) {\n                warning(\"Unexpected '{a}'.\", nexttoken, nexttoken.value);\n            }\n            advance();\n        }\n        if (nexttoken.id === '-') {\n            if (!option.css) {\n                warning(\"Unexpected '{a}'.\", nexttoken, nexttoken.value);\n            }\n            advance('-');\n            if (!nexttoken.identifier) {\n                warning(\n\"Expected a non-standard style attribute and instead saw '{a}'.\",\n                    nexttoken, nexttoken.value);\n            }\n            advance();\n            return cssAny;\n        } else {\n            if (!nexttoken.identifier) {\n                warning(\"Excepted a style attribute, and instead saw '{a}'.\",\n                    nexttoken, nexttoken.value);\n            } else {\n                if (is_own(cssAttributeData, nexttoken.value)) {\n                    v = cssAttributeData[nexttoken.value];\n                } else {\n                    v = cssAny;\n                    if (!option.css) {\n                        warning(\"Unrecognized style attribute '{a}'.\",\n                                nexttoken, nexttoken.value);\n                    }\n                }\n            }\n            advance();\n            return v;\n        }\n    }\n\n\n    function styleValue(v) {\n        var i = 0,\n            n,\n            once,\n            match,\n            round,\n            start = 0,\n            vi;\n        switch (typeof v) {\n        case 'function':\n            return v();\n        case 'string':\n            if (nexttoken.identifier && nexttoken.value === v) {\n                advance();\n                return true;\n            }\n            return false;\n        }\n        for (;;) {\n            if (i >= v.length) {\n                return false;\n            }\n            vi = v[i];\n            i += 1;\n            if (vi === true) {\n                break;\n            } else if (typeof vi === 'number') {\n                n = vi;\n                vi = v[i];\n                i += 1;\n            } else {\n                n = 1;\n            }\n            match = false;\n            while (n > 0) {\n                if (styleValue(vi)) {\n                    match = true;\n                    n -= 1;\n                } else {\n                    break;\n                }\n            }\n            if (match) {\n                return true;\n            }\n        }\n        start = i;\n        once = [];\n        for (;;) {\n            round = false;\n            for (i = start; i < v.length; i += 1) {\n                if (!once[i]) {\n                    if (styleValue(cssAttributeData[v[i]])) {\n                        match = true;\n                        round = true;\n                        once[i] = true;\n                        break;\n                    }\n                }\n            }\n            if (!round) {\n                return match;\n            }\n        }\n    }\n\n    function styleChild() {\n        if (nexttoken.id === '(number)') {\n            advance();\n            if (nexttoken.value === 'n' && nexttoken.identifier) {\n                adjacent();\n                advance();\n                if (nexttoken.id === '+') {\n                    adjacent();\n                    advance('+');\n                    adjacent();\n                    advance('(number)');\n                }\n            }\n            return;\n        } else {\n            switch (nexttoken.value) {\n            case 'odd':\n            case 'even':\n                if (nexttoken.identifier) {\n                    advance();\n                    return;\n                }\n            }\n        }\n        warning(\"Unexpected token '{a}'.\", nexttoken, nexttoken.value);\n    }\n\n    function substyle() {\n        var v;\n        for (;;) {\n            if (nexttoken.id === '}' || nexttoken.id === '(end)' ||\n                    xquote && nexttoken.id === xquote) {\n                return;\n            }\n            while (nexttoken.id === ';') {\n                warning(\"Misplaced ';'.\");\n                advance(';');\n            }\n            v = styleAttribute();\n            advance(':');\n            if (nexttoken.identifier && nexttoken.value === 'inherit') {\n                advance();\n            } else {\n                if (!styleValue(v)) {\n                    warning(\"Unexpected token '{a}'.\", nexttoken,\n                        nexttoken.value);\n                    advance();\n                }\n            }\n            if (nexttoken.id === '!') {\n                advance('!');\n                adjacent();\n                if (nexttoken.identifier && nexttoken.value === 'important') {\n                    advance();\n                } else {\n                    warning(\"Expected '{a}' and instead saw '{b}'.\",\n                        nexttoken, 'important', nexttoken.value);\n                }\n            }\n            if (nexttoken.id === '}' || nexttoken.id === xquote) {\n                warning(\"Missing '{a}'.\", nexttoken, ';');\n            } else {\n                advance(';');\n            }\n        }\n    }\n\n    function styleSelector() {\n        if (nexttoken.identifier) {\n            if (!is_own(htmltag, option.cap ?\n                    nexttoken.value.toLowerCase() : nexttoken.value)) {\n                warning(\"Expected a tagName, and instead saw {a}.\",\n                    nexttoken, nexttoken.value);\n            }\n            advance();\n        } else {\n            switch (nexttoken.id) {\n            case '>':\n            case '+':\n                advance();\n                styleSelector();\n                break;\n            case ':':\n                advance(':');\n                switch (nexttoken.value) {\n                case 'active':\n                case 'after':\n                case 'before':\n                case 'checked':\n                case 'disabled':\n                case 'empty':\n                case 'enabled':\n                case 'first-child':\n                case 'first-letter':\n                case 'first-line':\n                case 'first-of-type':\n                case 'focus':\n                case 'hover':\n                case 'last-child':\n                case 'last-of-type':\n                case 'link':\n                case 'only-of-type':\n                case 'root':\n                case 'target':\n                case 'visited':\n                    advance();\n                    break;\n                case 'lang':\n                    advance();\n                    advance('(');\n                    if (!nexttoken.identifier) {\n                        warning(\"Expected a lang code, and instead saw :{a}.\",\n                            nexttoken, nexttoken.value);\n                    }\n                    advance(')');\n                    break;\n                case 'nth-child':\n                case 'nth-last-child':\n                case 'nth-last-of-type':\n                case 'nth-of-type':\n                    advance();\n                    advance('(');\n                    styleChild();\n                    advance(')');\n                    break;\n                case 'not':\n                    advance();\n                    advance('(');\n                    if (nexttoken.id === ':' && peek(0).value === 'not') {\n                        warning(\"Nested not.\");\n                    }\n                    styleSelector();\n                    advance(')');\n                    break;\n                default:\n                    warning(\"Expected a pseudo, and instead saw :{a}.\",\n                        nexttoken, nexttoken.value);\n                }\n                break;\n            case '#':\n                advance('#');\n                if (!nexttoken.identifier) {\n                    warning(\"Expected an id, and instead saw #{a}.\",\n                        nexttoken, nexttoken.value);\n                }\n                advance();\n                break;\n            case '*':\n                advance('*');\n                break;\n            case '.':\n                advance('.');\n                if (!nexttoken.identifier) {\n                    warning(\"Expected a class, and instead saw #.{a}.\",\n                        nexttoken, nexttoken.value);\n                }\n                advance();\n                break;\n            case '[':\n                advance('[');\n                if (!nexttoken.identifier) {\n                    warning(\"Expected an attribute, and instead saw [{a}].\",\n                        nexttoken, nexttoken.value);\n                }\n                advance();\n                if (nexttoken.id === '=' || nexttoken.value === '~=' ||\n                        nexttoken.value === '$=' ||\n                        nexttoken.value === '|=' ||\n                        nexttoken.id === '*=' ||\n                        nexttoken.id === '^=') {\n                    advance();\n                    if (nexttoken.type !== '(string)') {\n                        warning(\"Expected a string, and instead saw {a}.\",\n                            nexttoken, nexttoken.value);\n                    }\n                    advance();\n                }\n                advance(']');\n                break;\n            default:\n                error(\"Expected a CSS selector, and instead saw {a}.\",\n                    nexttoken, nexttoken.value);\n            }\n        }\n    }\n\n    function stylePattern() {\n        if (nexttoken.id === '{') {\n            warning(\"Expected a style pattern, and instead saw '{a}'.\", nexttoken,\n                nexttoken.id);\n        }\n        for (;;) {\n            styleSelector();\n            if (nexttoken.id === '</' || nexttoken.id === '{' ||\n                    nexttoken.id === '(end)') {\n                return '';\n            }\n            if (nexttoken.id === ',') {\n                comma();\n            }\n        }\n    }\n\n    function stylelist() {\n        while (nexttoken.id !== '</' && nexttoken.id !== '(end)') {\n            stylePattern();\n            xmode = 'styleproperty';\n            if (nexttoken.id === ';') {\n                advance(';');\n            } else {\n                advance('{');\n                substyle();\n                xmode = 'style';\n                advance('}');\n            }\n        }\n    }\n\n    function styles() {\n        var i;\n        while (nexttoken.id === '@') {\n            i = peek();\n            advance('@');\n            if (nexttoken.identifier) {\n                switch (nexttoken.value) {\n                case 'import':\n                    advance();\n                    if (!cssUrl()) {\n                        warning(\"Expected '{a}' and instead saw '{b}'.\",\n                            nexttoken, 'url', nexttoken.value);\n                        advance();\n                    }\n                    advance(';');\n                    break;\n                case 'media':\n                    advance();\n                    for (;;) {\n                        if (!nexttoken.identifier || cssMedia[nexttoken.value] === true) {\n                            error(\"Expected a CSS media type, and instead saw '{a}'.\", nexttoken, nexttoken.id);\n                        }\n                        advance();\n                        if (nexttoken.id !== ',') {\n                            break;\n                        }\n                        advance(',');\n                    }\n                    advance('{');\n                    stylelist();\n                    advance('}');\n                    break;\n                default:\n                    warning(\"Expected an at-rule, and instead saw @{a}.\",\n                        nexttoken, nexttoken.value);\n                }\n            } else {\n                warning(\"Expected an at-rule, and instead saw '{a}'.\",\n                    nexttoken, nexttoken.value);\n            }\n        }\n        stylelist();\n    }\n\n\n// HTML parsing.\n\n    function doBegin(n) {\n        if (n !== 'html' && !option.fragment) {\n            if (n === 'div' && option.adsafe) {\n                error(\"ADSAFE: Use the fragment option.\");\n            } else {\n                error(\"Expected '{a}' and instead saw '{b}'.\",\n                    token, 'html', n);\n            }\n        }\n        if (option.adsafe) {\n            if (n === 'html') {\n                error(\n\"Currently, ADsafe does not operate on whole HTML documents. It operates on <div> fragments and .js files.\", token);\n            }\n            if (option.fragment) {\n                if (n !== 'div') {\n                    error(\"ADsafe violation: Wrap the widget in a div.\", token);\n                }\n            } else {\n                error(\"Use the fragment option.\", token);\n            }\n        }\n        option.browser = true;\n        assume();\n    }\n\n    function doAttribute(n, a, v) {\n        var u, x;\n        if (a === 'id') {\n            u = typeof v === 'string' ? v.toUpperCase() : '';\n            if (ids[u] === true) {\n                warning(\"Duplicate id='{a}'.\", nexttoken, v);\n            }\n            if (!/^[A-Za-z][A-Za-z0-9._:\\-]*$/.test(v)) {\n                warning(\"Bad id: '{a}'.\", nexttoken, v);\n            } else if (option.adsafe) {\n                if (adsafe_id) {\n                    if (v.slice(0, adsafe_id.length) !== adsafe_id) {\n                        warning(\"ADsafe violation: An id must have a '{a}' prefix\",\n                                nexttoken, adsafe_id);\n                    } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) {\n                        warning(\"ADSAFE violation: bad id.\");\n                    }\n                } else {\n                    adsafe_id = v;\n                    if (!/^[A-Z]+_$/.test(v)) {\n                        warning(\"ADSAFE violation: bad id.\");\n                    }\n                }\n            }\n            x = v.search(dx);\n            if (x >= 0) {\n                warning(\"Unexpected character '{a}' in {b}.\", token, v.charAt(x), a);\n            }\n            ids[u] = true;\n        } else if (a === 'class' || a === 'type' || a === 'name') {\n            x = v.search(qx);\n            if (x >= 0) {\n                warning(\"Unexpected character '{a}' in {b}.\", token, v.charAt(x), a);\n            }\n            ids[u] = true;\n        } else if (a === 'href' || a === 'background' ||\n                a === 'content' || a === 'data' ||\n                a.indexOf('src') >= 0 || a.indexOf('url') >= 0) {\n            if (option.safe && ux.test(v)) {\n                error(\"ADsafe URL violation.\");\n            }\n            urls.push(v);\n        } else if (a === 'for') {\n            if (option.adsafe) {\n                if (adsafe_id) {\n                    if (v.slice(0, adsafe_id.length) !== adsafe_id) {\n                        warning(\"ADsafe violation: An id must have a '{a}' prefix\",\n                                nexttoken, adsafe_id);\n                    } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) {\n                        warning(\"ADSAFE violation: bad id.\");\n                    }\n                } else {\n                    warning(\"ADSAFE violation: bad id.\");\n                }\n            }\n        } else if (a === 'name') {\n            if (option.adsafe && v.indexOf('_') >= 0) {\n                warning(\"ADsafe name violation.\");\n            }\n        }\n    }\n\n    function doTag(n, a) {\n        var i, t = htmltag[n], x;\n        src = false;\n        if (!t) {\n            error(\"Unrecognized tag '<{a}>'.\",\n                    nexttoken,\n                    n === n.toLowerCase() ? n :\n                        n + ' (capitalization error)');\n        }\n        if (stack.length > 0) {\n            if (n === 'html') {\n                error(\"Too many <html> tags.\", token);\n            }\n            x = t.parent;\n            if (x) {\n                if (x.indexOf(' ' + stack[stack.length - 1].name + ' ') < 0) {\n                    error(\"A '<{a}>' must be within '<{b}>'.\",\n                            token, n, x);\n                }\n            } else if (!option.adsafe && !option.fragment) {\n                i = stack.length;\n                do {\n                    if (i <= 0) {\n                        error(\"A '<{a}>' must be within '<{b}>'.\",\n                                token, n, 'body');\n                    }\n                    i -= 1;\n                } while (stack[i].name !== 'body');\n            }\n        }\n        switch (n) {\n        case 'div':\n            if (option.adsafe && stack.length === 1 && !adsafe_id) {\n                warning(\"ADSAFE violation: missing ID_.\");\n            }\n            break;\n        case 'script':\n            xmode = 'script';\n            advance('>');\n            indent = nexttoken.from;\n            if (a.lang) {\n                warning(\"lang is deprecated.\", token);\n            }\n            if (option.adsafe && stack.length !== 1) {\n                warning(\"ADsafe script placement violation.\", token);\n            }\n            if (a.src) {\n                if (option.adsafe && (!adsafe_may || !approved[a.src])) {\n                    warning(\"ADsafe unapproved script source.\", token);\n                }\n                if (a.type) {\n                    warning(\"type is unnecessary.\", token);\n                }\n            } else {\n                if (adsafe_went) {\n                    error(\"ADsafe script violation.\", token);\n                }\n                use_strict();\n                statements('script');\n            }\n            xmode = 'html';\n            advance('</');\n            if (!nexttoken.identifier && nexttoken.value !== 'script') {\n                warning(\"Expected '{a}' and instead saw '{b}'.\",\n                        nexttoken, 'script', nexttoken.value);\n            }\n            advance();\n            xmode = 'outer';\n            break;\n        case 'style':\n            xmode = 'style';\n            advance('>');\n            styles();\n            xmode = 'html';\n            advance('</');\n            if (!nexttoken.identifier && nexttoken.value !== 'style') {\n                warning(\"Expected '{a}' and instead saw '{b}'.\",\n                        nexttoken, 'style', nexttoken.value);\n            }\n            advance();\n            xmode = 'outer';\n            break;\n        case 'input':\n            switch (a.type) {\n            case 'radio':\n            case 'checkbox':\n            case 'button':\n            case 'reset':\n            case 'submit':\n                break;\n            case 'text':\n            case 'file':\n            case 'password':\n            case 'file':\n            case 'hidden':\n            case 'image':\n                if (option.adsafe && a.autocomplete !== 'off') {\n                    warning(\"ADsafe autocomplete violation.\");\n                }\n                break;\n            default:\n                warning(\"Bad input type.\");\n            }\n            break;\n        case 'applet':\n        case 'body':\n        case 'embed':\n        case 'frame':\n        case 'frameset':\n        case 'head':\n        case 'iframe':\n        case 'noembed':\n        case 'noframes':\n        case 'object':\n        case 'param':\n            if (option.adsafe) {\n                warning(\"ADsafe violation: Disallowed tag: \" + n);\n            }\n            break;\n        }\n    }\n\n\n    function closetag(n) {\n        return '</' + n + '>';\n    }\n\n    function html() {\n        var a, attributes, e, n, q, t, v, w = option.white, wmode;\n        xmode = 'html';\n        xquote = '';\n        stack = null;\n        for (;;) {\n            switch (nexttoken.value) {\n            case '<':\n                xmode = 'html';\n                advance('<');\n                attributes = {};\n                t = nexttoken;\n                if (!t.identifier) {\n                    warning(\"Bad identifier {a}.\", t, t.value);\n                }\n                n = t.value;\n                if (option.cap) {\n                    n = n.toLowerCase();\n                }\n                t.name = n;\n                advance();\n                if (!stack) {\n                    stack = [];\n                    doBegin(n);\n                }\n                v = htmltag[n];\n                if (typeof v !== 'object') {\n                    error(\"Unrecognized tag '<{a}>'.\", t, n);\n                }\n                e = v.empty;\n                t.type = n;\n                for (;;) {\n                    if (nexttoken.id === '/') {\n                        advance('/');\n                        if (nexttoken.id !== '>') {\n                            warning(\"Expected '{a}' and instead saw '{b}'.\",\n                                    nexttoken, '>', nexttoken.value);\n                        }\n                        break;\n                    }\n                    if (nexttoken.id && nexttoken.id.substr(0, 1) === '>') {\n                        break;\n                    }\n                    if (!nexttoken.identifier) {\n                        if (nexttoken.id === '(end)' || nexttoken.id === '(error)') {\n                            error(\"Missing '>'.\", nexttoken);\n                        }\n                        warning(\"Bad identifier.\");\n                    }\n                    option.white = true;\n                    nonadjacent(token, nexttoken);\n                    a = nexttoken.value;\n                    option.white = w;\n                    advance();\n                    if (!option.cap && a !== a.toLowerCase()) {\n                        warning(\"Attribute '{a}' not all lower case.\", nexttoken, a);\n                    }\n                    a = a.toLowerCase();\n                    xquote = '';\n                    if (is_own(attributes, a)) {\n                        warning(\"Attribute '{a}' repeated.\", nexttoken, a);\n                    }\n                    if (a.slice(0, 2) === 'on') {\n                        if (!option.on) {\n                            warning(\"Avoid HTML event handlers.\");\n                        }\n                        xmode = 'scriptstring';\n                        advance('=');\n                        q = nexttoken.id;\n                        if (q !== '\"' && q !== \"'\") {\n                            error(\"Missing quote.\");\n                        }\n                        xquote = q;\n                        wmode = option.white;\n                        option.white = false;\n                        advance(q);\n                        use_strict();\n                        statements('on');\n                        option.white = wmode;\n                        if (nexttoken.id !== q) {\n                            error(\"Missing close quote on script attribute.\");\n                        }\n                        xmode = 'html';\n                        xquote = '';\n                        advance(q);\n                        v = false;\n                    } else if (a === 'style') {\n                        xmode = 'scriptstring';\n                        advance('=');\n                        q = nexttoken.id;\n                        if (q !== '\"' && q !== \"'\") {\n                            error(\"Missing quote.\");\n                        }\n                        xmode = 'styleproperty';\n                        xquote = q;\n                        advance(q);\n                        substyle();\n                        xmode = 'html';\n                        xquote = '';\n                        advance(q);\n                        v = false;\n                    } else {\n                        if (nexttoken.id === '=') {\n                            advance('=');\n                            v = nexttoken.value;\n                            if (!nexttoken.identifier &&\n                                    nexttoken.id !== '\"' &&\n                                    nexttoken.id !== '\\'' &&\n                                    nexttoken.type !== '(string)' &&\n                                    nexttoken.type !== '(number)' &&\n                                    nexttoken.type !== '(color)') {\n                                warning(\"Expected an attribute value and instead saw '{a}'.\", token, a);\n                            }\n                            advance();\n                        } else {\n                            v = true;\n                        }\n                    }\n                    attributes[a] = v;\n                    doAttribute(n, a, v);\n                }\n                doTag(n, attributes);\n                if (!e) {\n                    stack.push(t);\n                }\n                xmode = 'outer';\n                advance('>');\n                break;\n            case '</':\n                xmode = 'html';\n                advance('</');\n                if (!nexttoken.identifier) {\n                    warning(\"Bad identifier.\");\n                }\n                n = nexttoken.value;\n                if (option.cap) {\n                    n = n.toLowerCase();\n                }\n                advance();\n                if (!stack) {\n                    error(\"Unexpected '{a}'.\", nexttoken, closetag(n));\n                }\n                t = stack.pop();\n                if (!t) {\n                    error(\"Unexpected '{a}'.\", nexttoken, closetag(n));\n                }\n                if (t.name !== n) {\n                    error(\"Expected '{a}' and instead saw '{b}'.\",\n                            nexttoken, closetag(t.name), closetag(n));\n                }\n                if (nexttoken.id !== '>') {\n                    error(\"Missing '{a}'.\", nexttoken, '>');\n                }\n                xmode = 'outer';\n                advance('>');\n                break;\n            case '<!':\n                if (option.safe) {\n                    warning(\"ADsafe HTML violation.\");\n                }\n                xmode = 'html';\n                for (;;) {\n                    advance();\n                    if (nexttoken.id === '>' || nexttoken.id === '(end)') {\n                        break;\n                    }\n                    if (nexttoken.value.indexOf('--') >= 0) {\n                        error(\"Unexpected --.\");\n                    }\n                    if (nexttoken.value.indexOf('<') >= 0) {\n                        error(\"Unexpected <.\");\n                    }\n                    if (nexttoken.value.indexOf('>') >= 0) {\n                        error(\"Unexpected >.\");\n                    }\n                }\n                xmode = 'outer';\n                advance('>');\n                break;\n            case '(end)':\n                return;\n            default:\n                if (nexttoken.id === '(end)') {\n                    error(\"Missing '{a}'.\", nexttoken,\n                            '</' + stack[stack.length - 1].value + '>');\n                } else {\n                    advance();\n                }\n            }\n            if (stack && stack.length === 0 && (option.adsafe ||\n                    !option.fragment || nexttoken.id === '(end)')) {\n                break;\n            }\n        }\n        if (nexttoken.id !== '(end)') {\n            error(\"Unexpected material after the end.\");\n        }\n    }\n\n\n// Build the syntax table by declaring the syntactic elements of the language.\n\n    type('(number)', function () {\n        return this;\n    });\n    type('(string)', function () {\n        return this;\n    });\n\n    syntax['(identifier)'] = {\n        type: '(identifier)',\n        lbp: 0,\n        identifier: true,\n        nud: function () {\n            var v = this.value,\n                s = scope[v],\n                f;\n            if (typeof s === 'function') {\n\n// Protection against accidental inheritance.\n\n                s = undefined;\n            } else if (typeof s === 'boolean') {\n                f = funct;\n                funct = functions[0];\n                addlabel(v, 'var');\n                s = funct;\n                funct = f;\n            }\n\n// The name is in scope and defined in the current function.\n\n            if (funct === s) {\n\n//      Change 'unused' to 'var', and reject labels.\n\n                switch (funct[v]) {\n                case 'unused':\n                    funct[v] = 'var';\n                    break;\n                case 'unction':\n                    funct[v] = 'function';\n                    this['function'] = true;\n                    break;\n                case 'function':\n                    this['function'] = true;\n                    break;\n                case 'label':\n                    warning(\"'{a}' is a statement label.\", token, v);\n                    break;\n                }\n\n// The name is not defined in the function.  If we are in the global scope,\n// then we have an undefined variable.\n\n            } else if (funct['(global)']) {\n                if (option.undef && typeof predefined[v] !== 'boolean') {\n                    warning(\"'{a}' is not defined.\", token, v);\n                }\n                note_implied(token);\n\n// If the name is already defined in the current\n// function, but not as outer, then there is a scope error.\n\n            } else {\n                switch (funct[v]) {\n                case 'closure':\n                case 'function':\n                case 'var':\n                case 'unused':\n                    warning(\"'{a}' used out of scope.\", token, v);\n                    break;\n                case 'label':\n                    warning(\"'{a}' is a statement label.\", token, v);\n                    break;\n                case 'outer':\n                case 'global':\n                    break;\n                default:\n\n// If the name is defined in an outer function, make an outer entry, and if\n// it was unused, make it var.\n\n                    if (s === true) {\n                        funct[v] = true;\n                    } else if (s === null) {\n                        warning(\"'{a}' is not allowed.\", token, v);\n                        note_implied(token);\n                    } else if (typeof s !== 'object') {\n                        if (option.undef) {\n                            warning(\"'{a}' is not defined.\", token, v);\n                        } else {\n                            funct[v] = true;\n                        }\n                        note_implied(token);\n                    } else {\n                        switch (s[v]) {\n                        case 'function':\n                        case 'unction':\n                            this['function'] = true;\n                            s[v] = 'closure';\n                            funct[v] = s['(global)'] ? 'global' : 'outer';\n                            break;\n                        case 'var':\n                        case 'unused':\n                            s[v] = 'closure';\n                            funct[v] = s['(global)'] ? 'global' : 'outer';\n                            break;\n                        case 'closure':\n                        case 'parameter':\n                            funct[v] = s['(global)'] ? 'global' : 'outer';\n                            break;\n                        case 'label':\n                            warning(\"'{a}' is a statement label.\", token, v);\n                        }\n                    }\n                }\n            }\n            return this;\n        },\n        led: function () {\n            error(\"Expected an operator and instead saw '{a}'.\",\n                nexttoken, nexttoken.value);\n        }\n    };\n\n    type('(regexp)', function () {\n        return this;\n    });\n\n\n// ECMAScript parser\n\n    delim('(endline)');\n    delim('(begin)');\n    delim('(end)').reach = true;\n    delim('</').reach = true;\n    delim('<!');\n    delim('<!--');\n    delim('-->');\n    delim('(error)').reach = true;\n    delim('}').reach = true;\n    delim(')');\n    delim(']');\n    delim('\"').reach = true;\n    delim(\"'\").reach = true;\n    delim(';');\n    delim(':').reach = true;\n    delim(',');\n    delim('#');\n    delim('@');\n    reserve('else');\n    reserve('case').reach = true;\n    reserve('catch');\n    reserve('default').reach = true;\n    reserve('finally');\n    reservevar('arguments', function (x) {\n        if (strict_mode && funct['(global)']) {\n            warning(\"Strict violation.\", x);\n        } else if (option.safe) {\n            warning(\"ADsafe violation.\", x);\n        }\n    });\n    reservevar('eval', function (x) {\n        if (option.safe) {\n            warning(\"ADsafe violation.\", x);\n        }\n    });\n    reservevar('false');\n    reservevar('Infinity');\n    reservevar('NaN');\n    reservevar('null');\n    reservevar('this', function (x) {\n        if (strict_mode && ((funct['(statement)'] &&\n                funct['(name)'].charAt(0) > 'Z') || funct['(global)'])) {\n            warning(\"Strict violation.\", x);\n        } else if (option.safe) {\n            warning(\"ADsafe violation.\", x);\n        }\n    });\n    reservevar('true');\n    reservevar('undefined');\n    assignop('=', 'assign', 20);\n    assignop('+=', 'assignadd', 20);\n    assignop('-=', 'assignsub', 20);\n    assignop('*=', 'assignmult', 20);\n    assignop('/=', 'assigndiv', 20).nud = function () {\n        error(\"A regular expression literal can be confused with '/='.\");\n    };\n    assignop('%=', 'assignmod', 20);\n    bitwiseassignop('&=', 'assignbitand', 20);\n    bitwiseassignop('|=', 'assignbitor', 20);\n    bitwiseassignop('^=', 'assignbitxor', 20);\n    bitwiseassignop('<<=', 'assignshiftleft', 20);\n    bitwiseassignop('>>=', 'assignshiftright', 20);\n    bitwiseassignop('>>>=', 'assignshiftrightunsigned', 20);\n    infix('?', function (left, that) {\n        that.left = left;\n        that.right = expression(10);\n        advance(':');\n        that['else'] = expression(10);\n        return that;\n    }, 30);\n\n    infix('||', 'or', 40);\n    infix('&&', 'and', 50);\n    bitwise('|', 'bitor', 70);\n    bitwise('^', 'bitxor', 80);\n    bitwise('&', 'bitand', 90);\n    relation('==', function (left, right) {\n        if (option.eqeqeq) {\n            warning(\"Expected '{a}' and instead saw '{b}'.\",\n                    this, '===', '==');\n        } else if (isPoorRelation(left)) {\n            warning(\"Use '{a}' to compare with '{b}'.\",\n                this, '===', left.value);\n        } else if (isPoorRelation(right)) {\n            warning(\"Use '{a}' to compare with '{b}'.\",\n                this, '===', right.value);\n        }\n        return this;\n    });\n    relation('===');\n    relation('!=', function (left, right) {\n        if (option.eqeqeq) {\n            warning(\"Expected '{a}' and instead saw '{b}'.\",\n                    this, '!==', '!=');\n        } else if (isPoorRelation(left)) {\n            warning(\"Use '{a}' to compare with '{b}'.\",\n                    this, '!==', left.value);\n        } else if (isPoorRelation(right)) {\n            warning(\"Use '{a}' to compare with '{b}'.\",\n                    this, '!==', right.value);\n        }\n        return this;\n    });\n    relation('!==');\n    relation('<');\n    relation('>');\n    relation('<=');\n    relation('>=');\n    bitwise('<<', 'shiftleft', 120);\n    bitwise('>>', 'shiftright', 120);\n    bitwise('>>>', 'shiftrightunsigned', 120);\n    infix('in', 'in', 120);\n    infix('instanceof', 'instanceof', 120);\n    infix('+', function (left, that) {\n        var right = expression(130);\n        if (left && right && left.id === '(string)' && right.id === '(string)') {\n            left.value += right.value;\n            left.character = right.character;\n            if (jx.test(left.value)) {\n                warning(\"JavaScript URL.\", left);\n            }\n            return left;\n        }\n        that.left = left;\n        that.right = right;\n        return that;\n    }, 130);\n    prefix('+', 'num');\n    prefix('+++', function () {\n        warning(\"Confusing pluses.\");\n        this.right = expression(150);\n        this.arity = 'unary';\n        return this;\n    });\n    infix('+++', function (left) {\n        warning(\"Confusing pluses.\");\n        this.left = left;\n        this.right = expression(130);\n        return this;\n    }, 130);\n    infix('-', 'sub', 130);\n    prefix('-', 'neg');\n    prefix('---', function () {\n        warning(\"Confusing minuses.\");\n        this.right = expression(150);\n        this.arity = 'unary';\n        return this;\n    });\n    infix('---', function (left) {\n        warning(\"Confusing minuses.\");\n        this.left = left;\n        this.right = expression(130);\n        return this;\n    }, 130);\n    infix('*', 'mult', 140);\n    infix('/', 'div', 140);\n    infix('%', 'mod', 140);\n\n    suffix('++', 'postinc');\n    prefix('++', 'preinc');\n    syntax['++'].exps = true;\n\n    suffix('--', 'postdec');\n    prefix('--', 'predec');\n    syntax['--'].exps = true;\n    prefix('delete', function () {\n        var p = expression(0);\n        if (!p || (p.id !== '.' && p.id !== '[')) {\n            warning(\"Variables should not be deleted.\");\n        }\n        this.first = p;\n        return this;\n    }).exps = true;\n\n\n    prefix('~', function () {\n        if (option.bitwise) {\n            warning(\"Unexpected '{a}'.\", this, '~');\n        }\n        expression(150);\n        return this;\n    });\n    prefix('!', function () {\n        this.right = expression(150);\n        this.arity = 'unary';\n        if (bang[this.right.id] === true) {\n            warning(\"Confusing use of '{a}'.\", this, '!');\n        }\n        return this;\n    });\n    prefix('typeof', 'typeof');\n    prefix('new', function () {\n        var c = expression(155), i;\n        if (c && c.id !== 'function') {\n            if (c.identifier) {\n                c['new'] = true;\n                switch (c.value) {\n                case 'Object':\n                    warning(\"Use the object literal notation {}.\", token);\n                    break;\n                case 'Array':\n                    if (nexttoken.id !== '(') {\n                        warning(\"Use the array literal notation [].\", token);\n                    } else {\n                        advance('(');\n                        if (nexttoken.id === ')') {\n                            warning(\"Use the array literal notation [].\", token);\n                        }\n                        advance(')');\n                    }\n                    this.first = c;\n                    return this;\n                case 'Number':\n                case 'String':\n                case 'Boolean':\n                case 'Math':\n                case 'JSON':\n                    warning(\"Do not use {a} as a constructor.\", token, c.value);\n                    break;\n                case 'Function':\n                    if (!option.evil) {\n                        warning(\"The Function constructor is eval.\");\n                    }\n                    break;\n                case 'Date':\n                case 'RegExp':\n                    break;\n                default:\n                    if (c.id !== 'function') {\n                        i = c.value.substr(0, 1);\n                        if (option.newcap && (i < 'A' || i > 'Z')) {\n                            warning(\n                    \"A constructor name should start with an uppercase letter.\",\n                                token);\n                        }\n                    }\n                }\n            } else {\n                if (c.id !== '.' && c.id !== '[' && c.id !== '(') {\n                    warning(\"Bad constructor.\", token);\n                }\n            }\n        } else {\n            warning(\"Weird construction. Delete 'new'.\", this);\n        }\n        adjacent(token, nexttoken);\n        if (nexttoken.id !== '(') {\n            warning(\"Missing '()' invoking a constructor.\");\n        }\n        this.first = c;\n        return this;\n    });\n    syntax['new'].exps = true;\n\n    infix('.', function (left, that) {\n        adjacent(prevtoken, token);\n        nobreak();\n        var m = identifier();\n        if (typeof m === 'string') {\n            countMember(m);\n        }\n        that.left = left;\n        that.right = m;\n        if (option.noarg && left && left.value === 'arguments' &&\n                (m === 'callee' || m === 'caller')) {\n            warning(\"Avoid arguments.{a}.\", left, m);\n        } else if (!option.evil && left && left.value === 'document' &&\n                (m === 'write' || m === 'writeln')) {\n            warning(\"document.write can be a form of eval.\", left);\n        } else if (option.adsafe) {\n            if (left && left.value === 'ADSAFE') {\n                if (m === 'id' || m === 'lib') {\n                    warning(\"ADsafe violation.\", that);\n                } else if (m === 'go') {\n                    if (xmode !== 'script') {\n                        warning(\"ADsafe violation.\", that);\n                    } else if (adsafe_went || nexttoken.id !== '(' ||\n                            peek(0).id !== '(string)' ||\n                            peek(0).value !== adsafe_id ||\n                            peek(1).id !== ',') {\n                        error(\"ADsafe violation: go.\", that);\n                    }\n                    adsafe_went = true;\n                    adsafe_may = false;\n                }\n            }\n        }\n        if (!option.evil && (m === 'eval' || m === 'execScript')) {\n            warning('eval is evil.');\n        } else if (option.safe) {\n            for (;;) {\n                if (banned[m] === true) {\n                    warning(\"ADsafe restricted word '{a}'.\", token, m);\n                }\n                if (typeof predefined[left.value] !== 'boolean' ||\n                        nexttoken.id === '(') {\n                    break;\n                }\n                if (standard_member[m] === true) {\n                    if (nexttoken.id === '.') {\n                        warning(\"ADsafe violation.\", that);\n                    }\n                    break;\n                }\n                if (nexttoken.id !== '.') {\n                    warning(\"ADsafe violation.\", that);\n                    break;\n                }\n                advance('.');\n                token.left = that;\n                token.right = m;\n                that = token;\n                m = identifier();\n                if (typeof m === 'string') {\n                    countMember(m);\n                }\n            }\n        }\n        return that;\n    }, 160, true);\n\n    infix('(', function (left, that) {\n        if (prevtoken.id !== '}' && prevtoken.id !== ')') {\n            nobreak(prevtoken, token);\n        }\n        nospace();\n        if (option.immed && !left.immed && left.id === 'function') {\n            warning(\"Wrap an immediate function invocation in parentheses \" +\n                \"to assist the reader in understanding that the expression \" +\n                \"is the result of a function, and not the function itself.\");\n        }\n        var n = 0,\n            p = [];\n        if (left) {\n            if (left.type === '(identifier)') {\n                if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {\n                    if (left.value !== 'Number' && left.value !== 'String' &&\n                            left.value !== 'Boolean' &&\n                            left.value !== 'Date') {\n                        if (left.value === 'Math') {\n                            warning(\"Math is not a function.\", left);\n                        } else if (option.newcap) {\n                            warning(\n\"Missing 'new' prefix when invoking a constructor.\", left);\n                        }\n                    }\n                }\n            } else if (left.id === '.') {\n                if (option.safe && left.left.value === 'Math' &&\n                        left.right === 'random') {\n                    warning(\"ADsafe violation.\", left);\n                }\n            }\n        }\n        if (nexttoken.id !== ')') {\n            for (;;) {\n                p[p.length] = expression(10);\n                n += 1;\n                if (nexttoken.id !== ',') {\n                    break;\n                }\n                comma();\n            }\n        }\n        advance(')');\n        nospace(prevtoken, token);\n        if (typeof left === 'object') {\n            if (left.value === 'parseInt' && n === 1) {\n                warning(\"Missing radix parameter.\", left);\n            }\n            if (!option.evil) {\n                if (left.value === 'eval' || left.value === 'Function' ||\n                        left.value === 'execScript') {\n                    warning(\"eval is evil.\", left);\n                } else if (p[0] && p[0].id === '(string)' &&\n                       (left.value === 'setTimeout' ||\n                        left.value === 'setInterval')) {\n                    warning(\n    \"Implied eval is evil. Pass a function instead of a string.\", left);\n                }\n            }\n            if (!left.identifier && left.id !== '.' && left.id !== '[' &&\n                    left.id !== '(' && left.id !== '&&' && left.id !== '||' &&\n                    left.id !== '?') {\n                warning(\"Bad invocation.\", left);\n            }\n        }\n        that.left = left;\n        return that;\n    }, 155, true).exps = true;\n\n    prefix('(', function () {\n        nospace();\n        if (nexttoken.id === 'function') {\n            nexttoken.immed = true;\n        }\n        var v = expression(0);\n        advance(')', this);\n        nospace(prevtoken, token);\n        if (option.immed && v.id === 'function') {\n            if (nexttoken.id === '(') {\n                warning(\n\"Move the invocation into the parens that contain the function.\", nexttoken);\n            } else {\n                warning(\n\"Do not wrap function literals in parens unless they are to be immediately invoked.\",\n                        this);\n            }\n        }\n        return v;\n    });\n\n    infix('[', function (left, that) {\n        nobreak(prevtoken, token);\n        nospace();\n        var e = expression(0), s;\n        if (e && e.type === '(string)') {\n            if (option.safe && banned[e.value] === true) {\n                warning(\"ADsafe restricted word '{a}'.\", that, e.value);\n            } else if (!option.evil &&\n                    (e.value === 'eval' || e.value === 'execScript')) {\n                warning(\"eval is evil.\", that);\n            } else if (option.safe &&\n                    (e.value.charAt(0) === '_' || e.value.charAt(0) === '-')) {\n                warning(\"ADsafe restricted subscript '{a}'.\", that, e.value);\n            }\n            countMember(e.value);\n            if (!option.sub && ix.test(e.value)) {\n                s = syntax[e.value];\n                if (!s || !s.reserved) {\n                    warning(\"['{a}'] is better written in dot notation.\",\n                            e, e.value);\n                }\n            }\n        } else if (!e || e.type !== '(number)' || e.value < 0) {\n            if (option.safe) {\n                warning('ADsafe subscripting.');\n            }\n        }\n        advance(']', that);\n        nospace(prevtoken, token);\n        that.left = left;\n        that.right = e;\n        return that;\n    }, 160, true);\n\n    prefix('[', function () {\n        var b = token.line !== nexttoken.line;\n        this.first = [];\n        if (b) {\n            indent += option.indent;\n            if (nexttoken.from === indent + option.indent) {\n                indent += option.indent;\n            }\n        }\n        while (nexttoken.id !== '(end)') {\n            while (nexttoken.id === ',') {\n                warning(\"Extra comma.\");\n                advance(',');\n            }\n            if (nexttoken.id === ']') {\n                break;\n            }\n            if (b && token.line !== nexttoken.line) {\n                indentation();\n            }\n            this.first.push(expression(10));\n            if (nexttoken.id === ',') {\n                comma();\n                if (nexttoken.id === ']' && !option.es5) {\n                    warning(\"Extra comma.\", token);\n                    break;\n                }\n            } else {\n                break;\n            }\n        }\n        if (b) {\n            indent -= option.indent;\n            indentation();\n        }\n        advance(']', this);\n        return this;\n    }, 160);\n\n\n    function property_name() {\n        var id = optionalidentifier(true);\n        if (!id) {\n            if (nexttoken.id === '(string)') {\n                id = nexttoken.value;\n                if (option.adsafe &&\n                        (id.charAt(0) === '_' ||\n                         id.charAt(id.length - 1) === '_')) {\n                    warning(\"Unexpected {a} in '{b}'.\", token,\n                        \"dangling '_'\", id);\n                }\n                advance();\n            } else if (nexttoken.id === '(number)') {\n                id = nexttoken.value.toString();\n                advance();\n            }\n        }\n        return id;\n    }\n\n\n    function functionparams() {\n        var i, t = nexttoken, p = [];\n        advance('(');\n        nospace();\n        if (nexttoken.id === ')') {\n            advance(')');\n            nospace(prevtoken, token);\n            return;\n        }\n        for (;;) {\n            i = identifier();\n            p.push(i);\n            addlabel(i, 'parameter');\n            if (nexttoken.id === ',') {\n                comma();\n            } else {\n                advance(')', t);\n                nospace(prevtoken, token);\n                return p;\n            }\n        }\n    }\n\n\n    function doFunction(i, statement) {\n        var f, s = scope;\n        scope = Object.create(s);\n        funct = {\n            '(name)'     : i || '\"' + anonname + '\"',\n            '(line)'     : nexttoken.line,\n            '(context)'  : funct,\n            '(breakage)' : 0,\n            '(loopage)'  : 0,\n            '(scope)'    : scope,\n            '(statement)': statement\n        };\n        f = funct;\n        token.funct = funct;\n        functions.push(funct);\n        if (i) {\n            addlabel(i, 'function');\n        }\n        funct['(params)'] = functionparams();\n\n        block(false);\n        scope = s;\n        funct['(last)'] = token.line;\n        funct = funct['(context)'];\n        return f;\n    }\n\n\n    (function (x) {\n        x.nud = function () {\n            var b, f, i, j, p, seen = {}, t;\n            b = token.line !== nexttoken.line;\n            if (b) {\n                indent += option.indent;\n                if (nexttoken.from === indent + option.indent) {\n                    indent += option.indent;\n                }\n            }\n            for (;;) {\n                if (nexttoken.id === '}') {\n                    break;\n                }\n                if (b) {\n                    indentation();\n                }\n                if (nexttoken.value === 'get' && peek().id !== ':') {\n                    advance('get');\n                    if (!option.es5) {\n                        error(\"get/set are ES5 features.\");\n                    }\n                    i = property_name();\n                    if (!i) {\n                        error(\"Missing property name.\");\n                    }\n                    t = nexttoken;\n                    adjacent(token, nexttoken);\n                    f = doFunction(i);\n                    if (funct['(loopage)']) {\n                        warning(\"Don't make functions within a loop.\", t);\n                    }\n                    p = f['(params)'];\n                    if (p) {\n                        warning(\"Unexpected parameter '{a}' in get {b} function.\", t, p[0], i);\n                    }\n                    adjacent(token, nexttoken);\n                    advance(',');\n                    indentation();\n                    advance('set');\n                    j = property_name();\n                    if (i !== j) {\n                        error(\"Expected {a} and instead saw {b}.\", token, i, j);\n                    }\n                    t = nexttoken;\n                    adjacent(token, nexttoken);\n                    f = doFunction(i);\n                    p = f['(params)'];\n                    if (!p || p.length !== 1 || p[0] !== 'value') {\n                        warning(\"Expected (value) in set {a} function.\", t, i);\n                    }\n                } else {\n                    i = property_name();\n                    if (typeof i !== 'string') {\n                        break;\n                    }\n                    advance(':');\n                    nonadjacent(token, nexttoken);\n                    expression(10);\n                }\n                if (seen[i] === true) {\n                    warning(\"Duplicate member '{a}'.\", nexttoken, i);\n                }\n                seen[i] = true;\n                countMember(i);\n                if (nexttoken.id === ',') {\n                    comma();\n                    if (nexttoken.id === ',') {\n                        warning(\"Extra comma.\", token);\n                    } else if (nexttoken.id === '}' && !option.es5) {\n                        warning(\"Extra comma.\", token);\n                    }\n                } else {\n                    break;\n                }\n            }\n            if (b) {\n                indent -= option.indent;\n                indentation();\n            }\n            advance('}', this);\n            return this;\n        };\n        x.fud = function () {\n            error(\"Expected to see a statement and instead saw a block.\", token);\n        };\n    }(delim('{')));\n\n\n    var varstatement = function varstatement(prefix) {\n\n// JavaScript does not have block scope. It only has function scope. So,\n// declaring a variable in a block can have unexpected consequences.\n\n        var id, name, value;\n\n        if (funct['(onevar)'] && option.onevar) {\n            warning(\"Too many var statements.\");\n        } else if (!funct['(global)']) {\n            funct['(onevar)'] = true;\n        }\n        this.first = [];\n        for (;;) {\n            nonadjacent(token, nexttoken);\n            id = identifier();\n            if (funct['(global)'] && predefined[id] === false) {\n                warning(\"Redefinition of '{a}'.\", token, id);\n            }\n            addlabel(id, 'unused');\n            if (prefix) {\n                break;\n            }\n            name = token;\n            this.first.push(token);\n            if (nexttoken.id === '=') {\n                nonadjacent(token, nexttoken);\n                advance('=');\n                nonadjacent(token, nexttoken);\n                if (nexttoken.id === 'undefined') {\n                    warning(\"It is not necessary to initialize '{a}' to 'undefined'.\", token, id);\n                }\n                if (peek(0).id === '=' && nexttoken.identifier) {\n                    error(\"Variable {a} was not declared correctly.\",\n                            nexttoken, nexttoken.value);\n                }\n                value = expression(0);\n                name.first = value;\n            }\n            if (nexttoken.id !== ',') {\n                break;\n            }\n            comma();\n        }\n        return this;\n    };\n\n\n    stmt('var', varstatement).exps = true;\n\n\n    blockstmt('function', function () {\n        if (inblock) {\n            warning(\n\"Function statements should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.\", token);\n\n        }\n        var i = identifier();\n        adjacent(token, nexttoken);\n        addlabel(i, 'unction');\n        doFunction(i, true);\n        if (nexttoken.id === '(' && nexttoken.line === token.line) {\n            error(\n\"Function statements are not invocable. Wrap the whole function invocation in parens.\");\n        }\n        return this;\n    });\n\n    prefix('function', function () {\n        var i = optionalidentifier();\n        if (i) {\n            adjacent(token, nexttoken);\n        } else {\n            nonadjacent(token, nexttoken);\n        }\n        doFunction(i);\n        if (funct['(loopage)']) {\n            warning(\"Don't make functions within a loop.\");\n        }\n        return this;\n    });\n\n    blockstmt('if', function () {\n        var t = nexttoken;\n        advance('(');\n        nonadjacent(this, t);\n        nospace();\n        expression(20);\n        if (nexttoken.id === '=') {\n            if (!option.boss)\n                warning(\"Expected a conditional expression and instead saw an assignment.\");\n            advance('=');\n            expression(20);\n        }\n        advance(')', t);\n        nospace(prevtoken, token);\n        block(true, true);\n        if (nexttoken.id === 'else') {\n            nonadjacent(token, nexttoken);\n            advance('else');\n            if (nexttoken.id === 'if' || nexttoken.id === 'switch') {\n                statement(true);\n            } else {\n                block(true, true);\n            }\n        }\n        return this;\n    });\n\n    blockstmt('try', function () {\n        var b, e, s;\n        if (option.adsafe) {\n            warning(\"ADsafe try violation.\", this);\n        }\n        block(false);\n        if (nexttoken.id === 'catch') {\n            advance('catch');\n            nonadjacent(token, nexttoken);\n            advance('(');\n            s = scope;\n            scope = Object.create(s);\n            e = nexttoken.value;\n            if (nexttoken.type !== '(identifier)') {\n                warning(\"Expected an identifier and instead saw '{a}'.\",\n                    nexttoken, e);\n            } else {\n                addlabel(e, 'exception');\n            }\n            advance();\n            advance(')');\n            block(false);\n            b = true;\n            scope = s;\n        }\n        if (nexttoken.id === 'finally') {\n            advance('finally');\n            block(false);\n            return;\n        } else if (!b) {\n            error(\"Expected '{a}' and instead saw '{b}'.\",\n                    nexttoken, 'catch', nexttoken.value);\n        }\n        return this;\n    });\n\n    blockstmt('while', function () {\n        var t = nexttoken;\n        funct['(breakage)'] += 1;\n        funct['(loopage)'] += 1;\n        advance('(');\n        nonadjacent(this, t);\n        nospace();\n        expression(20);\n        if (nexttoken.id === '=') {\n            if (!option.boss)\n                warning(\"Expected a conditional expression and instead saw an assignment.\");\n            advance('=');\n            expression(20);\n        }\n        advance(')', t);\n        nospace(prevtoken, token);\n        block(true, true);\n        funct['(breakage)'] -= 1;\n        funct['(loopage)'] -= 1;\n        return this;\n    }).labelled = true;\n\n    reserve('with');\n\n    blockstmt('switch', function () {\n        var t = nexttoken,\n            g = false;\n        funct['(breakage)'] += 1;\n        advance('(');\n        nonadjacent(this, t);\n        nospace();\n        this.condition = expression(20);\n        advance(')', t);\n        nospace(prevtoken, token);\n        nonadjacent(token, nexttoken);\n        t = nexttoken;\n        advance('{');\n        nonadjacent(token, nexttoken);\n        indent += option.indent;\n        this.cases = [];\n        for (;;) {\n            switch (nexttoken.id) {\n            case 'case':\n                switch (funct['(verb)']) {\n                case 'break':\n                case 'case':\n                case 'continue':\n                case 'return':\n                case 'switch':\n                case 'throw':\n                    break;\n                default:\n                    warning(\n                        \"Expected a 'break' statement before 'case'.\",\n                        token);\n                }\n                indentation(-option.indent);\n                advance('case');\n                this.cases.push(expression(20));\n                g = true;\n                advance(':');\n                funct['(verb)'] = 'case';\n                break;\n            case 'default':\n                switch (funct['(verb)']) {\n                case 'break':\n                case 'continue':\n                case 'return':\n                case 'throw':\n                    break;\n                default:\n                    warning(\n                        \"Expected a 'break' statement before 'default'.\",\n                        token);\n                }\n                indentation(-option.indent);\n                advance('default');\n                g = true;\n                advance(':');\n                break;\n            case '}':\n                indent -= option.indent;\n                indentation();\n                advance('}', t);\n                if (this.cases.length === 1 || this.condition.id === 'true' ||\n                        this.condition.id === 'false') {\n                    warning(\"This 'switch' should be an 'if'.\", this);\n                }\n                funct['(breakage)'] -= 1;\n                funct['(verb)'] = undefined;\n                return;\n            case '(end)':\n                error(\"Missing '{a}'.\", nexttoken, '}');\n                return;\n            default:\n                if (g) {\n                    switch (token.id) {\n                    case ',':\n                        error(\"Each value should have its own case label.\");\n                        return;\n                    case ':':\n                        statements();\n                        break;\n                    default:\n                        error(\"Missing ':' on a case clause.\", token);\n                    }\n                } else {\n                    error(\"Expected '{a}' and instead saw '{b}'.\",\n                        nexttoken, 'case', nexttoken.value);\n                }\n            }\n        }\n    }).labelled = true;\n\n    stmt('debugger', function () {\n        if (!option.debug) {\n            warning(\"All 'debugger' statements should be removed.\");\n        }\n        return this;\n    }).exps = true;\n\n    (function () {\n        var x = stmt('do', function () {\n            funct['(breakage)'] += 1;\n            funct['(loopage)'] += 1;\n            this.first = block(true);\n            advance('while');\n            var t = nexttoken;\n            nonadjacent(token, t);\n            advance('(');\n            nospace();\n            expression(20);\n            if (nexttoken.id === '=') {\n                if (!option.boss)\n                    warning(\"Expected a conditional expression and instead saw an assignment.\");\n                advance('=');\n                expression(20);\n            }\n            advance(')', t);\n            nospace(prevtoken, token);\n            funct['(breakage)'] -= 1;\n            funct['(loopage)'] -= 1;\n            return this;\n        });\n        x.labelled = true;\n        x.exps = true;\n    }());\n\n    blockstmt('for', function () {\n        var f = option.forin, s, t = nexttoken;\n        funct['(breakage)'] += 1;\n        funct['(loopage)'] += 1;\n        advance('(');\n        nonadjacent(this, t);\n        nospace();\n        if (peek(nexttoken.id === 'var' ? 1 : 0).id === 'in') {\n            if (nexttoken.id === 'var') {\n                advance('var');\n                varstatement(true);\n            } else {\n                switch (funct[nexttoken.value]) {\n                case 'unused':\n                    funct[nexttoken.value] = 'var';\n                    break;\n                case 'var':\n                    break;\n                default:\n                    warning(\"Bad for in variable '{a}'.\",\n                            nexttoken, nexttoken.value);\n                }\n                advance();\n            }\n            advance('in');\n            expression(20);\n            advance(')', t);\n            s = block(true, true);\n            if (!f && (s.length > 1 || typeof s[0] !== 'object' ||\n                    s[0].value !== 'if')) {\n                warning(\"The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.\", this);\n            }\n            funct['(breakage)'] -= 1;\n            funct['(loopage)'] -= 1;\n            return this;\n        } else {\n            if (nexttoken.id !== ';') {\n                if (nexttoken.id === 'var') {\n                    advance('var');\n                    varstatement();\n                } else {\n                    for (;;) {\n                        expression(0, 'for');\n                        if (nexttoken.id !== ',') {\n                            break;\n                        }\n                        comma();\n                    }\n                }\n            }\n            nolinebreak(token);\n            advance(';');\n            if (nexttoken.id !== ';') {\n                expression(20);\n                if (nexttoken.id === '=') {\n                    if (!option.boss)\n                        warning(\"Expected a conditional expression and instead saw an assignment.\");\n                    advance('=');\n                    expression(20);\n                }\n            }\n            nolinebreak(token);\n            advance(';');\n            if (nexttoken.id === ';') {\n                error(\"Expected '{a}' and instead saw '{b}'.\",\n                        nexttoken, ')', ';');\n            }\n            if (nexttoken.id !== ')') {\n                for (;;) {\n                    expression(0, 'for');\n                    if (nexttoken.id !== ',') {\n                        break;\n                    }\n                    comma();\n                }\n            }\n            advance(')', t);\n            nospace(prevtoken, token);\n            block(true, true);\n            funct['(breakage)'] -= 1;\n            funct['(loopage)'] -= 1;\n            return this;\n        }\n    }).labelled = true;\n\n\n    stmt('break', function () {\n        var v = nexttoken.value;\n        if (funct['(breakage)'] === 0) {\n            warning(\"Unexpected '{a}'.\", nexttoken, this.value);\n        }\n        nolinebreak(this);\n        if (nexttoken.id !== ';') {\n            if (token.line === nexttoken.line) {\n                if (funct[v] !== 'label') {\n                    warning(\"'{a}' is not a statement label.\", nexttoken, v);\n                } else if (scope[v] !== funct) {\n                    warning(\"'{a}' is out of scope.\", nexttoken, v);\n                }\n                this.first = nexttoken;\n                advance();\n            }\n        }\n        reachable('break');\n        return this;\n    }).exps = true;\n\n\n    stmt('continue', function () {\n        var v = nexttoken.value;\n        if (funct['(breakage)'] === 0) {\n            warning(\"Unexpected '{a}'.\", nexttoken, this.value);\n        }\n        nolinebreak(this);\n        if (nexttoken.id !== ';') {\n            if (token.line === nexttoken.line) {\n                if (funct[v] !== 'label') {\n                    warning(\"'{a}' is not a statement label.\", nexttoken, v);\n                } else if (scope[v] !== funct) {\n                    warning(\"'{a}' is out of scope.\", nexttoken, v);\n                }\n                this.first = nexttoken;\n                advance();\n            }\n        } else if (!funct['(loopage)']) {\n            warning(\"Unexpected '{a}'.\", nexttoken, this.value);\n        }\n        reachable('continue');\n        return this;\n    }).exps = true;\n\n\n    stmt('return', function () {\n        nolinebreak(this);\n        if (nexttoken.id === '(regexp)') {\n            warning(\"Wrap the /regexp/ literal in parens to disambiguate the slash operator.\");\n        }\n        if (nexttoken.id !== ';' && !nexttoken.reach) {\n            nonadjacent(token, nexttoken);\n            this.first = expression(20);\n        }\n        reachable('return');\n        return this;\n    }).exps = true;\n\n\n    stmt('throw', function () {\n        nolinebreak(this);\n        nonadjacent(token, nexttoken);\n        this.first = expression(20);\n        reachable('throw');\n        return this;\n    }).exps = true;\n\n    reserve('void');\n\n//  Superfluous reserved words\n\n    reserve('class');\n    reserve('const');\n    reserve('enum');\n    reserve('export');\n    reserve('extends');\n    reserve('import');\n    reserve('super');\n\n    reserve('let');\n    reserve('yield');\n    reserve('implements');\n    reserve('interface');\n    reserve('package');\n    reserve('private');\n    reserve('protected');\n    reserve('public');\n    reserve('static');\n\n\n// Parse JSON\n\n    function jsonValue() {\n\n        function jsonObject() {\n            var o = {}, t = nexttoken;\n            advance('{');\n            if (nexttoken.id !== '}') {\n                for (;;) {\n                    if (nexttoken.id === '(end)') {\n                        error(\"Missing '}' to match '{' from line {a}.\",\n                                nexttoken, t.line);\n                    } else if (nexttoken.id === '}') {\n                        warning(\"Unexpected comma.\", token);\n                        break;\n                    } else if (nexttoken.id === ',') {\n                        error(\"Unexpected comma.\", nexttoken);\n                    } else if (nexttoken.id !== '(string)') {\n                        warning(\"Expected a string and instead saw {a}.\",\n                                nexttoken, nexttoken.value);\n                    }\n                    if (o[nexttoken.value] === true) {\n                        warning(\"Duplicate key '{a}'.\",\n                                nexttoken, nexttoken.value);\n                    } else if (nexttoken.value === '__proto__') {\n                        warning(\"Stupid key '{a}'.\",\n                                nexttoken, nexttoken.value);\n                    } else {\n                        o[nexttoken.value] = true;\n                    }\n                    advance();\n                    advance(':');\n                    jsonValue();\n                    if (nexttoken.id !== ',') {\n                        break;\n                    }\n                    advance(',');\n                }\n            }\n            advance('}');\n        }\n\n        function jsonArray() {\n            var t = nexttoken;\n            advance('[');\n            if (nexttoken.id !== ']') {\n                for (;;) {\n                    if (nexttoken.id === '(end)') {\n                        error(\"Missing ']' to match '[' from line {a}.\",\n                                nexttoken, t.line);\n                    } else if (nexttoken.id === ']') {\n                        warning(\"Unexpected comma.\", token);\n                        break;\n                    } else if (nexttoken.id === ',') {\n                        error(\"Unexpected comma.\", nexttoken);\n                    }\n                    jsonValue();\n                    if (nexttoken.id !== ',') {\n                        break;\n                    }\n                    advance(',');\n                }\n            }\n            advance(']');\n        }\n\n        switch (nexttoken.id) {\n        case '{':\n            jsonObject();\n            break;\n        case '[':\n            jsonArray();\n            break;\n        case 'true':\n        case 'false':\n        case 'null':\n        case '(number)':\n        case '(string)':\n            advance();\n            break;\n        case '-':\n            advance('-');\n            if (token.character !== nexttoken.from) {\n                warning(\"Unexpected space after '-'.\", token);\n            }\n            adjacent(token, nexttoken);\n            advance('(number)');\n            break;\n        default:\n            error(\"Expected a JSON value.\", nexttoken);\n        }\n    }\n\n\n// The actual JSHINT function itself.\n\n    var itself = function (s, o) {\n        var a, i, k;\n        JSHINT.errors = [];\n        predefined = Object.create(standard);\n        if (o) {\n            a = o.predef;\n            if (a) {\n                if (Array.isArray(a)) {\n                    for (i = 0; i < a.length; i += 1) {\n                        predefined[a[i]] = true;\n                    }\n                } else if (typeof a === 'object') {\n                    k = Object.keys(a);\n                    for (i = 0; i < k.length; i += 1) {\n                        predefined[k[i]] = !!a[k];\n                    }\n                }\n            }\n            if (o.adsafe) {\n                o.safe = true;\n            }\n            if (o.safe) {\n                o.browser =\n                o.css     =\n                o.debug   =\n                o.devel   =\n                o.evil    =\n                o.forin   =\n                o.on      =\n                o.rhino   =\n                o.windows =\n                o.sub     =\n                o.widget  = false;\n\n                o.eqeqeq  =\n                o.nomen   =\n                o.safe    =\n                o.undef   = true;\n\n                predefined.Date =\n                predefined['eval'] =\n                predefined.Function =\n                predefined.Object = null;\n\n                predefined.ADSAFE =\n                predefined.lib = false;\n            }\n            option = o;\n        } else {\n            option = {};\n        }\n        option.indent = option.indent || 4;\n        option.maxerr = option.maxerr || 50;\n        adsafe_id = '';\n        adsafe_may = false;\n        adsafe_went = false;\n        approved = {};\n        if (option.approved) {\n            for (i = 0; i < option.approved.length; i += 1) {\n                approved[option.approved[i]] = option.approved[i];\n            }\n        } else {\n            approved.test = 'test';\n        }\n        tab = '';\n        for (i = 0; i < option.indent; i += 1) {\n            tab += ' ';\n        }\n        indent = 1;\n        global = Object.create(predefined);\n        scope = global;\n        funct = {\n            '(global)': true,\n            '(name)': '(global)',\n            '(scope)': scope,\n            '(breakage)': 0,\n            '(loopage)': 0\n        };\n        functions = [funct];\n        ids = {};\n        urls = [];\n        src = false;\n        xmode = false;\n        stack = null;\n        member = {};\n        membersOnly = null;\n        implied = {};\n        inblock = false;\n        lookahead = [];\n        jsonmode = false;\n        warnings = 0;\n        lex.init(s);\n        prereg = true;\n        strict_mode = false;\n\n        prevtoken = token = nexttoken = syntax['(begin)'];\n        assume();\n\n        try {\n            advance();\n            if (nexttoken.value.charAt(0) === '<') {\n                html();\n                if (option.adsafe && !adsafe_went) {\n                    warning(\"ADsafe violation: Missing ADSAFE.go.\", this);\n                }\n            } else {\n                switch (nexttoken.id) {\n                case '{':\n                case '[':\n                    option.laxbreak = true;\n                    jsonmode = true;\n                    jsonValue();\n                    break;\n                case '@':\n                case '*':\n                case '#':\n                case '.':\n                case ':':\n                    xmode = 'style';\n                    advance();\n                    if (token.id !== '@' || !nexttoken.identifier ||\n                            nexttoken.value !== 'charset' || token.line !== 1 ||\n                            token.from !== 1) {\n                        error(\"A css file should begin with @charset 'UTF-8';\");\n                    }\n                    advance();\n                    if (nexttoken.type !== '(string)' &&\n                            nexttoken.value !== 'UTF-8') {\n                        error(\"A css file should begin with @charset 'UTF-8';\");\n                    }\n                    advance();\n                    advance(';');\n                    styles();\n                    break;\n\n                default:\n                    if (option.adsafe && option.fragment) {\n                        error(\"Expected '{a}' and instead saw '{b}'.\",\n                            nexttoken, '<div>', nexttoken.value);\n                    }\n                    if (nexttoken.value === 'use strict') {\n                        warning(\"Use the function form of \\\"use strict\\\".\");\n                        use_strict();\n                    }\n                    statements('lib');\n                }\n            }\n            advance('(end)');\n        } catch (e) {\n            if (e) {\n                JSHINT.errors.push({\n                    reason    : e.message,\n                    line      : e.line || nexttoken.line,\n                    character : e.character || nexttoken.from\n                }, null);\n            }\n        }\n        return JSHINT.errors.length === 0;\n    };\n\n\n// Data summary.\n\n    itself.data = function () {\n\n        var data = {functions: []}, fu, globals, implieds = [], f, i, j,\n            members = [], n, unused = [], v;\n        if (itself.errors.length) {\n            data.errors = itself.errors;\n        }\n\n        if (jsonmode) {\n            data.json = true;\n        }\n\n        for (n in implied) {\n            if (is_own(implied, n)) {\n                implieds.push({\n                    name: n,\n                    line: implied[n]\n                });\n            }\n        }\n        if (implieds.length > 0) {\n            data.implieds = implieds;\n        }\n\n        if (urls.length > 0) {\n            data.urls = urls;\n        }\n\n        globals = Object.keys(scope);\n        if (globals.length > 0) {\n            data.globals = globals;\n        }\n\n        for (i = 1; i < functions.length; i += 1) {\n            f = functions[i];\n            fu = {};\n            for (j = 0; j < functionicity.length; j += 1) {\n                fu[functionicity[j]] = [];\n            }\n            for (n in f) {\n                if (is_own(f, n) && n.charAt(0) !== '(') {\n                    v = f[n];\n                    if (v === 'unction') {\n                        v = 'unused';\n                    }\n                    if (Array.isArray(fu[v])) {\n                        fu[v].push(n);\n                        if (v === 'unused') {\n                            unused.push({\n                                name: n,\n                                line: f['(line)'],\n                                'function': f['(name)']\n                            });\n                        }\n                    }\n                }\n            }\n            for (j = 0; j < functionicity.length; j += 1) {\n                if (fu[functionicity[j]].length === 0) {\n                    delete fu[functionicity[j]];\n                }\n            }\n            fu.name = f['(name)'];\n            fu.param = f['(params)'];\n            fu.line = f['(line)'];\n            fu.last = f['(last)'];\n            data.functions.push(fu);\n        }\n\n        if (unused.length > 0) {\n            data.unused = unused;\n        }\n\n        members = [];\n        for (n in member) {\n            if (typeof member[n] === 'number') {\n                data.member = member;\n                break;\n            }\n        }\n\n        return data;\n    };\n\n    itself.report = function (option) {\n        var data = itself.data();\n\n        var a = [], c, e, err, f, i, k, l, m = '', n, o = [], s;\n\n        function detail(h, array) {\n            var b, i, singularity;\n            if (array) {\n                o.push('<div><i>' + h + '</i> ');\n                array = array.sort();\n                for (i = 0; i < array.length; i += 1) {\n                    if (array[i] !== singularity) {\n                        singularity = array[i];\n                        o.push((b ? ', ' : '') + singularity);\n                        b = true;\n                    }\n                }\n                o.push('</div>');\n            }\n        }\n\n\n        if (data.errors || data.implieds || data.unused) {\n            err = true;\n            o.push('<div id=errors><i>Error:</i>');\n            if (data.errors) {\n                for (i = 0; i < data.errors.length; i += 1) {\n                    c = data.errors[i];\n                    if (c) {\n                        e = c.evidence || '';\n                        o.push('<p>Problem' + (isFinite(c.line) ? ' at line ' +\n                                c.line + ' character ' + c.character : '') +\n                                ': ' + c.reason.entityify() +\n                                '</p><p class=evidence>' +\n                                (e && (e.length > 80 ? e.slice(0, 77) + '...' :\n                                e).entityify()) + '</p>');\n                    }\n                }\n            }\n\n            if (data.implieds) {\n                s = [];\n                for (i = 0; i < data.implieds.length; i += 1) {\n                    s[i] = '<code>' + data.implieds[i].name + '</code>&nbsp;<i>' +\n                        data.implieds[i].line + '</i>';\n                }\n                o.push('<p><i>Implied global:</i> ' + s.join(', ') + '</p>');\n            }\n\n            if (data.unused) {\n                s = [];\n                for (i = 0; i < data.unused.length; i += 1) {\n                    s[i] = '<code><u>' + data.unused[i].name + '</u></code>&nbsp;<i>' +\n                        data.unused[i].line + '</i> <code>' +\n                        data.unused[i]['function'] + '</code>';\n                }\n                o.push('<p><i>Unused variable:</i> ' + s.join(', ') + '</p>');\n            }\n            if (data.json) {\n                o.push('<p>JSON: bad.</p>');\n            }\n            o.push('</div>');\n        }\n\n        if (!option) {\n\n            o.push('<br><div id=functions>');\n\n            if (data.urls) {\n                detail(\"URLs<br>\", data.urls, '<br>');\n            }\n\n            if (xmode === 'style') {\n                o.push('<p>CSS.</p>');\n            } else if (data.json && !err) {\n                o.push('<p>JSON: good.</p>');\n            } else if (data.globals) {\n                o.push('<div><i>Global</i> ' +\n                        data.globals.sort().join(', ') + '</div>');\n            } else {\n                o.push('<div><i>No new global variables introduced.</i></div>');\n            }\n\n            for (i = 0; i < data.functions.length; i += 1) {\n                f = data.functions[i];\n\n                o.push('<br><div class=function><i>' + f.line + '-' +\n                        f.last + '</i> ' + (f.name || '') + '(' +\n                        (f.param ? f.param.join(', ') : '') + ')</div>');\n                detail('<big><b>Unused</b></big>', f.unused);\n                detail('Closure', f.closure);\n                detail('Variable', f['var']);\n                detail('Exception', f.exception);\n                detail('Outer', f.outer);\n                detail('Global', f.global);\n                detail('Label', f.label);\n            }\n\n            if (data.member) {\n                a = Object.keys(data.member);\n                if (a.length) {\n                    a = a.sort();\n                    m = '<br><pre id=members>/*members ';\n                    l = 10;\n                    for (i = 0; i < a.length; i += 1) {\n                        k = a[i];\n                        n = k.name();\n                        if (l + n.length > 72) {\n                            o.push(m + '<br>');\n                            m = '    ';\n                            l = 1;\n                        }\n                        l += n.length + 2;\n                        if (data.member[k] === 1) {\n                            n = '<i>' + n + '</i>';\n                        }\n                        if (i < a.length - 1) {\n                            n += ', ';\n                        }\n                        m += n;\n                    }\n                    o.push(m + '<br>*/</pre>');\n                }\n                o.push('</div>');\n            }\n        }\n        return o.join('');\n    };\n    itself.jshint = itself;\n\n    return itself;\n\n}());\n\n// Make JSHINT a Node module, if possible.\nif (typeof exports == 'object' && exports)\n    exports.JSHINT = JSHINT;\n    \n\n// Command line integration via Rhino\n(function (args) {\n    var name = args[0],\n        optstr = args[1], // arg1=val1,arg2=val2,...\n        opts = { rhino: true },\n        input;\n\n    if (!name) {\n        print('No files present in the fileset; Check your pattern match in build.xml');\n        quit(1);\n    }\n\n    if (optstr) {\n        optstr.split(',').forEach(function (arg) {\n            var o = arg.split('=');\n            opts[o[0]] = (function (ov) {\n                switch (ov) {\n                case 'true':\n                    return true;\n                case 'false':\n                    return false;\n                default:\n                    return ov;\n                }\n            })(o[1]);\n        });\n    }\n\n    input = readFile(name);\n\n    if (!input) {\n        print('JSHint: Couldn\\'t open file ' + name);\n        quit(1);\n    }\n    if (!JSHINT(input, opts)) {\n        for (var i = 0, err; err = JSHINT.errors[i]; i++) {\n            print(err.reason + ' (line: ' + err.line + ', character: ' + err.character + ')');\n            print('> ' + (err.evidence || '').replace(/^\\s*(\\S*(\\s+\\S+)*)\\s*$/, \"$1\"));\n            print('');\n        }\n        quit(1);\n    }\n\n    quit(0);\n}(arguments));\n\n\n\n\n"
  },
  {
    "path": "app/static_dev/build/tools/fulljslint.js",
    "content": "/*global quit:false, readFile: false */\n\n// Rhino Edition\n\n\n// jslint.js\n// 2011-03-29\n\n// Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)\n\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n\n// The Software shall be used for Good, not Evil.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n\n// JSLINT is a global function. It takes two parameters.\n\n//     var myResult = JSLINT(source, option);\n\n// The first parameter is either a string or an array of strings. If it is a\n// string, it will be split on '\\n' or '\\r'. If it is an array of strings, it\n// is assumed that each string represents one line. The source can be a\n// JavaScript text, or HTML text, or a JSON text, or a CSS text.\n\n// The second parameter is an optional object of options that control the\n// operation of JSLINT. Most of the options are booleans: They are all\n// optional and have a default value of false. One of the options, predef,\n// can be an array of names, which will be used to declare global variables,\n// or an object whose keys are used as global names, with a boolean value\n// that determines if they are assignable.\n\n// If it checks out, JSLINT returns true. Otherwise, it returns false.\n\n// If false, you can inspect JSLINT.errors to find out the problems.\n// JSLINT.errors is an array of objects containing these properties:\n\n//  {\n//      line      : The line (relative to 0) at which the lint was found\n//      character : The character (relative to 0) at which the lint was found\n//      reason    : The problem\n//      evidence  : The text line in which the problem occurred\n//      raw       : The raw message before the details were inserted\n//      a         : The first detail\n//      b         : The second detail\n//      c         : The third detail\n//      d         : The fourth detail\n//  }\n\n// If a stopping error was found, a null will be the last element of the\n// JSLINT.errors array. A stopping error means that JSLint was not confident\n// enough to continue. It does not necessarily mean that the error was\n// especailly heinous.\n\n// You can request a Function Report, which shows all of the functions\n// and the parameters and vars that they use. This can be used to find\n// implied global variables and other problems. The report is in HTML and\n// can be inserted in an HTML <body>.\n\n//     var myReport = JSLINT.report(errors_only);\n\n// If errors_only is true, then the report will be limited to only errors.\n\n// You can request a data structure that contains JSLint's results.\n\n//     var myData = JSLINT.data();\n\n// It returns a structure with this form:\n\n//     {\n//         errors: [\n//             {\n//                 line: NUMBER,\n//                 character: NUMBER,\n//                 reason: STRING,\n//                 evidence: STRING\n//             }\n//         ],\n//         functions: [\n//             name: STRING,\n//             line: NUMBER,\n//             last: NUMBER,\n//             param: [\n//                 TOKEN\n//             ],\n//             closure: [\n//                 STRING\n//             ],\n//             var: [\n//                 STRING\n//             ],\n//             exception: [\n//                 STRING\n//             ],\n//             outer: [\n//                 STRING\n//             ],\n//             unused: [\n//                 STRING\n//             ],\n//             global: [\n//                 STRING\n//             ],\n//             label: [\n//                 STRING\n//             ]\n//         ],\n//         globals: [\n//             STRING\n//         ],\n//         member: {\n//             STRING: NUMBER\n//         },\n//         unuseds: [\n//             {\n//                 name: STRING,\n//                 line: NUMBER\n//             }\n//         ],\n//         implieds: [\n//             {\n//                 name: STRING,\n//                 line: NUMBER\n//             }\n//         ],\n//         urls: [\n//             STRING\n//         ],\n//         json: BOOLEAN\n//     }\n\n// Empty arrays will not be included.\n\n// You can obtain the parse tree that JSLint constructed while parsing. The\n// latest tree is kept in JSLINT.tree. A nice stringication can be produced\n// with\n\n//     JSON.stringify(JSLINT.tree, [\n//         'value',  'arity', 'name',  'first',\n//         'second', 'third', 'block', 'else'\n//     ], 4));\n\n// JSLint provides three directives. They look like slashstar comments, and\n// allow for setting options, declaring global variables, and establishing a\n// set of allowed property names.\n\n// These directives respect function scope.\n\n// The jslint directive is a special comment that can set one or more options.\n// The current option set is\n\n//     adsafe     true, if ADsafe rules should be enforced\n//     bitwise    true, if bitwise operators should not be allowed\n//     browser    true, if the standard browser globals should be predefined\n//     cap        true, if upper case HTML should be allowed\n//     'continue' true, if the continuation statement should be tolerated\n//     css        true, if CSS workarounds should be tolerated\n//     debug      true, if debugger statements should be allowed\n//     devel      true, if logging should be allowed (console, alert, etc.)\n//     es5        true, if ES5 syntax should be allowed\n//     evil       true, if eval should be allowed\n//     forin      true, if for in statements need not filter\n//     fragment   true, if HTML fragments should be allowed\n//     indent     the indentation factor\n//     maxerr     the maximum number of errors to allow\n//     maxlen     the maximum length of a source line\n//     newcap     true, if constructor names must be capitalized\n//     node       true, if Node.js globals should be predefined\n//     nomen      true, if names should be checked\n//     on         true, if HTML event handlers should be allowed\n//     onevar     true, if only one var statement per function should be allowed\n//     passfail   true, if the scan should stop on first error\n//     plusplus   true, if increment/decrement should not be allowed\n//     regexp     true, if the . should not be allowed in regexp literals\n//     rhino      true, if the Rhino environment globals should be predefined\n//     undef      true, if variables should be declared before used\n//     safe       true, if use of some browser features should be restricted\n//     windows    true, if MS Windows-specific globals should be predefined\n//     strict     true, require the \"use strict\"; pragma\n//     sub        true, if all forms of subscript notation are tolerated\n//     white      true, if strict whitespace rules apply\n//     widget     true  if the Yahoo Widgets globals should be predefined\n\n// For example:\n\n/*jslint\n    evil: true, nomen: false, onevar: false, regexp: false, strict: true\n*/\n\n// The properties directive declares an exclusive list of property names.\n// Any properties named in the program that are not in the list will\n// produce a warning.\n\n// For example:\n\n/*properties \"\\b\", \"\\t\", \"\\n\", \"\\f\", \"\\r\", \"!=\", \"!==\", \"\\\"\", \"%\", \"'\",\n    \"(begin)\", \"(breakage)\", \"(context)\", \"(error)\", \"(global)\",\n    \"(identifier)\", \"(line)\", \"(loopage)\", \"(name)\", \"(onevar)\", \"(params)\",\n    \"(scope)\", \"(statement)\", \"(token)\", \"(verb)\", \")\", \"*\", \"+\", \"-\", \"\\/\",\n    \";\", \"<\", \"<=\", \"==\", \"===\", \">\", \">=\", ADSAFE, ActiveXObject,\n    Array, Boolean, Buffer, COM, CScript, Canvas, CustomAnimation, Date,\n    Debug, E, Enumerator, Error, EvalError, FadeAnimation, Flash, FormField,\n    Frame, Function, HotKey, Image, JSON, LN10, LN2, LOG10E, LOG2E,\n    MAX_VALUE, MIN_VALUE, Math, MenuItem, MoveAnimation, NEGATIVE_INFINITY,\n    Number, Object, Option, PI, POSITIVE_INFINITY, Point, RangeError,\n    Rectangle, ReferenceError, RegExp, ResizeAnimation, RotateAnimation,\n    SQRT1_2, SQRT2, ScrollBar, String, Style, SyntaxError, System, Text,\n    TextArea, Timer, TypeError, URIError, URL, VBArray, WScript, Web,\n    Window, XMLDOM, XMLHttpRequest, \"\\\\\", __dirname, __filename, a,\n    a_function, a_label, a_not_allowed, a_not_defined, a_scope, abbr,\n    acronym, activeborder, activecaption, address, adsafe, adsafe_a,\n    adsafe_autocomplete, adsafe_bad_id, adsafe_div, adsafe_fragment,\n    adsafe_go, adsafe_html, adsafe_id, adsafe_id_go, adsafe_lib,\n    adsafe_lib_second, adsafe_missing_id, adsafe_name_a, adsafe_placement,\n    adsafe_prefix_a, adsafe_script, adsafe_source, adsafe_subscript_a,\n    adsafe_tag, alert, aliceblue, all, already_defined, and, animator,\n    antiquewhite, appleScript, applet, apply, approved, appworkspace, aqua,\n    aquamarine, area, arguments, arity, article, aside, assign,\n    assign_exception, assignment_function_expression, at, attribute_case_a,\n    audio, autocomplete, avoid_a, azure, b, background,\n    \"background-attachment\", \"background-color\", \"background-image\",\n    \"background-position\", \"background-repeat\", bad_assignment, bad_color_a,\n    bad_constructor, bad_entity, bad_html, bad_id_a, bad_in_a,\n    bad_invocation, bad_name_a, bad_new, bad_number, bad_operand, bad_type,\n    bad_url, bad_wrap, base, bdo, beep, beige, big, bisque, bitwise, black,\n    blanchedalmond, block, blockquote, blue, blueviolet, body, border,\n    \"border-bottom\", \"border-bottom-color\", \"border-bottom-style\",\n    \"border-bottom-width\", \"border-collapse\", \"border-color\", \"border-left\",\n    \"border-left-color\", \"border-left-style\", \"border-left-width\",\n    \"border-right\", \"border-right-color\", \"border-right-style\",\n    \"border-right-width\", \"border-spacing\", \"border-style\", \"border-top\",\n    \"border-top-color\", \"border-top-style\", \"border-top-width\",\n    \"border-width\", bottom, br, braille, brown, browser, burlywood, button,\n    buttonface, buttonhighlight, buttonshadow, buttontext, bytesToUIString,\n    c, cadetblue, call, callee, caller, canvas, cap, caption,\n    \"caption-side\", captiontext, center, charAt, charCodeAt, character,\n    chartreuse, chocolate, chooseColor, chooseFile, chooseFolder, cite,\n    clear, clearInterval, clearTimeout, clearTimout, clip, closeWidget,\n    closure, cm, code, col, colgroup, color, combine_var, command, comment,\n    comments, concat, conditional_assignment, confirm, confusing_a,\n    confusing_regexp, console, constructor, constructor_name_a, content,\n    continue, control_a, convertPathToHFS, convertPathToPlatform, coral,\n    cornflowerblue, cornsilk, \"counter-increment\", \"counter-reset\", create,\n    crimson, css, cursor, cyan, d, dangerous_comment, dangling_a, darkblue,\n    darkcyan, darkgoldenrod, darkgray, darkgreen, darkkhaki, darkmagenta,\n    darkolivegreen, darkorange, darkorchid, darkred, darksalmon,\n    darkseagreen, darkslateblue, darkslategray, darkturquoise, darkviolet,\n    data, datalist, dd, debug, decodeURI, decodeURIComponent, deeppink,\n    deepskyblue, defineClass, del, deleted, deserialize, details, devel,\n    dfn, dialog, dimgray, dir, direction, display, disrupt, div, dl,\n    document, dodgerblue, dt, duplicate_a, edge, edition, else, em, embed,\n    embossed, empty, \"empty-cells\", empty_block, empty_case, empty_class,\n    encodeURI, encodeURIComponent, entityify, errors, es5, escape, eval,\n    event, evidence, evil, ex, exception, exec, expected_a,\n    expected_a_at_b_c, expected_a_b, expected_a_b_from_c_d, expected_at_a,\n    expected_attribute_a, expected_attribute_value_a, expected_class_a,\n    expected_fraction_a, expected_id_a, expected_identifier_a,\n    expected_identifier_a_reserved, expected_lang_a, expected_linear_a,\n    expected_media_a, expected_name_a, expected_nonstandard_style_attribute,\n    expected_number_a, expected_operator_a, expected_percent_a,\n    expected_positive_a, expected_pseudo_a, expected_selector_a,\n    expected_small_a, expected_space_a_b, expected_string_a,\n    expected_style_attribute, expected_style_pattern, expected_tagname_a,\n    fieldset, figure, filesystem, filter, firebrick, first, float, floor,\n    floralwhite, focusWidget, font, \"font-family\", \"font-size\",\n    \"font-size-adjust\", \"font-stretch\", \"font-style\", \"font-variant\",\n    \"font-weight\", footer, for_if, forestgreen, forin, form, fragment,\n    frame, frames, frameset, from, fromCharCode, fuchsia, fud, funct,\n    function, function_block, function_eval, function_loop,\n    function_statement, function_strict, functions, g, gainsboro, gc,\n    get_set, ghostwhite, global, globals, gold, goldenrod, gray, graytext,\n    green, greenyellow, h1, h2, h3, h4, h5, h6, handheld, hasOwnProperty,\n    head, header, height, help, hgroup, highlight, highlighttext, history,\n    honeydew, hotpink, hr, \"hta:application\", html, html_confusion_a,\n    html_handlers, i, iTunes, id, identifier, identifier_function, iframe,\n    img, immed, implied_evil, implieds, in, inactiveborder, inactivecaption,\n    inactivecaptiontext, include, indent, indexOf, indianred, indigo,\n    infix_in, infobackground, infotext, init, input, ins, insecure_a,\n    isAlpha, isApplicationRunning, isArray, isDigit, isFinite, isNaN, ivory,\n    join, jslint, json, kbd, keygen, keys, khaki, konfabulatorVersion,\n    label, label_a_b, labeled, lang, lavender, lavenderblush, lawngreen,\n    lbp, leading_decimal_a, led, left, legend, lemonchiffon, length,\n    \"letter-spacing\", li, lib, lightblue, lightcoral, lightcyan,\n    lightgoldenrodyellow, lightgreen, lightpink, lightsalmon, lightseagreen,\n    lightskyblue, lightslategray, lightsteelblue, lightyellow, lime,\n    limegreen, line, \"line-height\", linen, link, \"list-style\",\n    \"list-style-image\", \"list-style-position\", \"list-style-type\", load,\n    loadClass, location, log, m, magenta, map, margin, \"margin-bottom\",\n    \"margin-left\", \"margin-right\", \"margin-top\", mark, \"marker-offset\",\n    maroon, match, \"max-height\", \"max-width\", maxerr, maxlen, md5,\n    mediumaquamarine, mediumblue, mediumorchid, mediumpurple,\n    mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise,\n    mediumvioletred, member, menu, menutext, message, meta, meter,\n    midnightblue, \"min-height\", \"min-width\", mintcream, missing_a,\n    missing_a_after_b, missing_option, missing_property, missing_space_a_b,\n    missing_url, missing_use_strict, mistyrose, mixed, mm, moccasin, mode,\n    module, move_invocation, move_var, name, name_function, nav,\n    navajowhite, navigator, navy, nested_comment, newcap, next, node,\n    noframes, nomen, noscript, not, not_a_constructor, not_a_defined,\n    not_a_function, not_a_label, not_a_scope, not_greater, nud, object, ol,\n    oldlace, olive, olivedrab, on, onevar, opacity, open, openURL, opera,\n    optgroup, option, orange, orangered, orchid, outer, outline,\n    \"outline-color\", \"outline-style\", \"outline-width\", output, overflow,\n    \"overflow-x\", \"overflow-y\", p, padding, \"padding-bottom\",\n    \"padding-left\", \"padding-right\", \"padding-top\", \"page-break-after\",\n    \"page-break-before\", palegoldenrod, palegreen, paleturquoise,\n    palevioletred, papayawhip, param, parameter_a_get_b, parameter_set_a,\n    paren, parent, parseFloat, parseInt, passfail, pc, peachpuff, peru,\n    pink, play, plum, plusplus, pop, popupMenu, position, postscript,\n    powderblue, pre, predef, preferenceGroups, preferences, prev, print,\n    process, progress, projection, prompt, prototype, pt, purple, push, px,\n    q, querystring, quit, quote, quotes, radix, random, range, raw,\n    readFile, readUrl, read_only, reason, red, redefinition_a, regexp,\n    reloadWidget, replace, report, require, reserved, reserved_a,\n    resolvePath, resumeUpdates, rhino, right, rosybrown, royalblue, rp, rt,\n    ruby, runCommand, runCommandInBg, saddlebrown, safe, salmon, samp,\n    sandybrown, saveAs, savePreferences, scanned_a_b, screen, script,\n    scrollbar, seagreen, seal, search, seashell, second, section, select,\n    serialize, setInterval, setTimeout, shift, showWidgetPreferences,\n    sienna, silver, skyblue, slash_equal, slateblue, slategray, sleep,\n    slice, small, snow, sort, source, span, spawn, speak, speech, split,\n    springgreen, src, stack, statement_block, steelblue, stopping,\n    strange_loop, strict, strong, style, styleproperty, sub, subscript,\n    substr, sup, supplant, suppressUpdates, sync, system, table,\n    \"table-layout\", tag_a_in_b, tan, tbody, td, teal, tellWidget, test,\n    \"text-align\", \"text-decoration\", \"text-indent\", \"text-shadow\",\n    \"text-transform\", textarea, tfoot, th, thead, third, thistle,\n    threeddarkshadow, threedface, threedhighlight, threedlightshadow,\n    threedshadow, thru, time, title, toLowerCase, toString, toUpperCase,\n    toint32, token, tomato, too_long, too_many, top, tr, trailing_decimal_a,\n    tree, tt, tty, turquoise, tv, type, u, ul, unclosed, unclosed_comment,\n    unclosed_regexp, undef, unescape, unescaped_a, unexpected_a,\n    unexpected_char_a_b, unexpected_comment, unexpected_member_a,\n    unexpected_space_a_b, \"unicode-bidi\", unnecessary_initialize,\n    unnecessary_use, unreachable_a_b, unrecognized_style_attribute_a,\n    unrecognized_tag_a, unsafe, unused, unwatch, updateNow, url, urls,\n    use_array, use_braces, use_object, used_before_a, util, value, valueOf,\n    var, var_a_not, version, \"vertical-align\", video, violet, visibility,\n    was, watch, weird_assignment, weird_condition, weird_new, weird_program,\n    weird_relation, weird_ternary, wheat, white, \"white-space\", whitesmoke,\n    widget, width, window, windowframe, windows, windowtext, \"word-spacing\",\n    \"word-wrap\", wrap, wrap_immediate, wrap_regexp, write_is_wrong,\n    yahooCheckLogin, yahooLogin, yahooLogout, yellow, yellowgreen,\n    \"z-index\"\n*/\n\n// The global directive is used to declare global variables that can\n// be accessed by the program. If a declaration is true, then the variable\n// is writeable. Otherwise, it is read-only.\n\n// We build the application inside a function so that we produce only a single\n// global variable. That function will be invoked immediately, and its return\n// value is the JSLINT function itself. That function is also an object that\n// can contain data and other functions.\n\nvar JSLINT = (function () {\n    \"use strict\";\n\n    var adsafe_id,      // The widget's ADsafe id.\n        adsafe_may,     // The widget may load approved scripts.\n        adsafe_top,     // At the top of the widget script.\n        adsafe_went,    // ADSAFE.go has been called.\n        anonname,       // The guessed name for anonymous functions.\n        approved,       // ADsafe approved urls.\n\n// These are operators that should not be used with the ! operator.\n\n        bang = {\n            '<'  : true,\n            '<=' : true,\n            '==' : true,\n            '===': true,\n            '!==': true,\n            '!=' : true,\n            '>'  : true,\n            '>=' : true,\n            '+'  : true,\n            '-'  : true,\n            '*'  : true,\n            '/'  : true,\n            '%'  : true\n        },\n\n// These are property names that should not be permitted in the safe subset.\n\n        banned = {\n            'arguments' : true,\n            callee      : true,\n            caller      : true,\n            constructor : true,\n            'eval'      : true,\n            prototype   : true,\n            stack       : true,\n            unwatch     : true,\n            valueOf     : true,\n            watch       : true\n        },\n        begin,          // The root token\n\n// browser contains a set of global names that are commonly provided by a\n// web browser environment.\n\n        browser = {\n            clearInterval  : false,\n            clearTimeout   : false,\n            document       : false,\n            event          : false,\n            frames         : false,\n            history        : false,\n            Image          : false,\n            location       : false,\n            name           : false,\n            navigator      : false,\n            Option         : false,\n            parent         : false,\n            screen         : false,\n            setInterval    : false,\n            setTimeout     : false,\n            window         : false,\n            XMLHttpRequest : false\n        },\n\n// bundle contains the text messages.\n\n        bundle = {\n            a_function: \"'{a}' is a function.\",\n            a_label: \"'{a}' is a statement label.\",\n            a_not_allowed: \"'{a}' is not allowed.\",\n            a_not_defined: \"'{a}' is not defined.\",\n            a_scope: \"'{a}' used out of scope.\",\n            adsafe: \"ADsafe violation.\",\n            adsafe_a: \"ADsafe violation: '{a}'.\",\n            adsafe_autocomplete: \"ADsafe autocomplete violation.\",\n            adsafe_bad_id: \"ADSAFE violation: bad id.\",\n            adsafe_div: \"ADsafe violation: Wrap the widget in a div.\",\n            adsafe_fragment: \"ADSAFE: Use the fragment option.\",\n            adsafe_go: \"ADsafe violation: Missing ADSAFE.go.\",\n            adsafe_html: \"Currently, ADsafe does not operate on whole HTML documents. It operates on <div> fragments and .js files.\",\n            adsafe_id: \"ADsafe violation: id does not match.\",\n            adsafe_id_go: \"ADsafe violation: Missing ADSAFE.id or ADSAFE.go.\",\n            adsafe_lib: \"ADsafe lib violation.\",\n            adsafe_lib_second: \"ADsafe: The second argument to lib must be a function.\",\n            adsafe_missing_id: \"ADSAFE violation: missing ID_.\",\n            adsafe_name_a: \"ADsafe name violation: '{a}'.\",\n            adsafe_placement: \"ADsafe script placement violation.\",\n            adsafe_prefix_a: \"ADsafe violation: An id must have a '{a}' prefix\",\n            adsafe_script: \"ADsafe script violation.\",\n            adsafe_source: \"ADsafe unapproved script source.\",\n            adsafe_subscript_a: \"ADsafe subscript '{a}'.\",\n            adsafe_tag: \"ADsafe violation: Disallowed tag '{a}'.\",\n            already_defined: \"'{a}' is already defined.\",\n            and: \"The '&&' subexpression should be wrapped in parens.\",\n            assign_exception: \"Do not assign to the exception parameter.\",\n            assignment_function_expression: \"Expected an assignment or function call and instead saw an expression.\",\n            attribute_case_a: \"Attribute '{a}' not all lower case.\",\n            avoid_a: \"Avoid '{a}'.\",\n            bad_assignment: \"Bad assignment.\",\n            bad_color_a: \"Bad hex color '{a}'.\",\n            bad_constructor: \"Bad constructor.\",\n            bad_entity: \"Bad entity.\",\n            bad_html: \"Bad HTML string\",\n            bad_id_a: \"Bad id: '{a}'.\",\n            bad_in_a: \"Bad for in variable '{a}'.\",\n            bad_invocation: \"Bad invocation.\",\n            bad_name_a: \"Bad name: '{a}'.\",\n            bad_new: \"Do not use 'new' for side effects.\",\n            bad_number: \"Bad number '{a}'.\",\n            bad_operand: \"Bad operand.\",\n            bad_type: \"Bad type.\",\n            bad_url: \"Bad url string.\",\n            bad_wrap: \"Do not wrap function literals in parens unless they are to be immediately invoked.\",\n            combine_var: \"Combine this with the previous 'var' statement.\",\n            conditional_assignment: \"Expected a conditional expression and instead saw an assignment.\",\n            confusing_a: \"Confusing use of '{a}'.\",\n            confusing_regexp: \"Confusing regular expression.\",\n            constructor_name_a: \"A constructor name '{a}' should start with an uppercase letter.\",\n            control_a: \"Unexpected control character '{a}'.\",\n            css: \"A css file should begin with @charset 'UTF-8';\",\n            dangling_a: \"Unexpected dangling '_' in '{a}'.\",\n            dangerous_comment: \"Dangerous comment.\",\n            deleted: \"Only properties should be deleted.\",\n            duplicate_a: \"Duplicate '{a}'.\",\n            empty_block: \"Empty block.\",\n            empty_case: \"Empty case.\",\n            empty_class: \"Empty class.\",\n            evil: \"eval is evil.\",\n            expected_a: \"Expected '{a}'.\",\n            expected_a_b: \"Expected '{a}' and instead saw '{b}'.\",\n            expected_a_b_from_c_d: \"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.\",\n            expected_at_a: \"Expected an at-rule, and instead saw @{a}.\",\n            expected_a_at_b_c: \"Expected '{a}' at column {b}, not column {c}.\",\n            expected_attribute_a: \"Expected an attribute, and instead saw [{a}].\",\n            expected_attribute_value_a: \"Expected an attribute value and instead saw '{a}'.\",\n            expected_class_a: \"Expected a class, and instead saw .{a}.\",\n            expected_fraction_a: \"Expected a number between 0 and 1 and instead saw '{a}'\",\n            expected_id_a: \"Expected an id, and instead saw #{a}.\",\n            expected_identifier_a: \"Expected an identifier and instead saw '{a}'.\",\n            expected_identifier_a_reserved: \"Expected an identifier and instead saw '{a}' (a reserved word).\",\n            expected_linear_a: \"Expected a linear unit and instead saw '{a}'.\",\n            expected_lang_a: \"Expected a lang code, and instead saw :{a}.\",\n            expected_media_a: \"Expected a CSS media type, and instead saw '{a}'.\",\n            expected_name_a: \"Expected a name and instead saw '{a}'.\",\n            expected_nonstandard_style_attribute: \"Expected a non-standard style attribute and instead saw '{a}'.\",\n            expected_number_a: \"Expected a number and instead saw '{a}'.\",\n            expected_operator_a: \"Expected an operator and instead saw '{a}'.\",\n            expected_percent_a: \"Expected a percentage and instead saw '{a}'\",\n            expected_positive_a: \"Expected a positive number and instead saw '{a}'\",\n            expected_pseudo_a: \"Expected a pseudo, and instead saw :{a}.\",\n            expected_selector_a: \"Expected a CSS selector, and instead saw {a}.\",\n            expected_small_a: \"Expected a small number and instead saw '{a}'\",\n            expected_space_a_b: \"Expected exactly one space between '{a}' and '{b}'.\",\n            expected_string_a: \"Expected a string and instead saw {a}.\",\n            expected_style_attribute: \"Excepted a style attribute, and instead saw '{a}'.\",\n            expected_style_pattern: \"Expected a style pattern, and instead saw '{a}'.\",\n            expected_tagname_a: \"Expected a tagName, and instead saw {a}.\",\n            for_if: \"The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.\",\n            function_block: \"Function statements should not be placed in blocks. \" +\n                \"Use a function expression or move the statement to the top of \" +\n                \"the outer function.\",\n            function_eval: \"The Function constructor is eval.\",\n            function_loop: \"Don't make functions within a loop.\",\n            function_statement: \"Function statements are not invocable. \" +\n                \"Wrap the whole function invocation in parens.\",\n            function_strict: \"Use the function form of \\\"use strict\\\".\",\n            get_set: \"get/set are ES5 features.\",\n            html_confusion_a: \"HTML confusion in regular expression '<{a}'.\",\n            html_handlers: \"Avoid HTML event handlers.\",\n            identifier_function: \"Expected an identifier in an assignment and instead saw a function invocation.\",\n            implied_evil: \"Implied eval is evil. Pass a function instead of a string.\",\n            infix_in: \"Unexpected 'in'. Compare with undefined, or use the hasOwnProperty method instead.\",\n            insecure_a: \"Insecure '{a}'.\",\n            isNaN: \"Use the isNaN function to compare with NaN.\",\n            label_a_b: \"Label '{a}' on '{b}' statement.\",\n            lang: \"lang is deprecated.\",\n            leading_decimal_a: \"A leading decimal point can be confused with a dot: '.{a}'.\",\n            missing_a: \"Missing '{a}'.\",\n            missing_a_after_b: \"Missing '{a}' after '{b}'.\",\n            missing_option: \"Missing option value.\",\n            missing_property: \"Missing property name.\",\n            missing_space_a_b: \"Missing space between '{a}' and '{b}'.\",\n            missing_url: \"Missing url.\",\n            missing_use_strict: \"Missing \\\"use strict\\\" statement.\",\n            mixed: \"Mixed spaces and tabs.\",\n            move_invocation: \"Move the invocation into the parens that contain the function.\",\n            move_var: \"Move 'var' declarations to the top of the function.\",\n            name_function: \"Missing name in function statement.\",\n            nested_comment: \"Nested comment.\",\n            not: \"Nested not.\",\n            not_a_constructor: \"Do not use {a} as a constructor.\",\n            not_a_defined: \"'{a}' has not been fully defined yet.\",\n            not_a_function: \"'{a}' is not a function.\",\n            not_a_label: \"'{a}' is not a label.\",\n            not_a_scope: \"'{a}' is out of scope.\",\n            not_greater: \"'{a}' should not be greater than '{b}'.\",\n            parameter_a_get_b: \"Unexpected parameter '{a}' in get {b} function.\",\n            parameter_set_a: \"Expected parameter (value) in set {a} function.\",\n            radix: \"Missing radix parameter.\",\n            read_only: \"Read only.\",\n            redefinition_a: \"Redefinition of '{a}'.\",\n            reserved_a: \"Reserved name '{a}'.\",\n            scanned_a_b: \"{a} ({b}% scanned).\",\n            slash_equal: \"A regular expression literal can be confused with '/='.\",\n            statement_block: \"Expected to see a statement and instead saw a block.\",\n            stopping: \"Stopping. \",\n            strange_loop: \"Strange loop.\",\n            strict: \"Strict violation.\",\n            subscript: \"['{a}'] is better written in dot notation.\",\n            tag_a_in_b: \"A '<{a}>' must be within '<{b}>'.\",\n            too_long: \"Line too long.\",\n            too_many: \"Too many errors.\",\n            trailing_decimal_a: \"A trailing decimal point can be confused with a dot: '.{a}'.\",\n            type: \"type is unnecessary.\",\n            unclosed: \"Unclosed string.\",\n            unclosed_comment: \"Unclosed comment.\",\n            unclosed_regexp: \"Unclosed regular expression.\",\n            unescaped_a: \"Unescaped '{a}'.\",\n            unexpected_a: \"Unexpected '{a}'.\",\n            unexpected_char_a_b: \"Unexpected character '{a}' in {b}.\",\n            unexpected_comment: \"Unexpected comment.\",\n            unexpected_member_a: \"Unexpected property '{a}'.\",\n            unexpected_space_a_b: \"Unexpected space between '{a}' and '{b}'.\",\n            unnecessary_initialize: \"It is not necessary to initialize '{a}' to 'undefined'.\",\n            unnecessary_use: \"Unnecessary \\\"use strict\\\".\",\n            unreachable_a_b: \"Unreachable '{a}' after '{b}'.\",\n            unrecognized_style_attribute_a: \"Unrecognized style attribute '{a}'.\",\n            unrecognized_tag_a: \"Unrecognized tag '<{a}>'.\",\n            unsafe: \"Unsafe character.\",\n            url: \"JavaScript URL.\",\n            use_array: \"Use the array literal notation [].\",\n            use_braces: \"Spaces are hard to count. Use {{a}}.\",\n            use_object: \"Use the object literal notation {}.\",\n            used_before_a: \"'{a}' was used before it was defined.\",\n            var_a_not: \"Variable {a} was not declared correctly.\",\n            weird_assignment: \"Weird assignment.\",\n            weird_condition: \"Weird condition.\",\n            weird_new: \"Weird construction. Delete 'new'.\",\n            weird_program: \"Weird program.\",\n            weird_relation: \"Weird relation.\",\n            weird_ternary: \"Weird ternary.\",\n            wrap_immediate: \"Wrap an immediate function invocation in parentheses \" +\n                \"to assist the reader in understanding that the expression \" +\n                \"is the result of a function, and not the function itself.\",\n            wrap_regexp: \"Wrap the /regexp/ literal in parens to disambiguate the slash operator.\",\n            write_is_wrong: \"document.write can be a form of eval.\"\n        },\n        comments_off,\n        css_attribute_data,\n        css_any,\n\n        css_colorData = {\n            \"aliceblue\"             : true,\n            \"antiquewhite\"          : true,\n            \"aqua\"                  : true,\n            \"aquamarine\"            : true,\n            \"azure\"                 : true,\n            \"beige\"                 : true,\n            \"bisque\"                : true,\n            \"black\"                 : true,\n            \"blanchedalmond\"        : true,\n            \"blue\"                  : true,\n            \"blueviolet\"            : true,\n            \"brown\"                 : true,\n            \"burlywood\"             : true,\n            \"cadetblue\"             : true,\n            \"chartreuse\"            : true,\n            \"chocolate\"             : true,\n            \"coral\"                 : true,\n            \"cornflowerblue\"        : true,\n            \"cornsilk\"              : true,\n            \"crimson\"               : true,\n            \"cyan\"                  : true,\n            \"darkblue\"              : true,\n            \"darkcyan\"              : true,\n            \"darkgoldenrod\"         : true,\n            \"darkgray\"              : true,\n            \"darkgreen\"             : true,\n            \"darkkhaki\"             : true,\n            \"darkmagenta\"           : true,\n            \"darkolivegreen\"        : true,\n            \"darkorange\"            : true,\n            \"darkorchid\"            : true,\n            \"darkred\"               : true,\n            \"darksalmon\"            : true,\n            \"darkseagreen\"          : true,\n            \"darkslateblue\"         : true,\n            \"darkslategray\"         : true,\n            \"darkturquoise\"         : true,\n            \"darkviolet\"            : true,\n            \"deeppink\"              : true,\n            \"deepskyblue\"           : true,\n            \"dimgray\"               : true,\n            \"dodgerblue\"            : true,\n            \"firebrick\"             : true,\n            \"floralwhite\"           : true,\n            \"forestgreen\"           : true,\n            \"fuchsia\"               : true,\n            \"gainsboro\"             : true,\n            \"ghostwhite\"            : true,\n            \"gold\"                  : true,\n            \"goldenrod\"             : true,\n            \"gray\"                  : true,\n            \"green\"                 : true,\n            \"greenyellow\"           : true,\n            \"honeydew\"              : true,\n            \"hotpink\"               : true,\n            \"indianred\"             : true,\n            \"indigo\"                : true,\n            \"ivory\"                 : true,\n            \"khaki\"                 : true,\n            \"lavender\"              : true,\n            \"lavenderblush\"         : true,\n            \"lawngreen\"             : true,\n            \"lemonchiffon\"          : true,\n            \"lightblue\"             : true,\n            \"lightcoral\"            : true,\n            \"lightcyan\"             : true,\n            \"lightgoldenrodyellow\"  : true,\n            \"lightgreen\"            : true,\n            \"lightpink\"             : true,\n            \"lightsalmon\"           : true,\n            \"lightseagreen\"         : true,\n            \"lightskyblue\"          : true,\n            \"lightslategray\"        : true,\n            \"lightsteelblue\"        : true,\n            \"lightyellow\"           : true,\n            \"lime\"                  : true,\n            \"limegreen\"             : true,\n            \"linen\"                 : true,\n            \"magenta\"               : true,\n            \"maroon\"                : true,\n            \"mediumaquamarine\"      : true,\n            \"mediumblue\"            : true,\n            \"mediumorchid\"          : true,\n            \"mediumpurple\"          : true,\n            \"mediumseagreen\"        : true,\n            \"mediumslateblue\"       : true,\n            \"mediumspringgreen\"     : true,\n            \"mediumturquoise\"       : true,\n            \"mediumvioletred\"       : true,\n            \"midnightblue\"          : true,\n            \"mintcream\"             : true,\n            \"mistyrose\"             : true,\n            \"moccasin\"              : true,\n            \"navajowhite\"           : true,\n            \"navy\"                  : true,\n            \"oldlace\"               : true,\n            \"olive\"                 : true,\n            \"olivedrab\"             : true,\n            \"orange\"                : true,\n            \"orangered\"             : true,\n            \"orchid\"                : true,\n            \"palegoldenrod\"         : true,\n            \"palegreen\"             : true,\n            \"paleturquoise\"         : true,\n            \"palevioletred\"         : true,\n            \"papayawhip\"            : true,\n            \"peachpuff\"             : true,\n            \"peru\"                  : true,\n            \"pink\"                  : true,\n            \"plum\"                  : true,\n            \"powderblue\"            : true,\n            \"purple\"                : true,\n            \"red\"                   : true,\n            \"rosybrown\"             : true,\n            \"royalblue\"             : true,\n            \"saddlebrown\"           : true,\n            \"salmon\"                : true,\n            \"sandybrown\"            : true,\n            \"seagreen\"              : true,\n            \"seashell\"              : true,\n            \"sienna\"                : true,\n            \"silver\"                : true,\n            \"skyblue\"               : true,\n            \"slateblue\"             : true,\n            \"slategray\"             : true,\n            \"snow\"                  : true,\n            \"springgreen\"           : true,\n            \"steelblue\"             : true,\n            \"tan\"                   : true,\n            \"teal\"                  : true,\n            \"thistle\"               : true,\n            \"tomato\"                : true,\n            \"turquoise\"             : true,\n            \"violet\"                : true,\n            \"wheat\"                 : true,\n            \"white\"                 : true,\n            \"whitesmoke\"            : true,\n            \"yellow\"                : true,\n            \"yellowgreen\"           : true,\n\n            \"activeborder\"          : true,\n            \"activecaption\"         : true,\n            \"appworkspace\"          : true,\n            \"background\"            : true,\n            \"buttonface\"            : true,\n            \"buttonhighlight\"       : true,\n            \"buttonshadow\"          : true,\n            \"buttontext\"            : true,\n            \"captiontext\"           : true,\n            \"graytext\"              : true,\n            \"highlight\"             : true,\n            \"highlighttext\"         : true,\n            \"inactiveborder\"        : true,\n            \"inactivecaption\"       : true,\n            \"inactivecaptiontext\"   : true,\n            \"infobackground\"        : true,\n            \"infotext\"              : true,\n            \"menu\"                  : true,\n            \"menutext\"              : true,\n            \"scrollbar\"             : true,\n            \"threeddarkshadow\"      : true,\n            \"threedface\"            : true,\n            \"threedhighlight\"       : true,\n            \"threedlightshadow\"     : true,\n            \"threedshadow\"          : true,\n            \"window\"                : true,\n            \"windowframe\"           : true,\n            \"windowtext\"            : true\n        },\n\n        css_border_style,\n        css_break,\n\n        css_lengthData = {\n            '%': true,\n            'cm': true,\n            'em': true,\n            'ex': true,\n            'in': true,\n            'mm': true,\n            'pc': true,\n            'pt': true,\n            'px': true\n        },\n\n        css_media,\n        css_overflow,\n\n        devel = {\n            alert           : false,\n            confirm         : false,\n            console         : false,\n            Debug           : false,\n            opera           : false,\n            prompt          : false\n        },\n\n        escapes = {\n            '\\b': '\\\\b',\n            '\\t': '\\\\t',\n            '\\n': '\\\\n',\n            '\\f': '\\\\f',\n            '\\r': '\\\\r',\n            '\"' : '\\\\\"',\n            '/' : '\\\\/',\n            '\\\\': '\\\\\\\\'\n        },\n\n        funct,          // The current function\n\n        functionicity = [\n            'closure', 'exception', 'global', 'label', 'outer', 'unused', 'var'\n        ],\n\n        functions,      // All of the functions\n        global,         // The global scope\n        html_tag = {\n            a:        {},\n            abbr:     {},\n            acronym:  {},\n            address:  {},\n            applet:   {},\n            area:     {empty: true, parent: ' map '},\n            article:  {},\n            aside:    {},\n            audio:    {},\n            b:        {},\n            base:     {empty: true, parent: ' head '},\n            bdo:      {},\n            big:      {},\n            blockquote: {},\n            body:     {parent: ' html noframes '},\n            br:       {empty: true},\n            button:   {},\n            canvas:   {parent: ' body p div th td '},\n            caption:  {parent: ' table '},\n            center:   {},\n            cite:     {},\n            code:     {},\n            col:      {empty: true, parent: ' table colgroup '},\n            colgroup: {parent: ' table '},\n            command:  {parent: ' menu '},\n            datalist: {},\n            dd:       {parent: ' dl '},\n            del:      {},\n            details:  {},\n            dialog:   {},\n            dfn:      {},\n            dir:      {},\n            div:      {},\n            dl:       {},\n            dt:       {parent: ' dl '},\n            em:       {},\n            embed:    {},\n            fieldset: {},\n            figure:   {},\n            font:     {},\n            footer:   {},\n            form:     {},\n            frame:    {empty: true, parent: ' frameset '},\n            frameset: {parent: ' html frameset '},\n            h1:       {},\n            h2:       {},\n            h3:       {},\n            h4:       {},\n            h5:       {},\n            h6:       {},\n            head:     {parent: ' html '},\n            header:   {},\n            hgroup:   {},\n            hr:       {empty: true},\n            'hta:application':\n                      {empty: true, parent: ' head '},\n            html:     {parent: '*'},\n            i:        {},\n            iframe:   {},\n            img:      {empty: true},\n            input:    {empty: true},\n            ins:      {},\n            kbd:      {},\n            keygen:   {},\n            label:    {},\n            legend:   {parent: ' details fieldset figure '},\n            li:       {parent: ' dir menu ol ul '},\n            link:     {empty: true, parent: ' head '},\n            map:      {},\n            mark:     {},\n            menu:     {},\n            meta:     {empty: true, parent: ' head noframes noscript '},\n            meter:    {},\n            nav:      {},\n            noframes: {parent: ' html body '},\n            noscript: {parent: ' body head noframes '},\n            object:   {},\n            ol:       {},\n            optgroup: {parent: ' select '},\n            option:   {parent: ' optgroup select '},\n            output:   {},\n            p:        {},\n            param:    {empty: true, parent: ' applet object '},\n            pre:      {},\n            progress: {},\n            q:        {},\n            rp:       {},\n            rt:       {},\n            ruby:     {},\n            samp:     {},\n            script:   {empty: true, parent: ' body div frame head iframe p pre span '},\n            section:  {},\n            select:   {},\n            small:    {},\n            span:     {},\n            source:   {},\n            strong:   {},\n            style:    {parent: ' head ', empty: true},\n            sub:      {},\n            sup:      {},\n            table:    {},\n            tbody:    {parent: ' table '},\n            td:       {parent: ' tr '},\n            textarea: {},\n            tfoot:    {parent: ' table '},\n            th:       {parent: ' tr '},\n            thead:    {parent: ' table '},\n            time:     {},\n            title:    {parent: ' head '},\n            tr:       {parent: ' table tbody thead tfoot '},\n            tt:       {},\n            u:        {},\n            ul:       {},\n            'var':    {},\n            video:    {}\n        },\n\n        ids,            // HTML ids\n        implied,        // Implied globals\n        in_block,\n        indent,\n        json_mode,\n        lines,\n        lookahead,\n        member,\n        node = {\n            Buffer       : false,\n            clearInterval: false,\n            clearTimout  : false,\n            console      : false,\n            global       : false,\n            module       : false,\n            process      : false,\n            querystring  : false,\n            require      : false,\n            setInterval  : false,\n            setTimeout   : false,\n            util         : false,\n            __filename   : false,\n            __dirname    : false\n        },\n        properties,\n        next_token,\n        older_token,\n        option,\n        predefined,     // Global variables defined by option\n        prereg,\n        prev_token,\n        regexp_flag = {\n            g: true,\n            i: true,\n            m: true\n        },\n        rhino = {\n            defineClass : false,\n            deserialize : false,\n            gc          : false,\n            help        : false,\n            load        : false,\n            loadClass   : false,\n            print       : false,\n            quit        : false,\n            readFile    : false,\n            readUrl     : false,\n            runCommand  : false,\n            seal        : false,\n            serialize   : false,\n            spawn       : false,\n            sync        : false,\n            toint32     : false,\n            version     : false\n        },\n\n        scope,      // The current scope\n        semicolon_coda = {\n            ';' : true,\n            '\"' : true,\n            '\\'': true,\n            ')' : true\n        },\n        src,\n        stack,\n\n// standard contains the global names that are provided by the\n// ECMAScript standard.\n\n        standard = {\n            Array               : false,\n            Boolean             : false,\n            Date                : false,\n            decodeURI           : false,\n            decodeURIComponent  : false,\n            encodeURI           : false,\n            encodeURIComponent  : false,\n            Error               : false,\n            'eval'              : false,\n            EvalError           : false,\n            Function            : false,\n            hasOwnProperty      : false,\n            isFinite            : false,\n            isNaN               : false,\n            JSON                : false,\n            Math                : false,\n            Number              : false,\n            Object              : false,\n            parseInt            : false,\n            parseFloat          : false,\n            RangeError          : false,\n            ReferenceError      : false,\n            RegExp              : false,\n            String              : false,\n            SyntaxError         : false,\n            TypeError           : false,\n            URIError            : false\n        },\n\n        standard_property = {\n            E                   : true,\n            LN2                 : true,\n            LN10                : true,\n            LOG2E               : true,\n            LOG10E              : true,\n            MAX_VALUE           : true,\n            MIN_VALUE           : true,\n            NEGATIVE_INFINITY   : true,\n            PI                  : true,\n            POSITIVE_INFINITY   : true,\n            SQRT1_2             : true,\n            SQRT2               : true\n        },\n\n        strict_mode,\n        syntax = {},\n        tab,\n        token,\n        urls,\n        var_mode,\n        warnings,\n\n// widget contains the global names which are provided to a Yahoo\n// (fna Konfabulator) widget.\n\n        widget = {\n            alert                   : true,\n            animator                : true,\n            appleScript             : true,\n            beep                    : true,\n            bytesToUIString         : true,\n            Canvas                  : true,\n            chooseColor             : true,\n            chooseFile              : true,\n            chooseFolder            : true,\n            closeWidget             : true,\n            COM                     : true,\n            convertPathToHFS        : true,\n            convertPathToPlatform   : true,\n            CustomAnimation         : true,\n            escape                  : true,\n            FadeAnimation           : true,\n            filesystem              : true,\n            Flash                   : true,\n            focusWidget             : true,\n            form                    : true,\n            FormField               : true,\n            Frame                   : true,\n            HotKey                  : true,\n            Image                   : true,\n            include                 : true,\n            isApplicationRunning    : true,\n            iTunes                  : true,\n            konfabulatorVersion     : true,\n            log                     : true,\n            md5                     : true,\n            MenuItem                : true,\n            MoveAnimation           : true,\n            openURL                 : true,\n            play                    : true,\n            Point                   : true,\n            popupMenu               : true,\n            preferenceGroups        : true,\n            preferences             : true,\n            print                   : true,\n            prompt                  : true,\n            random                  : true,\n            Rectangle               : true,\n            reloadWidget            : true,\n            ResizeAnimation         : true,\n            resolvePath             : true,\n            resumeUpdates           : true,\n            RotateAnimation         : true,\n            runCommand              : true,\n            runCommandInBg          : true,\n            saveAs                  : true,\n            savePreferences         : true,\n            screen                  : true,\n            ScrollBar               : true,\n            showWidgetPreferences   : true,\n            sleep                   : true,\n            speak                   : true,\n            Style                   : true,\n            suppressUpdates         : true,\n            system                  : true,\n            tellWidget              : true,\n            Text                    : true,\n            TextArea                : true,\n            Timer                   : true,\n            unescape                : true,\n            updateNow               : true,\n            URL                     : true,\n            Web                     : true,\n            widget                  : true,\n            Window                  : true,\n            XMLDOM                  : true,\n            XMLHttpRequest          : true,\n            yahooCheckLogin         : true,\n            yahooLogin              : true,\n            yahooLogout             : true\n        },\n\n        windows = {\n            ActiveXObject: false,\n            CScript      : false,\n            Debug        : false,\n            Enumerator   : false,\n            System       : false,\n            VBArray      : false,\n            WScript      : false\n        },\n\n//  xmode is used to adapt to the exceptions in html parsing.\n//  It can have these states:\n//      false   .js script file\n//      html\n//      outer\n//      script\n//      style\n//      scriptstring\n//      styleproperty\n\n        xmode,\n        xquote,\n\n// Regular expressions. Some of these are stupidly long.\n\n// unsafe comment or string\n        ax = /@cc|<\\/?|script|\\]\\s*\\]|<\\s*!|&lt/i,\n// unsafe characters that are silently deleted by one or more browsers\n        cx = /[\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/,\n// token\n        tx = /^\\s*([(){}\\[.,:;'\"~\\?\\]#@]|==?=?|\\/(\\*(jslint|properties|members|global)?|=|\\/)?|\\*[\\/=]?|\\+(?:=|\\++)?|-(?:=|-+)?|%=?|&[&=]?|\\|[|=]?|>>?>?=?|<([\\/=!]|\\!(\\[|--)?|<=?)?|\\^=?|\\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\\.[0-9]*)?([eE][+\\-]?[0-9]+)?)/,\n// html token\n        hx = /^\\s*(['\"=>\\/&#]|<(?:\\/|\\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\\-:]*|[0-9]+|--)/,\n// characters in strings that need escapement\n        nx = /[\\u0000-\\u001f&<\"\\/\\\\\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/,\n        nxg = /[\\u0000-\\u001f&<\"\\/\\\\\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n// outer html token\n        ox = /[>&]|<[\\/!]?|--/,\n// star slash\n        lx = /\\*\\/|\\/\\*/,\n// identifier\n        ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,\n// javascript url\n        jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\\s*:/i,\n// url badness\n        ux = /&|\\+|\\u00AD|\\.\\.|\\/\\*|%[^;]|base64|url|expression|data|mailto/i,\n// style\n        sx = /^\\s*([{:#%.=,>+\\[\\]@()\"';]|\\*=?|\\$=|\\|=|\\^=|~=|[a-zA-Z_][a-zA-Z0-9_\\-]*|[0-9]+|<\\/|\\/\\*)/,\n        ssx = /^\\s*([@#!\"'};:\\-%.=,+\\[\\]()*_]|[a-zA-Z][a-zA-Z0-9._\\-]*|\\/\\*?|\\d+(?:\\.\\d+)?|<\\/)/,\n// attributes characters\n        qx = /[^a-zA-Z0-9+\\-_\\/ ]/,\n// query characters for ids\n        dx = /[\\[\\]\\/\\\\\"'*<>.&:(){}+=#]/,\n\n        rx = {\n            outer: hx,\n            html: hx,\n            style: sx,\n            styleproperty: ssx\n        };\n\n\n    function return_this() {\n        return this;\n    }\n\n    function F() {}     // Used by Object.create\n\n// Provide critical ES5 functions to ES3.\n\n    if (typeof Array.prototype.filter !== 'function') {\n        Array.prototype.filter = function (f) {\n            var i, length = this.length, result = [];\n            for (i = 0; i < length; i += 1) {\n                try {\n                    result.push(f(this[i]));\n                } catch (ignore) {\n                }\n            }\n            return result;\n        };\n    }\n\n    if (typeof Array.isArray !== 'function') {\n        Array.isArray = function (o) {\n            return Object.prototype.toString.apply(o) === '[object Array]';\n        };\n    }\n\n    if (!Object.hasOwnProperty('create')) {\n        Object.create = function (o) {\n            F.prototype = o;\n            return new F();\n        };\n    }\n\n    if (typeof Object.keys !== 'function') {\n        Object.keys = function (o) {\n            var array = [], key;\n            for (key in o) {\n                if (Object.prototype.hasOwnProperty.call(o, key)) {\n                    array.push(key);\n                }\n            }\n            return array;\n        };\n    }\n\n// Substandard methods\n\n    if (typeof String.prototype.entityify !== 'function') {\n        String.prototype.entityify = function () {\n            return this\n                .replace(/&/g, '&amp;')\n                .replace(/</g, '&lt;')\n                .replace(/>/g, '&gt;');\n        };\n    }\n\n    if (typeof String.prototype.isAlpha !== 'function') {\n        String.prototype.isAlpha = function () {\n            return (this >= 'a' && this <= 'z\\uffff') ||\n                (this >= 'A' && this <= 'Z\\uffff');\n        };\n    }\n\n    if (typeof String.prototype.isDigit !== 'function') {\n        String.prototype.isDigit = function () {\n            return (this >= '0' && this <= '9');\n        };\n    }\n\n    if (typeof String.prototype.supplant !== 'function') {\n        String.prototype.supplant = function (o) {\n            return this.replace(/\\{([^{}]*)\\}/g, function (a, b) {\n                var replacement = o[b];\n                return typeof replacement === 'string' ||\n                    typeof replacement === 'number' ? replacement : a;\n            });\n        };\n    }\n\n    if (typeof String.prototype.name !== 'function') {\n        String.prototype.name = function () {\n\n// If the string looks like an identifier, then we can return it as is.\n// If the string contains no control characters, no quote characters, and no\n// backslash characters, then we can simply slap some quotes around it.\n// Otherwise we must also replace the offending characters with safe\n// sequences.\n\n            if (ix.test(this)) {\n                return this;\n            }\n            if (nx.test(this)) {\n                return '\"' + this.replace(nxg, function (a) {\n                    if (escapes[a]) {\n                        return escapes[a];\n                    }\n                    return '\\\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4);\n                }) + '\"';\n            }\n            return '\"' + this + '\"';\n        };\n    }\n\n\n    function combine(a, b) {\n        var name;\n        for (name in b) {\n            if (Object.prototype.hasOwnProperty.call(b, name)) {\n                a[name] = b[name];\n            }\n        }\n    }\n\n    function assume() {\n        if (!option.safe) {\n            if (option.rhino) {\n                combine(predefined, rhino);\n            }\n            if (option.devel) {\n                combine(predefined, devel);\n            }\n            if (option.browser) {\n                combine(predefined, browser);\n            }\n            if (option.windows) {\n                combine(predefined, windows);\n            }\n            if (option.node) {\n                combine(predefined, node);\n            }\n            if (option.widget) {\n                combine(predefined, widget);\n            }\n        }\n    }\n\n\n// Produce an error warning.\n\n    function quit(message, line, character) {\n        throw {\n            name: 'JSLintError',\n            line: line,\n            character: character,\n            message: bundle.scanned_a_b.supplant({\n                a: message,\n                b: Math.floor((line / lines.length) * 100)\n            })\n        };\n    }\n\n    function warn(message, offender, a, b, c, d) {\n        var character, line, warning;\n        offender = offender || next_token;  // `~\n        line = offender.line || 0;\n        character = offender.from || 0;\n        warning = {\n            id: '(error)',\n            raw: bundle[message] || message,\n            evidence: lines[line - 1] || '',\n            line: line,\n            character: character,\n            a: a || offender.value,\n            b: b,\n            c: c,\n            d: d\n        };\n        warning.reason = warning.raw.supplant(warning);\n        JSLINT.errors.push(warning);\n        if (option.passfail) {\n            quit(bundle.stopping, line, character);\n        }\n        warnings += 1;\n        if (warnings >= option.maxerr) {\n            quit(bundle.too_many, line, character);\n        }\n        return warning;\n    }\n\n    function warn_at(message, line, character, a, b, c, d) {\n        return warn(message, {\n            line: line,\n            from: character\n        }, a, b, c, d);\n    }\n\n    function fail(message, offender, a, b, c, d) {\n        var warning = warn(message, offender, a, b, c, d);\n        quit(bundle.stopping, warning.line, warning.character);\n    }\n\n    function fail_at(message, line, character, a, b, c, d) {\n        return fail(message, {\n            line: line,\n            from: character\n        }, a, b, c, d);\n    }\n\n    function expected_at(at) {\n        if (option.white && next_token.from !== at) {\n            warn('expected_a_at_b_c', next_token, next_token.value, at,\n                next_token.from);\n        }\n    }\n\n    function aint(it, name, expected) {\n        if (it[name] !== expected) {\n            warn('expected_a_b', it, expected, it[name]);\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n\n// lexical analysis and token construction\n\n    var lex = (function lex() {\n        var character, from, line, source_row;\n\n// Private lex methods\n\n        function collect_comment(comment, quote, line, at) {\n            var comment_object = {\n                comment: comment,\n                quote: quote,\n                at: at,\n                line: line\n            };\n            if (comments_off || src || (xmode && xmode !== 'script' &&\n                    xmode !== 'style' && xmode !== 'styleproperty')) {\n                warn_at('unexpected_comment', line, character);\n            } else if (xmode === 'script' && /<\\//i.test(source_row)) {\n                warn_at('unexpected_a', line, character, '<\\/');\n            } else if (option.safe && ax.test(comment)) {\n                warn_at('dangerous_comment', line, at);\n            }\n            if (older_token.comments) {\n                older_token.comments.push(comment_object);\n            } else {\n                older_token.comments = [comment_object];\n            }\n            JSLINT.comments.push(comment_object);\n        }\n\n        function next_line() {\n            var at;\n            if (line >= lines.length) {\n                return false;\n            }\n            character = 1;\n            source_row = lines[line];\n            line += 1;\n            at = source_row.search(/ \\t/);\n            if (at >= 0) {\n                warn_at('mixed', line, at + 1);\n            }\n            source_row = source_row.replace(/\\t/g, tab);\n            at = source_row.search(cx);\n            if (at >= 0) {\n                warn_at('unsafe', line, at);\n            }\n            if (option.maxlen && option.maxlen < source_row.length) {\n                warn_at('too_long', line, source_row.length);\n            }\n            return true;\n        }\n\n// Produce a token object.  The token inherits from a syntax symbol.\n\n        function it(type, value, quote) {\n            var id, the_token;\n            if (type === '(string)' || type === '(range)') {\n                if (jx.test(value)) {\n                    warn_at('url', line, from);\n                }\n            }\n            the_token = Object.create(syntax[(\n                type === '(punctuator)' ||\n                    (type === '(identifier)' &&\n                    Object.prototype.hasOwnProperty.call(syntax, value)) ?\n                value :\n                type\n            )] || syntax['(error)']);\n            if (type === '(identifier)') {\n                the_token.identifier = true;\n                if (value === '__iterator__' || value === '__proto__') {\n                    fail_at('reserved_a', line, from, value);\n                } else if (option.nomen &&\n                        (value.charAt(0) === '_' ||\n                        value.charAt(value.length - 1) === '_')) {\n                    warn_at('dangling_a', line, from, value);\n                }\n            }\n            if (value !== undefined) {\n                the_token.value = value;\n            }\n            if (quote) {\n                the_token.quote = quote;\n            }\n            the_token.line = line;\n            the_token.from = from;\n            the_token.thru = character;\n            the_token.prev = older_token;\n            id = the_token.id;\n            prereg = id && (\n                ('(,=:[!&|?{};'.indexOf(id.charAt(id.length - 1)) >= 0) ||\n                id === 'return'\n            );\n            older_token.next = the_token;\n            older_token = the_token;\n            return the_token;\n        }\n\n// Public lex methods\n\n        return {\n            init: function (source) {\n                if (typeof source === 'string') {\n                    lines = source\n                        .replace(/\\r\\n/g, '\\n')\n                        .replace(/\\r/g, '\\n')\n                        .split('\\n');\n                } else {\n                    lines = source;\n                }\n                line = 0;\n                next_line();\n                from = 1;\n            },\n\n            range: function (begin, end) {\n                var c, value = '';\n                from = character;\n                if (source_row.charAt(0) !== begin) {\n                    fail_at('expected_a_b', line, character, begin,\n                        source_row.charAt(0));\n                }\n                for (;;) {\n                    source_row = source_row.slice(1);\n                    character += 1;\n                    c = source_row.charAt(0);\n                    switch (c) {\n                    case '':\n                        fail_at('missing_a', line, character, c);\n                        break;\n                    case end:\n                        source_row = source_row.slice(1);\n                        character += 1;\n                        return it('(range)', value);\n                    case xquote:\n                    case '\\\\':\n                        warn_at('unexpected_a', line, character, c);\n                        break;\n                    }\n                    value += c;\n                }\n            },\n\n// token -- this is called by advance to get the next token.\n\n            token: function () {\n                var b, c, captures, digit, depth, flag, high, i, j, length, low, quote, symbol;\n\n                function match(x) {\n                    var exec = x.exec(source_row), first;\n                    if (exec) {\n                        length = exec[0].length;\n                        first = exec[1];\n                        c = first.charAt(0);\n                        source_row = source_row.substr(length);\n                        from = character + length - first.length;\n                        character += length;\n                        return first;\n                    }\n                }\n\n                function string(x) {\n                    var c, j, r = '';\n\n                    function hex(n) {\n                        var i = parseInt(source_row.substr(j + 1, n), 16);\n                        j += n;\n                        if (i >= 32 && i <= 126 &&\n                                i !== 34 && i !== 92 && i !== 39) {\n                            warn_at('unexpected_a', line, character, '\\\\');\n                        }\n                        character += n;\n                        c = String.fromCharCode(i);\n                    }\n\n                    if (json_mode && x !== '\"') {\n                        warn_at('expected_a', line, character, '\"');\n                    }\n\n                    if (xquote === x || (xmode === 'scriptstring' && !xquote)) {\n                        return it('(punctuator)', x);\n                    }\n\n                    j = 0;\n                    for (;;) {\n                        while (j >= source_row.length) {\n                            j = 0;\n                            if (xmode !== 'html' || !next_line()) {\n                                fail_at('unclosed', line, from);\n                            }\n                        }\n                        c = source_row.charAt(j);\n                        if (c === x) {\n                            character += 1;\n                            source_row = source_row.substr(j + 1);\n                            return it('(string)', r, x);\n                        }\n                        if (c < ' ') {\n                            if (c === '\\n' || c === '\\r') {\n                                break;\n                            }\n                            warn_at('control_a',\n                                line, character + j, source_row.slice(0, j));\n                        } else if (c === xquote) {\n                            warn_at('bad_html', line, character + j);\n                        } else if (c === '<') {\n                            if (option.safe && xmode === 'html') {\n                                warn_at('adsafe_a', line, character + j, c);\n                            } else if (source_row.charAt(j + 1) === '/' && (xmode || option.safe)) {\n                                warn_at('expected_a_b', line, character,\n                                    '<\\\\/', '</');\n                            } else if (source_row.charAt(j + 1) === '!' && (xmode || option.safe)) {\n                                warn_at('unexpected_a', line, character, '<!');\n                            }\n                        } else if (c === '\\\\') {\n                            if (xmode === 'html') {\n                                if (option.safe) {\n                                    warn_at('adsafe_a', line, character + j, c);\n                                }\n                            } else if (xmode === 'styleproperty') {\n                                j += 1;\n                                character += 1;\n                                c = source_row.charAt(j);\n                                if (c !== x) {\n                                    warn_at('unexpected_a', line, character, '\\\\');\n                                }\n                            } else {\n                                j += 1;\n                                character += 1;\n                                c = source_row.charAt(j);\n                                switch (c) {\n                                case xquote:\n                                    warn_at('bad_html', line, character + j);\n                                    break;\n                                case '\\\\':\n                                case '\"':\n                                case '/':\n                                    break;\n                                case '\\'':\n                                    if (json_mode) {\n                                        warn_at('unexpected_a', line, character, '\\\\\\'');\n                                    }\n                                    break;\n                                case 'b':\n                                    c = '\\b';\n                                    break;\n                                case 'f':\n                                    c = '\\f';\n                                    break;\n                                case 'n':\n                                    c = '\\n';\n                                    break;\n                                case 'r':\n                                    c = '\\r';\n                                    break;\n                                case 't':\n                                    c = '\\t';\n                                    break;\n                                case 'u':\n                                    hex(4);\n                                    break;\n                                case 'v':\n                                    if (json_mode) {\n                                        warn_at('unexpected_a', line, character, '\\\\v');\n                                    }\n                                    c = '\\v';\n                                    break;\n                                case 'x':\n                                    if (json_mode) {\n                                        warn_at('unexpected_a', line, character, '\\\\x');\n                                    }\n                                    hex(2);\n                                    break;\n                                default:\n                                    warn_at('unexpected_a', line, character, '\\\\');\n                                }\n                            }\n                        }\n                        r += c;\n                        character += 1;\n                        j += 1;\n                    }\n                }\n\n                for (;;) {\n                    while (!source_row) {\n                        if (!next_line()) {\n                            return it('(end)');\n                        }\n                    }\n                    while (xmode === 'outer') {\n                        i = source_row.search(ox);\n                        if (i === 0) {\n                            break;\n                        } else if (i > 0) {\n                            character += 1;\n                            source_row = source_row.slice(i);\n                            break;\n                        } else {\n                            if (!next_line()) {\n                                return it('(end)', '');\n                            }\n                        }\n                    }\n                    symbol = match(rx[xmode] || tx);\n                    if (!symbol) {\n                        symbol = '';\n                        c = '';\n                        while (source_row && source_row < '!') {\n                            source_row = source_row.substr(1);\n                        }\n                        if (source_row) {\n                            if (xmode === 'html') {\n                                return it('(error)', source_row.charAt(0));\n                            } else {\n                                fail_at('unexpected_a',\n                                    line, character, source_row.substr(0, 1));\n                            }\n                        }\n                    } else {\n\n//      identifier\n\n                        if (c.isAlpha() || c === '_' || c === '$') {\n                            return it('(identifier)', symbol);\n                        }\n\n//      number\n\n                        if (c.isDigit()) {\n                            if (xmode !== 'style' &&\n                                    xmode !== 'styleproperty' &&\n                                    source_row.substr(0, 1).isAlpha()) {\n                                warn_at('expected_space_a_b',\n                                    line, character, c, source_row.charAt(0));\n                            }\n                            if (c === '0') {\n                                digit = symbol.substr(1, 1);\n                                if (digit.isDigit()) {\n                                    if (token.id !== '.' && xmode !== 'styleproperty') {\n                                        warn_at('unexpected_a',\n                                            line, character, symbol);\n                                    }\n                                } else if (json_mode && (digit === 'x' || digit === 'X')) {\n                                    warn_at('unexpected_a', line, character, '0x');\n                                }\n                            }\n                            if (symbol.substr(symbol.length - 1) === '.') {\n                                warn_at('trailing_decimal_a', line,\n                                    character, symbol);\n                            }\n                            if (xmode !== 'style') {\n                                digit = +symbol;\n                                if (!isFinite(digit)) {\n                                    warn_at('bad_number', line, character, symbol);\n                                }\n                                symbol = digit;\n                            }\n                            return it('(number)', symbol);\n                        }\n                        switch (symbol) {\n\n//      string\n\n                        case '\"':\n                        case \"'\":\n                            return string(symbol);\n\n//      // comment\n\n                        case '//':\n                            collect_comment(source_row, '//', line, character);\n                            source_row = '';\n                            break;\n\n//      /* comment\n\n                        case '/*':\n                            quote = '/*';\n                            for (;;) {\n                                i = source_row.search(lx);\n                                if (i >= 0) {\n                                    break;\n                                }\n                                collect_comment(source_row, quote, line, character);\n                                quote = '';\n                                if (!next_line()) {\n                                    fail_at('unclosed_comment', line, character);\n                                }\n                            }\n                            collect_comment(source_row.slice(0, i), quote, character, line);\n                            character += i + 2;\n                            if (source_row.substr(i, 1) === '/') {\n                                fail_at('nested_comment', line, character);\n                            }\n                            source_row = source_row.substr(i + 2);\n                            break;\n\n                        case '':\n                            break;\n//      /\n                        case '/':\n                            if (token.id === '/=') {\n                                fail_at(\n                                    bundle.slash_equal,\n                                    line,\n                                    from\n                                );\n                            }\n                            if (prereg) {\n                                depth = 0;\n                                captures = 0;\n                                length = 0;\n                                for (;;) {\n                                    b = true;\n                                    c = source_row.charAt(length);\n                                    length += 1;\n                                    switch (c) {\n                                    case '':\n                                        fail_at('unclosed_regexp', line, from);\n                                        return;\n                                    case '/':\n                                        if (depth > 0) {\n                                            warn_at('unescaped_a',\n                                                line, from + length, '/');\n                                        }\n                                        c = source_row.substr(0, length - 1);\n                                        flag = Object.create(regexp_flag);\n                                        while (flag[source_row.charAt(length)] === true) {\n                                            flag[source_row.charAt(length)] = false;\n                                            length += 1;\n                                        }\n                                        if (source_row.charAt(length).isAlpha()) {\n                                            fail_at('unexpected_a',\n                                                line, from, source_row.charAt(length));\n                                        }\n                                        character += length;\n                                        source_row = source_row.substr(length);\n                                        quote = source_row.charAt(0);\n                                        if (quote === '/' || quote === '*') {\n                                            fail_at('confusing_regexp',\n                                                line, from);\n                                        }\n                                        return it('(regexp)', c);\n                                    case '\\\\':\n                                        c = source_row.charAt(length);\n                                        if (c < ' ') {\n                                            warn_at('control_a',\n                                                line, from + length, String(c));\n                                        } else if (c === '<') {\n                                            warn_at(\n                                                bundle.unexpected_a,\n                                                line,\n                                                from + length,\n                                                '\\\\'\n                                            );\n                                        }\n                                        length += 1;\n                                        break;\n                                    case '(':\n                                        depth += 1;\n                                        b = false;\n                                        if (source_row.charAt(length) === '?') {\n                                            length += 1;\n                                            switch (source_row.charAt(length)) {\n                                            case ':':\n                                            case '=':\n                                            case '!':\n                                                length += 1;\n                                                break;\n                                            default:\n                                                warn_at(\n                                                    bundle.expected_a_b,\n                                                    line,\n                                                    from + length,\n                                                    ':',\n                                                    source_row.charAt(length)\n                                                );\n                                            }\n                                        } else {\n                                            captures += 1;\n                                        }\n                                        break;\n                                    case '|':\n                                        b = false;\n                                        break;\n                                    case ')':\n                                        if (depth === 0) {\n                                            warn_at('unescaped_a',\n                                                line, from + length, ')');\n                                        } else {\n                                            depth -= 1;\n                                        }\n                                        break;\n                                    case ' ':\n                                        j = 1;\n                                        while (source_row.charAt(length) === ' ') {\n                                            length += 1;\n                                            j += 1;\n                                        }\n                                        if (j > 1) {\n                                            warn_at('use_braces',\n                                                line, from + length, j);\n                                        }\n                                        break;\n                                    case '[':\n                                        c = source_row.charAt(length);\n                                        if (c === '^') {\n                                            length += 1;\n                                            if (option.regexp) {\n                                                warn_at('insecure_a',\n                                                    line, from + length, c);\n                                            } else if (source_row.charAt(length) === ']') {\n                                                fail_at('unescaped_a',\n                                                    line, from + length, '^');\n                                            }\n                                        }\n                                        quote = false;\n                                        if (c === ']') {\n                                            warn_at('empty_class', line,\n                                                from + length - 1);\n                                            quote = true;\n                                        }\nklass:                                  do {\n                                            c = source_row.charAt(length);\n                                            length += 1;\n                                            switch (c) {\n                                            case '[':\n                                            case '^':\n                                                warn_at('unescaped_a',\n                                                    line, from + length, c);\n                                                quote = true;\n                                                break;\n                                            case '-':\n                                                if (quote) {\n                                                    quote = false;\n                                                } else {\n                                                    warn_at('unescaped_a',\n                                                        line, from + length, '-');\n                                                    quote = true;\n                                                }\n                                                break;\n                                            case ']':\n                                                if (!quote) {\n                                                    warn_at('unescaped_a',\n                                                        line, from + length - 1, '-');\n                                                }\n                                                break klass;\n                                            case '\\\\':\n                                                c = source_row.charAt(length);\n                                                if (c < ' ') {\n                                                    warn_at(\n                                                        bundle.control_a,\n                                                        line,\n                                                        from + length,\n                                                        String(c)\n                                                    );\n                                                } else if (c === '<') {\n                                                    warn_at(\n                                                        bundle.unexpected_a,\n                                                        line,\n                                                        from + length,\n                                                        '\\\\'\n                                                    );\n                                                }\n                                                length += 1;\n                                                quote = true;\n                                                break;\n                                            case '/':\n                                                warn_at('unescaped_a',\n                                                    line, from + length - 1, '/');\n                                                quote = true;\n                                                break;\n                                            case '<':\n                                                if (xmode === 'script') {\n                                                    c = source_row.charAt(length);\n                                                    if (c === '!' || c === '/') {\n                                                        warn_at(\n                                                            bundle.html_confusion_a,\n                                                            line,\n                                                            from + length,\n                                                            c\n                                                        );\n                                                    }\n                                                }\n                                                quote = true;\n                                                break;\n                                            default:\n                                                quote = true;\n                                            }\n                                        } while (c);\n                                        break;\n                                    case '.':\n                                        if (option.regexp) {\n                                            warn_at('insecure_a', line,\n                                                from + length, c);\n                                        }\n                                        break;\n                                    case ']':\n                                    case '?':\n                                    case '{':\n                                    case '}':\n                                    case '+':\n                                    case '*':\n                                        warn_at('unescaped_a', line,\n                                            from + length, c);\n                                        break;\n                                    case '<':\n                                        if (xmode === 'script') {\n                                            c = source_row.charAt(length);\n                                            if (c === '!' || c === '/') {\n                                                warn_at(\n                                                    bundle.html_confusion_a,\n                                                    line,\n                                                    from + length,\n                                                    c\n                                                );\n                                            }\n                                        }\n                                        break;\n                                    }\n                                    if (b) {\n                                        switch (source_row.charAt(length)) {\n                                        case '?':\n                                        case '+':\n                                        case '*':\n                                            length += 1;\n                                            if (source_row.charAt(length) === '?') {\n                                                length += 1;\n                                            }\n                                            break;\n                                        case '{':\n                                            length += 1;\n                                            c = source_row.charAt(length);\n                                            if (c < '0' || c > '9') {\n                                                warn_at(\n                                                    bundle.expected_number_a,\n                                                    line,\n                                                    from + length,\n                                                    c\n                                                );\n                                            }\n                                            length += 1;\n                                            low = +c;\n                                            for (;;) {\n                                                c = source_row.charAt(length);\n                                                if (c < '0' || c > '9') {\n                                                    break;\n                                                }\n                                                length += 1;\n                                                low = +c + (low * 10);\n                                            }\n                                            high = low;\n                                            if (c === ',') {\n                                                length += 1;\n                                                high = Infinity;\n                                                c = source_row.charAt(length);\n                                                if (c >= '0' && c <= '9') {\n                                                    length += 1;\n                                                    high = +c;\n                                                    for (;;) {\n                                                        c = source_row.charAt(length);\n                                                        if (c < '0' || c > '9') {\n                                                            break;\n                                                        }\n                                                        length += 1;\n                                                        high = +c + (high * 10);\n                                                    }\n                                                }\n                                            }\n                                            if (source_row.charAt(length) !== '}') {\n                                                warn_at(\n                                                    bundle.expected_a_b,\n                                                    line,\n                                                    from + length,\n                                                    '}',\n                                                    c\n                                                );\n                                            } else {\n                                                length += 1;\n                                            }\n                                            if (source_row.charAt(length) === '?') {\n                                                length += 1;\n                                            }\n                                            if (low > high) {\n                                                warn_at(\n                                                    bundle.not_greater,\n                                                    line,\n                                                    from + length,\n                                                    low,\n                                                    high\n                                                );\n                                            }\n                                            break;\n                                        }\n                                    }\n                                }\n                                c = source_row.substr(0, length - 1);\n                                character += length;\n                                source_row = source_row.substr(length);\n                                return it('(regexp)', c);\n                            }\n                            return it('(punctuator)', symbol);\n\n//      punctuator\n\n                        case '<!--':\n                            length = line;\n                            c = character;\n                            for (;;) {\n                                i = source_row.indexOf('--');\n                                if (i >= 0) {\n                                    break;\n                                }\n                                i = source_row.indexOf('<!');\n                                if (i >= 0) {\n                                    fail_at('nested_comment',\n                                        line, character + i);\n                                }\n                                if (!next_line()) {\n                                    fail_at('unclosed_comment', length, c);\n                                }\n                            }\n                            length = source_row.indexOf('<!');\n                            if (length >= 0 && length < i) {\n                                fail_at('nested_comment',\n                                    line, character + length);\n                            }\n                            character += i;\n                            if (source_row.charAt(i + 2) !== '>') {\n                                fail_at('expected_a', line, character, '-->');\n                            }\n                            character += 3;\n                            source_row = source_row.slice(i + 3);\n                            break;\n                        case '#':\n                            if (xmode === 'html' || xmode === 'styleproperty') {\n                                for (;;) {\n                                    c = source_row.charAt(0);\n                                    if ((c < '0' || c > '9') &&\n                                            (c < 'a' || c > 'f') &&\n                                            (c < 'A' || c > 'F')) {\n                                        break;\n                                    }\n                                    character += 1;\n                                    source_row = source_row.substr(1);\n                                    symbol += c;\n                                }\n                                if (symbol.length !== 4 && symbol.length !== 7) {\n                                    warn_at('bad_color_a', line,\n                                        from + length, symbol);\n                                }\n                                return it('(color)', symbol);\n                            }\n                            return it('(punctuator)', symbol);\n\n                        default:\n                            if (xmode === 'outer' && c === '&') {\n                                character += 1;\n                                source_row = source_row.substr(1);\n                                for (;;) {\n                                    c = source_row.charAt(0);\n                                    character += 1;\n                                    source_row = source_row.substr(1);\n                                    if (c === ';') {\n                                        break;\n                                    }\n                                    if (!((c >= '0' && c <= '9') ||\n                                            (c >= 'a' && c <= 'z') ||\n                                            c === '#')) {\n                                        fail_at('bad_entity', line, from + length,\n                                            character);\n                                    }\n                                }\n                                break;\n                            }\n                            return it('(punctuator)', symbol);\n                        }\n                    }\n                }\n            }\n        };\n    }());\n\n\n    function add_label(symbol, type) {\n\n        if (option.safe && funct['(global)'] &&\n                typeof predefined[symbol] !== 'boolean') {\n            warn('adsafe_a', token, symbol);\n        } else if (symbol === 'hasOwnProperty') {\n            warn('bad_name_a', token, symbol);\n        }\n\n// Define symbol in the current function in the current scope.\n\n        if (Object.prototype.hasOwnProperty.call(funct, symbol) && !funct['(global)']) {\n            warn(funct[symbol] === true ?\n                bundle.used_before_a :\n                bundle.already_defined,\n                next_token, symbol);\n        }\n        funct[symbol] = type;\n        if (funct['(global)']) {\n            if (global[symbol] === false) {\n                warn('read_only');\n            }\n            global[symbol] = true;\n            if (Object.prototype.hasOwnProperty.call(implied, symbol)) {\n                warn('used_before_a', next_token, symbol);\n                delete implied[symbol];\n            }\n        } else {\n            scope[symbol] = funct;\n        }\n    }\n\n\n    function peek(distance) {\n\n// Peek ahead to a future token. The distance is how far ahead to look. The\n// default is the next token.\n\n        var found, slot = 0;\n\n        distance = distance || 0;\n        while (slot <= distance) {\n            found = lookahead[slot];\n            if (!found) {\n                found = lookahead[slot] = lex.token();\n            }\n            slot += 1;\n        }\n        return found;\n    }\n\n\n    function discard(it) {\n\n// The token will not be included in the parse tree, so move the comments\n// that are attached to the token to tokens that are in the tree.\n\n        it = it || token;\n        if (it.comments) {\n            var prev = it.prev;\n            while (prev.comments === null) {\n                prev = prev.prev;\n            }\n            if (prev.comments) {\n                prev.comments = prev.comments.concat(it.comments);\n            } else {\n                prev.comments = it.comments;\n            }\n        }\n        it.comments = null;\n    }\n\n\n    function advance(id, match) {\n\n// Produce the next token, also looking for programming errors.\n\n        if (indent) {\n\n// In indentation checking was requested, then inspect all of the line breakings.\n// The var statement is tricky because the names might be aligned or not. We\n// look at the first line break after the var to determine the programmer's\n// intention.\n\n            if (var_mode && next_token.line !== token.line) {\n                if ((var_mode !== indent || !next_token.edge) &&\n                        next_token.from === indent.at -\n                        (next_token.edge ? option.indent : 0)) {\n                    var dent = indent;\n                    for (;;) {\n                        dent.at -= option.indent;\n                        if (dent === var_mode) {\n                            break;\n                        }\n                        dent = dent.was;\n                    }\n                    dent.open = false;\n                }\n                var_mode = false;\n            }\n            if (indent.open) {\n\n// If the token is an edge.\n\n                if (next_token.edge) {\n                    if (next_token.edge === 'label') {\n                        expected_at(1);\n                    } else if (next_token.edge === 'case') {\n                        expected_at(indent.at - option.indent);\n                    } else if (indent.mode !== 'array' || next_token.line !== token.line) {\n                        expected_at(indent.at);\n                    }\n\n// If the token is not an edge, but is the first token on the line.\n\n                } else if (next_token.line !== token.line &&\n                        next_token.from < indent.at + (indent.mode ===\n                        'expression' ? 0 : option.indent)) {\n                    expected_at(indent.at + option.indent);\n                }\n            } else if (next_token.line !== token.line) {\n                if (next_token.edge) {\n                    expected_at(indent.at);\n                } else {\n                    indent.wrap = true;\n                    if (indent.mode === 'statement' || indent.mode === 'var') {\n                        expected_at(indent.at + option.indent);\n                    } else if (next_token.from < indent.at + (indent.mode ===\n                            'expression' ? 0 : option.indent)) {\n                        expected_at(indent.at + option.indent);\n                    }\n                }\n            }\n        }\n\n        switch (token.id) {\n        case '(number)':\n            if (next_token.id === '.') {\n                warn('trailing_decimal_a');\n            }\n            break;\n        case '-':\n            if (next_token.id === '-' || next_token.id === '--') {\n                warn('confusing_a');\n            }\n            break;\n        case '+':\n            if (next_token.id === '+' || next_token.id === '++') {\n                warn('confusing_a');\n            }\n            break;\n        }\n        if (token.arity === 'string' || token.identifier) {\n            anonname = token.value;\n        }\n\n        if (id && next_token.id !== id) {\n            if (match) {\n                warn('expected_a_b_from_c_d', next_token, id,\n                    match.id, match.line, next_token.value);\n            } else if (!next_token.identifier || next_token.value !== id) {\n                warn('expected_a_b', next_token, id, next_token.value);\n            }\n        }\n        prev_token = token;\n        token = next_token;\n        next_token = lookahead.shift() || lex.token();\n        if (token.id === '(end)') {\n            discard();\n        }\n    }\n\n\n    function directive() {\n        var command = this.id,\n            name,\n            old_comments_off = comments_off,\n            old_option_white = option.white,\n            value;\n        comments_off = true;\n        option.white = false;\n        if (lookahead.length > 0 || next_token.comments) {\n            warn('unexpected_a', this);\n        }\n        switch (command) {\n        case '/*properties':\n        case '/*members':\n            command = '/*properties';\n            if (!properties) {\n                properties = {};\n            }\n            break;\n        case '/*jslint':\n            if (option.safe) {\n                warn('adsafe_a', this);\n            }\n            break;\n        case '/*global':\n            if (option.safe) {\n                warn('adsafe_a', this);\n            }\n            break;\n        default:\n            fail('unpexpected_a', this);\n        }\nloop:   for (;;) {\n            for (;;) {\n                if (next_token.id === '*/') {\n                    break loop;\n                }\n                if (next_token.id !== ',') {\n                    break;\n                }\n                advance();\n            }\n            if (next_token.arity !== 'string' && !next_token.identifier) {\n                fail('unexpected_a', next_token);\n            }\n            name = next_token.value;\n            advance();\n            switch (command) {\n            case '/*global':\n                if (next_token.id === ':') {\n                    advance(':');\n                    switch (next_token.id) {\n                    case 'true':\n                        if (typeof scope[name] === 'object' ||\n                                global[name] === false) {\n                            fail('unexpected_a');\n                        }\n                        global[name] = true;\n                        advance('true');\n                        break;\n                    case 'false':\n                        if (typeof scope[name] === 'object') {\n                            fail('unexpected_a');\n                        }\n                        global[name] = false;\n                        advance('false');\n                        break;\n                    default:\n                        fail('unexpected_a');\n                    }\n                } else {\n                    if (typeof scope[name] === 'object') {\n                        fail('unexpected_a');\n                    }\n                    global[name] = false;\n                }\n                break;\n            case '/*jslint':\n                if (next_token.id !== ':') {\n                    fail('expected_a_b', next_token, ':', next_token.value);\n                }\n                advance(':');\n                switch (name) {\n                case 'indent':\n                    value = +next_token.value;\n                    if (typeof value !== 'number' ||\n                            !isFinite(value) || value < 0 ||\n                            Math.floor(value) !== value) {\n                        fail('expected_small_a');\n                    }\n                    if (value > 0) {\n                        old_option_white = true;\n                    }\n                    option.indent = value;\n                    break;\n                case 'maxerr':\n                    value = +next_token.value;\n                    if (typeof value !== 'number' ||\n                            !isFinite(value) ||\n                            value <= 0 ||\n                            Math.floor(value) !== value) {\n                        fail('expected_small_a', next_token);\n                    }\n                    option.maxerr = value;\n                    break;\n                case 'maxlen':\n                    value = +next_token.value;\n                    if (typeof value !== 'number' || !isFinite(value) || value < 0 ||\n                            Math.floor(value) !== value) {\n                        fail('expected_small_a');\n                    }\n                    option.maxlen = value;\n                    break;\n                case 'white':\n                    if (next_token.id === 'true') {\n                        old_option_white = true;\n                    } else if (next_token.id === 'false') {\n                        old_option_white = false;\n                    } else {\n                        fail('unexpected_a');\n                    }\n                    break;\n                default:\n                    if (next_token.id === 'true') {\n                        option[name] = true;\n                    } else if (next_token.id === 'false') {\n                        option[name] = false;\n                    } else {\n                        fail('unexpected_a');\n                    }\n                }\n                advance();\n                break;\n            case '/*properties':\n                properties[name] = true;\n                break;\n            default:\n                fail('unexpected_a');\n            }\n        }\n        if (command === '/*jslint') {\n            assume();\n        }\n        comments_off = old_comments_off;\n        advance('*/');\n        option.white = old_option_white;\n    }\n\n\n// Indentation intention\n\n    function edge(mode) {\n        next_token.edge = !indent || (indent.open && (mode || true));\n    }\n\n\n    function step_in(mode) {\n        var open, was;\n        if (typeof mode === 'number') {\n            indent = {\n                at: mode,\n                open: true,\n                was: was\n            };\n        } else if (!indent) {\n            indent = {\n                at: 1,\n                mode: 'statement',\n                open: true\n            };\n        } else {\n            was = indent;\n            open = mode === 'var' ||\n                (next_token.line !== token.line && mode !== 'statement');\n            indent = {\n                at: (open || mode === 'control' ?\n                    was.at + option.indent : was.at) +\n                    (was.wrap ? option.indent : 0),\n                mode: mode,\n                open: open,\n                was: was\n            };\n            if (mode === 'var' && open) {\n                var_mode = indent;\n            }\n        }\n    }\n\n    function step_out(id, symbol) {\n        if (id) {\n            if (indent && indent.open) {\n                indent.at -= option.indent;\n                edge();\n            }\n            advance(id, symbol);\n        }\n        if (indent) {\n            indent = indent.was;\n        }\n    }\n\n// Functions for conformance of whitespace.\n\n    function one_space(left, right) {\n        left = left || token;\n        right = right || next_token;\n        if (right.id !== '(end)' && option.white &&\n                (token.line !== right.line ||\n                token.thru + 1 !== right.from)) {\n            warn('expected_space_a_b', right, token.value, right.value);\n        }\n    }\n\n    function one_space_only(left, right) {\n        left = left || token;\n        right = right || next_token;\n        if (right.id !== '(end)' && (left.line !== right.line ||\n                (option.white && left.thru + 1 !== right.from))) {\n            warn('expected_space_a_b', right, left.value, right.value);\n        }\n    }\n\n    function no_space(left, right) {\n        left = left || token;\n        right = right || next_token;\n        if ((option.white || xmode === 'styleproperty' || xmode === 'style') &&\n                left.thru !== right.from && left.line === right.line) {\n            warn('unexpected_space_a_b', right, left.value, right.value);\n        }\n    }\n\n    function no_space_only(left, right) {\n        left = left || token;\n        right = right || next_token;\n        if (right.id !== '(end)' && (left.line !== right.line ||\n                (option.white && left.thru !== right.from))) {\n            warn('unexpected_space_a_b', right, left.value, right.value);\n        }\n    }\n\n    function spaces(left, right) {\n        if (option.white) {\n            left = left || token;\n            right = right || next_token;\n            if (left.thru === right.from && left.line === right.line) {\n                warn('missing_space_a_b', right, left.value, right.value);\n            }\n        }\n    }\n\n    function comma() {\n        if (next_token.id !== ',') {\n            warn_at('expected_a_b', token.line, token.thru, ',', next_token.value);\n        } else {\n            if (option.white) {\n                no_space_only();\n            }\n            advance(',');\n            discard();\n            spaces();\n        }\n    }\n\n\n    function semicolon() {\n        if (next_token.id !== ';') {\n            warn_at('expected_a_b', token.line, token.thru, ';', next_token.value);\n        } else {\n            if (option.white) {\n                no_space_only();\n            }\n            advance(';');\n            discard();\n            if (semicolon_coda[next_token.id] !== true) {\n                spaces();\n            }\n        }\n    }\n\n    function use_strict() {\n        if (next_token.value === 'use strict') {\n            if (strict_mode) {\n                warn('unnecessary_use');\n            }\n            edge();\n            advance();\n            semicolon();\n            strict_mode = true;\n            option.newcap = true;\n            option.undef = true;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n\n    function are_similar(a, b) {\n        if (a === b) {\n            return true;\n        }\n        if (Array.isArray(a)) {\n            if (Array.isArray(b) && a.length === b.length) {\n                var i;\n                for (i = 0; i < a.length; i += 1) {\n                    if (!are_similar(a[i], b[i])) {\n                        return false;\n                    }\n                }\n                return true;\n            }\n            return false;\n        }\n        if (Array.isArray(b)) {\n            return false;\n        }\n        if (a.arity === b.arity && a.value === b.value) {\n            switch (a.arity) {\n            case 'prefix':\n            case 'suffix':\n            case undefined:\n                return are_similar(a.first, b.first);\n            case 'infix':\n                return are_similar(a.first, b.first) &&\n                    are_similar(a.second, b.second);\n            case 'ternary':\n                return are_similar(a.first, b.first) &&\n                    are_similar(a.second, b.second) &&\n                    are_similar(a.third, b.third);\n            case 'function':\n            case 'regexp':\n                return false;\n            default:\n                return true;\n            }\n        } else {\n            if (a.id === '.' && b.id === '[' && b.arity === 'infix') {\n                return a.second.value === b.second.value && b.second.arity === 'string';\n            } else if (a.id === '[' && a.arity === 'infix' && b.id === '.') {\n                return a.second.value === b.second.value && a.second.arity === 'string';\n            }\n        }\n        return false;\n    }\n\n\n// This is the heart of JSLINT, the Pratt parser. In addition to parsing, it\n// is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is\n// like .nud except that it is only used on the first token of a statement.\n// Having .fud makes it much easier to define statement-oriented languages like\n// JavaScript. I retained Pratt's nomenclature.\n\n// .nud     Null denotation\n// .fud     First null denotation\n// .led     Left denotation\n//  lbp     Left binding power\n//  rbp     Right binding power\n\n// They are elements of the parsing method called Top Down Operator Precedence.\n\n    function expression(rbp, initial) {\n\n// rbp is the right binding power.\n// initial indicates that this is the first expression of a statement.\n\n        var left;\n        if (next_token.id === '(end)') {\n            fail('unexpected_a', token, next_token.id);\n        }\n        advance();\n        if (option.safe && typeof predefined[token.value] === 'boolean' &&\n                (next_token.id !== '(' && next_token.id !== '.')) {\n            warn('adsafe', token);\n        }\n        if (initial) {\n            anonname = 'anonymous';\n            funct['(verb)'] = token.value;\n        }\n        if (initial === true && token.fud) {\n            left = token.fud();\n        } else {\n            if (token.nud) {\n                left = token.nud();\n            } else {\n                if (next_token.arity === 'number' && token.id === '.') {\n                    warn('leading_decimal_a', token,\n                        next_token.value);\n                    advance();\n                    return token;\n                } else {\n                    fail('expected_identifier_a', token, token.id);\n                }\n            }\n            while (rbp < next_token.lbp) {\n                advance();\n                if (token.led) {\n                    left = token.led(left);\n                } else {\n                    fail('expected_operator_a', token, token.id);\n                }\n            }\n        }\n        return left;\n    }\n\n\n// Functional constructors for making the symbols that will be inherited by\n// tokens.\n\n    function symbol(s, p) {\n        var x = syntax[s];\n        if (!x || typeof x !== 'object') {\n            syntax[s] = x = {\n                id: s,\n                lbp: p,\n                value: s\n            };\n        }\n        return x;\n    }\n\n\n    function delim(s) {\n        return symbol(s, 0);\n    }\n\n\n    function postscript(x) {\n        x.postscript = true;\n        return x;\n    }\n\n    function ultimate(s) {\n        var x = symbol(s, 0);\n        x.from = 1;\n        x.thru = 1;\n        x.line = 0;\n        x.edge = true;\n        s.value = s;\n        return postscript(x);\n    }\n\n\n    function stmt(s, f) {\n        var x = delim(s);\n        x.identifier = x.reserved = true;\n        x.fud = f;\n        return x;\n    }\n\n    function labeled_stmt(s, f) {\n        var x = stmt(s, f);\n        x.labeled = true;\n    }\n\n    function disrupt_stmt(s, f) {\n        var x = stmt(s, f);\n        x.disrupt = true;\n    }\n\n\n    function reserve_name(x) {\n        var c = x.id.charAt(0);\n        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {\n            x.identifier = x.reserved = true;\n        }\n        return x;\n    }\n\n\n    function prefix(s, f) {\n        var x = symbol(s, 150);\n        reserve_name(x);\n        x.nud = (typeof f === 'function') ? f : function () {\n            if (s === 'typeof') {\n                one_space();\n            } else {\n                no_space_only();\n            }\n            this.first = expression(150);\n            this.arity = 'prefix';\n            if (this.id === '++' || this.id === '--') {\n                if (option.plusplus) {\n                    warn('unexpected_a', this);\n                } else if ((!this.first.identifier || this.first.reserved) &&\n                        this.first.id !== '.' && this.first.id !== '[') {\n                    warn('bad_operand', this);\n                }\n            }\n            return this;\n        };\n        return x;\n    }\n\n\n    function type(s, arity, nud) {\n        var x = delim(s);\n        x.arity = arity;\n        if (nud) {\n            x.nud = nud;\n        }\n        return x;\n    }\n\n\n    function reserve(s, f) {\n        var x = delim(s);\n        x.identifier = x.reserved = true;\n        if (typeof f === 'function') {\n            x.nud = f;\n        }\n        return x;\n    }\n\n\n    function reservevar(s, v) {\n        return reserve(s, function () {\n            if (typeof v === 'function') {\n                v(this);\n            }\n            return this;\n        });\n    }\n\n\n    function infix(s, p, f, w) {\n        var x = symbol(s, p);\n        reserve_name(x);\n        x.led = function (left) {\n            this.arity = 'infix';\n            if (!w) {\n                spaces(prev_token, token);\n                spaces();\n            }\n            if (typeof f === 'function') {\n                return f(left, this);\n            } else {\n                this.first = left;\n                this.second = expression(p);\n                return this;\n            }\n        };\n        return x;\n    }\n\n    function expected_relation(node, message) {\n        if (node.assign) {\n            warn(message || bundle.conditional_assignment, node);\n        }\n        return node;\n    }\n\n    function expected_condition(node, message) {\n        switch (node.id) {\n        case '[':\n        case '-':\n            if (node.arity !== 'infix') {\n                warn(message || bundle.weird_condition, node);\n            }\n            break;\n        case 'false':\n        case 'function':\n        case 'Infinity':\n        case 'NaN':\n        case 'null':\n        case 'true':\n        case 'undefined':\n        case 'void':\n        case '(number)':\n        case '(regexp)':\n        case '(string)':\n        case '{':\n            warn(message || bundle.weird_condition, node);\n            break;\n        }\n        return node;\n    }\n\n    function check_relation(node) {\n        switch (node.arity) {\n        case 'prefix':\n            switch (node.id) {\n            case '{':\n            case '[':\n                warn('unexpected_a', node);\n                break;\n            case '!':\n                warn('confusing_a', node);\n                break;\n            }\n            break;\n        case 'function':\n        case 'regexp':\n            warn('unexpected_a', node);\n            break;\n        default:\n            if (node.id  === 'NaN') {\n                warn('isnan', node);\n            }\n        }\n        return node;\n    }\n\n\n    function relation(s, eqeq) {\n        var x = infix(s, 100, function (left, that) {\n            check_relation(left);\n            if (eqeq) {\n                warn('expected_a_b', that, eqeq, that.id);\n            }\n            var right = expression(100);\n            if (are_similar(left, right) ||\n                    ((left.arity === 'string' || left.arity === 'number') &&\n                    (right.arity === 'string' || right.arity === 'number'))) {\n                warn('weird_relation', that);\n            }\n            that.first = left;\n            that.second = check_relation(right);\n            return that;\n        });\n        return x;\n    }\n\n\n    function assignop(s, bit) {\n        var x = infix(s, 20, function (left, that) {\n            var l;\n            if (option.bitwise && bit) {\n                warn('unexpected_a', that);\n            }\n            that.first = left;\n            if (funct[left.value] === false) {\n                warn('read_only', left);\n            } else if (left['function']) {\n                warn('a_function', left);\n            }\n            if (option.safe) {\n                l = left;\n                do {\n                    if (typeof predefined[l.value] === 'boolean') {\n                        warn('adsafe', l);\n                    }\n                    l = l.first;\n                } while (l);\n            }\n            if (left) {\n                if (left === syntax['function']) {\n                    warn('identifier_function', token);\n                }\n                if (left.id === '.' || left.id === '[') {\n                    if (!left.first || left.first.value === 'arguments') {\n                        warn('bad_assignment', that);\n                    }\n                    that.second = expression(19);\n                    if (that.id === '=' && are_similar(that.first, that.second)) {\n                        warn('weird_assignment', that);\n                    }\n                    return that;\n                } else if (left.identifier && !left.reserved) {\n                    if (funct[left.value] === 'exception') {\n                        warn('assign_exception', left);\n                    }\n                    that.second = expression(19);\n                    if (that.id === '=' && are_similar(that.first, that.second)) {\n                        warn('weird_assignment', that);\n                    }\n                    return that;\n                }\n            }\n            fail('bad_assignment', that);\n        });\n        x.assign = true;\n        return x;\n    }\n\n\n    function bitwise(s, p) {\n        return infix(s, p, function (left, that) {\n            if (option.bitwise) {\n                warn('unexpected_a', that);\n            }\n            that.first = left;\n            that.second = expression(p);\n            return that;\n        });\n    }\n\n\n    function suffix(s, f) {\n        var x = symbol(s, 150);\n        x.led = function (left) {\n            no_space_only(prev_token, token);\n            if (option.plusplus) {\n                warn('unexpected_a', this);\n            } else if ((!left.identifier || left.reserved) &&\n                    left.id !== '.' && left.id !== '[') {\n                warn('bad_operand', this);\n            }\n            this.first = left;\n            this.arity = 'suffix';\n            return this;\n        };\n        return x;\n    }\n\n\n    function optional_identifier() {\n        if (next_token.identifier) {\n            advance();\n            if (option.safe && banned[token.value]) {\n                warn('adsafe_a', token);\n            } else if (token.reserved && !option.es5) {\n                warn('expected_identifier_a_reserved', token);\n            }\n            return token.value;\n        }\n    }\n\n\n    function identifier() {\n        var i = optional_identifier();\n        if (i) {\n            return i;\n        }\n        if (token.id === 'function' && next_token.id === '(') {\n            warn('name_function');\n        } else {\n            fail('expected_identifier_a');\n        }\n    }\n\n\n    function statement(no_indent) {\n\n// Usually a statement starts a line. Exceptions include the var statement in the\n// initialization part of a for statement, and an if after an else.\n\n        var label, old_scope = scope, the_statement;\n\n// We don't like the empty statement.\n\n        if (next_token.id === ';') {\n            warn('unexpected_a');\n            semicolon();\n            return;\n        }\n\n// Is this a labeled statement?\n\n        if (next_token.identifier && !next_token.reserved && peek().id === ':') {\n            edge('label');\n            label = next_token;\n            advance();\n            discard();\n            advance(':');\n            discard();\n            scope = Object.create(old_scope);\n            add_label(label.value, 'label');\n            if (next_token.labeled !== true) {\n                warn('label_a_b', next_token, label.value, next_token.value);\n            }\n            if (jx.test(label.value + ':')) {\n                warn('url', label);\n            }\n            next_token.label = label;\n        }\n\n// Parse the statement.\n\n        edge();\n        step_in('statement');\n        the_statement = expression(0, true);\n        if (the_statement) {\n\n// Look for the final semicolon.\n\n            if (the_statement.arity === 'statement') {\n                if (the_statement.id === 'switch' ||\n                        (the_statement.block && the_statement.id !== 'do')) {\n                    spaces();\n                } else {\n                    semicolon();\n                }\n            } else {\n\n// If this is an expression statement, determine if it is acceptble.\n// We do not like\n//      new Blah();\n// statments. If it is to be used at all, new should only be used to make\n// objects, not side effects. The expression statements we do like do\n// assignment or invocation or delete.\n\n                if (the_statement.id === '(') {\n                    if (the_statement.first.id === 'new') {\n                        warn('bad_new');\n                    }\n                } else if (!the_statement.assign &&\n                        the_statement.id !== 'delete' &&\n                        the_statement.id !== '++' &&\n                        the_statement.id !== '--') {\n                    warn('assignment_function_expression', token);\n                }\n                semicolon();\n            }\n        }\n        step_out();\n        scope = old_scope;\n        return the_statement;\n    }\n\n\n    function statements() {\n        var array = [], disruptor, the_statement;\n\n// A disrupt statement may not be followed by any other statement.\n// If the last statement is disrupt, then the sequence is disrupt.\n\n        while (next_token.postscript !== true) {\n            if (next_token.id === ';') {\n                warn('unexpected_a', next_token);\n                semicolon();\n            } else {\n                if (disruptor) {\n                    warn('unreachable_a_b', next_token, next_token.value,\n                        disruptor.value);\n                    disruptor = null;\n                }\n                the_statement = statement();\n                if (the_statement) {\n                    array.push(the_statement);\n                    if (the_statement.disrupt) {\n                        disruptor = the_statement;\n                        array.disrupt = true;\n                    }\n                }\n            }\n        }\n        return array;\n    }\n\n\n    function block(ordinary) {\n\n// array block is array sequence of statements wrapped in braces.\n// ordinary is false for function bodies and try blocks.\n// ordinary is true for if statements, while, etc.\n\n        var array,\n            curly = next_token,\n            old_inblock = in_block,\n            old_scope = scope,\n            old_strict_mode = strict_mode;\n\n        in_block = ordinary;\n        scope = Object.create(scope);\n        spaces();\n        if (next_token.id === '{') {\n            advance('{');\n            step_in();\n            if (!ordinary && !use_strict() && !old_strict_mode &&\n                    option.strict && funct['(context)']['(global)']) {\n                warn('missing_use_strict');\n            }\n            array = statements();\n            strict_mode = old_strict_mode;\n            step_out('}', curly);\n            discard();\n        } else if (!ordinary) {\n            fail('expected_a_b', next_token, '{', next_token.value);\n        } else {\n            warn('expected_a_b', next_token, '{', next_token.value);\n            array = [statement()];\n            array.disrupt = array[0].disrupt;\n        }\n        funct['(verb)'] = null;\n        scope = old_scope;\n        in_block = old_inblock;\n        if (ordinary && array.length === 0) {\n            warn('empty_block');\n        }\n        return array;\n    }\n\n\n    function tally_property(name) {\n        if (properties && typeof properties[name] !== 'boolean') {\n            warn('unexpected_member_a', token, name);\n        }\n        if (typeof member[name] === 'number') {\n            member[name] += 1;\n        } else {\n            member[name] = 1;\n        }\n    }\n\n\n    function note_implied(token) {\n        var name = token.value, line = token.line, a = implied[name];\n        if (typeof a === 'function') {\n            a = false;\n        }\n        if (!a) {\n            a = [line];\n            implied[name] = a;\n        } else if (a[a.length - 1] !== line) {\n            a.push(line);\n        }\n    }\n\n\n// ECMAScript parser\n\n    syntax['(identifier)'] = {\n        type: '(identifier)',\n        lbp: 0,\n        identifier: true,\n        nud: function () {\n            var variable = this.value,\n                site = scope[variable];\n            if (typeof site === 'function') {\n                site = undefined;\n            }\n\n// The name is in scope and defined in the current function.\n\n            if (funct === site) {\n\n//      Change 'unused' to 'var', and reject labels.\n\n                switch (funct[variable]) {\n                case 'error':\n                    warn('unexpected_a', token);\n                    funct[variable] = 'var';\n                    break;\n                case 'unused':\n                    funct[variable] = 'var';\n                    break;\n                case 'unction':\n                    funct[variable] = 'function';\n                    this['function'] = true;\n                    break;\n                case 'function':\n                    this['function'] = true;\n                    break;\n                case 'label':\n                    warn('a_label', token, variable);\n                    break;\n                }\n\n// The name is not defined in the function.  If we are in the global scope,\n// then we have an undefined variable.\n\n            } else if (funct['(global)']) {\n                if (typeof global[variable] === 'boolean') {\n                    funct[variable] = global[variable];\n                } else {\n                    if (option.undef) {\n                        warn('not_a_defined', token, variable);\n                    } else {\n                        note_implied(token);\n                    }\n                }\n\n// If the name is already defined in the current\n// function, but not as outer, then there is a scope error.\n\n            } else {\n                switch (funct[variable]) {\n                case 'closure':\n                case 'function':\n                case 'var':\n                case 'unused':\n                    warn('a_scope', token, variable);\n                    break;\n                case 'label':\n                    warn('a_label', token, variable);\n                    break;\n                case 'outer':\n                case true:\n                case false:\n                    break;\n                default:\n\n// If the name is defined in an outer function, make an outer entry, and if\n// it was unused, make it var.\n\n                    if (typeof site === 'boolean') {\n                        funct[variable] = site;\n                        functions[0][variable] = true;\n                    } else if (site === null) {\n                        warn('a_not_allowed', token, variable);\n                        note_implied(token);\n                    } else if (typeof site !== 'object') {\n                        if (option.undef) {\n                            warn('a_not_defined', token, variable);\n                        } else {\n                            funct[variable] = true;\n                        }\n                        note_implied(token);\n                    } else {\n                        switch (site[variable]) {\n                        case 'function':\n                        case 'unction':\n                            this['function'] = true;\n                            site[variable] = 'closure';\n                            funct[variable] = site['(global)'] ? false : 'outer';\n                            break;\n                        case 'var':\n                        case 'unused':\n                            site[variable] = 'closure';\n                            funct[variable] = site['(global)'] ? true : 'outer';\n                            break;\n                        case 'closure':\n                        case 'parameter':\n                            funct[variable] = site['(global)'] ? true : 'outer';\n                            break;\n                        case 'error':\n                            warn('not_a_defined', token);\n                            break;\n                        case 'label':\n                            warn('a_label', token, variable);\n                            break;\n                        }\n                    }\n                }\n            }\n            return this;\n        },\n        led: function () {\n            fail('expected_operator_a');\n        }\n    };\n\n// Build the syntax table by declaring the syntactic elements.\n\n    type('(color)', 'color');\n    type('(number)', 'number', return_this);\n    type('(string)', 'string', return_this);\n    type('(range)', 'range');\n    type('(regexp)', 'regexp', return_this);\n\n    ultimate('(begin)');\n    ultimate('(end)');\n    ultimate('(error)');\n    postscript(delim('</'));\n    delim('<!');\n    delim('<!--');\n    delim('-->');\n    postscript(delim('}'));\n    delim(')');\n    delim(']');\n    postscript(delim('\"'));\n    postscript(delim('\\''));\n    delim(';');\n    delim(':');\n    delim(',');\n    delim('#');\n    delim('@');\n    delim('*/');\n    postscript(reserve('case'));\n    reserve('catch');\n    postscript(reserve('default'));\n    reserve('else');\n    reserve('finally');\n\n    reservevar('arguments', function (x) {\n        if (strict_mode && funct['(global)']) {\n            warn('strict', x);\n        } else if (option.safe) {\n            warn('adsafe', x);\n        }\n    });\n    reservevar('eval', function (x) {\n        if (option.safe) {\n            warn('adsafe', x);\n        }\n    });\n    reservevar('false');\n    reservevar('Infinity');\n    reservevar('NaN');\n    reservevar('null');\n    reservevar('this', function (x) {\n        if (strict_mode && ((funct['(statement)'] &&\n                funct['(name)'].charAt(0) > 'Z') || funct['(global)'])) {\n            warn('strict', x);\n        } else if (option.safe) {\n            warn('adsafe', x);\n        }\n    });\n    reservevar('true');\n    reservevar('undefined');\n\n    assignop('=');\n    assignop('+=');\n    assignop('-=');\n    assignop('*=');\n    assignop('/=').nud = function () {\n        fail('slash_equal');\n    };\n    assignop('%=');\n    assignop('&=', true);\n    assignop('|=', true);\n    assignop('^=', true);\n    assignop('<<=', true);\n    assignop('>>=', true);\n    assignop('>>>=', true);\n\n    infix('?', 30, function (left, that) {\n        that.first = expected_condition(expected_relation(left));\n        that.second = expression(0);\n        spaces();\n        advance(':');\n        discard();\n        spaces();\n        that.third = expression(10);\n        that.arity = 'ternary';\n        if (are_similar(that.second, that.third)) {\n            warn('weird_ternary', that);\n        }\n        return that;\n    });\n\n    infix('||', 40, function (left, that) {\n        function paren_check(that) {\n            if (that.id === '&&' && !that.paren) {\n                warn('and', that);\n            }\n            return that;\n        }\n\n        that.first = paren_check(expected_condition(expected_relation(left)));\n        that.second = paren_check(expected_relation(expression(40)));\n        if (are_similar(that.first, that.second)) {\n            warn('weird_condition', that);\n        }\n        return that;\n    });\n\n    infix('&&', 50, function (left, that) {\n        that.first = expected_condition(expected_relation(left));\n        that.second = expected_relation(expression(50));\n        if (are_similar(that.first, that.second)) {\n            warn('weird_condition', that);\n        }\n        return that;\n    });\n\n    prefix('void', function () {\n        this.first = expression(0);\n        if (this.first.arity !== 'number' || this.first.value) {\n            warn('unexpected_a', this);\n            return this;\n        }\n        return this;\n    });\n\n    bitwise('|', 70);\n    bitwise('^', 80);\n    bitwise('&', 90);\n\n    relation('==', '===');\n    relation('===');\n    relation('!=', '!==');\n    relation('!==');\n    relation('<');\n    relation('>');\n    relation('<=');\n    relation('>=');\n\n    bitwise('<<', 120);\n    bitwise('>>', 120);\n    bitwise('>>>', 120);\n\n    infix('in', 120, function (left, that) {\n        warn('infix_in', that);\n        that.left = left;\n        that.right = expression(130);\n        return that;\n    });\n    infix('instanceof', 120);\n    infix('+', 130, function (left, that) {\n        if (!left.value) {\n            if (left.arity === 'number') {\n                warn('unexpected_a', left);\n            } else if (left.arity === 'string') {\n                warn('expected_a_b', left, 'String', '\\'\\'');\n            }\n        }\n        var right = expression(130);\n        if (!right.value) {\n            if (right.arity === 'number') {\n                warn('unexpected_a', right);\n            } else if (right.arity === 'string') {\n                warn('expected_a_b', right, 'String', '\\'\\'');\n            }\n        }\n        if (left.arity === right.arity &&\n                (left.arity === 'string' || left.arity === 'number')) {\n            left.value += right.value;\n            left.thru = right.thru;\n            if (left.arity === 'string' && jx.test(left.value)) {\n                warn('url', left);\n            }\n            discard(right);\n            discard(that);\n            return left;\n        }\n        that.first = left;\n        that.second = right;\n        return that;\n    });\n    prefix('+', 'num');\n    prefix('+++', function () {\n        warn('confusing_a', token);\n        this.first = expression(150);\n        this.arity = 'prefix';\n        return this;\n    });\n    infix('+++', 130, function (left) {\n        warn('confusing_a', token);\n        this.first = left;\n        this.second = expression(130);\n        return this;\n    });\n    infix('-', 130, function (left, that) {\n        if ((left.arity === 'number' && left.value === 0) || left.arity === 'string') {\n            warn('unexpected_a', left);\n        }\n        var right = expression(130);\n        if ((right.arity === 'number' && right.value === 0) || right.arity === 'string') {\n            warn('unexpected_a', left);\n        }\n        if (left.arity === right.arity && left.arity === 'number') {\n            left.value -= right.value;\n            left.thru = right.thru;\n            discard(right);\n            discard(that);\n            return left;\n        }\n        that.first = left;\n        that.second = right;\n        return that;\n    });\n    prefix('-');\n    prefix('---', function () {\n        warn('confusing_a', token);\n        this.first = expression(150);\n        this.arity = 'prefix';\n        return this;\n    });\n    infix('---', 130, function (left) {\n        warn('confusing_a', token);\n        this.first = left;\n        this.second = expression(130);\n        return this;\n    });\n    infix('*', 140, function (left, that) {\n        if ((left.arity === 'number' && (left.value === 0 || left.value === 1)) || left.arity === 'string') {\n            warn('unexpected_a', left);\n        }\n        var right = expression(140);\n        if ((right.arity === 'number' && (right.value === 0 || right.value === 1)) || right.arity === 'string') {\n            warn('unexpected_a', right);\n        }\n        if (left.arity === right.arity && left.arity === 'number') {\n            left.value *= right.value;\n            left.thru = right.thru;\n            discard(right);\n            discard(that);\n            return left;\n        }\n        that.first = left;\n        that.second = right;\n        return that;\n    });\n    infix('/', 140, function (left, that) {\n        if ((left.arity === 'number' && left.value === 0) || left.arity === 'string') {\n            warn('unexpected_a', left);\n        }\n        var right = expression(140);\n        if ((right.arity === 'number' && (right.value === 0 || right.value === 1)) || right.arity === 'string') {\n            warn('unexpected_a', right);\n        }\n        if (left.arity === right.arity && left.arity === 'number') {\n            left.value /= right.value;\n            left.thru = right.thru;\n            discard(right);\n            discard(that);\n            return left;\n        }\n        that.first = left;\n        that.second = right;\n        return that;\n    });\n    infix('%', 140, function (left, that) {\n        if ((left.arity === 'number' && (left.value === 0 || left.value === 1)) || left.arity === 'string') {\n            warn('unexpected_a', left);\n        }\n        var right = expression(140);\n        if ((right.arity === 'number' && (right.value === 0 || right.value === 1)) || right.arity === 'string') {\n            warn('unexpected_a', right);\n        }\n        if (left.arity === right.arity && left.arity === 'number') {\n            left.value %= right.value;\n            left.thru = right.thru;\n            discard(right);\n            discard(that);\n            return left;\n        }\n        that.first = left;\n        that.second = right;\n        return that;\n    });\n\n    suffix('++');\n    prefix('++');\n\n    suffix('--');\n    prefix('--');\n    prefix('delete', function () {\n        one_space();\n        var p = expression(0);\n        if (!p || (p.id !== '.' && p.id !== '[')) {\n            warn('deleted');\n        }\n        this.first = p;\n        return this;\n    });\n\n\n    prefix('~', function () {\n        no_space_only();\n        if (option.bitwise) {\n            warn('unexpected_a', this);\n        }\n        expression(150);\n        return this;\n    });\n    prefix('!', function () {\n        no_space_only();\n        this.first = expression(150);\n        this.arity = 'prefix';\n        if (bang[this.first.id] === true) {\n            warn('confusing_a', this);\n        }\n        return this;\n    });\n    prefix('typeof');\n    prefix('new', function () {\n        one_space();\n        var c = expression(160), i, p;\n        this.first = c;\n        if (c.id !== 'function') {\n            if (c.identifier) {\n                switch (c.value) {\n                case 'Object':\n                    warn('use_object', token);\n                    break;\n                case 'Array':\n                    if (next_token.id === '(') {\n                        p = next_token;\n                        p.first = this;\n                        advance('(');\n                        if (next_token.id !== ')') {\n                            p.second = expression(0);\n                            if (p.second.arity !== 'number' || !p.second.value) {\n                                expected_condition(p.second,  bundle.use_array);\n                                i = false;\n                            } else {\n                                i = true;\n                            }\n                            while (next_token.id !== ')' && next_token.id !== '(end)') {\n                                if (i) {\n                                    warn('use_array', p);\n                                    i = false;\n                                }\n                                advance();\n                            }\n                        } else {\n                            warn('use_array', token);\n                        }\n                        advance(')', p);\n                        discard();\n                        return p;\n                    }\n                    warn('use_array', token);\n                    break;\n                case 'Number':\n                case 'String':\n                case 'Boolean':\n                case 'Math':\n                case 'JSON':\n                    warn('not_a_constructor', c);\n                    break;\n                case 'Function':\n                    if (!option.evil) {\n                        warn('function_eval');\n                    }\n                    break;\n                case 'Date':\n                case 'RegExp':\n                    break;\n                default:\n                    if (c.id !== 'function') {\n                        i = c.value.substr(0, 1);\n                        if (option.newcap && (i < 'A' || i > 'Z')) {\n                            warn('constructor_name_a', token);\n                        }\n                    }\n                }\n            } else {\n                if (c.id !== '.' && c.id !== '[' && c.id !== '(') {\n                    warn('bad_constructor', token);\n                }\n            }\n        } else {\n            warn('weird_new', this);\n        }\n        if (next_token.id !== '(') {\n            warn('missing_a', next_token, '()');\n        }\n        return this;\n    });\n\n    infix('(', 160, function (left, that) {\n        if (indent && indent.mode === 'expression') {\n            no_space(prev_token, token);\n        } else {\n            no_space_only(prev_token, token);\n        }\n        if (!left.immed && left.id === 'function') {\n            warn('wrap_immediate');\n        }\n        var p = [];\n        if (left) {\n            if (left.identifier) {\n                if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {\n                    if (left.value !== 'Number' && left.value !== 'String' &&\n                            left.value !== 'Boolean' && left.value !== 'Date') {\n                        if (left.value === 'Math' || left.value === 'JSON') {\n                            warn('not_a_function', left);\n                        } else if (left.value === 'Object') {\n                            warn('use_object', token);\n                        } else if (left.value === 'Array' || option.newcap) {\n                            warn('missing_a', left, 'new');\n                        }\n                    }\n                }\n            } else if (left.id === '.') {\n                if (option.safe && left.first.value === 'Math' &&\n                        left.second === 'random') {\n                    warn('adsafe', left);\n                }\n            }\n        }\n        step_in();\n        if (next_token.id !== ')') {\n            no_space();\n            for (;;) {\n                edge();\n                p.push(expression(10));\n                if (next_token.id !== ',') {\n                    break;\n                }\n                comma();\n            }\n        }\n        no_space();\n        step_out(')', that);\n        if (typeof left === 'object') {\n            if (left.value === 'parseInt' && p.length === 1) {\n                warn('radix', left);\n            }\n            if (!option.evil) {\n                if (left.value === 'eval' || left.value === 'Function' ||\n                        left.value === 'execScript') {\n                    warn('evil', left);\n                } else if (p[0] && p[0].arity === 'string' &&\n                        (left.value === 'setTimeout' ||\n                        left.value === 'setInterval')) {\n                    warn('implied_evil', left);\n                }\n            }\n            if (!left.identifier && left.id !== '.' && left.id !== '[' &&\n                    left.id !== '(' && left.id !== '&&' && left.id !== '||' &&\n                    left.id !== '?') {\n                warn('bad_invocation', left);\n            }\n        }\n        that.first = left;\n        that.second = p;\n        return that;\n    }, true);\n\n    prefix('(', function () {\n        step_in('expression');\n        discard();\n        no_space();\n        edge();\n        if (next_token.id === 'function') {\n            next_token.immed = true;\n        }\n        var value = expression(0);\n        value.paren = true;\n        no_space();\n        step_out(')', this);\n        discard();\n        if (value.id === 'function') {\n            if (next_token.id === '(') {\n                warn('move_invocation');\n            } else {\n                warn('bad_wrap', this);\n            }\n        }\n        return value;\n    });\n\n    infix('.', 170, function (left, that) {\n        no_space(prev_token, token);\n        no_space();\n        var name = identifier();\n        if (typeof name === 'string') {\n            tally_property(name);\n        }\n        that.first = left;\n        that.second = token;\n        if (left && left.value === 'arguments' &&\n                (name === 'callee' || name === 'caller')) {\n            warn('avoid_a', left, 'arguments.' + name);\n        } else if (!option.evil && left && left.value === 'document' &&\n                (name === 'write' || name === 'writeln')) {\n            warn('write_is_wrong', left);\n        } else if (option.adsafe) {\n            if (!adsafe_top && left.value === 'ADSAFE') {\n                if (name === 'id' || name === 'lib') {\n                    warn('adsafe', that);\n                } else if (name === 'go') {\n                    if (xmode !== 'script') {\n                        warn('adsafe', that);\n                    } else if (adsafe_went || next_token.id !== '(' ||\n                            peek(0).arity !== 'string' ||\n                            peek(0).value !== adsafe_id ||\n                            peek(1).id !== ',') {\n                        fail('adsafe_a', that, 'go');\n                    }\n                    adsafe_went = true;\n                    adsafe_may = false;\n                }\n            }\n            adsafe_top = false;\n        }\n        if (!option.evil && (name === 'eval' || name === 'execScript')) {\n            warn('evil');\n        } else if (option.safe) {\n            for (;;) {\n                if (banned[name] === true) {\n                    warn('adsafe_a', token, name);\n                }\n                if (typeof predefined[left.value] !== 'boolean' ||\n                        next_token.id === '(') {\n                    break;\n                }\n                if (standard_property[name] === true) {\n                    if (next_token.id === '.') {\n                        warn('adsafe', that);\n                    }\n                    break;\n                }\n                if (next_token.id !== '.') {\n                    warn('adsafe', that);\n                    break;\n                }\n                advance('.');\n                token.first = that;\n                token.second = name;\n                that = token;\n                name = identifier();\n                if (typeof name === 'string') {\n                    tally_property(name);\n                }\n            }\n        }\n        return that;\n    }, true);\n\n    infix('[', 170, function (left, that) {\n        no_space_only(prev_token, token);\n        no_space();\n        step_in();\n        edge();\n        var e = expression(0), s;\n        if (e.arity === 'string') {\n            if (option.safe && banned[e.value] === true) {\n                warn('adsafe_a', e);\n            } else if (!option.evil &&\n                    (e.value === 'eval' || e.value === 'execScript')) {\n                warn('evil', e);\n            } else if (option.safe &&\n                    (e.value.charAt(0) === '_' || e.value.charAt(0) === '-')) {\n                warn('adsafe_subscript_a', e);\n            }\n            tally_property(e.value);\n            if (!option.sub && ix.test(e.value)) {\n                s = syntax[e.value];\n                if (!s || !s.reserved) {\n                    warn('subscript', e);\n                }\n            }\n        } else if (e.arity !== 'number' || e.value < 0) {\n            if (option.safe) {\n                warn('adsafe_subscript_a', e);\n            }\n        }\n        step_out(']', that);\n        discard();\n        no_space(prev_token, token);\n        that.first = left;\n        that.second = e;\n        return that;\n    }, true);\n\n    prefix('[', function () {\n        this.arity = 'prefix';\n        this.first = [];\n        step_in('array');\n        while (next_token.id !== '(end)') {\n            while (next_token.id === ',') {\n                warn('unexpected_a', next_token);\n                advance(',');\n                discard();\n            }\n            if (next_token.id === ']') {\n                break;\n            }\n            edge();\n            this.first.push(expression(10));\n            if (next_token.id === ',') {\n                comma();\n                if (next_token.id === ']' && !option.es5) {\n                    warn('unexpected_a', token);\n                    break;\n                }\n            } else {\n                break;\n            }\n        }\n        step_out(']', this);\n        discard();\n        return this;\n    }, 170);\n\n\n    function property_name() {\n        var id = optional_identifier(true);\n        if (!id) {\n            if (next_token.arity === 'string') {\n                id = next_token.value;\n                if (option.safe) {\n                    if (banned[id]) {\n                        warn('adsafe_a');\n                    } else if (id.charAt(0) === '_' ||\n                            id.charAt(id.length - 1) === '_') {\n                        warn('dangling_a');\n                    }\n                }\n                advance();\n            } else if (next_token.arity === 'number') {\n                id = next_token.value.toString();\n                advance();\n            }\n        }\n        return id;\n    }\n\n\n    function function_params() {\n        var id, paren = next_token, params = [];\n        advance('(');\n        step_in();\n        discard();\n        no_space();\n        if (next_token.id === ')') {\n            no_space();\n            step_out(')', paren);\n            discard();\n            return;\n        }\n        for (;;) {\n            edge();\n            id = identifier();\n            params.push(token);\n            add_label(id, 'parameter');\n            if (next_token.id === ',') {\n                comma();\n            } else {\n                no_space();\n                step_out(')', paren);\n                discard();\n                return params;\n            }\n        }\n    }\n\n\n    function do_function(func, name) {\n        var old_properties = properties,\n            old_option     = option,\n            old_global     = global,\n            old_scope      = scope;\n        funct = {\n            '(name)'     : name || '\"' + anonname + '\"',\n            '(line)'     : next_token.line,\n            '(context)'  : funct,\n            '(breakage)' : 0,\n            '(loopage)'  : 0,\n            '(scope)'    : scope,\n            '(token)'    : func\n        };\n        properties  = old_properties && Object.create(old_properties);\n        option      = Object.create(old_option);\n        global      = Object.create(old_global);\n        scope       = Object.create(old_scope);\n        token.funct = funct;\n        functions.push(funct);\n        if (name) {\n            add_label(name, 'function');\n        }\n        func.name = name || '';\n        func.first = funct['(params)'] = function_params();\n        one_space();\n        func.block = block(false);\n        funct      = funct['(context)'];\n        properties = old_properties;\n        option     = old_option;\n        global     = old_global;\n        scope      = old_scope;\n    }\n\n\n    prefix('{', function () {\n        var get, i, j, name, p, set, seen = {};\n        this.arity = 'prefix';\n        this.first = [];\n        step_in();\n        while (next_token.id !== '}') {\n\n// JSLint recognizes the ES5 extension for get/set in object literals,\n// but requires that they be used in pairs.\n\n            edge();\n            if (next_token.value === 'get' && peek().id !== ':') {\n                if (!option.es5) {\n                    warn('get_set');\n                }\n                get = next_token;\n                advance('get');\n                one_space_only();\n                name = next_token;\n                i = property_name();\n                if (!i) {\n                    fail('missing_property');\n                }\n                do_function(get, '');\n                if (funct['(loopage)']) {\n                    warn('function_loop', get);\n                }\n                p = get.first;\n                if (p) {\n                    warn('parameter_a_get_b', p[0], p[0].value, i);\n                }\n                comma();\n                set = next_token;\n                spaces();\n                edge();\n                advance('set');\n                one_space_only();\n                j = property_name();\n                if (i !== j) {\n                    fail('expected_a_b', token, i, j || next_token.value);\n                }\n                do_function(set, '');\n                p = set.first;\n                if (!p || p.length !== 1) {\n                    fail('parameter_set_a', set, 'value');\n                } else if (p[0].value !== 'value') {\n                    fail('expected_a_b', p[0], 'value', p[0].value);\n                }\n                name.first = [get, set];\n            } else {\n                name = next_token;\n                i = property_name();\n                if (typeof i !== 'string') {\n                    fail('missing_property');\n                }\n                advance(':');\n                discard();\n                spaces();\n                name.first = expression(10);\n            }\n            this.first.push(name);\n            if (seen[i] === true) {\n                warn('duplicate_a', next_token, i);\n            }\n            seen[i] = true;\n            tally_property(i);\n            if (next_token.id !== ',') {\n                break;\n            }\n            for (;;) {\n                comma();\n                if (next_token.id !== ',') {\n                    break;\n                }\n                warn('unexpected_a', next_token);\n            }\n            if (next_token.id === '}' && !option.es5) {\n                warn('unexpected_a', token);\n            }\n        }\n        step_out('}', this);\n        discard();\n        return this;\n    });\n\n    stmt('{', function () {\n        discard();\n        warn('statement_block');\n        this.arity = 'statement';\n        this.block = statements();\n        this.disrupt = this.block.disrupt;\n        advance('}', this);\n        discard();\n        return this;\n    });\n\n    stmt('/*global', directive);\n    stmt('/*jslint', directive);\n    stmt('/*members', directive);\n    stmt('/*properties', directive);\n\n    stmt('var', function () {\n\n// JavaScript does not have block scope. It only has function scope. So,\n// declaring a variable in a block can have unexpected consequences.\n\n// var.first will contain an array, the array containing name tokens\n// and assignment tokens.\n\n        var assign, id, name;\n\n        if (funct['(onevar)'] && option.onevar) {\n            warn('combine_var');\n        } else if (!funct['(global)']) {\n            funct['(onevar)'] = true;\n        }\n        this.arity = 'statement';\n        this.first = [];\n        step_in('var');\n        for (;;) {\n            name = next_token;\n            id = identifier();\n            if (funct['(global)'] && predefined[id] === false) {\n                warn('redefinition_a', token, id);\n            }\n            add_label(id, 'error');\n\n            if (next_token.id === '=') {\n                assign = next_token;\n                assign.first = name;\n                spaces();\n                advance('=');\n                spaces();\n                if (next_token.id === 'undefined') {\n                    warn('unnecessary_initialize', token, id);\n                }\n                if (peek(0).id === '=' && next_token.identifier) {\n                    fail('var_a_not');\n                }\n                assign.second = expression(0);\n                assign.arity = 'infix';\n                this.first.push(assign);\n            } else {\n                this.first.push(name);\n            }\n            funct[id] = 'unused';\n            if (next_token.id !== ',') {\n                break;\n            }\n            comma();\n            if (var_mode && next_token.line === token.line &&\n                    this.first.length === 1) {\n                var_mode = false;\n                indent.open = false;\n                indent.at -= option.indent;\n            }\n            spaces();\n            edge();\n        }\n        var_mode = false;\n        step_out();\n        return this;\n    });\n\n    stmt('function', function () {\n        one_space();\n        if (in_block) {\n            warn('function_block', token);\n        }\n        var i = identifier();\n        if (i) {\n            add_label(i, 'unction');\n            no_space();\n        }\n        do_function(this, i, true);\n        if (next_token.id === '(' && next_token.line === token.line) {\n            fail('function_statement');\n        }\n        this.arity = 'statement';\n        return this;\n    });\n\n    prefix('function', function () {\n        one_space();\n        var i = optional_identifier();\n        if (i) {\n            no_space();\n        }\n        do_function(this, i);\n        if (funct['(loopage)']) {\n            warn('function_loop');\n        }\n        this.arity = 'function';\n        return this;\n    });\n\n    stmt('if', function () {\n        var paren = next_token;\n        one_space();\n        advance('(');\n        step_in('control');\n        discard();\n        no_space();\n        edge();\n        this.arity = 'statement';\n        this.first = expected_condition(expected_relation(expression(0)));\n        no_space();\n        step_out(')', paren);\n        discard();\n        one_space();\n        this.block = block(true);\n        if (next_token.id === 'else') {\n            one_space();\n            advance('else');\n            discard();\n            one_space();\n            this['else'] = next_token.id === 'if' || next_token.id === 'switch' ?\n                statement(true) : block(true);\n            if (this['else'].disrupt && this.block.disrupt) {\n                this.disrupt = true;\n            }\n        }\n        return this;\n    });\n\n    stmt('try', function () {\n\n// try.first    The catch variable\n// try.second   The catch clause\n// try.third    The finally clause\n// try.block    The try block\n\n        var exception_variable, old_scope, paren;\n        if (option.adsafe) {\n            warn('adsafe_a', this);\n        }\n        one_space();\n        this.arity = 'statement';\n        this.block = block(false);\n        if (next_token.id === 'catch') {\n            one_space();\n            advance('catch');\n            discard();\n            one_space();\n            paren = next_token;\n            advance('(');\n            step_in('control');\n            discard();\n            no_space();\n            edge();\n            old_scope = scope;\n            scope = Object.create(old_scope);\n            exception_variable = next_token.value;\n            this.first = exception_variable;\n            if (!next_token.identifier) {\n                warn('expected_identifier_a', next_token);\n            } else {\n                add_label(exception_variable, 'exception');\n            }\n            advance();\n            no_space();\n            step_out(')', paren);\n            discard();\n            one_space();\n            this.second = block(false);\n            scope = old_scope;\n        }\n        if (next_token.id === 'finally') {\n            discard();\n            one_space();\n            advance('finally');\n            discard();\n            one_space();\n            this.third = block(false);\n        } else if (!this.second) {\n            fail('expected_a_b', next_token, 'catch', next_token.value);\n        }\n        return this;\n    });\n\n    labeled_stmt('while', function () {\n        one_space();\n        var paren = next_token;\n        funct['(breakage)'] += 1;\n        funct['(loopage)'] += 1;\n        advance('(');\n        step_in('control');\n        discard();\n        no_space();\n        edge();\n        this.arity = 'statement';\n        this.first = expected_relation(expression(0));\n        if (this.first.id !== 'true') {\n            expected_condition(this.first, bundle.unexpected_a);\n        }\n        no_space();\n        step_out(')', paren);\n        discard();\n        one_space();\n        this.block = block(true);\n        if (this.block.disrupt) {\n            warn('strange_loop', prev_token);\n        }\n        funct['(breakage)'] -= 1;\n        funct['(loopage)'] -= 1;\n        return this;\n    });\n\n    reserve('with');\n\n    labeled_stmt('switch', function () {\n\n// switch.first             the switch expression\n// switch.second            the array of cases. A case is 'case' or 'default' token:\n//    case.first            the array of case expressions\n//    case.second           the array of statements\n// If all of the arrays of statements are disrupt, then the switch is disrupt.\n\n        var particular,\n            the_case = next_token,\n            unbroken = true;\n        funct['(breakage)'] += 1;\n        one_space();\n        advance('(');\n        discard();\n        no_space();\n        step_in();\n        this.arity = 'statement';\n        this.first = expected_condition(expected_relation(expression(0)));\n        no_space();\n        step_out(')', the_case);\n        discard();\n        one_space();\n        advance('{');\n        step_in();\n        this.second = [];\n        while (next_token.id === 'case') {\n            the_case = next_token;\n            the_case.first = [];\n            spaces();\n            edge('case');\n            advance('case');\n            for (;;) {\n                one_space();\n                particular = expression(0);\n                the_case.first.push(particular);\n                if (particular.id === 'NaN') {\n                    warn('unexpected_a', particular);\n                }\n                no_space_only();\n                advance(':');\n                discard();\n                if (next_token.id !== 'case') {\n                    break;\n                }\n                spaces();\n                edge('case');\n                advance('case');\n                discard();\n            }\n            spaces();\n            the_case.second = statements();\n            if (the_case.second && the_case.second.length > 0) {\n                particular = the_case.second[the_case.second.length - 1];\n                if (particular.disrupt) {\n                    if (particular.id === 'break') {\n                        unbroken = false;\n                    }\n                } else {\n                    warn('missing_a_after_b', next_token, 'break', 'case');\n                }\n            } else {\n                warn('empty_case');\n            }\n            this.second.push(the_case);\n        }\n        if (this.second.length === 0) {\n            warn('missing_a', next_token, 'case');\n        }\n        if (next_token.id === 'default') {\n            spaces();\n            the_case = next_token;\n            edge('case');\n            advance('default');\n            discard();\n            no_space_only();\n            advance(':');\n            discard();\n            spaces();\n            the_case.second = statements();\n            if (the_case.second && the_case.second.length > 0) {\n                particular = the_case.second[the_case.second.length - 1];\n                if (unbroken && particular.disrupt && particular.id !== 'break') {\n                    this.disrupt = true;\n                }\n            }\n            this.second.push(the_case);\n        }\n        funct['(breakage)'] -= 1;\n        spaces();\n        step_out('}', this);\n        return this;\n    });\n\n    stmt('debugger', function () {\n        if (!option.debug) {\n            warn('unexpected_a', this);\n        }\n        this.arity = 'statement';\n        return this;\n    });\n\n    labeled_stmt('do', function () {\n        funct['(breakage)'] += 1;\n        funct['(loopage)'] += 1;\n        one_space();\n        this.arity = 'statement';\n        this.block = block(true);\n        if (this.block.disrupt) {\n            warn('strange_loop', prev_token);\n        }\n        one_space();\n        advance('while');\n        discard();\n        var paren = next_token;\n        one_space();\n        advance('(');\n        step_in();\n        discard();\n        no_space();\n        edge();\n        this.first = expected_condition(expected_relation(expression(0)), bundle.unexpected_a);\n        no_space();\n        step_out(')', paren);\n        discard();\n        funct['(breakage)'] -= 1;\n        funct['(loopage)'] -= 1;\n        return this;\n    });\n\n    labeled_stmt('for', function () {\n        var blok, filter, ok = false, paren = next_token, the_in, value;\n        this.arity = 'statement';\n        funct['(breakage)'] += 1;\n        funct['(loopage)'] += 1;\n        advance('(');\n        step_in('control');\n        discard();\n        spaces(this, paren);\n        no_space();\n        if (next_token.id === 'var') {\n            fail('move_var');\n        }\n        edge();\n        if (peek(0).id === 'in') {\n            value = next_token;\n            switch (funct[value.value]) {\n            case 'unused':\n                funct[value.value] = 'var';\n                break;\n            case 'var':\n                break;\n            default:\n                warn('bad_in_a', value);\n            }\n            advance();\n            the_in = next_token;\n            advance('in');\n            the_in.first = value;\n            the_in.second = expression(20);\n            step_out(')', paren);\n            discard();\n            this.first = the_in;\n            blok = block(true);\n            if (!option.forin) {\n                if (blok.length === 1 && typeof blok[0] === 'object' &&\n                        blok[0].value === 'if' && !blok[0]['else']) {\n                    filter = blok[0].first;\n                    while (filter.id === '&&') {\n                        filter = filter.first;\n                    }\n                    switch (filter.id) {\n                    case '===':\n                    case '!==':\n                        ok = filter.first.id === '[' ? (\n                            filter.first.first.value === the_in.second.value &&\n                            filter.first.second.value === the_in.first.value\n                        ) : (\n                            filter.first.id === 'typeof' &&\n                            filter.first.first.id === '[' &&\n                            filter.first.first.first.value === the_in.second.value &&\n                            filter.first.first.second.value === the_in.first.value\n                        );\n                        break;\n                    case '(':\n                        ok = filter.first.id === '.' && ((\n                            filter.first.first.value === the_in.second.value &&\n                            filter.first.second.value === 'hasOwnProperty' &&\n                            filter.second[0].value === the_in.first.value\n                        ) || (\n                            filter.first.first.value === 'ADSAFE' &&\n                            filter.first.second.value === 'has' &&\n                            filter.second[0].value === the_in.second.value &&\n                            filter.second[1].value === the_in.first.value\n                        ) || (\n                            filter.first.first.id === '.' &&\n                            filter.first.first.first.id === '.' &&\n                            filter.first.first.first.first.value === 'Object' &&\n                            filter.first.first.first.second.value === 'prototype' &&\n                            filter.first.first.second.value === 'hasOwnProperty' &&\n                            filter.first.second.value === 'call' &&\n                            filter.second[0].value === the_in.second.value &&\n                            filter.second[1].value === the_in.first.value\n                        ));\n                        break;\n                    }\n                }\n                if (!ok) {\n                    warn('for_if', this);\n                }\n            }\n        } else {\n            if (next_token.id !== ';') {\n                edge();\n                this.first = [];\n                for (;;) {\n                    this.first.push(expression(0, 'for'));\n                    if (next_token.id !== ',') {\n                        break;\n                    }\n                    comma();\n                }\n            }\n            semicolon();\n            if (next_token.id !== ';') {\n                edge();\n                this.second = expected_relation(expression(0));\n                if (this.second.id !== 'true') {\n                    expected_condition(this.second, bundle.unexpected_a);\n                }\n            }\n            semicolon(token);\n            if (next_token.id === ';') {\n                fail('expected_a_b', next_token, ')', ';');\n            }\n            if (next_token.id !== ')') {\n                this.third = [];\n                edge();\n                for (;;) {\n                    this.third.push(expression(0, 'for'));\n                    if (next_token.id !== ',') {\n                        break;\n                    }\n                    comma();\n                }\n            }\n            no_space();\n            step_out(')', paren);\n            discard();\n            one_space();\n            blok = block(true);\n        }\n        if (blok.disrupt) {\n            warn('strange_loop', prev_token);\n        }\n        this.block = blok;\n        funct['(breakage)'] -= 1;\n        funct['(loopage)'] -= 1;\n        return this;\n    });\n\n    disrupt_stmt('break', function () {\n        var label = next_token.value;\n        this.arity = 'statement';\n        if (funct['(breakage)'] === 0) {\n            warn('unexpected_a', this);\n        }\n        if (next_token.identifier && token.line === next_token.line) {\n            one_space_only();\n            if (funct[label] !== 'label') {\n                warn('not_a_label', next_token);\n            } else if (scope[label] !== funct) {\n                warn('not_a_scope', next_token);\n            }\n            this.first = next_token;\n            advance();\n        }\n        return this;\n    });\n\n    disrupt_stmt('continue', function () {\n        if (!option['continue']) {\n            warn('unexpected_a', this);\n        }\n        var label = next_token.value;\n        this.arity = 'statement';\n        if (funct['(breakage)'] === 0) {\n            warn('unexpected_a', this);\n        }\n        if (next_token.identifier && token.line === next_token.line) {\n            one_space_only();\n            if (funct[label] !== 'label') {\n                warn('not_a_label', next_token);\n            } else if (scope[label] !== funct) {\n                warn('not_a_scope', next_token);\n            }\n            this.first = next_token;\n            advance();\n        }\n        return this;\n    });\n\n    disrupt_stmt('return', function () {\n        this.arity = 'statement';\n        if (next_token.id !== ';' && next_token.line === token.line) {\n            one_space_only();\n            if (next_token.id === '/' || next_token.id === '(regexp)') {\n                warn('wrap_regexp');\n            }\n            this.first = expression(20);\n        }\n        return this;\n    });\n\n    disrupt_stmt('throw', function () {\n        this.arity = 'statement';\n        one_space_only();\n        this.first = expression(20);\n        return this;\n    });\n\n\n//  Superfluous reserved words\n\n    reserve('class');\n    reserve('const');\n    reserve('enum');\n    reserve('export');\n    reserve('extends');\n    reserve('import');\n    reserve('super');\n\n// Harmony reserved words\n\n    reserve('let');\n    reserve('yield');\n    reserve('implements');\n    reserve('interface');\n    reserve('package');\n    reserve('private');\n    reserve('protected');\n    reserve('public');\n    reserve('static');\n\n\n// Parse JSON\n\n    function json_value() {\n\n        function json_object() {\n            var brace = next_token, object = {};\n            advance('{');\n            if (next_token.id !== '}') {\n                while (next_token.id !== '(end)') {\n                    while (next_token.id === ',') {\n                        warn('unexpected_a', next_token);\n                        comma();\n                    }\n                    if (next_token.arity !== 'string') {\n                        warn('expected_string_a');\n                    }\n                    if (object[next_token.value] === true) {\n                        warn('duplicate_a');\n                    } else if (next_token.value === '__proto__') {\n                        warn('dangling_a');\n                    } else {\n                        object[next_token.value] = true;\n                    }\n                    advance();\n                    advance(':');\n                    json_value();\n                    if (next_token.id !== ',') {\n                        break;\n                    }\n                    comma();\n                    if (next_token.id === '}') {\n                        warn('unexpected_a', token);\n                        break;\n                    }\n                }\n            }\n            advance('}', brace);\n        }\n\n        function json_array() {\n            var bracket = next_token;\n            advance('[');\n            if (next_token.id !== ']') {\n                while (next_token.id !== '(end)') {\n                    while (next_token.id === ',') {\n                        warn('unexpected_a', next_token);\n                        comma();\n                    }\n                    json_value();\n                    if (next_token.id !== ',') {\n                        break;\n                    }\n                    comma();\n                    if (next_token.id === ']') {\n                        warn('unexpected_a', token);\n                        break;\n                    }\n                }\n            }\n            advance(']', bracket);\n        }\n\n        switch (next_token.id) {\n        case '{':\n            json_object();\n            break;\n        case '[':\n            json_array();\n            break;\n        case 'true':\n        case 'false':\n        case 'null':\n        case '(number)':\n        case '(string)':\n            advance();\n            break;\n        case '-':\n            advance('-');\n            no_space_only();\n            advance('(number)');\n            break;\n        default:\n            fail('unexpected_a');\n        }\n    }\n\n\n// CSS parsing.\n\n    function css_name() {\n        if (next_token.identifier) {\n            advance();\n            return true;\n        }\n    }\n\n\n    function css_number() {\n        if (next_token.id === '-') {\n            advance('-');\n            no_space_only();\n        }\n        if (next_token.arity === 'number') {\n            advance('(number)');\n            return true;\n        }\n    }\n\n\n    function css_string() {\n        if (next_token.arity === 'string') {\n            advance();\n            return true;\n        }\n    }\n\n    function css_color() {\n        var i, number, paren, value;\n        if (next_token.identifier) {\n            value = next_token.value;\n            if (value === 'rgb' || value === 'rgba') {\n                advance();\n                paren = next_token;\n                advance('(');\n                for (i = 0; i < 3; i += 1) {\n                    if (i) {\n                        comma();\n                    }\n                    number = next_token.value;\n                    if (next_token.arity !== 'number' || number < 0) {\n                        warn('expected_positive_a', next_token);\n                        advance();\n                    } else {\n                        advance();\n                        if (next_token.id === '%') {\n                            advance('%');\n                            if (number > 100) {\n                                warn('expected_percent_a', token, number);\n                            }\n                        } else {\n                            if (number > 255) {\n                                warn('expected_small_a', token, number);\n                            }\n                        }\n                    }\n                }\n                if (value === 'rgba') {\n                    comma();\n                    number = +next_token.value;\n                    if (next_token.arity !== 'number' || number < 0 || number > 1) {\n                        warn('expected_fraction_a', next_token);\n                    }\n                    advance();\n                    if (next_token.id === '%') {\n                        warn('unexpected_a');\n                        advance('%');\n                    }\n                }\n                advance(')', paren);\n                return true;\n            } else if (css_colorData[next_token.value] === true) {\n                advance();\n                return true;\n            }\n        } else if (next_token.id === '(color)') {\n            advance();\n            return true;\n        }\n        return false;\n    }\n\n\n    function css_length() {\n        if (next_token.id === '-') {\n            advance('-');\n            no_space_only();\n        }\n        if (next_token.arity === 'number') {\n            advance();\n            if (next_token.arity !== 'string' &&\n                    css_lengthData[next_token.value] === true) {\n                no_space_only();\n                advance();\n            } else if (+token.value !== 0) {\n                warn('expected_linear_a');\n            }\n            return true;\n        }\n        return false;\n    }\n\n\n    function css_line_height() {\n        if (next_token.id === '-') {\n            advance('-');\n            no_space_only();\n        }\n        if (next_token.arity === 'number') {\n            advance();\n            if (next_token.arity !== 'string' &&\n                    css_lengthData[next_token.value] === true) {\n                no_space_only();\n                advance();\n            }\n            return true;\n        }\n        return false;\n    }\n\n\n    function css_width() {\n        if (next_token.identifier) {\n            switch (next_token.value) {\n            case 'thin':\n            case 'medium':\n            case 'thick':\n                advance();\n                return true;\n            }\n        } else {\n            return css_length();\n        }\n    }\n\n\n    function css_margin() {\n        if (next_token.identifier) {\n            if (next_token.value === 'auto') {\n                advance();\n                return true;\n            }\n        } else {\n            return css_length();\n        }\n    }\n\n    function css_attr() {\n        if (next_token.identifier && next_token.value === 'attr') {\n            advance();\n            advance('(');\n            if (!next_token.identifier) {\n                warn('expected_name_a');\n            }\n            advance();\n            advance(')');\n            return true;\n        }\n        return false;\n    }\n\n\n    function css_comma_list() {\n        while (next_token.id !== ';') {\n            if (!css_name() && !css_string()) {\n                warn('expected_name_a');\n            }\n            if (next_token.id !== ',') {\n                return true;\n            }\n            comma();\n        }\n    }\n\n\n    function css_counter() {\n        if (next_token.identifier && next_token.value === 'counter') {\n            advance();\n            advance('(');\n            advance();\n            if (next_token.id === ',') {\n                comma();\n                if (next_token.arity !== 'string') {\n                    warn('expected_string_a');\n                }\n                advance();\n            }\n            advance(')');\n            return true;\n        }\n        if (next_token.identifier && next_token.value === 'counters') {\n            advance();\n            advance('(');\n            if (!next_token.identifier) {\n                warn('expected_name_a');\n            }\n            advance();\n            if (next_token.id === ',') {\n                comma();\n                if (next_token.arity !== 'string') {\n                    warn('expected_string_a');\n                }\n                advance();\n            }\n            if (next_token.id === ',') {\n                comma();\n                if (next_token.arity !== 'string') {\n                    warn('expected_string_a');\n                }\n                advance();\n            }\n            advance(')');\n            return true;\n        }\n        return false;\n    }\n\n\n    function css_shape() {\n        var i;\n        if (next_token.identifier && next_token.value === 'rect') {\n            advance();\n            advance('(');\n            for (i = 0; i < 4; i += 1) {\n                if (!css_length()) {\n                    warn('expected_number_a');\n                    break;\n                }\n            }\n            advance(')');\n            return true;\n        }\n        return false;\n    }\n\n\n    function css_url() {\n        var c, url;\n        if (next_token.identifier && next_token.value === 'url') {\n            next_token = lex.range('(', ')');\n            url = next_token.value;\n            c = url.charAt(0);\n            if (c === '\"' || c === '\\'') {\n                if (url.slice(-1) !== c) {\n                    warn('bad_url');\n                } else {\n                    url = url.slice(1, -1);\n                    if (url.indexOf(c) >= 0) {\n                        warn('bad_url');\n                    }\n                }\n            }\n            if (!url) {\n                warn('missing_url');\n            }\n            if (option.safe && ux.test(url)) {\n                fail('adsafe_a', next_token, url);\n            }\n            urls.push(url);\n            advance();\n            return true;\n        }\n        return false;\n    }\n\n\n    css_any = [css_url, function () {\n        for (;;) {\n            if (next_token.identifier) {\n                switch (next_token.value.toLowerCase()) {\n                case 'url':\n                    css_url();\n                    break;\n                case 'expression':\n                    warn('unexpected_a');\n                    advance();\n                    break;\n                default:\n                    advance();\n                }\n            } else {\n                if (next_token.id === ';' || next_token.id === '!'  ||\n                        next_token.id === '(end)' || next_token.id === '}') {\n                    return true;\n                }\n                advance();\n            }\n        }\n    }];\n\n\n    css_border_style = [\n        'none', 'dashed', 'dotted', 'double', 'groove',\n        'hidden', 'inset', 'outset', 'ridge', 'solid'\n    ];\n\n    css_break = [\n        'auto', 'always', 'avoid', 'left', 'right'\n    ];\n\n    css_media = {\n        'all': true,\n        'braille': true,\n        'embossed': true,\n        'handheld': true,\n        'print': true,\n        'projection': true,\n        'screen': true,\n        'speech': true,\n        'tty': true,\n        'tv': true\n    };\n\n    css_overflow = [\n        'auto', 'hidden', 'scroll', 'visible'\n    ];\n\n    css_attribute_data = {\n        background: [\n            true, 'background-attachment', 'background-color',\n            'background-image', 'background-position', 'background-repeat'\n        ],\n        'background-attachment': ['scroll', 'fixed'],\n        'background-color': ['transparent', css_color],\n        'background-image': ['none', css_url],\n        'background-position': [\n            2, [css_length, 'top', 'bottom', 'left', 'right', 'center']\n        ],\n        'background-repeat': [\n            'repeat', 'repeat-x', 'repeat-y', 'no-repeat'\n        ],\n        'border': [true, 'border-color', 'border-style', 'border-width'],\n        'border-bottom': [\n            true, 'border-bottom-color', 'border-bottom-style',\n            'border-bottom-width'\n        ],\n        'border-bottom-color': css_color,\n        'border-bottom-style': css_border_style,\n        'border-bottom-width': css_width,\n        'border-collapse': ['collapse', 'separate'],\n        'border-color': ['transparent', 4, css_color],\n        'border-left': [\n            true, 'border-left-color', 'border-left-style', 'border-left-width'\n        ],\n        'border-left-color': css_color,\n        'border-left-style': css_border_style,\n        'border-left-width': css_width,\n        'border-right': [\n            true, 'border-right-color', 'border-right-style',\n            'border-right-width'\n        ],\n        'border-right-color': css_color,\n        'border-right-style': css_border_style,\n        'border-right-width': css_width,\n        'border-spacing': [2, css_length],\n        'border-style': [4, css_border_style],\n        'border-top': [\n            true, 'border-top-color', 'border-top-style', 'border-top-width'\n        ],\n        'border-top-color': css_color,\n        'border-top-style': css_border_style,\n        'border-top-width': css_width,\n        'border-width': [4, css_width],\n        bottom: [css_length, 'auto'],\n        'caption-side' : ['bottom', 'left', 'right', 'top'],\n        clear: ['both', 'left', 'none', 'right'],\n        clip: [css_shape, 'auto'],\n        color: css_color,\n        content: [\n            'open-quote', 'close-quote', 'no-open-quote', 'no-close-quote',\n            css_string, css_url, css_counter, css_attr\n        ],\n        'counter-increment': [\n            css_name, 'none'\n        ],\n        'counter-reset': [\n            css_name, 'none'\n        ],\n        cursor: [\n            css_url, 'auto', 'crosshair', 'default', 'e-resize', 'help', 'move',\n            'n-resize', 'ne-resize', 'nw-resize', 'pointer', 's-resize',\n            'se-resize', 'sw-resize', 'w-resize', 'text', 'wait'\n        ],\n        direction: ['ltr', 'rtl'],\n        display: [\n            'block', 'compact', 'inline', 'inline-block', 'inline-table',\n            'list-item', 'marker', 'none', 'run-in', 'table', 'table-caption',\n            'table-cell', 'table-column', 'table-column-group',\n            'table-footer-group', 'table-header-group', 'table-row',\n            'table-row-group'\n        ],\n        'empty-cells': ['show', 'hide'],\n        'float': ['left', 'none', 'right'],\n        font: [\n            'caption', 'icon', 'menu', 'message-box', 'small-caption',\n            'status-bar', true, 'font-size', 'font-style', 'font-weight',\n            'font-family'\n        ],\n        'font-family': css_comma_list,\n        'font-size': [\n            'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large',\n            'xx-large', 'larger', 'smaller', css_length\n        ],\n        'font-size-adjust': ['none', css_number],\n        'font-stretch': [\n            'normal', 'wider', 'narrower', 'ultra-condensed',\n            'extra-condensed', 'condensed', 'semi-condensed',\n            'semi-expanded', 'expanded', 'extra-expanded'\n        ],\n        'font-style': [\n            'normal', 'italic', 'oblique'\n        ],\n        'font-variant': [\n            'normal', 'small-caps'\n        ],\n        'font-weight': [\n            'normal', 'bold', 'bolder', 'lighter', css_number\n        ],\n        height: [css_length, 'auto'],\n        left: [css_length, 'auto'],\n        'letter-spacing': ['normal', css_length],\n        'line-height': ['normal', css_line_height],\n        'list-style': [\n            true, 'list-style-image', 'list-style-position', 'list-style-type'\n        ],\n        'list-style-image': ['none', css_url],\n        'list-style-position': ['inside', 'outside'],\n        'list-style-type': [\n            'circle', 'disc', 'square', 'decimal', 'decimal-leading-zero',\n            'lower-roman', 'upper-roman', 'lower-greek', 'lower-alpha',\n            'lower-latin', 'upper-alpha', 'upper-latin', 'hebrew', 'katakana',\n            'hiragana-iroha', 'katakana-oroha', 'none'\n        ],\n        margin: [4, css_margin],\n        'margin-bottom': css_margin,\n        'margin-left': css_margin,\n        'margin-right': css_margin,\n        'margin-top': css_margin,\n        'marker-offset': [css_length, 'auto'],\n        'max-height': [css_length, 'none'],\n        'max-width': [css_length, 'none'],\n        'min-height': css_length,\n        'min-width': css_length,\n        opacity: css_number,\n        outline: [true, 'outline-color', 'outline-style', 'outline-width'],\n        'outline-color': ['invert', css_color],\n        'outline-style': [\n            'dashed', 'dotted', 'double', 'groove', 'inset', 'none',\n            'outset', 'ridge', 'solid'\n        ],\n        'outline-width': css_width,\n        overflow: css_overflow,\n        'overflow-x': css_overflow,\n        'overflow-y': css_overflow,\n        padding: [4, css_length],\n        'padding-bottom': css_length,\n        'padding-left': css_length,\n        'padding-right': css_length,\n        'padding-top': css_length,\n        'page-break-after': css_break,\n        'page-break-before': css_break,\n        position: ['absolute', 'fixed', 'relative', 'static'],\n        quotes: [8, css_string],\n        right: [css_length, 'auto'],\n        'table-layout': ['auto', 'fixed'],\n        'text-align': ['center', 'justify', 'left', 'right'],\n        'text-decoration': [\n            'none', 'underline', 'overline', 'line-through', 'blink'\n        ],\n        'text-indent': css_length,\n        'text-shadow': ['none', 4, [css_color, css_length]],\n        'text-transform': ['capitalize', 'uppercase', 'lowercase', 'none'],\n        top: [css_length, 'auto'],\n        'unicode-bidi': ['normal', 'embed', 'bidi-override'],\n        'vertical-align': [\n            'baseline', 'bottom', 'sub', 'super', 'top', 'text-top', 'middle',\n            'text-bottom', css_length\n        ],\n        visibility: ['visible', 'hidden', 'collapse'],\n        'white-space': [\n            'normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'inherit'\n        ],\n        width: [css_length, 'auto'],\n        'word-spacing': ['normal', css_length],\n        'word-wrap': ['break-word', 'normal'],\n        'z-index': ['auto', css_number]\n    };\n\n    function style_attribute() {\n        var v;\n        while (next_token.id === '*' || next_token.id === '#' ||\n                next_token.value === '_') {\n            if (!option.css) {\n                warn('unexpected_a');\n            }\n            advance();\n        }\n        if (next_token.id === '-') {\n            if (!option.css) {\n                warn('unexpected_a');\n            }\n            advance('-');\n            if (!next_token.identifier) {\n                warn('expected_nonstandard_style_attribute');\n            }\n            advance();\n            return css_any;\n        } else {\n            if (!next_token.identifier) {\n                warn('expected_style_attribute');\n            } else {\n                if (Object.prototype.hasOwnProperty.call(css_attribute_data, next_token.value)) {\n                    v = css_attribute_data[next_token.value];\n                } else {\n                    v = css_any;\n                    if (!option.css) {\n                        warn('unrecognized_style_attribute_a');\n                    }\n                }\n            }\n            advance();\n            return v;\n        }\n    }\n\n\n    function style_value(v) {\n        var i = 0,\n            n,\n            once,\n            match,\n            round,\n            start = 0,\n            vi;\n        switch (typeof v) {\n        case 'function':\n            return v();\n        case 'string':\n            if (next_token.identifier && next_token.value === v) {\n                advance();\n                return true;\n            }\n            return false;\n        }\n        for (;;) {\n            if (i >= v.length) {\n                return false;\n            }\n            vi = v[i];\n            i += 1;\n            if (vi === true) {\n                break;\n            } else if (typeof vi === 'number') {\n                n = vi;\n                vi = v[i];\n                i += 1;\n            } else {\n                n = 1;\n            }\n            match = false;\n            while (n > 0) {\n                if (style_value(vi)) {\n                    match = true;\n                    n -= 1;\n                } else {\n                    break;\n                }\n            }\n            if (match) {\n                return true;\n            }\n        }\n        start = i;\n        once = [];\n        for (;;) {\n            round = false;\n            for (i = start; i < v.length; i += 1) {\n                if (!once[i]) {\n                    if (style_value(css_attribute_data[v[i]])) {\n                        match = true;\n                        round = true;\n                        once[i] = true;\n                        break;\n                    }\n                }\n            }\n            if (!round) {\n                return match;\n            }\n        }\n    }\n\n    function style_child() {\n        if (next_token.arity === 'number') {\n            advance();\n            if (next_token.value === 'n' && next_token.identifier) {\n                no_space_only();\n                advance();\n                if (next_token.id === '+') {\n                    no_space_only();\n                    advance('+');\n                    no_space_only();\n                    advance('(number)');\n                }\n            }\n            return;\n        } else {\n            if (next_token.identifier &&\n                    (next_token.value === 'odd' || next_token.value === 'even')) {\n                advance();\n                return;\n            }\n        }\n        warn('unexpected_a');\n    }\n\n    function substyle() {\n        var v;\n        for (;;) {\n            if (next_token.id === '}' || next_token.id === '(end)' ||\n                    (xquote && next_token.id === xquote)) {\n                return;\n            }\n            while (next_token.id === ';') {\n                warn('unexpected_a');\n                semicolon();\n            }\n            v = style_attribute();\n            advance(':');\n            if (next_token.identifier && next_token.value === 'inherit') {\n                advance();\n            } else {\n                if (!style_value(v)) {\n                    warn('unexpected_a');\n                    advance();\n                }\n            }\n            if (next_token.id === '!') {\n                advance('!');\n                no_space_only();\n                if (next_token.identifier && next_token.value === 'important') {\n                    advance();\n                } else {\n                    warn('expected_a_b',\n                        next_token, 'important', next_token.value);\n                }\n            }\n            if (next_token.id === '}' || next_token.id === xquote) {\n                warn('expected_a_b', next_token, ';', next_token.value);\n            } else {\n                semicolon();\n            }\n        }\n    }\n\n    function style_selector() {\n        if (next_token.identifier) {\n            if (!Object.prototype.hasOwnProperty.call(html_tag, option.cap ?\n                    next_token.value.toLowerCase() : next_token.value)) {\n                warn('expected_tagname_a');\n            }\n            advance();\n        } else {\n            switch (next_token.id) {\n            case '>':\n            case '+':\n                advance();\n                style_selector();\n                break;\n            case ':':\n                advance(':');\n                switch (next_token.value) {\n                case 'active':\n                case 'after':\n                case 'before':\n                case 'checked':\n                case 'disabled':\n                case 'empty':\n                case 'enabled':\n                case 'first-child':\n                case 'first-letter':\n                case 'first-line':\n                case 'first-of-type':\n                case 'focus':\n                case 'hover':\n                case 'last-child':\n                case 'last-of-type':\n                case 'link':\n                case 'only-of-type':\n                case 'root':\n                case 'target':\n                case 'visited':\n                    advance();\n                    break;\n                case 'lang':\n                    advance();\n                    advance('(');\n                    if (!next_token.identifier) {\n                        warn('expected_lang_a');\n                    }\n                    advance(')');\n                    break;\n                case 'nth-child':\n                case 'nth-last-child':\n                case 'nth-last-of-type':\n                case 'nth-of-type':\n                    advance();\n                    advance('(');\n                    style_child();\n                    advance(')');\n                    break;\n                case 'not':\n                    advance();\n                    advance('(');\n                    if (next_token.id === ':' && peek(0).value === 'not') {\n                        warn('not');\n                    }\n                    style_selector();\n                    advance(')');\n                    break;\n                default:\n                    warn('expected_pseudo_a');\n                }\n                break;\n            case '#':\n                advance('#');\n                if (!next_token.identifier) {\n                    warn('expected_id_a');\n                }\n                advance();\n                break;\n            case '*':\n                advance('*');\n                break;\n            case '.':\n                advance('.');\n                if (!next_token.identifier) {\n                    warn('expected_class_a');\n                }\n                advance();\n                break;\n            case '[':\n                advance('[');\n                if (!next_token.identifier) {\n                    warn('expected_attribute_a');\n                }\n                advance();\n                if (next_token.id === '=' || next_token.value === '~=' ||\n                        next_token.value === '$=' ||\n                        next_token.value === '|=' ||\n                        next_token.id === '*=' ||\n                        next_token.id === '^=') {\n                    advance();\n                    if (next_token.arity !== 'string') {\n                        warn('expected_string_a');\n                    }\n                    advance();\n                }\n                advance(']');\n                break;\n            default:\n                fail('expected_selector_a');\n            }\n        }\n    }\n\n    function style_pattern() {\n        if (next_token.id === '{') {\n            warn('expected_style_pattern');\n        }\n        for (;;) {\n            style_selector();\n            if (next_token.id === '</' || next_token.id === '{' ||\n                    next_token.id === '(end)') {\n                return '';\n            }\n            if (next_token.id === ',') {\n                comma();\n            }\n        }\n    }\n\n    function style_list() {\n        while (next_token.id !== '</' && next_token.id !== '(end)') {\n            style_pattern();\n            xmode = 'styleproperty';\n            if (next_token.id === ';') {\n                semicolon();\n            } else {\n                advance('{');\n                substyle();\n                xmode = 'style';\n                advance('}');\n            }\n        }\n    }\n\n    function styles() {\n        var i;\n        while (next_token.id === '@') {\n            i = peek();\n            advance('@');\n            if (next_token.identifier) {\n                switch (next_token.value) {\n                case 'import':\n                    advance();\n                    if (!css_url()) {\n                        warn('expected_a_b',\n                            next_token, 'url', next_token.value);\n                        advance();\n                    }\n                    semicolon();\n                    break;\n                case 'media':\n                    advance();\n                    for (;;) {\n                        if (!next_token.identifier || css_media[next_token.value] === true) {\n                            fail('expected_media_a');\n                        }\n                        advance();\n                        if (next_token.id !== ',') {\n                            break;\n                        }\n                        comma();\n                    }\n                    advance('{');\n                    style_list();\n                    advance('}');\n                    break;\n                default:\n                    warn('expected_at_a');\n                }\n            } else {\n                warn('expected_at_a');\n            }\n        }\n        style_list();\n    }\n\n\n// Parse HTML\n\n    function do_begin(n) {\n        if (n !== 'html' && !option.fragment) {\n            if (n === 'div' && option.adsafe) {\n                fail('adsafe_fragment');\n            } else {\n                fail('expected_a_b', token, 'html', n);\n            }\n        }\n        if (option.adsafe) {\n            if (n === 'html') {\n                fail('adsafe_html', token);\n            }\n            if (option.fragment) {\n                if (n !== 'div') {\n                    fail('adsafe_div', token);\n                }\n            } else {\n                fail('adsafe_fragment', token);\n            }\n        }\n        option.browser = true;\n        assume();\n    }\n\n    function do_attribute(n, a, v) {\n        var u, x;\n        if (a === 'id') {\n            u = typeof v === 'string' ? v.toUpperCase() : '';\n            if (ids[u] === true) {\n                warn('duplicate_a', next_token, v);\n            }\n            if (!/^[A-Za-z][A-Za-z0-9._:\\-]*$/.test(v)) {\n                warn('bad_id_a', next_token, v);\n            } else if (option.adsafe) {\n                if (adsafe_id) {\n                    if (v.slice(0, adsafe_id.length) !== adsafe_id) {\n                        warn('adsafe_prefix_a', next_token, adsafe_id);\n                    } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) {\n                        warn('adsafe_bad_id');\n                    }\n                } else {\n                    adsafe_id = v;\n                    if (!/^[A-Z]+_$/.test(v)) {\n                        warn('adsafe_bad_id');\n                    }\n                }\n            }\n            x = v.search(dx);\n            if (x >= 0) {\n                warn('unexpected_char_a_b', token, v.charAt(x), a);\n            }\n            ids[u] = true;\n        } else if (a === 'class' || a === 'type' || a === 'name') {\n            x = v.search(qx);\n            if (x >= 0) {\n                warn('unexpected_char_a_b', token, v.charAt(x), a);\n            }\n            ids[u] = true;\n        } else if (a === 'href' || a === 'background' ||\n                a === 'content' || a === 'data' ||\n                a.indexOf('src') >= 0 || a.indexOf('url') >= 0) {\n            if (option.safe && ux.test(v)) {\n                fail('bad_url', next_token, v);\n            }\n            urls.push(v);\n        } else if (a === 'for') {\n            if (option.adsafe) {\n                if (adsafe_id) {\n                    if (v.slice(0, adsafe_id.length) !== adsafe_id) {\n                        warn('adsafe_prefix_a', next_token, adsafe_id);\n                    } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) {\n                        warn('adsafe_bad_id');\n                    }\n                } else {\n                    warn('adsafe_bad_id');\n                }\n            }\n        } else if (a === 'name') {\n            if (option.adsafe && v.indexOf('_') >= 0) {\n                warn('adsafe_name_a', next_token, v);\n            }\n        }\n    }\n\n    function do_tag(name, attribute) {\n        var i, tag = html_tag[name], script, x;\n        src = false;\n        if (!tag) {\n            fail(\n                bundle.unrecognized_tag_a,\n                next_token,\n                name === name.toLowerCase() ? name : name + ' (capitalization error)'\n            );\n        }\n        if (stack.length > 0) {\n            if (name === 'html') {\n                fail('unexpected_a', token, name);\n            }\n            x = tag.parent;\n            if (x) {\n                if (x.indexOf(' ' + stack[stack.length - 1].name + ' ') < 0) {\n                    fail('tag_a_in_b', token, name, x);\n                }\n            } else if (!option.adsafe && !option.fragment) {\n                i = stack.length;\n                do {\n                    if (i <= 0) {\n                        fail('tag_a_in_b', token, name, 'body');\n                    }\n                    i -= 1;\n                } while (stack[i].name !== 'body');\n            }\n        }\n        switch (name) {\n        case 'div':\n            if (option.adsafe && stack.length === 1 && !adsafe_id) {\n                warn('adsafe_missing_id');\n            }\n            break;\n        case 'script':\n            xmode = 'script';\n            advance('>');\n            if (attribute.lang) {\n                warn('lang', token);\n            }\n            if (option.adsafe && stack.length !== 1) {\n                warn('adsafe_placement', token);\n            }\n            if (attribute.src) {\n                if (option.adsafe && (!adsafe_may || !approved[attribute.src])) {\n                    warn('adsafe_source', token);\n                }\n                if (attribute.type) {\n                    warn('type', token);\n                }\n            } else {\n                step_in(next_token.from);\n                edge();\n                use_strict();\n                adsafe_top = true;\n                script = statements();\n\n// JSLint is also the static analyzer for ADsafe. See www.ADsafe.org.\n\n                if (option.adsafe) {\n                    if (adsafe_went) {\n                        fail('adsafe_script', token);\n                    }\n                    if (script.length !== 1 ||\n                            aint(script[0],             'id',    '(') ||\n                            aint(script[0].first,       'id',    '.') ||\n                            aint(script[0].first.first, 'value', 'ADSAFE') ||\n                            aint(script[0].second[0],   'value', adsafe_id)) {\n                        fail('adsafe_id_go');\n                    }\n                    switch (script[0].first.second.value) {\n                    case 'id':\n                        if (adsafe_may || script[0].second.length !== 1) {\n                            fail('adsafe_id', next_token);\n                        }\n                        adsafe_may = true;\n                        break;\n                    case 'go':\n                        if (!adsafe_may) {\n                            fail('adsafe_id');\n                        }\n                        if (script[0].second.length !== 2 ||\n                                aint(script[0].second[1], 'id', 'function') ||\n                                script[0].second[1].first.length !== 2 ||\n                                aint(script[0].second[1].first[0], 'value', 'dom') ||\n                                aint(script[0].second[1].first[1], 'value', 'lib')) {\n                            fail('adsafe_go', next_token);\n                        }\n                        adsafe_went = true;\n                        break;\n                    default:\n                        fail('adsafe_id_go');\n                    }\n                }\n                indent = null;\n            }\n            xmode = 'html';\n            advance('</');\n            if (!next_token.identifier && next_token.value !== 'script') {\n                warn('expected_a_b', next_token, 'script', next_token.value);\n            }\n            advance();\n            xmode = 'outer';\n            break;\n        case 'style':\n            xmode = 'style';\n            advance('>');\n            styles();\n            xmode = 'html';\n            advance('</');\n            if (!next_token.identifier && next_token.value !== 'style') {\n                warn('expected_a_b', next_token, 'style', next_token.value);\n            }\n            advance();\n            xmode = 'outer';\n            break;\n        case 'input':\n            switch (attribute.type) {\n            case 'radio':\n            case 'checkbox':\n            case 'button':\n            case 'reset':\n            case 'submit':\n                break;\n            case 'text':\n            case 'file':\n            case 'password':\n            case 'file':\n            case 'hidden':\n            case 'image':\n                if (option.adsafe && attribute.autocomplete !== 'off') {\n                    warn('adsafe_autocomplete');\n                }\n                break;\n            default:\n                warn('bad_type');\n            }\n            break;\n        case 'applet':\n        case 'body':\n        case 'embed':\n        case 'frame':\n        case 'frameset':\n        case 'head':\n        case 'iframe':\n        case 'noembed':\n        case 'noframes':\n        case 'object':\n        case 'param':\n            if (option.adsafe) {\n                warn('adsafe_tag', next_token, name);\n            }\n            break;\n        }\n    }\n\n\n    function closetag(name) {\n        return '</' + name + '>';\n    }\n\n    function html() {\n        var attribute, attributes, is_empty, name, old_white = option.white,\n            quote, tag_name, tag, wmode;\n        xmode = 'html';\n        xquote = '';\n        stack = null;\n        for (;;) {\n            switch (next_token.value) {\n            case '<':\n                xmode = 'html';\n                advance('<');\n                attributes = {};\n                tag_name = next_token;\n                if (!tag_name.identifier) {\n                    warn('bad_name_a', tag_name);\n                }\n                name = tag_name.value;\n                if (option.cap) {\n                    name = name.toLowerCase();\n                }\n                tag_name.name = name;\n                advance();\n                if (!stack) {\n                    stack = [];\n                    do_begin(name);\n                }\n                tag = html_tag[name];\n                if (typeof tag !== 'object') {\n                    fail('unrecognized_tag_a', tag_name, name);\n                }\n                is_empty = tag.empty;\n                tag_name.type = name;\n                for (;;) {\n                    if (next_token.id === '/') {\n                        advance('/');\n                        if (next_token.id !== '>') {\n                            warn('expected_a_b', next_token, '>', next_token.value);\n                        }\n                        break;\n                    }\n                    if (next_token.id && next_token.id.substr(0, 1) === '>') {\n                        break;\n                    }\n                    if (!next_token.identifier) {\n                        if (next_token.id === '(end)' || next_token.id === '(error)') {\n                            warn('expected_a_b', next_token, '>', next_token.value);\n                        }\n                        warn('bad_name_a');\n                    }\n                    option.white = true;\n                    spaces();\n                    attribute = next_token.value;\n                    option.white = old_white;\n                    advance();\n                    if (!option.cap && attribute !== attribute.toLowerCase()) {\n                        warn('attribute_case_a', token);\n                    }\n                    attribute = attribute.toLowerCase();\n                    xquote = '';\n                    if (Object.prototype.hasOwnProperty.call(attributes, attribute)) {\n                        warn('duplicate_a', token, attribute);\n                    }\n                    if (attribute.slice(0, 2) === 'on') {\n                        if (!option.on) {\n                            warn('html_handlers');\n                        }\n                        xmode = 'scriptstring';\n                        advance('=');\n                        quote = next_token.id;\n                        if (quote !== '\"' && quote !== '\\'') {\n                            fail('expected_a_b', next_token, '\"', next_token.value);\n                        }\n                        xquote = quote;\n                        wmode = option.white;\n                        option.white = false;\n                        advance(quote);\n                        use_strict();\n                        statements();\n                        option.white = wmode;\n                        if (next_token.id !== quote) {\n                            fail('expected_a_b', next_token, quote, next_token.value);\n                        }\n                        xmode = 'html';\n                        xquote = '';\n                        advance(quote);\n                        tag = false;\n                    } else if (attribute === 'style') {\n                        xmode = 'scriptstring';\n                        advance('=');\n                        quote = next_token.id;\n                        if (quote !== '\"' && quote !== '\\'') {\n                            fail('expected_a_b', next_token, '\"', next_token.value);\n                        }\n                        xmode = 'styleproperty';\n                        xquote = quote;\n                        advance(quote);\n                        substyle();\n                        xmode = 'html';\n                        xquote = '';\n                        advance(quote);\n                        tag = false;\n                    } else {\n                        if (next_token.id === '=') {\n                            advance('=');\n                            tag = next_token.value;\n                            if (!next_token.identifier &&\n                                    next_token.id !== '\"' &&\n                                    next_token.id !== '\\'' &&\n                                    next_token.arity !== 'string' &&\n                                    next_token.arity !== 'number' &&\n                                    next_token.id !== '(color)') {\n                                warn('expected_attribute_value_a', token, attribute);\n                            }\n                            advance();\n                        } else {\n                            tag = true;\n                        }\n                    }\n                    attributes[attribute] = tag;\n                    do_attribute(name, attribute, tag);\n                }\n                do_tag(name, attributes);\n                if (!is_empty) {\n                    stack.push(tag_name);\n                }\n                xmode = 'outer';\n                advance('>');\n                break;\n            case '</':\n                xmode = 'html';\n                advance('</');\n                if (!next_token.identifier) {\n                    warn('bad_name_a');\n                }\n                name = next_token.value;\n                if (option.cap) {\n                    name = name.toLowerCase();\n                }\n                advance();\n                if (!stack) {\n                    fail('unexpected_a', next_token, closetag(name));\n                }\n                tag_name = stack.pop();\n                if (!tag_name) {\n                    fail('unexpected_a', next_token, closetag(name));\n                }\n                if (tag_name.name !== name) {\n                    fail('expected_a_b',\n                        next_token, closetag(tag_name.name), closetag(name));\n                }\n                if (next_token.id !== '>') {\n                    fail('expected_a_b', next_token, '>', next_token.value);\n                }\n                xmode = 'outer';\n                advance('>');\n                break;\n            case '<!':\n                if (option.safe) {\n                    warn('adsafe_a');\n                }\n                xmode = 'html';\n                for (;;) {\n                    advance();\n                    if (next_token.id === '>' || next_token.id === '(end)') {\n                        break;\n                    }\n                    if (next_token.value.indexOf('--') >= 0) {\n                        fail('unexpected_a', next_token, '--');\n                    }\n                    if (next_token.value.indexOf('<') >= 0) {\n                        fail('unexpected_a', next_token, '<');\n                    }\n                    if (next_token.value.indexOf('>') >= 0) {\n                        fail('unexpected_a', next_token, '>');\n                    }\n                }\n                xmode = 'outer';\n                advance('>');\n                break;\n            case '(end)':\n                return;\n            default:\n                if (next_token.id === '(end)') {\n                    fail('missing_a', next_token,\n                        '</' + stack[stack.length - 1].value + '>');\n                } else {\n                    advance();\n                }\n            }\n            if (stack && stack.length === 0 && (option.adsafe ||\n                    !option.fragment || next_token.id === '(end)')) {\n                break;\n            }\n        }\n        if (next_token.id !== '(end)') {\n            fail('unexpected_a');\n        }\n    }\n\n\n// The actual JSLINT function itself.\n\n    var itself = function (the_source, the_option) {\n        var i, keys, predef;\n        JSLINT.comments = [];\n        JSLINT.errors = [];\n        JSLINT.tree = '';\n        begin = older_token = prev_token = token = next_token =\n            Object.create(syntax['(begin)']);\n        predefined = Object.create(standard);\n        if (the_option) {\n            option = Object.create(the_option);\n            predef = option.predef;\n            if (predef) {\n                if (Array.isArray(predef)) {\n                    for (i = 0; i < predef.length; i += 1) {\n                        predefined[predef[i]] = true;\n                    }\n                } else if (typeof predef === 'object') {\n                    keys = Object.keys(predef);\n                    for (i = 0; i < keys.length; i += 1) {\n                        predefined[keys[i]] = !!predef[keys];\n                    }\n                }\n            }\n            if (option.adsafe) {\n                option.safe = true;\n            }\n            if (option.safe) {\n                option.browser     =\n                    option['continue'] =\n                    option.css     =\n                    option.debug   =\n                    option.devel   =\n                    option.evil    =\n                    option.forin   =\n                    option.on      =\n                    option.rhino   =\n                    option.sub     =\n                    option.widget  =\n                    option.windows = false;\n\n                option.nomen       =\n                    option.strict  =\n                    option.undef   = true;\n\n                predefined.Date         =\n                    predefined['eval']  =\n                    predefined.Function =\n                    predefined.Object   = null;\n\n                predefined.ADSAFE  =\n                    predefined.lib = false;\n            }\n        } else {\n            option = {};\n        }\n        option.indent = +option.indent || 0;\n        option.maxerr = option.maxerr || 50;\n        adsafe_id = '';\n        adsafe_may = adsafe_top = adsafe_went = false;\n        approved = {};\n        if (option.approved) {\n            for (i = 0; i < option.approved.length; i += 1) {\n                approved[option.approved[i]] = option.approved[i];\n            }\n        } else {\n            approved.test = 'test';\n        }\n        tab = '';\n        for (i = 0; i < option.indent; i += 1) {\n            tab += ' ';\n        }\n        global = Object.create(predefined);\n        scope = global;\n        funct = {\n            '(global)': true,\n            '(name)': '(global)',\n            '(scope)': scope,\n            '(breakage)': 0,\n            '(loopage)': 0\n        };\n        functions = [funct];\n\n        comments_off = false;\n        ids = {};\n        implied = {};\n        in_block = false;\n        indent = false;\n        json_mode = false;\n        lookahead = [];\n        member = {};\n        properties = null;\n        prereg = true;\n        src = false;\n        stack = null;\n        strict_mode = false;\n        urls = [];\n        var_mode = false;\n        warnings = 0;\n        xmode = false;\n        lex.init(the_source);\n\n        assume();\n\n        try {\n            advance();\n            if (next_token.arity === 'number') {\n                fail('unexpected_a');\n            } else if (next_token.value.charAt(0) === '<') {\n                html();\n                if (option.adsafe && !adsafe_went) {\n                    warn('adsafe_go', this);\n                }\n            } else {\n                switch (next_token.id) {\n                case '{':\n                case '[':\n                    json_mode = true;\n                    json_value();\n                    break;\n                case '@':\n                case '*':\n                case '#':\n                case '.':\n                case ':':\n                    xmode = 'style';\n                    advance();\n                    if (token.id !== '@' || !next_token.identifier ||\n                            next_token.value !== 'charset' || token.line !== 1 ||\n                            token.from !== 1) {\n                        fail('css');\n                    }\n                    advance();\n                    if (next_token.arity !== 'string' &&\n                            next_token.value !== 'UTF-8') {\n                        fail('css');\n                    }\n                    advance();\n                    semicolon();\n                    styles();\n                    break;\n\n                default:\n                    if (option.adsafe && option.fragment) {\n                        fail('expected_a_b',\n                            next_token, '<div>', next_token.value);\n                    }\n\n// If the first token is predef semicolon, ignore it. This is sometimes used when\n// files are intended to be appended to files that may be sloppy. predef sloppy\n// file may be depending on semicolon insertion on its last line.\n\n                    step_in(1);\n                    if (next_token.id === ';') {\n                        semicolon();\n                    }\n                    if (next_token.value === 'use strict') {\n                        warn('function_strict');\n                        use_strict();\n                    }\n                    adsafe_top = true;\n                    begin.first = statements();\n                    JSLINT.tree = begin;\n                    if (option.adsafe && (JSLINT.tree.length !== 1 ||\n                            aint(JSLINT.tree[0], 'id', '(') ||\n                            aint(JSLINT.tree[0].first, 'id', '.') ||\n                            aint(JSLINT.tree[0].first.first, 'value', 'ADSAFE') ||\n                            aint(JSLINT.tree[0].first.second, 'value', 'lib') ||\n                            JSLINT.tree[0].second.length !== 2 ||\n                            JSLINT.tree[0].second[0].arity !== 'string' ||\n                            aint(JSLINT.tree[0].second[1], 'id', 'function'))) {\n                        fail('adsafe_lib');\n                    }\n                    if (JSLINT.tree.disrupt) {\n                        warn('weird_program', prev_token);\n                    }\n                }\n            }\n            indent = null;\n            advance('(end)');\n        } catch (e) {\n            if (e) {        // `~\n                JSLINT.errors.push({\n                    reason    : e.message,\n                    line      : e.line || next_token.line,\n                    character : e.character || next_token.from\n                }, null);\n            }\n        }\n        return JSLINT.errors.length === 0;\n    };\n\n\n// Data summary.\n\n    itself.data = function () {\n        var data = {functions: []},\n            function_data,\n            globals,\n            i,\n            implieds = [],\n            j,\n            kind,\n            members = [],\n            name,\n            the_function,\n            unused = [];\n        if (itself.errors.length) {\n            data.errors = itself.errors;\n        }\n\n        if (json_mode) {\n            data.json = true;\n        }\n\n        for (name in implied) {\n            if (Object.prototype.hasOwnProperty.call(implied, name)) {\n                implieds.push({\n                    name: name,\n                    line: implied[name]\n                });\n            }\n        }\n        if (implieds.length > 0) {\n            data.implieds = implieds;\n        }\n\n        if (urls.length > 0) {\n            data.urls = urls;\n        }\n\n        globals = Object.keys(functions[0]).filter(function (value) {\n            return value.charAt(0) !== '(' ? value : undefined;\n        });\n        if (globals.length > 0) {\n            data.globals = globals;\n        }\n\n        for (i = 1; i < functions.length; i += 1) {\n            the_function = functions[i];\n            function_data = {};\n            for (j = 0; j < functionicity.length; j += 1) {\n                function_data[functionicity[j]] = [];\n            }\n            for (name in the_function) {\n                if (Object.prototype.hasOwnProperty.call(the_function, name)) {\n                    if (name.charAt(0) !== '(') {\n                        kind = the_function[name];\n                        if (kind === 'unction') {\n                            kind = 'unused';\n                        } else if (typeof kind === 'boolean') {\n                            kind = 'global';\n                        }\n                        if (Array.isArray(function_data[kind])) {\n                            function_data[kind].push(name);\n                            if (kind === 'unused') {\n                                unused.push({\n                                    name: name,\n                                    line: the_function['(line)'],\n                                    'function': the_function['(name)']\n                                });\n                            }\n                        }\n                    }\n                }\n            }\n            for (j = 0; j < functionicity.length; j += 1) {\n                if (function_data[functionicity[j]].length === 0) {\n                    delete function_data[functionicity[j]];\n                }\n            }\n            function_data.name = the_function['(name)'];\n            function_data.param = the_function['(params)'];\n            function_data.line = the_function['(line)'];\n            data.functions.push(function_data);\n        }\n\n        if (unused.length > 0) {\n            data.unused = unused;\n        }\n\n        members = [];\n        for (name in member) {\n            if (typeof member[name] === 'number') {\n                data.member = member;\n                break;\n            }\n        }\n\n        return data;\n    };\n\n\n    itself.report = function (errors_only) {\n        var data = itself.data();\n\n        var err, evidence, i, j, key, keys, length, mem = '', name, names,\n            output = [], snippets, the_function, warning;\n\n        function detail(h, array) {\n            var comma_needed, i, singularity;\n            if (array) {\n                output.push('<div><i>' + h + '</i> ');\n                array = array.sort();\n                for (i = 0; i < array.length; i += 1) {\n                    if (array[i] !== singularity) {\n                        singularity = array[i];\n                        output.push((comma_needed ? ', ' : '') + singularity);\n                        comma_needed = true;\n                    }\n                }\n                output.push('</div>');\n            }\n        }\n\n        if (data.errors || data.implieds || data.unused) {\n            err = true;\n            output.push('<div id=errors><i>Error:</i>');\n            if (data.errors) {\n                for (i = 0; i < data.errors.length; i += 1) {\n                    warning = data.errors[i];\n                    if (warning) {\n                        evidence = warning.evidence || '';\n                        output.push('<p>Problem' + (isFinite(warning.line) ? ' at line ' +\n                            warning.line + ' character ' + warning.character : '') +\n                            ': ' + warning.reason.entityify() +\n                            '</p><p class=evidence>' +\n                            (evidence && (evidence.length > 80 ? evidence.slice(0, 77) + '...' :\n                            evidence).entityify()) + '</p>');\n                    }\n                }\n            }\n\n            if (data.implieds) {\n                snippets = [];\n                for (i = 0; i < data.implieds.length; i += 1) {\n                    snippets[i] = '<code>' + data.implieds[i].name + '</code>&nbsp;<i>' +\n                        data.implieds[i].line + '</i>';\n                }\n                output.push('<p><i>Implied global:</i> ' + snippets.join(', ') + '</p>');\n            }\n\n            if (data.unused) {\n                snippets = [];\n                for (i = 0; i < data.unused.length; i += 1) {\n                    snippets[i] = '<code><u>' + data.unused[i].name + '</u></code>&nbsp;<i>' +\n                        data.unused[i].line + ' </i> <small>' +\n                        data.unused[i]['function'] + '</small>';\n                }\n                output.push('<p><i>Unused variable:</i> ' + snippets.join(', ') + '</p>');\n            }\n            if (data.json) {\n                output.push('<p>JSON: bad.</p>');\n            }\n            output.push('</div>');\n        }\n\n        if (!errors_only) {\n\n            output.push('<br><div id=functions>');\n\n            if (data.urls) {\n                detail(\"URLs<br>\", data.urls, '<br>');\n            }\n\n            if (xmode === 'style') {\n                output.push('<p>CSS.</p>');\n            } else if (data.json && !err) {\n                output.push('<p>JSON: good.</p>');\n            } else if (data.globals) {\n                output.push('<div><i>Global</i> ' +\n                    data.globals.sort().join(', ') + '</div>');\n            } else {\n                output.push('<div><i>No new global variables introduced.</i></div>');\n            }\n\n            for (i = 0; i < data.functions.length; i += 1) {\n                the_function = data.functions[i];\n                names = [];\n                if (the_function.param) {\n                    for (j = 0; j < the_function.param.length; j += 1) {\n                        names[j] = the_function.param[j].value;\n                    }\n                }\n                output.push('<br><div class=function><i>' + the_function.line + '</i> ' +\n                    (the_function.name || '') + '(' + names.join(', ') + ')</div>');\n                detail('<big><b>Unused</b></big>', the_function.unused);\n                detail('Closure', the_function.closure);\n                detail('Variable', the_function['var']);\n                detail('Exception', the_function.exception);\n                detail('Outer', the_function.outer);\n                detail('Global', the_function.global);\n                detail('Label', the_function.label);\n            }\n\n            if (data.member) {\n                keys = Object.keys(data.member);\n                if (keys.length) {\n                    keys = keys.sort();\n                    mem = '<br><pre id=properties>/*properties ';\n                    length = 13;\n                    for (i = 0; i < keys.length; i += 1) {\n                        key = keys[i];\n                        name = key.name();\n                        if (length + name.length > 72) {\n                            output.push(mem + '<br>');\n                            mem = '    ';\n                            length = 1;\n                        }\n                        length += name.length + 2;\n                        if (data.member[key] === 1) {\n                            name = '<i>' + name + '</i>';\n                        }\n                        if (i < keys.length - 1) {\n                            name += ', ';\n                        }\n                        mem += name;\n                    }\n                    output.push(mem + '<br>*/</pre>');\n                }\n                output.push('</div>');\n            }\n        }\n        return output.join('');\n    };\n    itself.jslint = itself;\n\n    itself.edition = '2011-03-29';\n\n    return itself;\n\n}());\n// END JSLint (Replace all above code when changing JSLint versions)\n\n\n\n// Command line integration via Rhino\n(function (args) {\n    var name = args[0],\n        optstr = args[1], // arg1=val1,arg2=val2,...\n        opts = { rhino: true },\n        input;\n\n    if (!name) {\n        print('No files present in the fileset; Check your pattern match in build.xml');\n        quit(1);\n    }\n\n    if (optstr) {\n        optstr.split(',').forEach(function (arg) {\n            var o = arg.split('=');\n            opts[o[0]] = (function (ov) {\n                switch (ov) {\n                case 'true':\n                    return true;\n                case 'false':\n                    return false;\n                default:\n                    return ov;\n                }\n            })(o[1]);\n        });\n    }\n\n    input = readFile(name);\n\n    if (!input) {\n        print('JSLint: Couldn\\'t open file ' + name);\n        quit(1);\n    }\n    if (!JSLINT(input, opts)) {\n        for (var i = 0, err; err = JSLINT.errors[i]; i++) {\n            print(err.reason + ' (line: ' + err.line + ', character: ' + err.character + ')');\n            print('> ' + (err.evidence || '').replace(/^\\s*(\\S*(\\s+\\S+)*)\\s*$/, \"$1\"));\n            print('');\n        }\n        quit(1);\n    }\n\n    quit(0);\n}(arguments));\n"
  },
  {
    "path": "app/static_dev/build/tools/optipng-0.6.4-exe/LICENSE.txt",
    "content": "\nCopyright (C) 2001-2010 Cosmin Truta.\n\nThis software is provided 'as-is', without any express or implied\nwarranty.  In no event will the author(s) be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n   claim that you wrote the original software.  If you use this software\n   in a product, an acknowledgment in the product documentation would be\n   appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and must not\n   be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source distribution.\n\n"
  },
  {
    "path": "app/static_dev/crossdomain.xml",
    "content": "<?xml version=\"1.0\"?>\n<!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n<cross-domain-policy>\n  \n  \n<!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->\n\n<!-- Most restrictive policy: -->\n\t<site-control permitted-cross-domain-policies=\"none\"/>\n\t\n\t\n\t\n<!-- Least restrictive policy: -->\n<!--\n\t<site-control permitted-cross-domain-policies=\"all\"/>\n\t<allow-access-from domain=\"*\" to-ports=\"*\" secure=\"false\"/>\n\t<allow-http-request-headers-from domain=\"*\" headers=\"*\" secure=\"false\"/>\n-->\n<!--\n  If you host a crossdomain.xml file with allow-access-from domain=\"*\" \t \t\n  and don’t understand all of the points described here, you probably \t \t\n  have a nasty security vulnerability. ~ simon willison\n-->\n\n</cross-domain-policy>\n"
  },
  {
    "path": "app/static_dev/css/custom.css",
    "content": "/**\n * Place custom styles in this file. Right now these are the presets for\n * appengine-boilerplate.com\n *\n * Author: \n */\nbody {\n    max-width: 480px;\n    padding: 0 10px;\n    margin: 0 auto;\n    font: 1em/1.4 Calibri, sans-serif;\n    color: #222;\n    background: #fff;\n    _width: 480px;\n}\n\na { \n    font-weight:bold; \n    text-decoration: none; \n    color: #2989C9; \n}\n\na:focus {\n    outline: thin dotted;\n}\n\na:hover, a:active {\n    outline: 0;\n}\n\na:hover, a:focus, a:active { \n    text-decoration: underline; \n    color: #2989C9; \n}\na:visited {\n    color: #2989C9\n}\n\npre {\n    display: block;\n    padding: 5px; \n    margin: 1em 0;\n    font-family: consolas, monospace;\n    font-size: 0.8em;\n    color: #fff;\n    background: #222;\n    white-space: pre;\n    white-space: pre-wrap;\n    word-wrap: break-word;\n}\n\nul {\n    list-style: square;\n    padding: 0;\n    margin: 1.4em 0;\n}\n\nli {\n    margin: 0.35em 0;\n}\n\nh1 { \n    margin: 0.25em 0 0.5em;\n    font-size: 3.5em; \n}\n\nh2 { \n    margin: 1.25em 0 0.75em;\n    font-size: 1.5em; \n}\n\nheader h1, header h1 a {\n    font-family: 'Holtwood One SC', serif;\n    font-weight:normal;\n    color: #2989C9;\n    font-size: 48px;\n}\n\np {\n    margin: 0 0 1em;\n}\n\ntd {\n    padding: 2px 10px;\n}\n/* structure */\nimg.logo_right {\n    float:right;\n    clear: right;\n    width:70px;\n    margin-right: -84px;\n    margin-bottom: 30px;\n    margin-top: 10px;\n}\n\n.fork img {\n    position: fixed;\n    top: 0;\n    right: 0;\n}\n\n.demo {\n    margin:1em 0 3em;\n}\n\n.demo p {\n    margin: 0.5em 0 0;\n    font-style: italic;\n}\n\n.button {\n    display: inline-block; \n    padding: 6px 15px; \n    border: 1px solid #155c8e;\n    margin: 20px 0 0; \n    font-size: 1.375em;\n    line-height: 1.273;\n    color: #fff; \n    background: #2989c9; \n    text-shadow:0 1px 1px rgba(0,0,0,0.4); \n    -moz-border-radius: 5px; \n         border-radius: 5px;\n    -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.4), \n                        inset 0 1px rgba(255,255,255,0.5), \n                        inset 0 12px rgba(255,255,255,0.2), \n                        inset 0 10px 20px rgba(255,255,255,0.25), \n                        inset 0 -12px 25px rgba(0,0,0,0.3);\n       -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.4), \n                        inset 0 1px rgba(255,255,255,0.5), \n                        inset 0 12px rgba(255,255,255,0.2), \n                        inset 0 10px 20px rgba(255,255,255,0.25), \n                        inset 0 -12px 25px rgba(0,0,0,0.3);\n            box-shadow: 0 1px 3px rgba(0,0,0,0.4), \n                        inset 0 1px rgba(255,255,255,0.5), \n                        inset 0 12px rgba(255,255,255,0.2), \n                        inset 0 10px 10px rgba(255,255,255,0.25), \n                        inset 0 -12px 25px rgba(0,0,0,0.3);\n    -webkit-transition: all 0.25s;\n       -moz-transition: all 0.25s;\n         -o-transition: all 0.25s;\n            transition: all 0.25s;\n}\n\n.button:hover,\n.button:focus,\n.button:active {\n    text-decoration: none; \n    color: #fff; \n    background: #1973b3;\n}\n.button:visited {\n    color: #fff;\n}\n\n.share-bar {\n    overflow: hidden;\n    margin: 40px 0 0;\n    *zoom: 1;\n}\n\n.share-opt {\n    float: left;\n    margin: 0 15px 0 0;\n    vertical-align: bottom;\n}\n\n.footer {\n    padding: 10px 0;\n    border-top: 1px solid #ccc;\n    margin: 3em 0 0;\n    font-size: 0.8125em;\n}\n\n@media screen and (max-width:480px) {\n    body {\n        font-size: 0.875em;\n    }\n    \n    h1 {\n        font-size: 3em;\n    }\n    \n    .fork {\n        display: none;\n    }\n}\n"
  },
  {
    "path": "app/static_dev/css/fonts.css",
    "content": "/* Add your custom web fonts here. http://www.google.com/webfonts */\n@import url(http://fonts.googleapis.com/css?family=Holtwood+One+SC);\n"
  },
  {
    "path": "app/static_dev/css/libs/openid.css",
    "content": "/*\n\tSimple OpenID Plugin\n\thttp://code.google.com/p/openid-selector/\n\t\n\tThis code is licensed under the New BSD License.\n*/\n\n#openid_form {\n\twidth: 580px;\n}\n\n#openid_form legend {\n\tfont-weight: bold;\n}\n\n#openid_choice {\n\tdisplay: none;\n}\n\n#openid_input_area {\n\tclear: both;\n\tpadding: 10px;\n}\n\n#openid_btns, #openid_btns br {\n\tclear: both;\n}\n\n#openid_highlight {\n\tpadding: 3px;\n\tbackground-color: #FFFCC9;\n\tfloat: left;\n}\n\n.openid_large_btn {\n\twidth: 100px;\n\theight: 60px;\n/* fix for IE 6 only: http://en.wikipedia.org/wiki/CSS_filter#Underscore_hack */\n\t_width: 102px;\n\t_height: 62px;\n\n\tborder: 1px solid #DDD;\n\tmargin: 3px;\n\tfloat: left;\n}\n\n.openid_small_btn {\n\twidth: 24px;\n\theight: 24px;\n/* fix for IE 6 only: http://en.wikipedia.org/wiki/CSS_filter#Underscore_hack */\n\t_width: 26px;\n\t_height: 26px;\n\n\tborder: 1px solid #DDD;\n\tmargin: 3px;\n\tfloat: left;\n}\n\na.openid_large_btn:focus {\n\toutline: none;\n}\n\na.openid_large_btn:focus {\n\t-moz-outline-style: none;\n}\n\n.openid_selected {\n\tborder: 4px solid #DDD;\n}\n"
  },
  {
    "path": "app/static_dev/css/normalize.css",
    "content": "/* \n * HTML5 ✰ Boilerplate\n *\n * What follows is the result of much research on cross-browser styling. \n * Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal,\n * Kroc Camen, and the H5BP dev community and team.\n *\n * Detailed information about this CSS: h5bp.com/css\n * \n * ==|== normalize ==========================================================\n */\n\n\n/* =============================================================================\n   HTML5 display definitions\n   ========================================================================== */\n\narticle, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; }\naudio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }\naudio:not([controls]) { display: none; }\n[hidden] { display: none; }\n\n\n/* =============================================================================\n   Base\n   ========================================================================== */\n\n/*\n * 1. Correct text resizing oddly in IE6/7 when body font-size is set using em units\n * 2. Force vertical scrollbar in non-IE\n * 3. Prevent iOS text size adjust on device orientation change, without disabling user zoom: h5bp.com/g\n */\n\nhtml { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }\n\nbody { margin: 0; font-size: 13px; line-height: 1.231; }\n\nbody, button, input, select, textarea { font-family: sans-serif; color: #222; }\n\n/* \n * Remove text-shadow in selection highlight: h5bp.com/i\n * These selection declarations have to be separate\n */\n\n::-moz-selection { background: #2989C9; color: #fff; text-shadow: none; }\n::selection { background: #2989C9; color: #fff; text-shadow: none; }\n\n\n/* =============================================================================\n   Links\n   ========================================================================== */\n\na { color: #00e; }\na:visited { color: #551a8b; }\na:hover { color: #06e; }\na:focus { outline: thin dotted; }\n\n/* Improve readability when focused and hovered in all browsers: h5bp.com/h */\na:hover, a:active { outline: 0; }\n\n\n/* =============================================================================\n   Typography\n   ========================================================================== */\n\nabbr[title] { border-bottom: 1px dotted; }\n\nb, strong { font-weight: bold; }\n\nblockquote { margin: 1em 40px; }\n\ndfn { font-style: italic; }\n\nhr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }\n\nins { background: #ff9; color: #000; text-decoration: none; }\n\nmark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }\n\n/* Redeclare monospace font family: h5bp.com/j */\npre, code, kbd, samp { font-family: monospace, serif; _font-family: 'courier new', monospace; font-size: 1em; }\n\n/* Improve readability of pre-formatted text in all browsers */\npre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }\n\nq { quotes: none; }\nq:before, q:after { content: \"\"; content: none; }\n\nsmall { font-size: 85%; }\n\n/* Position subscript and superscript content without affecting line-height: h5bp.com/k */\nsub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }\nsup { top: -0.5em; }\nsub { bottom: -0.25em; }\n\n\n/* =============================================================================\n   Lists\n   ========================================================================== */\n\nul, ol { margin: 1em 0; padding: 0 0 0 40px; }\ndd { margin: 0 0 0 40px; }\nnav ul, nav ol { list-style: none; list-style-image: none; margin: 0; padding: 0; }\n\n\n/* =============================================================================\n   Embedded content\n   ========================================================================== */\n\n/*\n * 1. Improve image quality when scaled in IE7: h5bp.com/d\n * 2. Remove the gap between images and borders on image containers: h5bp.com/e \n */\n\nimg { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }\n\n/*\n * Correct overflow not hidden in IE9 \n */\n\nsvg:not(:root) { overflow: hidden; }\n\n\n/* =============================================================================\n   Figures\n   ========================================================================== */\n\nfigure { margin: 0; }\n\n\n/* =============================================================================\n   Forms\n   ========================================================================== */\n\nform { margin: 0; }\nfieldset { border: 0; margin: 0; padding: 0; }\n\n/* Indicate that 'label' will shift focus to the associated form element */\nlabel { cursor: pointer; }\n\n/* \n * 1. Correct color not inheriting in IE6/7/8/9 \n * 2. Correct alignment displayed oddly in IE6/7 \n */\n\nlegend { border: 0; *margin-left: -7px; padding: 0; }\n\n/*\n * 1. Correct font-size not inheriting in all browsers\n * 2. Remove margins in FF3/4 S5 Chrome\n * 3. Define consistent vertical alignment display in all browsers\n */\n\nbutton, input, select, textarea { font-size: 100%; margin: 0; vertical-align: baseline; *vertical-align: middle; }\n\n/*\n * 1. Define line-height as normal to match FF3/4 (set using !important in the UA stylesheet)\n * 2. Correct inner spacing displayed oddly in IE6/7\n */\n\nbutton, input { line-height: normal; *overflow: visible; }\n\n/*\n * Reintroduce inner spacing in 'table' to avoid overlap and whitespace issues in IE6/7\n */\n\ntable button, table input { *overflow: auto; }\n\n/*\n * 1. Display hand cursor for clickable form elements\n * 2. Allow styling of clickable form elements in iOS\n */\n\nbutton, input[type=\"button\"], input[type=\"reset\"], input[type=\"submit\"] { cursor: pointer; -webkit-appearance: button; }\n\n/*\n * Consistent box sizing and appearance\n */\n\ninput[type=\"checkbox\"], input[type=\"radio\"] { box-sizing: border-box; }\ninput[type=\"search\"] { -webkit-appearance: textfield; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; }\ninput[type=\"search\"]::-webkit-search-decoration { -webkit-appearance: none; }\n\n/* \n * Remove inner padding and border in FF3/4: h5bp.com/l \n */\n\nbutton::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }\n\n/* \n * 1. Remove default vertical scrollbar in IE6/7/8/9 \n * 2. Allow only vertical resizing\n */\n\ntextarea { overflow: auto; vertical-align: top; resize: vertical; }\n\n/* Colors for form validity */\ninput:valid, textarea:valid {  }\ninput:invalid, textarea:invalid { background-color: #f0dddd; }\n\n\n/* =============================================================================\n   Tables\n   ========================================================================== */\n\ntable { border-collapse: collapse; border-spacing: 0; }\ntd { vertical-align: top; }\n\n\n/* ==|== primary styles =====================================================\n   Author: \n   ========================================================================== */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/* ==|== non-semantic helper classes ========================================\n   Please define your styles before this section.\n   ========================================================================== */\n\n/* For image replacement */\n.ir { display: block; border: 0; text-indent: -999em; overflow: hidden; background-color: transparent; background-repeat: no-repeat; text-align: left; direction: ltr; }\n.ir br { display: none; }\n\n/* Hide from both screenreaders and browsers: h5bp.com/u */\n.hidden { display: none !important; visibility: hidden; }\n\n/* Hide only visually, but have it available for screenreaders: h5bp.com/v */\n.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }\n\n/* Extends the .visuallyhidden class to allow the element to be focusable when navigated to via the keyboard: h5bp.com/p */\n.visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }\n\n/* Hide visually and from screenreaders, but maintain layout */\n.invisible { visibility: hidden; }\n\n/* Contain floats: h5bp.com/q */ \n.clearfix:before, .clearfix:after { content: \"\"; display: table; }\n.clearfix:after { clear: both; }\n.clearfix { zoom: 1; }\n\n\n\n/* ==|== media queries ======================================================\n   PLACEHOLDER Media Queries for Responsive Design.\n   These override the primary ('mobile first') styles\n   Modify as content requires.\n   ========================================================================== */\n\n@media only screen and (min-width: 480px) {\n  /* Style adjustments for viewports 480px and over go here */\n\n}\n\n@media only screen and (min-width: 768px) {\n  /* Style adjustments for viewports 768px and over go here */\n\n}\n\n\n\n/* ==|== print styles =======================================================\n   Print styles.\n   Inlined to avoid required HTTP connection: h5bp.com/r\n   ========================================================================== */\n \n@media print {\n  * { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; } /* Black prints faster: h5bp.com/s */\n  a, a:visited { text-decoration: underline; }\n  a[href]:after { content: \" (\" attr(href) \")\"; }\n  abbr[title]:after { content: \" (\" attr(title) \")\"; }\n  .ir a:after, a[href^=\"javascript:\"]:after, a[href^=\"#\"]:after { content: \"\"; }  /* Don't show links for images, or javascript/internal links */\n  pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }\n  thead { display: table-header-group; } /* h5bp.com/t */\n  tr, img { page-break-inside: avoid; }\n  img { max-width: 100% !important; }\n  @page { margin: 0.5cm; }\n  p, h2, h3 { orphans: 3; widows: 3; }\n  h2, h3 { page-break-after: avoid; }\n}\n\n\n"
  },
  {
    "path": "app/static_dev/css/style.css",
    "content": "@import url(\"fonts.css\");\n@import url(\"normalize.css\");\n@import url(\"libs/openid.css\");\n@import url(\"custom.css\");\n\n"
  },
  {
    "path": "app/static_dev/demo/elements.html",
    "content": "<!doctype html>  \n<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->\n<!--[if lt IE 7]> <html class=\"no-js ie6 oldie\" lang=\"en\"> <![endif]-->\n<!--[if IE 7]>    <html class=\"no-js ie7 oldie\" lang=\"en\"> <![endif]-->\n<!--[if IE 8]>    <html class=\"no-js ie8 oldie\" lang=\"en\"> <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\"> <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n\n  <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame \n       Remove this if you use the .htaccess -->\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n\n  <title>Element Consistency Tests</title>\n  <meta name=\"description\" content=\"\">\n  <meta name=\"author\" content=\"\">\n\n  <!-- Mobile viewport optimized: j.mp/bplateviewport -->\n  <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n\n  <!-- Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons -->\n\n  <!-- CSS: implied media=all -->\n  <link rel=\"stylesheet\" href=\"../css/style.css\">\n  <style>\n    /* box-sizing test */\n    #boxsize button,\n    #boxsize input,\n    #boxsize select,\n    #boxsize textarea {\n      width: 200px;\n      padding: 4px;\n      border: 1px solid #333;\n    }\n  </style>\n\n<!-- All JavaScript at the bottom, except for Modernizr / Respond.\n     Modernizr enables HTML5 elements & feature detects; Respond is a polyfill for min/max-width CSS3 Media Queries\n     For optimal performance, use a custom Modernizr build: www.modernizr.com/download/ -->\n  <script src=\"../js/libs/modernizr-2.0.6.min.js\"></script>\n</head>\n\n<body>\n\n  <div id=\"container\">\n\n      <!-- \n           demo content lovingly lifted from the azbuka project \n           http://code.google.com/p/azbuka/ \n           \n           and the bluetrip project\n           http://bluetrip.org/  \n           \n           and the normalize.css project\n           http://github.com/necolas/normalize.css\n\n           and peter beverloo\n           http://peter.sh/examples/?/html/meter-progress.html\n      -->\n           \n    <header>\n      <hgroup>\n        <h1>Grouped Heading 1</h1>\n        <h2>Grouped Heading 2</h2>\n      </hgroup>\n      <nav>\n        <ul>\n          <li><a href=\"#\">navigation item #1</a></li>\n          <li><a href=\"#\">navigation item #2</a></li>\n          <li><a href=\"#\">navigation item #3</a></li>\n        </ul>\n      </nav>\n    </header>\n        \n    <h1>Heading 1</h1>\n    <h2>Heading 2</h2>\n    <h3>Heading 3</h3>\n    <h4>Heading 4</h4>\n    <h5>Heading 5</h5>\n    <h6>Heading 6</h6>\n\n    <section>\n      <h1>Section Heading 1</h1>            \n      <article>\n        <h4>Article Heading 2</h4>\n        <address>Address: somewhere, world</address>\n        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et m. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et m. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et m.</p>\n        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et m. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et m. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et m.</p>\n      </article>\n    </section>\n        \n    <h1>Text-level semantics</h1>\n\n    <p>\n    The <a href=\"#\">a element</a> example<br>\n    The <abbr title=\"Title text\">abbr element</abbr> example<br>\n    The <b>b element</b> example<br>\n    The <cite>cite element</cite> example<br>\n    The <code>code element</code> example<br>\n    The <del>del element</del> example<br>\n    The <dfn>dfn element</dfn> example<br>\n    The <em>em element</em> example<br>\n    The <i>i element</i> example<br>\n    The img element <img src=\"http://placekitten.com/16/16\" alt=\"\"> example<br>\n    The <ins>ins element</ins> example<br>\n    The <kbd>kbd element</kbd> example<br>\n    The <mark>mark element</mark> example<br>\n    The <q>q element <q>inside</q> a q element</q> example<br>\n    The <s>s element</s> example<br>\n    The <samp>samp element</samp> example<br>\n    The <small>small element</small> example<br>\n    The <span>span element</span> example<br>\n    The <strike>strike element</strike> example<br>\n    The <strong>strong element</strong> example<br>\n    The <sub>sub element</sub> example<br>\n    The <sup>sup element</sup> example<br>\n    The <var>var element</var> example<br>\n    The <u>u element</u> example\n    </p>\n\n    <h1>Embedded content</h1>\n        \n    <h3>img</h3>\n\n    <img src=\"http://placekitten.com/100/100\" alt=\"\">\n    <a href=\"#\"><img src=\"http://placekitten.com/100/100\" alt=\"\"></a>\n\n    <h3>svg</h3>\n        \n    <svg style=\"width:100px; height:100px;\"><circle cx=\"100\" cy=\"100\" r=\"100\" fill=\"#ff0000\"></svg>\n\n    <h1>Grouping content</h1>\n        \n    <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et m.</p>\n        \n    <h3>pre</h3>\n        \n    <pre>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et me.</pre>\n\n    <pre><code>&lt;html>\n    &lt;head>\n    &lt;/head>\n    &lt;body>\n        &lt;div class=\"main\"> &lt;div>\n    &lt;/body>\n&lt;/html></code></pre>\n        \n    <h3>blockquote</h3>\n        \n    <blockquote>\n      <p>Some sort of famous witty quote marked up with a &lt;blockquote> and a child &lt;p> element.</p>\n    </blockquote>\n        \n    <blockquote>Even better philosophical quote marked up with just a &lt;blockquote> element.</blockquote>\n        \n    <h3>ordered list</h3>\n        \n    <ol>\n      <li>list item 1</li>\n      <li>list item 1\n        <ol>\n          <li>list item 2</li>\n          <li>list item 2\n            <ol>\n              <li>list item 3</li>\n              <li>list item 3</li>\n            </ol>\n          </li>\n          <li>list item 2</li>\n          <li>list item 2</li>\n        </ol>\n      </li>\n      <li>list item 1</li>\n      <li>list item 1</li>\n    </ol>\n        \n    <h3>unordered list</h3>\n        \n    <ul>\n      <li>list item 1</li>\n      <li>list item 1\n        <ul>\n          <li>list item 2</li>\n          <li>list item 2\n            <ul>\n              <li>list item 3</li>\n              <li>list item 3</li>\n            </ul>\n          </li>\n          <li>list item 2</li>\n          <li>list item 2</li>\n        </ul>\n      </li>\n      <li>list item 1</li>\n      <li>list item 1</li>\n    </ul>\n        \n    <h3>description list</h3>\n        \n    <dl>\n      <dt>Description name</dt>\n      <dd>Description value</dd>\n      <dt>Description name</dt>\n      <dd>Description value</dd>\n      <dd>Description value</dd>\n      <dt>Description name</dt>\n      <dt>Description name</dt>\n      <dd>Description value</dd>\n    </dl>\n        \n    <h3>figure</h3>\n        \n    <figure>\n      <img src=\"http://placekitten.com/400/200\" alt=\"\">\n      <figcaption>Figcaption content</figcaption>\n    </figure>\n\n    <h1>Tablular data</h1>\n\n    <table summary=\"Jimi Hendrix albums\">\n      <caption>\n        Jimi Hendrix - albums\n      </caption>\n      <thead>\n        <tr>\n          <th>Album</th>\n          <th>Year</th>\n          <th>Price</th>\n        </tr>\n      </thead>\n      <tfoot>\n        <tr>\n          <td>Album</td>\n          <td>Year</td>\n          <td>Price</td>\n        </tr>\n      </tfoot>\n      <tbody>\n        <tr>\n          <td>Are You Experienced</td>\n          <td>1967</td>\n          <td>$10.00</td>\n        </tr>\n        <tr>\n          <td>Axis: Bold as Love</td>\n          <td>1967</td>\n          <td>$12.00</td>\n        </tr>\n        <tr>\n          <td>Electric Ladyland</td>\n          <td>1968</td>\n          <td>$10.00</td>\n        </tr>\n        <tr>\n          <td>Band of Gypsys</td>\n          <td>1970</td>\n          <td>$12.00</td>\n        </tr>\n      </tbody>\n    </table>\n\n    <h1>Forms</h1>\n        \n    <form>\n      <fieldset>\n        <legend>Inputs as descendents of labels (form legend)</legend>\n        <p><label>Text input <input type=\"text\" value=\"value\"></label></p>\n        <p><label>Text input (required) <input type=\"text\" required></label></p>\n        <p><label>Text input (with pattern requirement and placeholder) <input type=\"text\" pattern=\"\\d{5}(-\\d{4})?\" title=\"a US Zip code, with or without the +4 exension\" placeholder=\"12345-6789\"></label></p>\n        <p><label>Email input <input type=\"email\"></label></p>\n        <p><label>Search input <input type=\"search\"></label></p>\n        <p><label>Tel input <input type=\"tel\"></label></p>\n        <p><label>URL input <input type=\"url\" placeholder=\"http://\"></label></p>\n        <p><label>Password input <input type=\"password\" value=\"password\"></label></p>\n        <p><label>File input <input type=\"file\"></label></p>\n        \n        <p><label>Radio input <input type=\"radio\" name=\"rad\"></label></p>\n        <p><label>Checkbox input <input type=\"checkbox\"></label></p>\n        <p><label><input type=\"radio\" name=\"rad\"> Radio input</label></p>\n        <p><label><input type=\"checkbox\"> Checkbox input</label></p>\n                \n        <p><label>Select field <select><option>Option 01</option><option>Option 02</option></select></label></p>\n        <p><label>Textarea <textarea cols=\"30\" rows=\"5\" >Textarea text</textarea></label></p>\n      </fieldset>\n            \n      <fieldset>\n        <legend>Inputs as siblings of labels</legend>\n        <p><label for=\"ic\">Color input</label> <input type=\"color\" id=\"ic\"></p>\n        <p><label for=\"in\">Number input</label> <input type=\"number\" id=\"in\" min=\"0\" max=\"10\"></p>\n        <p><label for=\"ir\">Range input</label> <input type=\"range\" id=\"ir\"></p>\n        <p><label for=\"idd\">Date input</label> <input type=\"date\" id=\"idd\"></p>\n        <p><label for=\"idm\">Month input</label> <input type=\"month\" id=\"idm\"></p>\n        <p><label for=\"idw\">Week input</label> <input type=\"week\" id=\"idw\"></p>\n        <p><label for=\"idt\">Datetime input</label> <input type=\"datetime\" id=\"idt\"></p>\n        <p><label for=\"idtl\">Datetime-local input</label> <input type=\"datetime-local\" id=\"idtl\"></p>\n\n        <p><label for=\"irb\">Radio input</label> <input type=\"radio\" id=\"irb\" name=\"rad\"></p>\n        <p><label for=\"icb\">Checkbox input</label> <input type=\"checkbox\" id=\"icb\"></p>\n        <p><input type=\"radio\" id=\"irb2\" name=\"rad\"> <label for=\"irb2\">Radio input</label></p>\n        <p><input type=\"checkbox\" id=\"icb2\"> <label for=\"icb2\">Checkbox input</label></p>\n                \n        <p><label for=\"s\">Select field</label> <select id=\"s\"><option>Option 01</option><option>Option 02</option></select></p>\n        <p><label for=\"t\">Textarea</label> <textarea id=\"t\" cols=\"30\" rows=\"5\" >Textarea text</textarea></p>\n      </fieldset>\n            \n      <fieldset>\n        <legend>Clickable inputs and buttons</legend>\n        <p><input type=\"image\" src=\"http://placekitten.com/90/24\" alt=\"Image (input)\"></p>\n        <p><input type=\"reset\" value=\"Reset (input)\"></p>\n        <p><input type=\"button\" value=\"Button (input)\"></p>\n        <p><input type=\"submit\" value=\"Submit (input)\"></p>\n\n        <p><button type=\"reset\">Reset (button)</button></p>\n        <p><button type=\"button\">Button (button)</button></p>\n        <p><button type=\"submit\">Submit (button)</button></p>\n      </fieldset>\n            \n      <fieldset id=\"boxsize\">\n        <legend>box-sizing tests</legend>\n        <div><input type=\"text\" value=\"text\"></div>\n        <div><input type=\"email\" value=\"email@example.com\"></div>\n        <div><input type=\"search\" value=\"search\"></div>\n        <div><input type=\"url\" value=\"http://\"></div>\n        <div><input type=\"password\" value=\"password\"></div>\n\n        <div><input type=\"color\"></div>\n        <div><input type=\"number\"></div>\n        <div><input type=\"range\"></div>\n        <div><input type=\"date\"></div>\n        <div><input type=\"month\"></div>\n        <div><input type=\"week\"></div>\n        <div><input type=\"datetime\"></div>\n        <div><input type=\"datetime-local\"></div>\n                \n        <div><input type=\"radio\"></div>\n        <div><input type=\"checkbox\"></div>\n                \n        <div><select><option>Option 01</option><option>Option 02</option></select></div>\n        <div><textarea cols=\"30\" rows=\"5\" >Textarea text</textarea></div>\n                \n        <div><input type=\"image\" src=\"http://placehold.it/90x24\" alt=\"Image (input)\"></div>\n        <div><input type=\"reset\" value=\"Reset (input)\"></div>\n        <div><input type=\"button\" value=\"Button (input)\"></div>\n        <div><input type=\"submit\" value=\"Submit (input)\"></div>\n\n        <div><button type=\"reset\">Reset (button)</button></div>\n        <div><button type=\"button\">Button (button)</button></div>\n        <div><button type=\"submit\">Submit (button)</button></div>\n      </fieldset>\n    </form>\n\n    <!-- thx peter beverloo: http://peter.sh/examples/?/html/meter-progress.html -->\n\n    <p id=\"no-support\" style=\"color: red; margin-bottom: 12px;\"> \n     Your browser does not support these elements yet! Consider downloading a <a href=\"http://tools.peter.sh/download-latest-chromium.php\">Chromium Nightly</a>.<br /> \n    </p> \n     \n    <h1>&lt;progress&gt;</h1>\n \n    <p> \n      The progress element (spec: <a href=\"http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-progress-element\">4.10.16</a>) represents the completion progress of a task and can be both indeterminate as determinate.\n    </p> \n    <ul class=\"compact\"> \n      <li> \n        <label>Indeterminate</label> \n        <progress max=\"100\"></progress> \n      </li> \n      <li> \n        <label>Progress: 0%</label> \n       <progress max=\"10\" value=\"0\"></progress> \n      </li> \n      <li> \n        <label>Progress: 100%</label> \n        <progress max=\"3254\" value=\"3254\"></progress> \n      </li> \n      <li> \n        <label>Progress: 57%</label> \n        <progress max=\"0.7\" value=\"0.4\"></progress> \n      </li> \n      <li> \n        <label>Javascript</label> \n        <progress id=\"progress-javascript-example\"></progress> \n      </li> \n    </ul> \n     \n    <h1>&lt;meter&gt;</h1>\n\n    <p> \n      Displaying a scalar measurement within a known range, like hard drive usage, can be done using the meter element (spec: <a href=\"http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-meter-element\">4.10.17</a>)\n    </p> \n    <ul class=\"compact\"> \n      <li> \n        <label>Meter: empty</label> \n        <meter value=\"0\"></meter> \n      </li> \n      <li> \n        <label>Meter: full</label> \n        <meter value=\"1\"></meter> \n      </li> \n      <li> \n        <label>Meter: \"a bit\"</label> \n        <meter min=\".34\" max=\".41\" value=\".36\"></meter> \n      </li> \n      <li> \n        <label>Preferred usage</label> \n        <meter min=\"50\" max=\"250\" low=\"100\" high=\"200\" value=\"120\"></meter> \n      </li> \n      <li> \n        <label>Too much traffic</label> \n        <meter min=\"1024\" max=\"10240\" low=\"2048\" high=\"8192\" value=\"9216\"></meter> \n      </li> \n      <li> \n        <label>Optimum value</label> \n        <meter value=\".5\" optimum=\".8\"></meter> \n      </li> \n      <li> \n        <label>Javascript</label> \n        <meter id=\"meter-javascript-example\" value=\"0\"></meter> \n      </li> \n    </ul> \n\n    <script> \n      (function () {\n        if (! (\"position\" in document.createElement (\"progress\"))) {\n          var elements = document.querySelectorAll (\"meter, progress\");\n          for (var i = 0, j = elements.length; i < j; i++) {\n            elements [i].style.border = \"1px solid red\";\n            elements [i].style.height = \"12px\";\n            elements [i].style.display = \"inline-block\";\n            elements [i].style.webkitAppearance = \"none\";\n          }\n          return ;\n        }\n           \n      document.getElementById (\"no-support\").style.display = \"none\";\n           \n        /** Setup the <progress> JavaScript example **/\n        var progressExample = document.getElementById (\"progress-javascript-example\");\n        progressExample.min = 50;\n        progressExample.max = 122;\n              \n        setInterval (function () {\n          progressExample.value = progressExample.min + Math.random () * (progressExample.max - progressExample.min);\n        }, 1000);\n           \n        /** We'd like some fancy <meter> examples too **/\n        var meterExample = document.getElementById (\"meter-javascript-example\");\n        meterExample.min = 0;\n        meterExample.max = 100;\n        meterExample.value = 50;\n        meterExample.low  = 20;\n        meterExample.high = 80;\n        meterExample.optimum = 65;\n               \n        setInterval (function () {\n          meterExample.value   = meterExample.min + Math.random () * (meterExample.max - meterExample.min);\n          meterExample.optimum = 65 + (5 - Math.random () * 10);\n        }, 1000);\n      })();\n    </script>\n\n  </div> <!--! end of #container -->\n\n\n  <!-- Javascript at the bottom for fast page loading -->\n\n  <!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if necessary -->\n  <script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js\"></script>\n  <script>window.jQuery || document.write('<script src=\"../js/libs/jquery-1.6.2.min.js\"><\\/script>')</script>\n  \n  <!-- scripts concatenated and minified via ant build script-->\n  <script defer src=\"../js/plugins.js\"></script>\n  <script defer src=\"../js/script.js\"></script>\n  <!-- end scripts-->\n\n\n  <!-- mathiasbynens.be/notes/async-analytics-snippet Change UA-XXXXX-X to be your site's ID -->\n  <script>\n    var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview'],['_trackPageLoadTime']];\n    (function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.async=1;\n    g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';\n    s.parentNode.insertBefore(g,s)}(document,'script'));\n  </script>\n\n</body>\n</html>\n"
  },
  {
    "path": "app/static_dev/demo/hack.css",
    "content": "/* \n  style.css contains a reset, font normalization and some base styles.\n  \n  credit is left where credit is due.\n  additionally, much inspiration was taken from these projects:\n    yui.yahooapis.com/2.8.1/build/base/base.css\n    camendesign.com/design/\n    praegnanz.de/weblog/htmlcssjs-kickstart\n*/\n\n/* \n  html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline)\n  v1.4 2009-07-27 | Authors: Eric Meyer & Richard Clark\n  html5doctor.com/html-5-reset-stylesheet/\n*/\n\nhtml, body, div, span, object, iframe,\nh1, h2, h3, h4, h5, h6, p, blockquote, pre,\nabbr, address, cite, code,\ndel, dfn, em, img, ins, kbd, q, samp,\nsmall, strong, sub, sup, var,\nb, i,\ndl, dt, dd, ol, ul, li,\nfieldset, form, label, legend,\ntable, caption, tbody, tfoot, thead, tr, th, td,\narticle, aside, canvas, details, figcaption, figure, \nfooter, header, hgroup, menu, nav, section, summary,\ntime, mark, audio, video {\n  margin:0;\n  padding:0;\n  border:0;\n  outline:0;\n  font-size:100%;\n  vertical-align:baseline;\n  background:transparent;\n}                  \n\narticle, aside, details, figcaption, figure,\nfooter, header, hgroup, menu, nav, section { \n    display:block;\n}\n\nnav ul { list-style:none; }\n\nblockquote, q { quotes:none; }\n\nblockquote:before, blockquote:after,\nq:before, q:after { content:\"\"; content:none; }\n\na { margin:0; padding:0; font-size:100%; vertical-align:baseline; background:transparent; }\n\nins { background-color:#ff9; color:#000; text-decoration:none; }\n\nmark { background-color:#ff9; color:#000; font-style:italic; font-weight:bold; }\n\ndel { text-decoration: line-through; }\n\nabbr[title], dfn[title] { border-bottom:1px dotted; cursor:help; }\n\n/* tables still need cellspacing=\"0\" in the markup */\ntable { border-collapse:collapse; border-spacing:0; }\n\nhr { display:block; height:1px; border:0; border-top:1px solid #ccc; margin:1em 0; padding:0; }\n\ninput, select { vertical-align:middle; }\n/* END RESET CSS */\n\n\n/* fonts.css from the YUI Library: developer.yahoo.com/yui/\n   Please refer to developer.yahoo.com/yui/fonts/ for font sizing percentages\n\n  There are three custom edits:\n   * remove arial, helvetica from explicit font stack\n   * we normalize monospace styles ourselves\n   * table font-size is reset in the HTML5 reset above so there is no need to repeat\n*/\nbody { font:13px/1.231 sans-serif; *font-size:small; } /* hack retained to preserve specificity */\n\nselect, input, textarea, button { font:99% sans-serif; }\n\n/* normalize monospace sizing \n * en.wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome\n */\npre, code, kbd, samp { font-family: monospace, sans-serif; }\n "
  },
  {
    "path": "app/static_dev/demo/hack2.css",
    "content": "body { font:13px/1.231 sans-serif; *font-size:small; } /* hack retained to preserve specificity */\n\t\tbody, select, input, textarea { \n\t\t\t/* #444 looks better than black: twitter.com/H_FJ/statuses/11800719859 */ \n\t\t\tcolor: #444; \n\t\t\t/* set your base font here, to apply evenly \n\t\t\t/* font-family: Georgia, serif;  */   \n\t\t}\n\t\t\n\t\t/* Headers (h1,h2,etc) have no default font-size or margin,\n\t\t you'll want to define those yourself. */ \n\t\th1,h2,h3,h4,h5,h6 { font-weight: bold; }\n    h1 { font-size: 2em; }\n\t\tselect, input, textarea, button { font:99% sans-serif; }\n\t\t\n\t\t/* Accessible focus treatment: people.opera.com/patrickl/experiments/keyboard/test */\n\t\ta:hover, a:active { outline: none; }\n\n    .current { background: #ccc; }\n    header span { padding: 0.2em 0.5em; display: inline-block; }\n    dd, h1, body, html { margin: 0;}\n    \n\n\t\ta, a:active, a:visited { color: #607890; }\n\t\ta:hover { color: #036; }\n\t\t.wrapper {width:200px; border:1px solid red;}\n\t\t\n\t\tdl {margin:0 auto; width:900px;}\n\t\tdt {background-color:#ccc; margin-bottom:20px; cursor:pointer; cursor:hand; padding:5px; font-weight:bold; }\n\t\tdd {margin-bottom:30px;}\n\t\t\n#clear-demo {width:500px; border:1px solid black;}\n#clear-demo-l {width:200px; border:1px solid black; float:left;}\n#clear-demo-r {width:200px; border:1px solid black; float:right;}\n#clear-demo-b {width:200px; border:1px solid black;}\n\nheader {text-align:center;}\n.show, .hide {color: #607890; cursor:pointer; cursor:hand;}\n\nbody {\n  padding-bottom: 200px;\n}"
  },
  {
    "path": "app/static_dev/demo/tests.html",
    "content": "<!doctype html>\n<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->\n<!--[if lt IE 7]> <html class=\"no-js ie6 oldie\" lang=\"en\"> <![endif]-->\n<!--[if IE 7]>    <html class=\"no-js ie7 oldie\" lang=\"en\"> <![endif]-->\n<!--[if IE 8]>    <html class=\"no-js ie8 oldie\" lang=\"en\"> <![endif]-->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\"> <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n\n  <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame \n       Remove this if you use the .htaccess -->\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n\n  <title>Boilerplate Test Suite</title>\n  <meta name=\"description\" content=\"\">\n  <meta name=\"author\" content=\"\">\n\n  <!-- Mobile viewport optimized: j.mp/bplateviewport -->\n  <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n\n  <!-- Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons -->\n\n  <!-- CSS: implied media=all -->\n  <link rel=\"stylesheet\" href=\"../css/style.css\">\n  <link rel=\"stylesheet\" href=\"hack2.css\">\n \n<!-- All JavaScript at the bottom, except for Modernizr / Respond.\n     Modernizr enables HTML5 elements & feature detects; Respond is a polyfill for min/max-width CSS3 Media Queries\n     For optimal performance, use a custom Modernizr build: www.modernizr.com/download/ -->\n  <script src=\"../js/libs/modernizr-2.0.6.min.js\"></script>\n</head>\n\n<body>\n\n  <div id=\"container\">\n    <header>\n        <br /><br /><h1>HTML5 Boilerplate CSS Hack Sheet</h1><br /><br />\n    </header>\n  \n    \n    <div id=\"main\" style=\"display:block;\">\n      <dl>\n        <dt>Hack 01 - Set default color</dt>\n          <dd>\n            HTML5 Boilerplate suggests the default color looks better when set to #444 instead of #000.<br />\n            <span style=\"color:black;\">Web font default color</span>\n          </dd>\n        \n        <dt>Hack 02 - Vertical Scroll Bar</dt>\n          <dd>\n            Click <a href=\"#\" id=\"shorten\">contract</a> | <a href=\"#\" id=\"expand\">expand</a> to see how Boilerplate forces a scrollbar in non-IE.\n          </dd>\n\n        <dt>Hack 03 - Accessible focus style</dt>\n          <dd>\n            Remove dotted outline around 'a' element on hover and on focus in certain browsers\n            <br /><br />\n            <span href=\"#\" class=\"show\">With Boilerplate CSS</span> | <span href=\"#\" class=\"hide\">Without Boilerplate CSS</span>\n            <br /><br />\n            <a href=\"#\" class=\"preventDefault\">Click me</a>\n          </dd>\n      \n        <dt>Hack 04 - Pre Wrapping</dt>\n          <dd>\n            Default <code>pre</code> doesn't wrap text. Boilerplate forces <code>pre</code> to wrap text.\n            <br /><br />\n            <span href=\"#\" class=\"show\">With Boilerplate CSS</span> | <span href=\"#\" class=\"hide\">Without Boilerplate CSS</span>\n            <br /><br />\n            with wrapping:<br /><br />\n            <div style=\"height:115px;\">\n              <div class=\"wrapper\">\n                <pre>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</pre>\n              </div>\n            </div><br />\n            without wrapping:<br /><br />\n            <div class=\"wrapper\">\n              aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n            </div>\n          </dd>\n          \n        <dt>Hack 05 - Remove default textarea scrollbar in IE</dt>\n          <dd>                 \n            IE shows a disabled scrollbar on empty <code>textarea</code>.<br><br>\n            <span href=\"#\" class=\"show\">With Boilerplate CSS</span> | <span href=\"#\" class=\"hide\">Without Boilerplate CSS</span>\n            <br /><br />\n            <form>\n              <textarea></textarea>\n            </form>\n          </dd>        \n      \n        <dt>Hack 06 - IE6,7 legend margin</dt>\n          <dd>\n            Left align form legend to the inner text in IE 6,7.<br /><br />\n            <span href=\"#\" class=\"show\">With Boilerplate CSS</span> | <span href=\"#\" class=\"hide\">Without Boilerplate CSS</span>\n            <br /><br />\n            <form>\n              <fieldset>\n                <legend>Information:</legend><br />\n                Name: <input type=\"text\" size=\"30\" /><br />\n                Email: <input type=\"text\" size=\"30\" /><br />\n                Date of birth: <input type=\"text\" size=\"10\" />\n              </fieldset>\n            </form>\n          </dd>\n        \n        <dt>Hack 07 - Vertically align checkboxes, radios, text inputs with their label</dt>\n          <dd>\n            <span href=\"#\" class=\"show\">With Boilerplate CSS</span> | <span href=\"#\" class=\"hide\">Without Boilerplate CSS</span>\n            <br /><br />\n            <input type=\"radio\" /> Option A <br /><br />\n            <input type=\"checkbox\" /> Item B <br /><br />\n            Name: <input type=\"text\" />\n          </dd>\n            \n        <dt>Hack 08 - Hand cursor on clickable input elements</dt>\n          <dd>\n            <span href=\"#\" class=\"show\">With Boilerplate CSS</span> | <span href=\"#\" class=\"hide\">Without Boilerplate CSS</span>\n            <br /><br />\n            Input with type submit <input type=\"submit\" value=\"submit\" />\n          </dd>\n          \n          \n        <dt>Hack 09 - Webkit browsers form elements margin</dt>\n          <dd>\n            Webkit browsers add a 2px margin outside the chrome of form elements.<br /><br />\n            <span href=\"#\" class=\"show\">With Boilerplate CSS</span> | <span href=\"#\" class=\"hide\">Without Boilerplate CSS</span>\n            <br /><br />\n            <form>\n            <input type=\"submit\" value=\"submit\" /><br /><br />\n            <button type=\"button\">Click Me!</button><br /><br />\n            <select><option>Default</option></select>\n            </form>\n          </dd>\n          \n        <dt>Hack 10 - Make buttons width rendered correctly</dt>\n          <dd>\n            IE adds extra padding to <code>button</code>. This fixes the issue. <br /><br />\n            <span href=\"#\" class=\"show\">With Boilerplate CSS</span> | <span href=\"#\" class=\"hide\">Without Boilerplate CSS</span>\n            <br /><br />\n            <form>\n              <button type=\"button\">Click Me!</button>\n              <button type=\"button\">This is a really long button</button>\n            </form>\n          </dd>\n        \n        <dt>Hack 11 - Bicubic resizing for non-native sized IMG</dt>\n          <dd>\n            IE7 hack to reduce distortion caused by image resizing <br /><br />\n            <span href=\"#\" class=\"show\">With Boilerplate CSS</span> | <span href=\"#\" class=\"hide\">Without Boilerplate CSS</span>\n            <br /><br />\n            <img src=\"../apple-touch-icon.png\" width=\"27\" /><br />\n            <img src=\"../apple-touch-icon.png\" width=\"57\" /><br />\n            <img src=\"../apple-touch-icon.png\" width=\"157\" /><br />\n          </dd>\n        \n        <dt>Hack 12 - Hide visually</dt>\n          <dd>\n            Hide elements visually, but have it available for screen readers.\n            <br /><br />\n            <span href=\"#\" class=\"show\">With Boilerplate CSS</span> | <span href=\"#\" class=\"hide\">Without Boilerplate CSS</span>\n            <br /><br />\n            <div class=\"visuallyhidden\">showing</div>\n          </dd>\n        \n        <dt>Hack 13 - Image text replacement</dt>\n          <dd>\n            Replace text with images. \n            <br /><br />\n            <span href=\"#\" class=\"show\">With Boilerplate CSS</span> | <span href=\"#\" class=\"hide\">Without Boilerplate CSS</span>\n            <br /><br />\n            \n            <div class=\"ir\" style=\"background:url('../apple-touch-icon.png'); width:57px; height:57px;\">Apple Touch Icon</div>\n            \n          </dd>  \n\n        <dt>Hack 14 - Clear Floats</dt>\n          <dd>\n            Clear Floated elements without extra markup. \n            <br /><br />\n            <span href=\"#\" class=\"show\">With Boilerplate CSS</span> | <span href=\"#\" class=\"hide\">Without Boilerplate CSS</span>\n            <br /><br />\n            <div id=\"clear-demo\" class=\"clearfix\">\n              <div id=\"clear-demo-l\">text floated left</div><div id=\"clear-demo-r\">text floated right</div>\n            </div>\n            <div id=\"clear-demo-b\">unfloated text</div>\n          </dd>  \n          \n          \n          <dt>Hack 15 - PNG fix</dt>\n          <dd>fix pngs for correct display in IE6\n            <br /> <br />\n\n          <div style=\"position:relative\">\n            \n            <!-- wassup gradient. -->\n            <div style=\"\n              position:absolute; height: 40px; background-color: #444444; background-image: -moz-linear-gradient(top, #444444, #999999);\n              background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #444444),color-stop(1, #999999));\n              filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#444444', EndColorStr='#999999');\n            \">\n              \n              <div class=\"png_bg\" style=\"\n                border:1px solid #ddd; width:100px; padding:10px 10px 10px 50px;\n                display:inline-block; background:url(test_tubes.png) no-repeat 5px center;\n              \">\n                <img src=\"internet_explorer.png\" alt=\"IE is so awesome\" />\n              </div>\n            </div>\n          </div>            \n        </dd>  \n      </dl>\n    </div>\n    <footer>\n\n    </footer>\n  </div> <!--! end of #container -->\n\n\n  <!-- Javascript at the bottom for fast page loading -->\n\n  <!-- Grab Google CDN's jQuery. fall back to local if necessary -->\n  <script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js\"></script>\n  <script>window.jQuery || document.write('<script src=\"../js/libs/jquery-1.6.2.min.js\"><\\/script>')</script>\n\n\n  <script>\n    $(\"#expand\").click(function() {\n      $(\"#container\").css(\"height\",\"auto\").css(\"overflow\",\"\");\n      return false;\n    });\n    \n    $(\"#shorten\").click(function() {\n      $(\"#container\").css(\"height\",\"300px\").css(\"overflow\",\"hidden\");\n      return false;\n    });\n    \n    $(\"#atag\").click(function() {\n      return false;\n    });\n    \n    $(\".show\").click(function(){\n      $(\".show\").addClass(\"current\")\n      $(\".hide\").removeClass(\"current\");\n      showStyle();\n      return false;\n    });\n    $(\".hide\").click(function(){\n      $(\".hide\").addClass(\"current\")\n      $(\".show\").removeClass(\"current\");\n      // freeze the size of each tests so the page doesnt jump.\n      $(\"dd\").each(function(){\n        $(this).height( $(this).height() );\n      });\n      \n      hideStyle();\n      return false;\n    });\n    \n    var linkTags = $(\"link\");\n    function hideStyle() {\n      // tee hee\n      $(\"link[href*='style.css']\").attr(\"media\",\"braille\");\n    }\n    function showStyle() {\n      $(\"link[href*='style.css']\").attr(\"media\",\"all\");\n    }\n    \n    $(\".preventDefault\").click(function() {\n      return false;\n    });\n    \n    $(function(){\n      $(\".show\").addClass(\"current\");\n    })\n  </script>\n\n\n  <!-- scripts concatenated and minified via ant build script-->\n  <script defer src=\"../js/plugins.js\"></script>\n  <script defer src=\"../js/script.js\"></script>\n  <!-- end scripts-->\n\n  \n  <!-- mathiasbynens.be/notes/async-analytics-snippet Change UA-XXXXX-X to be your site's ID -->\n  <script>\n    var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview'],['_trackPageLoadTime']];\n    (function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.async=1;\n    g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';\n    s.parentNode.insertBefore(g,s)}(document,'script'));\n  </script>\n\n</body>\n</html>\n"
  },
  {
    "path": "app/static_dev/humans.txt",
    "content": "/* the humans responsible & colophon */\n/* humanstxt.org */\n\n\n/* TEAM */\n  <your title>: <your name>\n  Site: \n  Twitter: \n  Location: \n\n/* THANKS */\n  Names (& URL): \n\n/* SITE */\n  Standards: HTML5, CSS3\n  Components: Modernizr, jQuery\n  Software:\n  \n\n                                    \n                               -o/-                       \n                               +oo//-                     \n                              :ooo+//:                    \n                             -ooooo///-                   \n                             /oooooo//:                   \n                            :ooooooo+//-                  \n                           -+oooooooo///-                 \n           -://////////////+oooooooooo++////////////::    \n            :+ooooooooooooooooooooooooooooooooooooo+:::-  \n              -/+ooooooooooooooooooooooooooooooo+/::////:-\n                -:+oooooooooooooooooooooooooooo/::///////:-\n                  --/+ooooooooooooooooooooo+::://////:-   \n                     -:+ooooooooooooooooo+:://////:--     \n                       /ooooooooooooooooo+//////:-        \n                      -ooooooooooooooooooo////-           \n                      /ooooooooo+oooooooooo//:            \n                     :ooooooo+/::/+oooooooo+//-           \n                    -oooooo/::///////+oooooo///-          \n                    /ooo+::://////:---:/+oooo//:          \n                   -o+/::///////:-      -:/+o+//-         \n                   :-:///////:-            -:/://         \n                     -////:-                 --//:        \n                       --                       -:        \n"
  },
  {
    "path": "app/static_dev/img/.gitignore",
    "content": "!.gitignore\n\n"
  },
  {
    "path": "app/static_dev/index.html",
    "content": "<!doctype html>\n<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->\n<!--[if lt IE 7]> <html class=\"no-js ie6 oldie\" lang=\"en\"> <![endif]-->\n<!--[if IE 7]>    <html class=\"no-js ie7 oldie\" lang=\"en\"> <![endif]-->\n<!--[if IE 8]>    <html class=\"no-js ie8 oldie\" lang=\"en\"> <![endif]-->\n<!-- Consider adding an manifest.appcache: h5bp.com/d/Offline -->\n<!--[if gt IE 8]><!--> <html class=\"no-js\" lang=\"en\"> <!--<![endif]-->\n<head>\n  <meta charset=\"utf-8\">\n\n  <!-- Use the .htaccess and remove these lines to avoid edge case issues.\n       More info: h5bp.com/b/378 -->\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n\n  {% block head %}\n  <title>{% block title %}{% endblock %}</title>\n  <meta name=\"description\" content=\"\">\n  {% endblock %}\n  <meta name=\"author\" content=\"\">\n\n  <!-- Mobile viewport optimized: j.mp/bplateviewport -->\n  <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n\n  <!-- Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons -->\n\n  <!-- CSS: implied media=all -->\n  <!-- CSS concatenated and minified via ant build script-->\n  <!-- Important: Do not reference other stylesheets here! The build-script won't include them. \n       Instead use @import in style.css -->\n  <link rel=\"stylesheet\" href=\"/css/style.css\">\n  <!-- end CSS-->\n\n  <!-- More ideas for your <head> here: h5bp.com/d/head-Tips -->\n\n  <!-- All JavaScript at the bottom, except for Modernizr / Respond.\n       Modernizr enables HTML5 elements & feature detects; Respond is a polyfill for min/max-width CSS3 Media Queries\n       For optimal performance, use a custom Modernizr build: www.modernizr.com/download/ -->\n  <script src=\"/js/libs/modernizr-2.0.6.min.js\"></script>\n  \n  {% block head_include %}{% endblock %}\n</head>\n\n<body>\n\n  <div id=\"container\">\n    <header>\n        {% include \"header.html\"%}\n    </header>\n    <div id=\"main\" role=\"main\">\n        {% block main %}{% endblock %}\n    </div>\n    <footer>\n        {% include \"footer.html\"%}\n    </footer>\n  </div> <!--! end of #container -->\n\n\n  <!-- JavaScript at the bottom for fast page loading -->\n\n  <!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if offline -->\n  <script src=\"//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js\"></script>\n  <script>window.jQuery || document.write('<script src=\"/js/libs/jquery-1.6.2.min.js\"><\\/script>')</script>\n\n\n  <!-- scripts concatenated and minified via ant build script-->\n  <script defer src=\"/js/plugins.js\"></script>\n  <script defer src=\"/js/script.js\"></script>\n  <script defer src=\"/js/mylibs/openid-en.js\"></script>\n  <!-- end scripts-->\n\n  {% block scripts %}{% endblock %}\n\t\n  <!-- Change UA-XXXXX-X to be your site's ID -->\n  <script>\n    window._gaq = [['_setAccount','UAXXXXXXXX1'],['_trackPageview'],['_trackPageLoadTime']];\n    Modernizr.load({\n      load: ('https:' == location.protocol ? '//ssl' : '//www') + '.google-analytics.com/ga.js'\n    });\n  </script>\n\n\n  <!-- Prompt IE 6 users to install Chrome Frame. Remove this if you want to support IE 6.\n       chromium.org/developers/how-tos/chrome-frame-getting-started -->\n  <!--[if lt IE 7 ]>\n    <script defer src=\"//ajax.googleapis.com/ajax/libs/chrome-frame/1.0.3/CFInstall.min.js\"></script>\n    <script defer>window.attachEvent('onload',function(){CFInstall.check({mode:'overlay'})})</script>\n  <![endif]-->\n  \n</body>\n</html>\n"
  },
  {
    "path": "app/static_dev/js/libs/dd_belatedpng.js",
    "content": "/**\n* DD_belatedPNG: Adds IE6 support: PNG images for CSS background-image and HTML <IMG/>.\n* Author: Drew Diller\n* Email: drew.diller@gmail.com\n* URL: http://www.dillerdesign.com/experiment/DD_belatedPNG/\n* Version: 0.0.8a\n* Licensed under the MIT License: http://dillerdesign.com/experiment/DD_belatedPNG/#license\n*\n* Example usage:\n* DD_belatedPNG.fix('.png_bg'); // argument is a CSS selector\n* DD_belatedPNG.fixPng( someNode ); // argument is an HTMLDomElement\n**/\nvar DD_belatedPNG={ns:\"DD_belatedPNG\",imgSize:{},delay:10,nodesFixed:0,createVmlNameSpace:function(){if(document.namespaces&&!document.namespaces[this.ns]){document.namespaces.add(this.ns,\"urn:schemas-microsoft-com:vml\")}},createVmlStyleSheet:function(){var b,a;b=document.createElement(\"style\");b.setAttribute(\"media\",\"screen\");document.documentElement.firstChild.insertBefore(b,document.documentElement.firstChild.firstChild);if(b.styleSheet){b=b.styleSheet;b.addRule(this.ns+\"\\\\:*\",\"{behavior:url(#default#VML)}\");b.addRule(this.ns+\"\\\\:shape\",\"position:absolute;\");b.addRule(\"img.\"+this.ns+\"_sizeFinder\",\"behavior:none; border:none; position:absolute; z-index:-1; top:-10000px; visibility:hidden;\");this.screenStyleSheet=b;a=document.createElement(\"style\");a.setAttribute(\"media\",\"print\");document.documentElement.firstChild.insertBefore(a,document.documentElement.firstChild.firstChild);a=a.styleSheet;a.addRule(this.ns+\"\\\\:*\",\"{display: none !important;}\");a.addRule(\"img.\"+this.ns+\"_sizeFinder\",\"{display: none !important;}\")}},readPropertyChange:function(){var b,c,a;b=event.srcElement;if(!b.vmlInitiated){return}if(event.propertyName.search(\"background\")!=-1||event.propertyName.search(\"border\")!=-1){DD_belatedPNG.applyVML(b)}if(event.propertyName==\"style.display\"){c=(b.currentStyle.display==\"none\")?\"none\":\"block\";for(a in b.vml){if(b.vml.hasOwnProperty(a)){b.vml[a].shape.style.display=c}}}if(event.propertyName.search(\"filter\")!=-1){DD_belatedPNG.vmlOpacity(b)}},vmlOpacity:function(b){if(b.currentStyle.filter.search(\"lpha\")!=-1){var a=b.currentStyle.filter;a=parseInt(a.substring(a.lastIndexOf(\"=\")+1,a.lastIndexOf(\")\")),10)/100;b.vml.color.shape.style.filter=b.currentStyle.filter;b.vml.image.fill.opacity=a}},handlePseudoHover:function(a){setTimeout(function(){DD_belatedPNG.applyVML(a)},1)},fix:function(a){if(this.screenStyleSheet){var c,b;c=a.split(\",\");for(b=0;b<c.length;b++){this.screenStyleSheet.addRule(c[b],\"behavior:expression(DD_belatedPNG.fixPng(this))\")}}},applyVML:function(a){a.runtimeStyle.cssText=\"\";this.vmlFill(a);this.vmlOffsets(a);this.vmlOpacity(a);if(a.isImg){this.copyImageBorders(a)}},attachHandlers:function(i){var d,c,g,e,b,f;d=this;c={resize:\"vmlOffsets\",move:\"vmlOffsets\"};if(i.nodeName==\"A\"){e={mouseleave:\"handlePseudoHover\",mouseenter:\"handlePseudoHover\",focus:\"handlePseudoHover\",blur:\"handlePseudoHover\"};for(b in e){if(e.hasOwnProperty(b)){c[b]=e[b]}}}for(f in c){if(c.hasOwnProperty(f)){g=function(){d[c[f]](i)};i.attachEvent(\"on\"+f,g)}}i.attachEvent(\"onpropertychange\",this.readPropertyChange)},giveLayout:function(a){a.style.zoom=1;if(a.currentStyle.position==\"static\"){a.style.position=\"relative\"}},copyImageBorders:function(b){var c,a;c={borderStyle:true,borderWidth:true,borderColor:true};for(a in c){if(c.hasOwnProperty(a)){b.vml.color.shape.style[a]=b.currentStyle[a]}}},vmlFill:function(e){if(!e.currentStyle){return}else{var d,f,g,b,a,c;d=e.currentStyle}for(b in e.vml){if(e.vml.hasOwnProperty(b)){e.vml[b].shape.style.zIndex=d.zIndex}}e.runtimeStyle.backgroundColor=\"\";e.runtimeStyle.backgroundImage=\"\";f=true;if(d.backgroundImage!=\"none\"||e.isImg){if(!e.isImg){e.vmlBg=d.backgroundImage;e.vmlBg=e.vmlBg.substr(5,e.vmlBg.lastIndexOf('\")')-5)}else{e.vmlBg=e.src}g=this;if(!g.imgSize[e.vmlBg]){a=document.createElement(\"img\");g.imgSize[e.vmlBg]=a;a.className=g.ns+\"_sizeFinder\";a.runtimeStyle.cssText=\"behavior:none; position:absolute; left:-10000px; top:-10000px; border:none; margin:0; padding:0;\";c=function(){this.width=this.offsetWidth;this.height=this.offsetHeight;g.vmlOffsets(e)};a.attachEvent(\"onload\",c);a.src=e.vmlBg;a.removeAttribute(\"width\");a.removeAttribute(\"height\");document.body.insertBefore(a,document.body.firstChild)}e.vml.image.fill.src=e.vmlBg;f=false}e.vml.image.fill.on=!f;e.vml.image.fill.color=\"none\";e.vml.color.shape.style.backgroundColor=d.backgroundColor;e.runtimeStyle.backgroundImage=\"none\";e.runtimeStyle.backgroundColor=\"transparent\"},vmlOffsets:function(d){var h,n,a,e,g,m,f,l,j,i,k;h=d.currentStyle;n={W:d.clientWidth+1,H:d.clientHeight+1,w:this.imgSize[d.vmlBg].width,h:this.imgSize[d.vmlBg].height,L:d.offsetLeft,T:d.offsetTop,bLW:d.clientLeft,bTW:d.clientTop};a=(n.L+n.bLW==1)?1:0;e=function(b,p,q,c,s,u){b.coordsize=c+\",\"+s;b.coordorigin=u+\",\"+u;b.path=\"m0,0l\"+c+\",0l\"+c+\",\"+s+\"l0,\"+s+\" xe\";b.style.width=c+\"px\";b.style.height=s+\"px\";b.style.left=p+\"px\";b.style.top=q+\"px\"};e(d.vml.color.shape,(n.L+(d.isImg?0:n.bLW)),(n.T+(d.isImg?0:n.bTW)),(n.W-1),(n.H-1),0);e(d.vml.image.shape,(n.L+n.bLW),(n.T+n.bTW),(n.W),(n.H),1);g={X:0,Y:0};if(d.isImg){g.X=parseInt(h.paddingLeft,10)+1;g.Y=parseInt(h.paddingTop,10)+1}else{for(j in g){if(g.hasOwnProperty(j)){this.figurePercentage(g,n,j,h[\"backgroundPosition\"+j])}}}d.vml.image.fill.position=(g.X/n.W)+\",\"+(g.Y/n.H);m=h.backgroundRepeat;f={T:1,R:n.W+a,B:n.H,L:1+a};l={X:{b1:\"L\",b2:\"R\",d:\"W\"},Y:{b1:\"T\",b2:\"B\",d:\"H\"}};if(m!=\"repeat\"||d.isImg){i={T:(g.Y),R:(g.X+n.w),B:(g.Y+n.h),L:(g.X)};if(m.search(\"repeat-\")!=-1){k=m.split(\"repeat-\")[1].toUpperCase();i[l[k].b1]=1;i[l[k].b2]=n[l[k].d]}if(i.B>n.H){i.B=n.H}d.vml.image.shape.style.clip=\"rect(\"+i.T+\"px \"+(i.R+a)+\"px \"+i.B+\"px \"+(i.L+a)+\"px)\"}else{d.vml.image.shape.style.clip=\"rect(\"+f.T+\"px \"+f.R+\"px \"+f.B+\"px \"+f.L+\"px)\"}},figurePercentage:function(d,c,f,a){var b,e;e=true;b=(f==\"X\");switch(a){case\"left\":case\"top\":d[f]=0;break;case\"center\":d[f]=0.5;break;case\"right\":case\"bottom\":d[f]=1;break;default:if(a.search(\"%\")!=-1){d[f]=parseInt(a,10)/100}else{e=false}}d[f]=Math.ceil(e?((c[b?\"W\":\"H\"]*d[f])-(c[b?\"w\":\"h\"]*d[f])):parseInt(a,10));if(d[f]%2===0){d[f]++}return d[f]},fixPng:function(c){c.style.behavior=\"none\";var g,b,f,a,d;if(c.nodeName==\"BODY\"||c.nodeName==\"TD\"||c.nodeName==\"TR\"){return}c.isImg=false;if(c.nodeName==\"IMG\"){if(c.src.toLowerCase().search(/\\.png$/)!=-1){c.isImg=true;c.style.visibility=\"hidden\"}else{return}}else{if(c.currentStyle.backgroundImage.toLowerCase().search(\".png\")==-1){return}}g=DD_belatedPNG;c.vml={color:{},image:{}};b={shape:{},fill:{}};for(a in c.vml){if(c.vml.hasOwnProperty(a)){for(d in b){if(b.hasOwnProperty(d)){f=g.ns+\":\"+d;c.vml[a][d]=document.createElement(f)}}c.vml[a].shape.stroked=false;c.vml[a].shape.appendChild(c.vml[a].fill);c.parentNode.insertBefore(c.vml[a].shape,c)}}c.vml.image.shape.fillcolor=\"none\";c.vml.image.fill.type=\"tile\";c.vml.color.fill.on=false;g.attachHandlers(c);g.giveLayout(c);g.giveLayout(c.offsetParent);c.vmlInitiated=true;g.applyVML(c)}};try{document.execCommand(\"BackgroundImageCache\",false,true)}catch(r){}DD_belatedPNG.createVmlNameSpace();DD_belatedPNG.createVmlStyleSheet();"
  },
  {
    "path": "app/static_dev/js/libs/jquery-1.5.1.js",
    "content": "/*!\n * jQuery JavaScript Library v1.5.1\n * http://jquery.com/\n *\n * Copyright 2011, John Resig\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n * Copyright 2011, The Dojo Foundation\n * Released under the MIT, BSD, and GPL Licenses.\n *\n * Date: Wed Feb 23 13:55:29 2011 -0500\n */\n(function( window, undefined ) {\n\n// Use the correct document accordingly with window argument (sandbox)\nvar document = window.document;\nvar jQuery = (function() {\n\n// Define a local copy of jQuery\nvar jQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\treturn new jQuery.fn.init( selector, context, rootjQuery );\n\t},\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$,\n\n\t// A central reference to the root jQuery(document)\n\trootjQuery,\n\n\t// A simple way to check for HTML strings or ID strings\n\t// (both of which we optimize for)\n\tquickExpr = /^(?:[^<]*(<[\\w\\W]+>)[^>]*$|#([\\w\\-]+)$)/,\n\n\t// Check if a string has a non-whitespace character in it\n\trnotwhite = /\\S/,\n\n\t// Used for trimming whitespace\n\ttrimLeft = /^\\s+/,\n\ttrimRight = /\\s+$/,\n\n\t// Check for digits\n\trdigit = /\\d/,\n\n\t// Match a standalone tag\n\trsingleTag = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>)?$/,\n\n\t// JSON RegExp\n\trvalidchars = /^[\\],:{}\\s]*$/,\n\trvalidescape = /\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g,\n\trvalidtokens = /\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g,\n\trvalidbraces = /(?:^|:|,)(?:\\s*\\[)+/g,\n\n\t// Useragent RegExp\n\trwebkit = /(webkit)[ \\/]([\\w.]+)/,\n\tropera = /(opera)(?:.*version)?[ \\/]([\\w.]+)/,\n\trmsie = /(msie) ([\\w.]+)/,\n\trmozilla = /(mozilla)(?:.*? rv:([\\w.]+))?/,\n\n\t// Keep a UserAgent string for use with jQuery.browser\n\tuserAgent = navigator.userAgent,\n\n\t// For matching the engine and version of the browser\n\tbrowserMatch,\n\n\t// Has the ready events already been bound?\n\treadyBound = false,\n\n\t// The deferred used on DOM ready\n\treadyList,\n\n\t// Promise methods\n\tpromiseMethods = \"then done fail isResolved isRejected promise\".split( \" \" ),\n\n\t// The ready event handler\n\tDOMContentLoaded,\n\n\t// Save a reference to some core methods\n\ttoString = Object.prototype.toString,\n\thasOwn = Object.prototype.hasOwnProperty,\n\tpush = Array.prototype.push,\n\tslice = Array.prototype.slice,\n\ttrim = String.prototype.trim,\n\tindexOf = Array.prototype.indexOf,\n\n\t// [[Class]] -> type pairs\n\tclass2type = {};\n\njQuery.fn = jQuery.prototype = {\n\tconstructor: jQuery,\n\tinit: function( selector, context, rootjQuery ) {\n\t\tvar match, elem, ret, doc;\n\n\t\t// Handle $(\"\"), $(null), or $(undefined)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle $(DOMElement)\n\t\tif ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\t\t}\n\n\t\t// The body element only exists once, optimize finding it\n\t\tif ( selector === \"body\" && !context && document.body ) {\n\t\t\tthis.context = document;\n\t\t\tthis[0] = document.body;\n\t\t\tthis.selector = \"body\";\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\t// Are we dealing with HTML string or an ID?\n\t\t\tmatch = quickExpr.exec( selector );\n\n\t\t\t// Verify a match, and that no context was specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\t\t\t\t\tdoc = (context ? context.ownerDocument || context : document);\n\n\t\t\t\t\t// If a single string is passed in and it's a single tag\n\t\t\t\t\t// just do a createElement and skip the rest\n\t\t\t\t\tret = rsingleTag.exec( selector );\n\n\t\t\t\t\tif ( ret ) {\n\t\t\t\t\t\tif ( jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\t\tselector = [ document.createElement( ret[1] ) ];\n\t\t\t\t\t\t\tjQuery.fn.attr.call( selector, context, true );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tselector = [ doc.createElement( ret[1] ) ];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tret = jQuery.buildFragment( [ match[1] ], [ doc ] );\n\t\t\t\t\t\tselector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.merge( this, selector );\n\n\t\t\t\t// HANDLE: $(\"#id\")\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn (context || rootjQuery).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn rootjQuery.ready( selector );\n\t\t}\n\n\t\tif (selector.selector !== undefined) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t},\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The current version of jQuery being used\n\tjquery: \"1.5.1\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\t// The number of elements contained in the matched element set\n\tsize: function() {\n\t\treturn this.length;\n\t},\n\n\ttoArray: function() {\n\t\treturn slice.call( this, 0 );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num == null ?\n\n\t\t\t// Return a 'clean' array\n\t\t\tthis.toArray() :\n\n\t\t\t// Return just the object\n\t\t\t( num < 0 ? this[ this.length + num ] : this[ num ] );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems, name, selector ) {\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = this.constructor();\n\n\t\tif ( jQuery.isArray( elems ) ) {\n\t\t\tpush.apply( ret, elems );\n\n\t\t} else {\n\t\t\tjQuery.merge( ret, elems );\n\t\t}\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\tret.context = this.context;\n\n\t\tif ( name === \"find\" ) {\n\t\t\tret.selector = this.selector + (this.selector ? \" \" : \"\") + selector;\n\t\t} else if ( name ) {\n\t\t\tret.selector = this.selector + \".\" + name + \"(\" + selector + \")\";\n\t\t}\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tready: function( fn ) {\n\t\t// Attach the listeners\n\t\tjQuery.bindReady();\n\n\t\t// Add the callback\n\t\treadyList.done( fn );\n\n\t\treturn this;\n\t},\n\n\teq: function( i ) {\n\t\treturn i === -1 ?\n\t\t\tthis.slice( i ) :\n\t\t\tthis.slice( i, +i + 1 );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ),\n\t\t\t\"slice\", slice.call(arguments).join(\",\") );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: [].sort,\n\tsplice: [].splice\n};\n\n// Give the init function the jQuery prototype for later instantiation\njQuery.fn.init.prototype = jQuery.fn;\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\t\ttarget = arguments[1] || {};\n\t\t// skip the boolean and the target\n\t\ti = 2;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( length === i ) {\n\t\ttarget = this;\n\t\t--i;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\tnoConflict: function( deep ) {\n\t\twindow.$ = _$;\n\n\t\tif ( deep ) {\n\t\t\twindow.jQuery = _jQuery;\n\t\t}\n\n\t\treturn jQuery;\n\t},\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\t\t// A third-party is pushing the ready event forwards\n\t\tif ( wait === true ) {\n\t\t\tjQuery.readyWait--;\n\t\t}\n\n\t\t// Make sure that the DOM is not already loaded\n\t\tif ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) {\n\t\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\t\tif ( !document.body ) {\n\t\t\t\treturn setTimeout( jQuery.ready, 1 );\n\t\t\t}\n\n\t\t\t// Remember that the DOM is ready\n\t\t\tjQuery.isReady = true;\n\n\t\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If there are functions bound, to execute\n\t\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t\t// Trigger any bound ready events\n\t\t\tif ( jQuery.fn.trigger ) {\n\t\t\t\tjQuery( document ).trigger( \"ready\" ).unbind( \"ready\" );\n\t\t\t}\n\t\t}\n\t},\n\n\tbindReady: function() {\n\t\tif ( readyBound ) {\n\t\t\treturn;\n\t\t}\n\n\t\treadyBound = true;\n\n\t\t// Catch cases where $(document).ready() is called after the\n\t\t// browser event has already occurred.\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\treturn setTimeout( jQuery.ready, 1 );\n\t\t}\n\n\t\t// Mozilla, Opera and webkit nightlies currently support this event\n\t\tif ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", jQuery.ready, false );\n\n\t\t// If IE event model is used\n\t\t} else if ( document.attachEvent ) {\n\t\t\t// ensure firing before onload,\n\t\t\t// maybe late but safe also for iframes\n\t\t\tdocument.attachEvent(\"onreadystatechange\", DOMContentLoaded);\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", jQuery.ready );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar toplevel = false;\n\n\t\t\ttry {\n\t\t\t\ttoplevel = window.frameElement == null;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( document.documentElement.doScroll && toplevel ) {\n\t\t\t\tdoScrollCheck();\n\t\t\t}\n\t\t}\n\t},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\t// A crude way of determining if an object is a window\n\tisWindow: function( obj ) {\n\t\treturn obj && typeof obj === \"object\" && \"setInterval\" in obj;\n\t},\n\n\tisNaN: function( obj ) {\n\t\treturn obj == null || !rdigit.test( obj ) || isNaN( obj );\n\t},\n\n\ttype: function( obj ) {\n\t\treturn obj == null ?\n\t\t\tString( obj ) :\n\t\t\tclass2type[ toString.call(obj) ] || \"object\";\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Not own constructor property must be Object\n\t\tif ( obj.constructor &&\n\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\n\t\tvar key;\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tfor ( var name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\terror: function( msg ) {\n\t\tthrow msg;\n\t},\n\n\tparseJSON: function( data ) {\n\t\tif ( typeof data !== \"string\" || !data ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Make sure leading/trailing whitespace is removed (IE can't handle it)\n\t\tdata = jQuery.trim( data );\n\n\t\t// Make sure the incoming data is actual JSON\n\t\t// Logic borrowed from http://json.org/json2.js\n\t\tif ( rvalidchars.test(data.replace(rvalidescape, \"@\")\n\t\t\t.replace(rvalidtokens, \"]\")\n\t\t\t.replace(rvalidbraces, \"\")) ) {\n\n\t\t\t// Try to use the native JSON parser first\n\t\t\treturn window.JSON && window.JSON.parse ?\n\t\t\t\twindow.JSON.parse( data ) :\n\t\t\t\t(new Function(\"return \" + data))();\n\n\t\t} else {\n\t\t\tjQuery.error( \"Invalid JSON: \" + data );\n\t\t}\n\t},\n\n\t// Cross-browser xml parsing\n\t// (xml & tmp used internally)\n\tparseXML: function( data , xml , tmp ) {\n\n\t\tif ( window.DOMParser ) { // Standard\n\t\t\ttmp = new DOMParser();\n\t\t\txml = tmp.parseFromString( data , \"text/xml\" );\n\t\t} else { // IE\n\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\txml.async = \"false\";\n\t\t\txml.loadXML( data );\n\t\t}\n\n\t\ttmp = xml.documentElement;\n\n\t\tif ( ! tmp || ! tmp.nodeName || tmp.nodeName === \"parsererror\" ) {\n\t\t\tjQuery.error( \"Invalid XML: \" + data );\n\t\t}\n\n\t\treturn xml;\n\t},\n\n\tnoop: function() {},\n\n\t// Evalulates a script in a global context\n\tglobalEval: function( data ) {\n\t\tif ( data && rnotwhite.test(data) ) {\n\t\t\t// Inspired by code by Andrea Giammarchi\n\t\t\t// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html\n\t\t\tvar head = document.head || document.getElementsByTagName( \"head\" )[0] || document.documentElement,\n\t\t\t\tscript = document.createElement( \"script\" );\n\n\t\t\tif ( jQuery.support.scriptEval() ) {\n\t\t\t\tscript.appendChild( document.createTextNode( data ) );\n\t\t\t} else {\n\t\t\t\tscript.text = data;\n\t\t\t}\n\n\t\t\t// Use insertBefore instead of appendChild to circumvent an IE6 bug.\n\t\t\t// This arises when a base node is used (#2709).\n\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\thead.removeChild( script );\n\t\t}\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( object, callback, args ) {\n\t\tvar name, i = 0,\n\t\t\tlength = object.length,\n\t\t\tisObj = length === undefined || jQuery.isFunction(object);\n\n\t\tif ( args ) {\n\t\t\tif ( isObj ) {\n\t\t\t\tfor ( name in object ) {\n\t\t\t\t\tif ( callback.apply( object[ name ], args ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( ; i < length; ) {\n\t\t\t\t\tif ( callback.apply( object[ i++ ], args ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isObj ) {\n\t\t\t\tfor ( name in object ) {\n\t\t\t\t\tif ( callback.call( object[ name ], name, object[ name ] ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( var value = object[0];\n\t\t\t\t\ti < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}\n\t\t\t}\n\t\t}\n\n\t\treturn object;\n\t},\n\n\t// Use native String.trim function wherever possible\n\ttrim: trim ?\n\t\tfunction( text ) {\n\t\t\treturn text == null ?\n\t\t\t\t\"\" :\n\t\t\t\ttrim.call( text );\n\t\t} :\n\n\t\t// Otherwise use our own trimming functionality\n\t\tfunction( text ) {\n\t\t\treturn text == null ?\n\t\t\t\t\"\" :\n\t\t\t\ttext.toString().replace( trimLeft, \"\" ).replace( trimRight, \"\" );\n\t\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( array, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( array != null ) {\n\t\t\t// The window, strings (and functions) also have 'length'\n\t\t\t// The extra typeof function check is to prevent crashes\n\t\t\t// in Safari 2 (See: #3039)\n\t\t\t// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930\n\t\t\tvar type = jQuery.type(array);\n\n\t\t\tif ( array.length == null || type === \"string\" || type === \"function\" || type === \"regexp\" || jQuery.isWindow( array ) ) {\n\t\t\t\tpush.call( ret, array );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( ret, array );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, array ) {\n\t\tif ( array.indexOf ) {\n\t\t\treturn array.indexOf( elem );\n\t\t}\n\n\t\tfor ( var i = 0, length = array.length; i < length; i++ ) {\n\t\t\tif ( array[ i ] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar i = first.length,\n\t\t\tj = 0;\n\n\t\tif ( typeof second.length === \"number\" ) {\n\t\t\tfor ( var l = second.length; j < l; j++ ) {\n\t\t\t\tfirst[ i++ ] = second[ j ];\n\t\t\t}\n\n\t\t} else {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, inv ) {\n\t\tvar ret = [], retVal;\n\t\tinv = !!inv;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( var i = 0, length = elems.length; i < length; i++ ) {\n\t\t\tretVal = !!callback( elems[ i ], i );\n\t\t\tif ( inv !== retVal ) {\n\t\t\t\tret.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar ret = [], value;\n\n\t\t// Go through the array, translating each of the items to their\n\t\t// new value (or values).\n\t\tfor ( var i = 0, length = elems.length; i < length; i++ ) {\n\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\tif ( value != null ) {\n\t\t\t\tret[ ret.length ] = value;\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn ret.concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\tproxy: function( fn, proxy, thisObject ) {\n\t\tif ( arguments.length === 2 ) {\n\t\t\tif ( typeof proxy === \"string\" ) {\n\t\t\t\tthisObject = fn;\n\t\t\t\tfn = thisObject[ proxy ];\n\t\t\t\tproxy = undefined;\n\n\t\t\t} else if ( proxy && !jQuery.isFunction( proxy ) ) {\n\t\t\t\tthisObject = proxy;\n\t\t\t\tproxy = undefined;\n\t\t\t}\n\t\t}\n\n\t\tif ( !proxy && fn ) {\n\t\t\tproxy = function() {\n\t\t\t\treturn fn.apply( thisObject || this, arguments );\n\t\t\t};\n\t\t}\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tif ( fn ) {\n\t\t\tproxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;\n\t\t}\n\n\t\t// So proxy can be declared as an argument\n\t\treturn proxy;\n\t},\n\n\t// Mutifunctional method to get and set values to a collection\n\t// The value/s can be optionally by executed if its a function\n\taccess: function( elems, key, value, exec, fn, pass ) {\n\t\tvar length = elems.length;\n\n\t\t// Setting many attributes\n\t\tif ( typeof key === \"object\" ) {\n\t\t\tfor ( var k in key ) {\n\t\t\t\tjQuery.access( elems, k, key[k], exec, fn, value );\n\t\t\t}\n\t\t\treturn elems;\n\t\t}\n\n\t\t// Setting one attribute\n\t\tif ( value !== undefined ) {\n\t\t\t// Optionally, function values get executed if exec is true\n\t\t\texec = !pass && exec && jQuery.isFunction(value);\n\n\t\t\tfor ( var i = 0; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );\n\t\t\t}\n\n\t\t\treturn elems;\n\t\t}\n\n\t\t// Getting an attribute\n\t\treturn length ? fn( elems[0], key ) : undefined;\n\t},\n\n\tnow: function() {\n\t\treturn (new Date()).getTime();\n\t},\n\n\t// Create a simple deferred (one callbacks list)\n\t_Deferred: function() {\n\t\tvar // callbacks list\n\t\t\tcallbacks = [],\n\t\t\t// stored [ context , args ]\n\t\t\tfired,\n\t\t\t// to avoid firing when already doing so\n\t\t\tfiring,\n\t\t\t// flag to know if the deferred has been cancelled\n\t\t\tcancelled,\n\t\t\t// the deferred itself\n\t\t\tdeferred  = {\n\n\t\t\t\t// done( f1, f2, ...)\n\t\t\t\tdone: function() {\n\t\t\t\t\tif ( !cancelled ) {\n\t\t\t\t\t\tvar args = arguments,\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tlength,\n\t\t\t\t\t\t\telem,\n\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\t_fired;\n\t\t\t\t\t\tif ( fired ) {\n\t\t\t\t\t\t\t_fired = fired;\n\t\t\t\t\t\t\tfired = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor ( i = 0, length = args.length; i < length; i++ ) {\n\t\t\t\t\t\t\telem = args[ i ];\n\t\t\t\t\t\t\ttype = jQuery.type( elem );\n\t\t\t\t\t\t\tif ( type === \"array\" ) {\n\t\t\t\t\t\t\t\tdeferred.done.apply( deferred, elem );\n\t\t\t\t\t\t\t} else if ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tcallbacks.push( elem );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( _fired ) {\n\t\t\t\t\t\t\tdeferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// resolve with given context and args\n\t\t\t\tresolveWith: function( context, args ) {\n\t\t\t\t\tif ( !cancelled && !fired && !firing ) {\n\t\t\t\t\t\tfiring = 1;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\twhile( callbacks[ 0 ] ) {\n\t\t\t\t\t\t\t\tcallbacks.shift().apply( context, args );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// We have to add a catch block for\n\t\t\t\t\t\t// IE prior to 8 or else the finally\n\t\t\t\t\t\t// block will never get executed\n\t\t\t\t\t\tcatch (e) {\n\t\t\t\t\t\t\tthrow e;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinally {\n\t\t\t\t\t\t\tfired = [ context, args ];\n\t\t\t\t\t\t\tfiring = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// resolve with this as context and given arguments\n\t\t\t\tresolve: function() {\n\t\t\t\t\tdeferred.resolveWith( jQuery.isFunction( this.promise ) ? this.promise() : this, arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Has this deferred been resolved?\n\t\t\t\tisResolved: function() {\n\t\t\t\t\treturn !!( firing || fired );\n\t\t\t\t},\n\n\t\t\t\t// Cancel\n\t\t\t\tcancel: function() {\n\t\t\t\t\tcancelled = 1;\n\t\t\t\t\tcallbacks = [];\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\treturn deferred;\n\t},\n\n\t// Full fledged deferred (two callbacks list)\n\tDeferred: function( func ) {\n\t\tvar deferred = jQuery._Deferred(),\n\t\t\tfailDeferred = jQuery._Deferred(),\n\t\t\tpromise;\n\t\t// Add errorDeferred methods, then and promise\n\t\tjQuery.extend( deferred, {\n\t\t\tthen: function( doneCallbacks, failCallbacks ) {\n\t\t\t\tdeferred.done( doneCallbacks ).fail( failCallbacks );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tfail: failDeferred.done,\n\t\t\trejectWith: failDeferred.resolveWith,\n\t\t\treject: failDeferred.resolve,\n\t\t\tisRejected: failDeferred.isResolved,\n\t\t\t// Get a promise for this deferred\n\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\tpromise: function( obj ) {\n\t\t\t\tif ( obj == null ) {\n\t\t\t\t\tif ( promise ) {\n\t\t\t\t\t\treturn promise;\n\t\t\t\t\t}\n\t\t\t\t\tpromise = obj = {};\n\t\t\t\t}\n\t\t\t\tvar i = promiseMethods.length;\n\t\t\t\twhile( i-- ) {\n\t\t\t\t\tobj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];\n\t\t\t\t}\n\t\t\t\treturn obj;\n\t\t\t}\n\t\t} );\n\t\t// Make sure only one callback list will be used\n\t\tdeferred.done( failDeferred.cancel ).fail( deferred.cancel );\n\t\t// Unexpose cancel\n\t\tdelete deferred.cancel;\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( object ) {\n\t\tvar lastIndex = arguments.length,\n\t\t\tdeferred = lastIndex <= 1 && object && jQuery.isFunction( object.promise ) ?\n\t\t\t\tobject :\n\t\t\t\tjQuery.Deferred(),\n\t\t\tpromise = deferred.promise();\n\n\t\tif ( lastIndex > 1 ) {\n\t\t\tvar array = slice.call( arguments, 0 ),\n\t\t\t\tcount = lastIndex,\n\t\t\t\tiCallback = function( index ) {\n\t\t\t\t\treturn function( value ) {\n\t\t\t\t\t\tarray[ index ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value;\n\t\t\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\t\t\tdeferred.resolveWith( promise, array );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\twhile( ( lastIndex-- ) ) {\n\t\t\t\tobject = array[ lastIndex ];\n\t\t\t\tif ( object && jQuery.isFunction( object.promise ) ) {\n\t\t\t\t\tobject.promise().then( iCallback(lastIndex), deferred.reject );\n\t\t\t\t} else {\n\t\t\t\t\t--count;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( !count ) {\n\t\t\t\tdeferred.resolveWith( promise, array );\n\t\t\t}\n\t\t} else if ( deferred !== object ) {\n\t\t\tdeferred.resolve( object );\n\t\t}\n\t\treturn promise;\n\t},\n\n\t// Use of jQuery.browser is frowned upon.\n\t// More details: http://docs.jquery.com/Utilities/jQuery.browser\n\tuaMatch: function( ua ) {\n\t\tua = ua.toLowerCase();\n\n\t\tvar match = rwebkit.exec( ua ) ||\n\t\t\tropera.exec( ua ) ||\n\t\t\trmsie.exec( ua ) ||\n\t\t\tua.indexOf(\"compatible\") < 0 && rmozilla.exec( ua ) ||\n\t\t\t[];\n\n\t\treturn { browser: match[1] || \"\", version: match[2] || \"0\" };\n\t},\n\n\tsub: function() {\n\t\tfunction jQuerySubclass( selector, context ) {\n\t\t\treturn new jQuerySubclass.fn.init( selector, context );\n\t\t}\n\t\tjQuery.extend( true, jQuerySubclass, this );\n\t\tjQuerySubclass.superclass = this;\n\t\tjQuerySubclass.fn = jQuerySubclass.prototype = this();\n\t\tjQuerySubclass.fn.constructor = jQuerySubclass;\n\t\tjQuerySubclass.subclass = this.subclass;\n\t\tjQuerySubclass.fn.init = function init( selector, context ) {\n\t\t\tif ( context && context instanceof jQuery && !(context instanceof jQuerySubclass) ) {\n\t\t\t\tcontext = jQuerySubclass(context);\n\t\t\t}\n\n\t\t\treturn jQuery.fn.init.call( this, selector, context, rootjQuerySubclass );\n\t\t};\n\t\tjQuerySubclass.fn.init.prototype = jQuerySubclass.fn;\n\t\tvar rootjQuerySubclass = jQuerySubclass(document);\n\t\treturn jQuerySubclass;\n\t},\n\n\tbrowser: {}\n});\n\n// Create readyList deferred\nreadyList = jQuery._Deferred();\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nbrowserMatch = jQuery.uaMatch( userAgent );\nif ( browserMatch.browser ) {\n\tjQuery.browser[ browserMatch.browser ] = true;\n\tjQuery.browser.version = browserMatch.version;\n}\n\n// Deprecated, use jQuery.browser.webkit instead\nif ( jQuery.browser.webkit ) {\n\tjQuery.browser.safari = true;\n}\n\nif ( indexOf ) {\n\tjQuery.inArray = function( elem, array ) {\n\t\treturn indexOf.call( array, elem );\n\t};\n}\n\n// IE doesn't match non-breaking spaces with \\s\nif ( rnotwhite.test( \"\\xA0\" ) ) {\n\ttrimLeft = /^[\\s\\xA0]+/;\n\ttrimRight = /[\\s\\xA0]+$/;\n}\n\n// All jQuery objects should point back to these\nrootjQuery = jQuery(document);\n\n// Cleanup functions for the document ready method\nif ( document.addEventListener ) {\n\tDOMContentLoaded = function() {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n\t\tjQuery.ready();\n\t};\n\n} else if ( document.attachEvent ) {\n\tDOMContentLoaded = function() {\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\tdocument.detachEvent( \"onreadystatechange\", DOMContentLoaded );\n\t\t\tjQuery.ready();\n\t\t}\n\t};\n}\n\n// The DOM ready check for Internet Explorer\nfunction doScrollCheck() {\n\tif ( jQuery.isReady ) {\n\t\treturn;\n\t}\n\n\ttry {\n\t\t// If IE is used, use the trick by Diego Perini\n\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\tdocument.documentElement.doScroll(\"left\");\n\t} catch(e) {\n\t\tsetTimeout( doScrollCheck, 1 );\n\t\treturn;\n\t}\n\n\t// and execute any waiting functions\n\tjQuery.ready();\n}\n\n// Expose jQuery to the global object\nreturn jQuery;\n\n})();\n\n\n(function() {\n\n\tjQuery.support = {};\n\n\tvar div = document.createElement(\"div\");\n\n\tdiv.style.display = \"none\";\n\tdiv.innerHTML = \"   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>\";\n\n\tvar all = div.getElementsByTagName(\"*\"),\n\t\ta = div.getElementsByTagName(\"a\")[0],\n\t\tselect = document.createElement(\"select\"),\n\t\topt = select.appendChild( document.createElement(\"option\") ),\n\t\tinput = div.getElementsByTagName(\"input\")[0];\n\n\t// Can't get basic test support\n\tif ( !all || !all.length || !a ) {\n\t\treturn;\n\t}\n\n\tjQuery.support = {\n\t\t// IE strips leading whitespace when .innerHTML is used\n\t\tleadingWhitespace: div.firstChild.nodeType === 3,\n\n\t\t// Make sure that tbody elements aren't automatically inserted\n\t\t// IE will insert them into empty tables\n\t\ttbody: !div.getElementsByTagName(\"tbody\").length,\n\n\t\t// Make sure that link elements get serialized correctly by innerHTML\n\t\t// This requires a wrapper element in IE\n\t\thtmlSerialize: !!div.getElementsByTagName(\"link\").length,\n\n\t\t// Get the style information from getAttribute\n\t\t// (IE uses .cssText insted)\n\t\tstyle: /red/.test( a.getAttribute(\"style\") ),\n\n\t\t// Make sure that URLs aren't manipulated\n\t\t// (IE normalizes it by default)\n\t\threfNormalized: a.getAttribute(\"href\") === \"/a\",\n\n\t\t// Make sure that element opacity exists\n\t\t// (IE uses filter instead)\n\t\t// Use a regex to work around a WebKit issue. See #5145\n\t\topacity: /^0.55$/.test( a.style.opacity ),\n\n\t\t// Verify style float existence\n\t\t// (IE uses styleFloat instead of cssFloat)\n\t\tcssFloat: !!a.style.cssFloat,\n\n\t\t// Make sure that if no value is specified for a checkbox\n\t\t// that it defaults to \"on\".\n\t\t// (WebKit defaults to \"\" instead)\n\t\tcheckOn: input.value === \"on\",\n\n\t\t// Make sure that a selected-by-default option has a working selected property.\n\t\t// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n\t\toptSelected: opt.selected,\n\n\t\t// Will be defined later\n\t\tdeleteExpando: true,\n\t\toptDisabled: false,\n\t\tcheckClone: false,\n\t\tnoCloneEvent: true,\n\t\tnoCloneChecked: true,\n\t\tboxModel: null,\n\t\tinlineBlockNeedsLayout: false,\n\t\tshrinkWrapBlocks: false,\n\t\treliableHiddenOffsets: true\n\t};\n\n\tinput.checked = true;\n\tjQuery.support.noCloneChecked = input.cloneNode( true ).checked;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as diabled)\n\tselect.disabled = true;\n\tjQuery.support.optDisabled = !opt.disabled;\n\n\tvar _scriptEval = null;\n\tjQuery.support.scriptEval = function() {\n\t\tif ( _scriptEval === null ) {\n\t\t\tvar root = document.documentElement,\n\t\t\t\tscript = document.createElement(\"script\"),\n\t\t\t\tid = \"script\" + jQuery.now();\n\n\t\t\ttry {\n\t\t\t\tscript.appendChild( document.createTextNode( \"window.\" + id + \"=1;\" ) );\n\t\t\t} catch(e) {}\n\n\t\t\troot.insertBefore( script, root.firstChild );\n\n\t\t\t// Make sure that the execution of code works by injecting a script\n\t\t\t// tag with appendChild/createTextNode\n\t\t\t// (IE doesn't support this, fails, and uses .text instead)\n\t\t\tif ( window[ id ] ) {\n\t\t\t\t_scriptEval = true;\n\t\t\t\tdelete window[ id ];\n\t\t\t} else {\n\t\t\t\t_scriptEval = false;\n\t\t\t}\n\n\t\t\troot.removeChild( script );\n\t\t\t// release memory in IE\n\t\t\troot = script = id  = null;\n\t\t}\n\n\t\treturn _scriptEval;\n\t};\n\n\t// Test to see if it's possible to delete an expando from an element\n\t// Fails in Internet Explorer\n\ttry {\n\t\tdelete div.test;\n\n\t} catch(e) {\n\t\tjQuery.support.deleteExpando = false;\n\t}\n\n\tif ( !div.addEventListener && div.attachEvent && div.fireEvent ) {\n\t\tdiv.attachEvent(\"onclick\", function click() {\n\t\t\t// Cloning a node shouldn't copy over any\n\t\t\t// bound event handlers (IE does this)\n\t\t\tjQuery.support.noCloneEvent = false;\n\t\t\tdiv.detachEvent(\"onclick\", click);\n\t\t});\n\t\tdiv.cloneNode(true).fireEvent(\"onclick\");\n\t}\n\n\tdiv = document.createElement(\"div\");\n\tdiv.innerHTML = \"<input type='radio' name='radiotest' checked='checked'/>\";\n\n\tvar fragment = document.createDocumentFragment();\n\tfragment.appendChild( div.firstChild );\n\n\t// WebKit doesn't clone checked state correctly in fragments\n\tjQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;\n\n\t// Figure out if the W3C box model works as expected\n\t// document.body must exist before we can do this\n\tjQuery(function() {\n\t\tvar div = document.createElement(\"div\"),\n\t\t\tbody = document.getElementsByTagName(\"body\")[0];\n\n\t\t// Frameset documents with no body should not run this code\n\t\tif ( !body ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdiv.style.width = div.style.paddingLeft = \"1px\";\n\t\tbody.appendChild( div );\n\t\tjQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;\n\n\t\tif ( \"zoom\" in div.style ) {\n\t\t\t// Check if natively block-level elements act like inline-block\n\t\t\t// elements when setting their display to 'inline' and giving\n\t\t\t// them layout\n\t\t\t// (IE < 8 does this)\n\t\t\tdiv.style.display = \"inline\";\n\t\t\tdiv.style.zoom = 1;\n\t\t\tjQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;\n\n\t\t\t// Check if elements with layout shrink-wrap their children\n\t\t\t// (IE 6 does this)\n\t\t\tdiv.style.display = \"\";\n\t\t\tdiv.innerHTML = \"<div style='width:4px;'></div>\";\n\t\t\tjQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;\n\t\t}\n\n\t\tdiv.innerHTML = \"<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>\";\n\t\tvar tds = div.getElementsByTagName(\"td\");\n\n\t\t// Check if table cells still have offsetWidth/Height when they are set\n\t\t// to display:none and there are still other visible table cells in a\n\t\t// table row; if so, offsetWidth/Height are not reliable for use when\n\t\t// determining if an element has been hidden directly using\n\t\t// display:none (it is still safe to use offsets if a parent element is\n\t\t// hidden; don safety goggles and see bug #4512 for more information).\n\t\t// (only IE 8 fails this test)\n\t\tjQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;\n\n\t\ttds[0].style.display = \"\";\n\t\ttds[1].style.display = \"none\";\n\n\t\t// Check if empty table cells still have offsetWidth/Height\n\t\t// (IE < 8 fail this test)\n\t\tjQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;\n\t\tdiv.innerHTML = \"\";\n\n\t\tbody.removeChild( div ).style.display = \"none\";\n\t\tdiv = tds = null;\n\t});\n\n\t// Technique from Juriy Zaytsev\n\t// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/\n\tvar eventSupported = function( eventName ) {\n\t\tvar el = document.createElement(\"div\");\n\t\teventName = \"on\" + eventName;\n\n\t\t// We only care about the case where non-standard event systems\n\t\t// are used, namely in IE. Short-circuiting here helps us to\n\t\t// avoid an eval call (in setAttribute) which can cause CSP\n\t\t// to go haywire. See: https://developer.mozilla.org/en/Security/CSP\n\t\tif ( !el.attachEvent ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tvar isSupported = (eventName in el);\n\t\tif ( !isSupported ) {\n\t\t\tel.setAttribute(eventName, \"return;\");\n\t\t\tisSupported = typeof el[eventName] === \"function\";\n\t\t}\n\t\tel = null;\n\n\t\treturn isSupported;\n\t};\n\n\tjQuery.support.submitBubbles = eventSupported(\"submit\");\n\tjQuery.support.changeBubbles = eventSupported(\"change\");\n\n\t// release memory in IE\n\tdiv = all = a = null;\n})();\n\n\n\nvar rbrace = /^(?:\\{.*\\}|\\[.*\\])$/;\n\njQuery.extend({\n\tcache: {},\n\n\t// Please use with caution\n\tuuid: 0,\n\n\t// Unique for each copy of jQuery on the page\n\t// Non-digits removed to match rinlinejQuery\n\texpando: \"jQuery\" + ( jQuery.fn.jquery + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// The following elements throw uncatchable exceptions if you\n\t// attempt to add expando properties to them.\n\tnoData: {\n\t\t\"embed\": true,\n\t\t// Ban all objects except for Flash (which handle expandos)\n\t\t\"object\": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\",\n\t\t\"applet\": true\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data, pvt /* Internal Use Only */ ) {\n\t\tif ( !jQuery.acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar internalKey = jQuery.expando, getByName = typeof name === \"string\", thisCache,\n\n\t\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t\t// can't GC object references properly across the DOM-JS boundary\n\t\t\tisNode = elem.nodeType,\n\n\t\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t\t// attached directly to the object so GC can occur automatically\n\t\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\t\tid = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;\n\n\t\t// Avoid doing any more work than we need to when trying to get data on an\n\t\t// object that has no data at all\n\t\tif ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !id ) {\n\t\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t\t// ends up in the global cache\n\t\t\tif ( isNode ) {\n\t\t\t\telem[ jQuery.expando ] = id = ++jQuery.uuid;\n\t\t\t} else {\n\t\t\t\tid = jQuery.expando;\n\t\t\t}\n\t\t}\n\n\t\tif ( !cache[ id ] ) {\n\t\t\tcache[ id ] = {};\n\n\t\t\t// TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery\n\t\t\t// metadata on plain JS objects when the object is serialized using\n\t\t\t// JSON.stringify\n\t\t\tif ( !isNode ) {\n\t\t\t\tcache[ id ].toJSON = jQuery.noop;\n\t\t\t}\n\t\t}\n\n\t\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t\t// shallow copied over onto the existing cache\n\t\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\t\tif ( pvt ) {\n\t\t\t\tcache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);\n\t\t\t} else {\n\t\t\t\tcache[ id ] = jQuery.extend(cache[ id ], name);\n\t\t\t}\n\t\t}\n\n\t\tthisCache = cache[ id ];\n\n\t\t// Internal jQuery data is stored in a separate object inside the object's data\n\t\t// cache in order to avoid key collisions between internal data and user-defined\n\t\t// data\n\t\tif ( pvt ) {\n\t\t\tif ( !thisCache[ internalKey ] ) {\n\t\t\t\tthisCache[ internalKey ] = {};\n\t\t\t}\n\n\t\t\tthisCache = thisCache[ internalKey ];\n\t\t}\n\n\t\tif ( data !== undefined ) {\n\t\t\tthisCache[ name ] = data;\n\t\t}\n\n\t\t// TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should\n\t\t// not attempt to inspect the internal events object using jQuery.data, as this\n\t\t// internal data object is undocumented and subject to change.\n\t\tif ( name === \"events\" && !thisCache[name] ) {\n\t\t\treturn thisCache[ internalKey ] && thisCache[ internalKey ].events;\n\t\t}\n\n\t\treturn getByName ? thisCache[ name ] : thisCache;\n\t},\n\n\tremoveData: function( elem, name, pvt /* Internal Use Only */ ) {\n\t\tif ( !jQuery.acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar internalKey = jQuery.expando, isNode = elem.nodeType,\n\n\t\t\t// See jQuery.data for more information\n\t\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t\t// See jQuery.data for more information\n\t\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t\t// If there is already no cache entry for this object, there is no\n\t\t// purpose in continuing\n\t\tif ( !cache[ id ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( name ) {\n\t\t\tvar thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];\n\n\t\t\tif ( thisCache ) {\n\t\t\t\tdelete thisCache[ name ];\n\n\t\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t\t// and let the cache object itself get destroyed\n\t\t\t\tif ( !isEmptyDataObject(thisCache) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// See jQuery.data for more information\n\t\tif ( pvt ) {\n\t\t\tdelete cache[ id ][ internalKey ];\n\n\t\t\t// Don't destroy the parent cache unless the internal data object\n\t\t\t// had been the only thing left in it\n\t\t\tif ( !isEmptyDataObject(cache[ id ]) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tvar internalCache = cache[ id ][ internalKey ];\n\n\t\t// Browsers that fail expando deletion also refuse to delete expandos on\n\t\t// the window, but it will allow it on all other JS objects; other browsers\n\t\t// don't care\n\t\tif ( jQuery.support.deleteExpando || cache != window ) {\n\t\t\tdelete cache[ id ];\n\t\t} else {\n\t\t\tcache[ id ] = null;\n\t\t}\n\n\t\t// We destroyed the entire user cache at once because it's faster than\n\t\t// iterating through each key, but we need to continue to persist internal\n\t\t// data if it existed\n\t\tif ( internalCache ) {\n\t\t\tcache[ id ] = {};\n\t\t\t// TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery\n\t\t\t// metadata on plain JS objects when the object is serialized using\n\t\t\t// JSON.stringify\n\t\t\tif ( !isNode ) {\n\t\t\t\tcache[ id ].toJSON = jQuery.noop;\n\t\t\t}\n\n\t\t\tcache[ id ][ internalKey ] = internalCache;\n\n\t\t// Otherwise, we need to eliminate the expando on the node to avoid\n\t\t// false lookups in the cache for entries that no longer exist\n\t\t} else if ( isNode ) {\n\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t// we must handle all of these cases\n\t\t\tif ( jQuery.support.deleteExpando ) {\n\t\t\t\tdelete elem[ jQuery.expando ];\n\t\t\t} else if ( elem.removeAttribute ) {\n\t\t\t\telem.removeAttribute( jQuery.expando );\n\t\t\t} else {\n\t\t\t\telem[ jQuery.expando ] = null;\n\t\t\t}\n\t\t}\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn jQuery.data( elem, name, data, true );\n\t},\n\n\t// A method for determining if a DOM node can handle the data expando\n\tacceptData: function( elem ) {\n\t\tif ( elem.nodeName ) {\n\t\t\tvar match = jQuery.noData[ elem.nodeName.toLowerCase() ];\n\n\t\t\tif ( match ) {\n\t\t\t\treturn !(match === true || elem.getAttribute(\"classid\") !== match);\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar data = null;\n\n\t\tif ( typeof key === \"undefined\" ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( this[0] );\n\n\t\t\t\tif ( this[0].nodeType === 1 ) {\n\t\t\t\t\tvar attr = this[0].attributes, name;\n\t\t\t\t\tfor ( var i = 0, l = attr.length; i < l; i++ ) {\n\t\t\t\t\t\tname = attr[i].name;\n\n\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\tname = name.substr( 5 );\n\t\t\t\t\t\t\tdataAttr( this[0], name, data[ name ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t} else if ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\tvar parts = key.split(\".\");\n\t\tparts[1] = parts[1] ? \".\" + parts[1] : \"\";\n\n\t\tif ( value === undefined ) {\n\t\t\tdata = this.triggerHandler(\"getData\" + parts[1] + \"!\", [parts[0]]);\n\n\t\t\t// Try to fetch any internally stored data first\n\t\t\tif ( data === undefined && this.length ) {\n\t\t\t\tdata = jQuery.data( this[0], key );\n\t\t\t\tdata = dataAttr( this[0], key, data );\n\t\t\t}\n\n\t\t\treturn data === undefined && parts[1] ?\n\t\t\t\tthis.data( parts[0] ) :\n\t\t\t\tdata;\n\n\t\t} else {\n\t\t\treturn this.each(function() {\n\t\t\t\tvar $this = jQuery( this ),\n\t\t\t\t\targs = [ parts[0], value ];\n\n\t\t\t\t$this.triggerHandler( \"setData\" + parts[1] + \"!\", args );\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t\t$this.triggerHandler( \"changeData\" + parts[1] + \"!\", args );\n\t\t\t});\n\t\t}\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tdata = elem.getAttribute( \"data-\" + key );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\tdata === \"false\" ? false :\n\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t!jQuery.isNaN( data ) ? parseFloat( data ) :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON\n// property to be considered empty objects; this property always exists in\n// order to make sure JSON.stringify does not expose internal metadata\nfunction isEmptyDataObject( obj ) {\n\tfor ( var name in obj ) {\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n\n\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\ttype = (type || \"fx\") + \"queue\";\n\t\tvar q = jQuery._data( elem, type );\n\n\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\tif ( !data ) {\n\t\t\treturn q || [];\n\t\t}\n\n\t\tif ( !q || jQuery.isArray(data) ) {\n\t\t\tq = jQuery._data( elem, type, jQuery.makeArray(data) );\n\n\t\t} else {\n\t\t\tq.push( data );\n\t\t}\n\n\t\treturn q;\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tfn = queue.shift();\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift(\"inprogress\");\n\t\t\t}\n\n\t\t\tfn.call(elem, function() {\n\t\t\t\tjQuery.dequeue(elem, type);\n\t\t\t});\n\t\t}\n\n\t\tif ( !queue.length ) {\n\t\t\tjQuery.removeData( elem, type + \"queue\", true );\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t}\n\n\t\tif ( data === undefined ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\t\treturn this.each(function( i ) {\n\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\n\t// Based off of the plugin by Clint Helfers, with permission.\n\t// http://blindsignals.com/index.php/2009/07/jquery-delay/\n\tdelay: function( time, type ) {\n\t\ttime = jQuery.fx ? jQuery.fx.speeds[time] || time : time;\n\t\ttype = type || \"fx\";\n\n\t\treturn this.queue( type, function() {\n\t\t\tvar elem = this;\n\t\t\tsetTimeout(function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t}, time );\n\t\t});\n\t},\n\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t}\n});\n\n\n\n\nvar rclass = /[\\n\\t\\r]/g,\n\trspaces = /\\s+/,\n\trreturn = /\\r/g,\n\trspecialurl = /^(?:href|src|style)$/,\n\trtype = /^(?:button|input)$/i,\n\trfocusable = /^(?:button|input|object|select|textarea)$/i,\n\trclickable = /^a(?:rea)?$/i,\n\trradiocheck = /^(?:radio|checkbox)$/i;\n\njQuery.props = {\n\t\"for\": \"htmlFor\",\n\t\"class\": \"className\",\n\treadonly: \"readOnly\",\n\tmaxlength: \"maxLength\",\n\tcellspacing: \"cellSpacing\",\n\trowspan: \"rowSpan\",\n\tcolspan: \"colSpan\",\n\ttabindex: \"tabIndex\",\n\tusemap: \"useMap\",\n\tframeborder: \"frameBorder\"\n};\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn jQuery.access( this, name, value, true, jQuery.attr );\n\t},\n\n\tremoveAttr: function( name, fn ) {\n\t\treturn this.each(function(){\n\t\t\tjQuery.attr( this, name, \"\" );\n\t\t\tif ( this.nodeType === 1 ) {\n\t\t\t\tthis.removeAttribute( name );\n\t\t\t}\n\t\t});\n\t},\n\n\taddClass: function( value ) {\n\t\tif ( jQuery.isFunction(value) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery(this);\n\t\t\t\tself.addClass( value.call(this, i, self.attr(\"class\")) );\n\t\t\t});\n\t\t}\n\n\t\tif ( value && typeof value === \"string\" ) {\n\t\t\tvar classNames = (value || \"\").split( rspaces );\n\n\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\tvar elem = this[i];\n\n\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\tif ( !elem.className ) {\n\t\t\t\t\t\telem.className = value;\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar className = \" \" + elem.className + \" \",\n\t\t\t\t\t\t\tsetClass = elem.className;\n\n\t\t\t\t\t\tfor ( var c = 0, cl = classNames.length; c < cl; c++ ) {\n\t\t\t\t\t\t\tif ( className.indexOf( \" \" + classNames[c] + \" \" ) < 0 ) {\n\t\t\t\t\t\t\t\tsetClass += \" \" + classNames[c];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telem.className = jQuery.trim( setClass );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tif ( jQuery.isFunction(value) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery(this);\n\t\t\t\tself.removeClass( value.call(this, i, self.attr(\"class\")) );\n\t\t\t});\n\t\t}\n\n\t\tif ( (value && typeof value === \"string\") || value === undefined ) {\n\t\t\tvar classNames = (value || \"\").split( rspaces );\n\n\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\tvar elem = this[i];\n\n\t\t\t\tif ( elem.nodeType === 1 && elem.className ) {\n\t\t\t\t\tif ( value ) {\n\t\t\t\t\t\tvar className = (\" \" + elem.className + \" \").replace(rclass, \" \");\n\t\t\t\t\t\tfor ( var c = 0, cl = classNames.length; c < cl; c++ ) {\n\t\t\t\t\t\t\tclassName = className.replace(\" \" + classNames[c] + \" \", \" \");\n\t\t\t\t\t\t}\n\t\t\t\t\t\telem.className = jQuery.trim( className );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\telem.className = \"\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisBool = typeof stateVal === \"boolean\";\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery(this);\n\t\t\t\tself.toggleClass( value.call(this, i, self.attr(\"class\"), stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tstate = stateVal,\n\t\t\t\t\tclassNames = value.split( rspaces );\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space seperated list\n\t\t\t\t\tstate = isBool ? state : !self.hasClass( className );\n\t\t\t\t\tself[ state ? \"addClass\" : \"removeClass\" ]( className );\n\t\t\t\t}\n\n\t\t\t} else if ( type === \"undefined\" || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// toggle whole className\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \";\n\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\tif ( (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) > -1 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t},\n\n\tval: function( value ) {\n\t\tif ( !arguments.length ) {\n\t\t\tvar elem = this[0];\n\n\t\t\tif ( elem ) {\n\t\t\t\tif ( jQuery.nodeName( elem, \"option\" ) ) {\n\t\t\t\t\t// attributes.value is undefined in Blackberry 4.7 but\n\t\t\t\t\t// uses .value. See #6932\n\t\t\t\t\tvar val = elem.attributes.value;\n\t\t\t\t\treturn !val || val.specified ? elem.value : elem.text;\n\t\t\t\t}\n\n\t\t\t\t// We need to handle select boxes special\n\t\t\t\tif ( jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\t\tvar index = elem.selectedIndex,\n\t\t\t\t\t\tvalues = [],\n\t\t\t\t\t\toptions = elem.options,\n\t\t\t\t\t\tone = elem.type === \"select-one\";\n\n\t\t\t\t\t// Nothing was selected\n\t\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Loop through all the selected options\n\t\t\t\t\tfor ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {\n\t\t\t\t\t\tvar option = options[ i ];\n\n\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\tif ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null) &&\n\t\t\t\t\t\t\t\t(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" )) ) {\n\n\t\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\t\tvalue = jQuery(option).val();\n\n\t\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fixes Bug #2551 -- select.val() broken in IE after form.reset()\n\t\t\t\t\tif ( one && !values.length && options.length ) {\n\t\t\t\t\t\treturn jQuery( options[ index ] ).val();\n\t\t\t\t\t}\n\n\t\t\t\t\treturn values;\n\t\t\t\t}\n\n\t\t\t\t// Handle the case where in Webkit \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\t\tif ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {\n\t\t\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t\t\t}\n\n\t\t\t\t// Everything else, we just grab the value\n\t\t\t\treturn (elem.value || \"\").replace(rreturn, \"\");\n\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t}\n\n\t\tvar isFunction = jQuery.isFunction(value);\n\n\t\treturn this.each(function(i) {\n\t\t\tvar self = jQuery(this), val = value;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call(this, i, self.val());\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray(val) ) {\n\t\t\t\tval = jQuery.map(val, function (value) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {\n\t\t\t\tthis.checked = jQuery.inArray( self.val(), val ) >= 0;\n\n\t\t\t} else if ( jQuery.nodeName( this, \"select\" ) ) {\n\t\t\t\tvar values = jQuery.makeArray(val);\n\n\t\t\t\tjQuery( \"option\", this ).each(function() {\n\t\t\t\t\tthis.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;\n\t\t\t\t});\n\n\t\t\t\tif ( !values.length ) {\n\t\t\t\t\tthis.selectedIndex = -1;\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tattrFn: {\n\t\tval: true,\n\t\tcss: true,\n\t\thtml: true,\n\t\ttext: true,\n\t\tdata: true,\n\t\twidth: true,\n\t\theight: true,\n\t\toffset: true\n\t},\n\n\tattr: function( elem, name, value, pass ) {\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif ( pass && name in jQuery.attrFn ) {\n\t\t\treturn jQuery(elem)[name](value);\n\t\t}\n\n\t\tvar notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),\n\t\t\t// Whether we are setting (or getting)\n\t\t\tset = value !== undefined;\n\n\t\t// Try to normalize/fix the name\n\t\tname = notxml && jQuery.props[ name ] || name;\n\n\t\t// Only do all the following if this is a node (faster for style)\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\t// These attributes require special treatment\n\t\t\tvar special = rspecialurl.test( name );\n\n\t\t\t// Safari mis-reports the default selected property of an option\n\t\t\t// Accessing the parent's selectedIndex property fixes it\n\t\t\tif ( name === \"selected\" && !jQuery.support.optSelected ) {\n\t\t\t\tvar parent = elem.parentNode;\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.selectedIndex;\n\n\t\t\t\t\t// Make sure that it also works with optgroups, see #5701\n\t\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If applicable, access the attribute via the DOM 0 way\n\t\t\t// 'in' checks fail in Blackberry 4.7 #6931\n\t\t\tif ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {\n\t\t\t\tif ( set ) {\n\t\t\t\t\t// We can't allow the type property to be changed (since it causes problems in IE)\n\t\t\t\t\tif ( name === \"type\" && rtype.test( elem.nodeName ) && elem.parentNode ) {\n\t\t\t\t\t\tjQuery.error( \"type property can't be changed\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( value === null ) {\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\telem.removeAttribute( name );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\telem[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// browsers index elements by id/name on forms, give priority to attributes.\n\t\t\t\tif ( jQuery.nodeName( elem, \"form\" ) && elem.getAttributeNode(name) ) {\n\t\t\t\t\treturn elem.getAttributeNode( name ).nodeValue;\n\t\t\t\t}\n\n\t\t\t\t// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n\t\t\t\t// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\tif ( name === \"tabIndex\" ) {\n\t\t\t\t\tvar attributeNode = elem.getAttributeNode( \"tabIndex\" );\n\n\t\t\t\t\treturn attributeNode && attributeNode.specified ?\n\t\t\t\t\t\tattributeNode.value :\n\t\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t\t0 :\n\t\t\t\t\t\t\tundefined;\n\t\t\t\t}\n\n\t\t\t\treturn elem[ name ];\n\t\t\t}\n\n\t\t\tif ( !jQuery.support.style && notxml && name === \"style\" ) {\n\t\t\t\tif ( set ) {\n\t\t\t\t\telem.style.cssText = \"\" + value;\n\t\t\t\t}\n\n\t\t\t\treturn elem.style.cssText;\n\t\t\t}\n\n\t\t\tif ( set ) {\n\t\t\t\t// convert the value to a string (all browsers do this but IE) see #1070\n\t\t\t\telem.setAttribute( name, \"\" + value );\n\t\t\t}\n\n\t\t\t// Ensure that missing attributes return undefined\n\t\t\t// Blackberry 4.7 returns \"\" from getAttribute #6938\n\t\t\tif ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tvar attr = !jQuery.support.hrefNormalized && notxml && special ?\n\t\t\t\t\t// Some attributes require a special call on IE\n\t\t\t\t\telem.getAttribute( name, 2 ) :\n\t\t\t\t\telem.getAttribute( name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn attr === null ? undefined : attr;\n\t\t}\n\t\t// Handle everything which isn't a DOM element node\n\t\tif ( set ) {\n\t\t\telem[ name ] = value;\n\t\t}\n\t\treturn elem[ name ];\n\t}\n});\n\n\n\n\nvar rnamespaces = /\\.(.*)$/,\n\trformElems = /^(?:textarea|input|select)$/i,\n\trperiod = /\\./g,\n\trspace = / /g,\n\trescape = /[^\\w\\s.|`]/g,\n\tfcleanup = function( nm ) {\n\t\treturn nm.replace(rescape, \"\\\\$&\");\n\t};\n\n/*\n * A number of helper functions used for managing events.\n * Many of the ideas behind this code originated from\n * Dean Edwards' addEvent library.\n */\njQuery.event = {\n\n\t// Bind an event to an element\n\t// Original by Dean Edwards\n\tadd: function( elem, types, handler, data ) {\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// TODO :: Use a try/catch until it's safe to pull this out (likely 1.6)\n\t\t// Minor release fix for bug #8018\n\t\ttry {\n\t\t\t// For whatever reason, IE has trouble passing the window object\n\t\t\t// around, causing it to be cloned in the process\n\t\t\tif ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {\n\t\t\t\telem = window;\n\t\t\t}\n\t\t}\n\t\tcatch ( e ) {}\n\n\t\tif ( handler === false ) {\n\t\t\thandler = returnFalse;\n\t\t} else if ( !handler ) {\n\t\t\t// Fixes bug #7229. Fix recommended by jdalton\n\t\t\treturn;\n\t\t}\n\n\t\tvar handleObjIn, handleObj;\n\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t}\n\n\t\t// Make sure that the function being executed has a unique ID\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure\n\t\tvar elemData = jQuery._data( elem );\n\n\t\t// If no elemData is found then we must be trying to bind to one of the\n\t\t// banned noData elements\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar events = elemData.events,\n\t\t\teventHandle = elemData.handle;\n\n\t\tif ( !events ) {\n\t\t\telemData.events = events = {};\n\t\t}\n\n\t\tif ( !eventHandle ) {\n\t\t\telemData.handle = eventHandle = function() {\n\t\t\t\t// Handle the second event of a trigger and when\n\t\t\t\t// an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && !jQuery.event.triggered ?\n\t\t\t\t\tjQuery.event.handle.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t}\n\n\t\t// Add elem as a property of the handle function\n\t\t// This is to prevent a memory leak with non-native events in IE.\n\t\teventHandle.elem = elem;\n\n\t\t// Handle multiple events separated by a space\n\t\t// jQuery(...).bind(\"mouseover mouseout\", fn);\n\t\ttypes = types.split(\" \");\n\n\t\tvar type, i = 0, namespaces;\n\n\t\twhile ( (type = types[ i++ ]) ) {\n\t\t\thandleObj = handleObjIn ?\n\t\t\t\tjQuery.extend({}, handleObjIn) :\n\t\t\t\t{ handler: handler, data: data };\n\n\t\t\t// Namespaced event handlers\n\t\t\tif ( type.indexOf(\".\") > -1 ) {\n\t\t\t\tnamespaces = type.split(\".\");\n\t\t\t\ttype = namespaces.shift();\n\t\t\t\thandleObj.namespace = namespaces.slice(0).sort().join(\".\");\n\n\t\t\t} else {\n\t\t\t\tnamespaces = [];\n\t\t\t\thandleObj.namespace = \"\";\n\t\t\t}\n\n\t\t\thandleObj.type = type;\n\t\t\tif ( !handleObj.guid ) {\n\t\t\t\thandleObj.guid = handler.guid;\n\t\t\t}\n\n\t\t\t// Get the current list of functions bound to this event\n\t\t\tvar handlers = events[ type ],\n\t\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// Init the event handler queue\n\t\t\tif ( !handlers ) {\n\t\t\t\thandlers = events[ type ] = [];\n\n\t\t\t\t// Check for a special event handler\n\t\t\t\t// Only use addEventListener/attachEvent if the special\n\t\t\t\t// events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add the function to the element's handler list\n\t\t\thandlers.push( handleObj );\n\n\t\t\t// Keep track of which events have been used, for global triggering\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\tglobal: {},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, pos ) {\n\t\t// don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( handler === false ) {\n\t\t\thandler = returnFalse;\n\t\t}\n\n\t\tvar ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem ),\n\t\t\tevents = elemData && elemData.events;\n\n\t\tif ( !elemData || !events ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// types is actually an event object here\n\t\tif ( types && types.type ) {\n\t\t\thandler = types.handler;\n\t\t\ttypes = types.type;\n\t\t}\n\n\t\t// Unbind all events for the element\n\t\tif ( !types || typeof types === \"string\" && types.charAt(0) === \".\" ) {\n\t\t\ttypes = types || \"\";\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tjQuery.event.remove( elem, type + types );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\t// jQuery(...).unbind(\"mouseover mouseout\", fn);\n\t\ttypes = types.split(\" \");\n\n\t\twhile ( (type = types[ i++ ]) ) {\n\t\t\torigType = type;\n\t\t\thandleObj = null;\n\t\t\tall = type.indexOf(\".\") < 0;\n\t\t\tnamespaces = [];\n\n\t\t\tif ( !all ) {\n\t\t\t\t// Namespaced event handlers\n\t\t\t\tnamespaces = type.split(\".\");\n\t\t\t\ttype = namespaces.shift();\n\n\t\t\t\tnamespace = new RegExp(\"(^|\\\\.)\" +\n\t\t\t\t\tjQuery.map( namespaces.slice(0).sort(), fcleanup ).join(\"\\\\.(?:.*\\\\.)?\") + \"(\\\\.|$)\");\n\t\t\t}\n\n\t\t\teventType = events[ type ];\n\n\t\t\tif ( !eventType ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( !handler ) {\n\t\t\t\tfor ( j = 0; j < eventType.length; j++ ) {\n\t\t\t\t\thandleObj = eventType[ j ];\n\n\t\t\t\t\tif ( all || namespace.test( handleObj.namespace ) ) {\n\t\t\t\t\t\tjQuery.event.remove( elem, origType, handleObj.handler, j );\n\t\t\t\t\t\teventType.splice( j--, 1 );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\tfor ( j = pos || 0; j < eventType.length; j++ ) {\n\t\t\t\thandleObj = eventType[ j ];\n\n\t\t\t\tif ( handler.guid === handleObj.guid ) {\n\t\t\t\t\t// remove the given handler for the given type\n\t\t\t\t\tif ( all || namespace.test( handleObj.namespace ) ) {\n\t\t\t\t\t\tif ( pos == null ) {\n\t\t\t\t\t\t\teventType.splice( j--, 1 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( pos != null ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// remove generic event handler if no more handlers exist\n\t\t\tif ( eventType.length === 0 || pos != null && eventType.length === 1 ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tret = null;\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tvar handle = elemData.handle;\n\t\t\tif ( handle ) {\n\t\t\t\thandle.elem = null;\n\t\t\t}\n\n\t\t\tdelete elemData.events;\n\t\t\tdelete elemData.handle;\n\n\t\t\tif ( jQuery.isEmptyObject( elemData ) ) {\n\t\t\t\tjQuery.removeData( elem, undefined, true );\n\t\t\t}\n\t\t}\n\t},\n\n\t// bubbling is internal\n\ttrigger: function( event, data, elem /*, bubbling */ ) {\n\t\t// Event object or event type\n\t\tvar type = event.type || event,\n\t\t\tbubbling = arguments[3];\n\n\t\tif ( !bubbling ) {\n\t\t\tevent = typeof event === \"object\" ?\n\t\t\t\t// jQuery.Event object\n\t\t\t\tevent[ jQuery.expando ] ? event :\n\t\t\t\t// Object literal\n\t\t\t\tjQuery.extend( jQuery.Event(type), event ) :\n\t\t\t\t// Just the event type (string)\n\t\t\t\tjQuery.Event(type);\n\n\t\t\tif ( type.indexOf(\"!\") >= 0 ) {\n\t\t\t\tevent.type = type = type.slice(0, -1);\n\t\t\t\tevent.exclusive = true;\n\t\t\t}\n\n\t\t\t// Handle a global trigger\n\t\t\tif ( !elem ) {\n\t\t\t\t// Don't bubble custom events when global (to avoid too much overhead)\n\t\t\t\tevent.stopPropagation();\n\n\t\t\t\t// Only trigger if we've ever bound an event for it\n\t\t\t\tif ( jQuery.event.global[ type ] ) {\n\t\t\t\t\t// XXX This code smells terrible. event.js should not be directly\n\t\t\t\t\t// inspecting the data cache\n\t\t\t\t\tjQuery.each( jQuery.cache, function() {\n\t\t\t\t\t\t// internalKey variable is just used to make it easier to find\n\t\t\t\t\t\t// and potentially change this stuff later; currently it just\n\t\t\t\t\t\t// points to jQuery.expando\n\t\t\t\t\t\tvar internalKey = jQuery.expando,\n\t\t\t\t\t\t\tinternalCache = this[ internalKey ];\n\t\t\t\t\t\tif ( internalCache && internalCache.events && internalCache.events[ type ] ) {\n\t\t\t\t\t\t\tjQuery.event.trigger( event, data, internalCache.handle.elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Handle triggering a single element\n\n\t\t\t// don't do events on text and comment nodes\n\t\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\t// Clean up in case it is reused\n\t\t\tevent.result = undefined;\n\t\t\tevent.target = elem;\n\n\t\t\t// Clone the incoming data, if any\n\t\t\tdata = jQuery.makeArray( data );\n\t\t\tdata.unshift( event );\n\t\t}\n\n\t\tevent.currentTarget = elem;\n\n\t\t// Trigger the event, it is assumed that \"handle\" is a function\n\t\tvar handle = jQuery._data( elem, \"handle\" );\n\n\t\tif ( handle ) {\n\t\t\thandle.apply( elem, data );\n\t\t}\n\n\t\tvar parent = elem.parentNode || elem.ownerDocument;\n\n\t\t// Trigger an inline bound script\n\t\ttry {\n\t\t\tif ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {\n\t\t\t\tif ( elem[ \"on\" + type ] && elem[ \"on\" + type ].apply( elem, data ) === false ) {\n\t\t\t\t\tevent.result = false;\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\n\t\t// prevent IE from throwing an error for some elements with some event types, see #3533\n\t\t} catch (inlineError) {}\n\n\t\tif ( !event.isPropagationStopped() && parent ) {\n\t\t\tjQuery.event.trigger( event, data, parent, true );\n\n\t\t} else if ( !event.isDefaultPrevented() ) {\n\t\t\tvar old,\n\t\t\t\ttarget = event.target,\n\t\t\t\ttargetType = type.replace( rnamespaces, \"\" ),\n\t\t\t\tisClick = jQuery.nodeName( target, \"a\" ) && targetType === \"click\",\n\t\t\t\tspecial = jQuery.event.special[ targetType ] || {};\n\n\t\t\tif ( (!special._default || special._default.call( elem, event ) === false) &&\n\t\t\t\t!isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {\n\n\t\t\t\ttry {\n\t\t\t\t\tif ( target[ targetType ] ) {\n\t\t\t\t\t\t// Make sure that we don't accidentally re-trigger the onFOO events\n\t\t\t\t\t\told = target[ \"on\" + targetType ];\n\n\t\t\t\t\t\tif ( old ) {\n\t\t\t\t\t\t\ttarget[ \"on\" + targetType ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tjQuery.event.triggered = true;\n\t\t\t\t\t\ttarget[ targetType ]();\n\t\t\t\t\t}\n\n\t\t\t\t// prevent IE from throwing an error for some elements with some event types, see #3533\n\t\t\t\t} catch (triggerError) {}\n\n\t\t\t\tif ( old ) {\n\t\t\t\t\ttarget[ \"on\" + targetType ] = old;\n\t\t\t\t}\n\n\t\t\t\tjQuery.event.triggered = false;\n\t\t\t}\n\t\t}\n\t},\n\n\thandle: function( event ) {\n\t\tvar all, handlers, namespaces, namespace_re, events,\n\t\t\tnamespace_sort = [],\n\t\t\targs = jQuery.makeArray( arguments );\n\n\t\tevent = args[0] = jQuery.event.fix( event || window.event );\n\t\tevent.currentTarget = this;\n\n\t\t// Namespaced event handlers\n\t\tall = event.type.indexOf(\".\") < 0 && !event.exclusive;\n\n\t\tif ( !all ) {\n\t\t\tnamespaces = event.type.split(\".\");\n\t\t\tevent.type = namespaces.shift();\n\t\t\tnamespace_sort = namespaces.slice(0).sort();\n\t\t\tnamespace_re = new RegExp(\"(^|\\\\.)\" + namespace_sort.join(\"\\\\.(?:.*\\\\.)?\") + \"(\\\\.|$)\");\n\t\t}\n\n\t\tevent.namespace = event.namespace || namespace_sort.join(\".\");\n\n\t\tevents = jQuery._data(this, \"events\");\n\n\t\thandlers = (events || {})[ event.type ];\n\n\t\tif ( events && handlers ) {\n\t\t\t// Clone the handlers to prevent manipulation\n\t\t\thandlers = handlers.slice(0);\n\n\t\t\tfor ( var j = 0, l = handlers.length; j < l; j++ ) {\n\t\t\t\tvar handleObj = handlers[ j ];\n\n\t\t\t\t// Filter the functions by class\n\t\t\t\tif ( all || namespace_re.test( handleObj.namespace ) ) {\n\t\t\t\t\t// Pass in a reference to the handler function itself\n\t\t\t\t\t// So that we can later remove it\n\t\t\t\t\tevent.handler = handleObj.handler;\n\t\t\t\t\tevent.data = handleObj.data;\n\t\t\t\t\tevent.handleObj = handleObj;\n\n\t\t\t\t\tvar ret = handleObj.handler.apply( this, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tevent.result = ret;\n\t\t\t\t\t\tif ( ret === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( event.isImmediatePropagationStopped() ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tprops: \"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(\" \"),\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// store a copy of the original event object\n\t\t// and \"clone\" to set read-only properties\n\t\tvar originalEvent = event;\n\t\tevent = jQuery.Event( originalEvent );\n\n\t\tfor ( var i = this.props.length, prop; i; ) {\n\t\t\tprop = this.props[ --i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Fix target property, if necessary\n\t\tif ( !event.target ) {\n\t\t\t// Fixes #1925 where srcElement might not be defined either\n\t\t\tevent.target = event.srcElement || document;\n\t\t}\n\n\t\t// check if target is a textnode (safari)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// Add relatedTarget, if necessary\n\t\tif ( !event.relatedTarget && event.fromElement ) {\n\t\t\tevent.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;\n\t\t}\n\n\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\tif ( event.pageX == null && event.clientX != null ) {\n\t\t\tvar doc = document.documentElement,\n\t\t\t\tbody = document.body;\n\n\t\t\tevent.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);\n\t\t\tevent.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);\n\t\t}\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && (event.charCode != null || event.keyCode != null) ) {\n\t\t\tevent.which = event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)\n\t\tif ( !event.metaKey && event.ctrlKey ) {\n\t\t\tevent.metaKey = event.ctrlKey;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t// Note: button is not normalized, so don't use it\n\t\tif ( !event.which && event.button !== undefined ) {\n\t\t\tevent.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));\n\t\t}\n\n\t\treturn event;\n\t},\n\n\t// Deprecated, use jQuery.guid instead\n\tguid: 1E8,\n\n\t// Deprecated, use jQuery.proxy instead\n\tproxy: jQuery.proxy,\n\n\tspecial: {\n\t\tready: {\n\t\t\t// Make sure the ready event is setup\n\t\t\tsetup: jQuery.bindReady,\n\t\t\tteardown: jQuery.noop\n\t\t},\n\n\t\tlive: {\n\t\t\tadd: function( handleObj ) {\n\t\t\t\tjQuery.event.add( this,\n\t\t\t\t\tliveConvert( handleObj.origType, handleObj.selector ),\n\t\t\t\t\tjQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );\n\t\t\t},\n\n\t\t\tremove: function( handleObj ) {\n\t\t\t\tjQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tsetup: function( data, namespaces, eventHandle ) {\n\t\t\t\t// We only want to do this special case on windows\n\t\t\t\tif ( jQuery.isWindow( this ) ) {\n\t\t\t\t\tthis.onbeforeunload = eventHandle;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tteardown: function( namespaces, eventHandle ) {\n\t\t\t\tif ( this.onbeforeunload === eventHandle ) {\n\t\t\t\t\tthis.onbeforeunload = null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.detachEvent ) {\n\t\t\telem.detachEvent( \"on\" + type, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !this.preventDefault ) {\n\t\treturn new jQuery.Event( src );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||\n\t\t\tsrc.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// timeStamp is buggy for some events on Firefox(#3843)\n\t// So we won't rely on the native value\n\tthis.timeStamp = jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\nfunction returnFalse() {\n\treturn false;\n}\nfunction returnTrue() {\n\treturn true;\n}\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tpreventDefault: function() {\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tvar e = this.originalEvent;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// if preventDefault exists run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// otherwise set the returnValue property of the original event to false (IE)\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tvar e = this.originalEvent;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// if stopPropagation exists run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t\t// otherwise set the cancelBubble property of the original event to true (IE)\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\t\tthis.stopPropagation();\n\t},\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse\n};\n\n// Checks if an event happened on an element within another element\n// Used in jQuery.event.special.mouseenter and mouseleave handlers\nvar withinElement = function( event ) {\n\t// Check if mouse(over|out) are still within the same parent element\n\tvar parent = event.relatedTarget;\n\n\t// Firefox sometimes assigns relatedTarget a XUL element\n\t// which we cannot access the parentNode property of\n\ttry {\n\n\t\t// Chrome does something similar, the parentNode property\n\t\t// can be accessed but is null.\n\t\tif ( parent !== document && !parent.parentNode ) {\n\t\t\treturn;\n\t\t}\n\t\t// Traverse up the tree\n\t\twhile ( parent && parent !== this ) {\n\t\t\tparent = parent.parentNode;\n\t\t}\n\n\t\tif ( parent !== this ) {\n\t\t\t// set the correct event type\n\t\t\tevent.type = event.data;\n\n\t\t\t// handle event if we actually just moused on to a non sub-element\n\t\t\tjQuery.event.handle.apply( this, arguments );\n\t\t}\n\n\t// assuming we've left the element since we most likely mousedover a xul element\n\t} catch(e) { }\n},\n\n// In case of event delegation, we only need to rename the event.type,\n// liveHandler will take care of the rest.\ndelegate = function( event ) {\n\tevent.type = event.data;\n\tjQuery.event.handle.apply( this, arguments );\n};\n\n// Create mouseenter and mouseleave events\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tsetup: function( data ) {\n\t\t\tjQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );\n\t\t},\n\t\tteardown: function( data ) {\n\t\t\tjQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );\n\t\t}\n\t};\n});\n\n// submit delegation\nif ( !jQuery.support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function( data, namespaces ) {\n\t\t\tif ( this.nodeName && this.nodeName.toLowerCase() !== \"form\" ) {\n\t\t\t\tjQuery.event.add(this, \"click.specialSubmit\", function( e ) {\n\t\t\t\t\tvar elem = e.target,\n\t\t\t\t\t\ttype = elem.type;\n\n\t\t\t\t\tif ( (type === \"submit\" || type === \"image\") && jQuery( elem ).closest(\"form\").length ) {\n\t\t\t\t\t\ttrigger( \"submit\", this, arguments );\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tjQuery.event.add(this, \"keypress.specialSubmit\", function( e ) {\n\t\t\t\t\tvar elem = e.target,\n\t\t\t\t\t\ttype = elem.type;\n\n\t\t\t\t\tif ( (type === \"text\" || type === \"password\") && jQuery( elem ).closest(\"form\").length && e.keyCode === 13 ) {\n\t\t\t\t\t\ttrigger( \"submit\", this, arguments );\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\n\t\tteardown: function( namespaces ) {\n\t\t\tjQuery.event.remove( this, \".specialSubmit\" );\n\t\t}\n\t};\n\n}\n\n// change delegation, happens here so we have bind.\nif ( !jQuery.support.changeBubbles ) {\n\n\tvar changeFilters,\n\n\tgetVal = function( elem ) {\n\t\tvar type = elem.type, val = elem.value;\n\n\t\tif ( type === \"radio\" || type === \"checkbox\" ) {\n\t\t\tval = elem.checked;\n\n\t\t} else if ( type === \"select-multiple\" ) {\n\t\t\tval = elem.selectedIndex > -1 ?\n\t\t\t\tjQuery.map( elem.options, function( elem ) {\n\t\t\t\t\treturn elem.selected;\n\t\t\t\t}).join(\"-\") :\n\t\t\t\t\"\";\n\n\t\t} else if ( elem.nodeName.toLowerCase() === \"select\" ) {\n\t\t\tval = elem.selectedIndex;\n\t\t}\n\n\t\treturn val;\n\t},\n\n\ttestChange = function testChange( e ) {\n\t\tvar elem = e.target, data, val;\n\n\t\tif ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdata = jQuery._data( elem, \"_change_data\" );\n\t\tval = getVal(elem);\n\n\t\t// the current data will be also retrieved by beforeactivate\n\t\tif ( e.type !== \"focusout\" || elem.type !== \"radio\" ) {\n\t\t\tjQuery._data( elem, \"_change_data\", val );\n\t\t}\n\n\t\tif ( data === undefined || val === data ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( data != null || val ) {\n\t\t\te.type = \"change\";\n\t\t\te.liveFired = undefined;\n\t\t\tjQuery.event.trigger( e, arguments[1], elem );\n\t\t}\n\t};\n\n\tjQuery.event.special.change = {\n\t\tfilters: {\n\t\t\tfocusout: testChange,\n\n\t\t\tbeforedeactivate: testChange,\n\n\t\t\tclick: function( e ) {\n\t\t\t\tvar elem = e.target, type = elem.type;\n\n\t\t\t\tif ( type === \"radio\" || type === \"checkbox\" || elem.nodeName.toLowerCase() === \"select\" ) {\n\t\t\t\t\ttestChange.call( this, e );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// Change has to be called before submit\n\t\t\t// Keydown will be called before keypress, which is used in submit-event delegation\n\t\t\tkeydown: function( e ) {\n\t\t\t\tvar elem = e.target, type = elem.type;\n\n\t\t\t\tif ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== \"textarea\") ||\n\t\t\t\t\t(e.keyCode === 32 && (type === \"checkbox\" || type === \"radio\")) ||\n\t\t\t\t\ttype === \"select-multiple\" ) {\n\t\t\t\t\ttestChange.call( this, e );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// Beforeactivate happens also before the previous element is blurred\n\t\t\t// with this event you can't trigger a change event, but you can store\n\t\t\t// information\n\t\t\tbeforeactivate: function( e ) {\n\t\t\t\tvar elem = e.target;\n\t\t\t\tjQuery._data( elem, \"_change_data\", getVal(elem) );\n\t\t\t}\n\t\t},\n\n\t\tsetup: function( data, namespaces ) {\n\t\t\tif ( this.type === \"file\" ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfor ( var type in changeFilters ) {\n\t\t\t\tjQuery.event.add( this, type + \".specialChange\", changeFilters[type] );\n\t\t\t}\n\n\t\t\treturn rformElems.test( this.nodeName );\n\t\t},\n\n\t\tteardown: function( namespaces ) {\n\t\t\tjQuery.event.remove( this, \".specialChange\" );\n\n\t\t\treturn rformElems.test( this.nodeName );\n\t\t}\n\t};\n\n\tchangeFilters = jQuery.event.special.change.filters;\n\n\t// Handle when the input is .focus()'d\n\tchangeFilters.focus = changeFilters.beforeactivate;\n}\n\nfunction trigger( type, elem, args ) {\n\t// Piggyback on a donor event to simulate a different one.\n\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t// simulated event prevents default then we do the same on the donor.\n\t// Don't pass args or remember liveFired; they apply to the donor event.\n\tvar event = jQuery.extend( {}, args[ 0 ] );\n\tevent.type = type;\n\tevent.originalEvent = {};\n\tevent.liveFired = undefined;\n\tjQuery.event.handle.call( elem, event );\n\tif ( event.isDefaultPrevented() ) {\n\t\targs[ 0 ].preventDefault();\n\t}\n}\n\n// Create \"bubbling\" focus and blur events\nif ( document.addEventListener ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tthis.addEventListener( orig, handler, true );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tthis.removeEventListener( orig, handler, true );\n\t\t\t}\n\t\t};\n\n\t\tfunction handler( e ) {\n\t\t\te = jQuery.event.fix( e );\n\t\t\te.type = fix;\n\t\t\treturn jQuery.event.handle.call( this, e );\n\t\t}\n\t});\n}\n\njQuery.each([\"bind\", \"one\"], function( i, name ) {\n\tjQuery.fn[ name ] = function( type, data, fn ) {\n\t\t// Handle object literals\n\t\tif ( typeof type === \"object\" ) {\n\t\t\tfor ( var key in type ) {\n\t\t\t\tthis[ name ](key, data, type[key], fn);\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( jQuery.isFunction( data ) || data === false ) {\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\tvar handler = name === \"one\" ? jQuery.proxy( fn, function( event ) {\n\t\t\tjQuery( this ).unbind( event, handler );\n\t\t\treturn fn.apply( this, arguments );\n\t\t}) : fn;\n\n\t\tif ( type === \"unload\" && name !== \"one\" ) {\n\t\t\tthis.one( type, data, fn );\n\n\t\t} else {\n\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( this[i], type, handler, data );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n});\n\njQuery.fn.extend({\n\tunbind: function( type, fn ) {\n\t\t// Handle object literals\n\t\tif ( typeof type === \"object\" && !type.preventDefault ) {\n\t\t\tfor ( var key in type ) {\n\t\t\t\tthis.unbind(key, type[key]);\n\t\t\t}\n\n\t\t} else {\n\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\tjQuery.event.remove( this[i], type, fn );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.live( types, data, fn, selector );\n\t},\n\n\tundelegate: function( selector, types, fn ) {\n\t\tif ( arguments.length === 0 ) {\n\t\t\t\treturn this.unbind( \"live\" );\n\n\t\t} else {\n\t\t\treturn this.die( types, null, fn, selector );\n\t\t}\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\n\ttriggerHandler: function( type, data ) {\n\t\tif ( this[0] ) {\n\t\t\tvar event = jQuery.Event( type );\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\tjQuery.event.trigger( event, data, this[0] );\n\t\t\treturn event.result;\n\t\t}\n\t},\n\n\ttoggle: function( fn ) {\n\t\t// Save reference to arguments for access in closure\n\t\tvar args = arguments,\n\t\t\ti = 1;\n\n\t\t// link all the functions, so any of them can unbind this click handler\n\t\twhile ( i < args.length ) {\n\t\t\tjQuery.proxy( fn, args[ i++ ] );\n\t\t}\n\n\t\treturn this.click( jQuery.proxy( fn, function( event ) {\n\t\t\t// Figure out which function to execute\n\t\t\tvar lastToggle = ( jQuery._data( this, \"lastToggle\" + fn.guid ) || 0 ) % i;\n\t\t\tjQuery._data( this, \"lastToggle\" + fn.guid, lastToggle + 1 );\n\n\t\t\t// Make sure that clicks stop\n\t\t\tevent.preventDefault();\n\n\t\t\t// and execute the function\n\t\t\treturn args[ lastToggle ].apply( this, arguments ) || false;\n\t\t}));\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n});\n\nvar liveMap = {\n\tfocus: \"focusin\",\n\tblur: \"focusout\",\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\"\n};\n\njQuery.each([\"live\", \"die\"], function( i, name ) {\n\tjQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {\n\t\tvar type, i = 0, match, namespaces, preType,\n\t\t\tselector = origSelector || this.selector,\n\t\t\tcontext = origSelector ? this : jQuery( this.context );\n\n\t\tif ( typeof types === \"object\" && !types.preventDefault ) {\n\t\t\tfor ( var key in types ) {\n\t\t\t\tcontext[ name ]( key, data, types[key], selector );\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\ttypes = (types || \"\").split(\" \");\n\n\t\twhile ( (type = types[ i++ ]) != null ) {\n\t\t\tmatch = rnamespaces.exec( type );\n\t\t\tnamespaces = \"\";\n\n\t\t\tif ( match )  {\n\t\t\t\tnamespaces = match[0];\n\t\t\t\ttype = type.replace( rnamespaces, \"\" );\n\t\t\t}\n\n\t\t\tif ( type === \"hover\" ) {\n\t\t\t\ttypes.push( \"mouseenter\" + namespaces, \"mouseleave\" + namespaces );\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tpreType = type;\n\n\t\t\tif ( type === \"focus\" || type === \"blur\" ) {\n\t\t\t\ttypes.push( liveMap[ type ] + namespaces );\n\t\t\t\ttype = type + namespaces;\n\n\t\t\t} else {\n\t\t\t\ttype = (liveMap[ type ] || type) + namespaces;\n\t\t\t}\n\n\t\t\tif ( name === \"live\" ) {\n\t\t\t\t// bind live handler\n\t\t\t\tfor ( var j = 0, l = context.length; j < l; j++ ) {\n\t\t\t\t\tjQuery.event.add( context[j], \"live.\" + liveConvert( type, selector ),\n\t\t\t\t\t\t{ data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\t// unbind live handler\n\t\t\t\tcontext.unbind( \"live.\" + liveConvert( type, selector ), fn );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n});\n\nfunction liveHandler( event ) {\n\tvar stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,\n\t\telems = [],\n\t\tselectors = [],\n\t\tevents = jQuery._data( this, \"events\" );\n\n\t// Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)\n\tif ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === \"click\" ) {\n\t\treturn;\n\t}\n\n\tif ( event.namespace ) {\n\t\tnamespace = new RegExp(\"(^|\\\\.)\" + event.namespace.split(\".\").join(\"\\\\.(?:.*\\\\.)?\") + \"(\\\\.|$)\");\n\t}\n\n\tevent.liveFired = this;\n\n\tvar live = events.live.slice(0);\n\n\tfor ( j = 0; j < live.length; j++ ) {\n\t\thandleObj = live[j];\n\n\t\tif ( handleObj.origType.replace( rnamespaces, \"\" ) === event.type ) {\n\t\t\tselectors.push( handleObj.selector );\n\n\t\t} else {\n\t\t\tlive.splice( j--, 1 );\n\t\t}\n\t}\n\n\tmatch = jQuery( event.target ).closest( selectors, event.currentTarget );\n\n\tfor ( i = 0, l = match.length; i < l; i++ ) {\n\t\tclose = match[i];\n\n\t\tfor ( j = 0; j < live.length; j++ ) {\n\t\t\thandleObj = live[j];\n\n\t\t\tif ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {\n\t\t\t\telem = close.elem;\n\t\t\t\trelated = null;\n\n\t\t\t\t// Those two events require additional checking\n\t\t\t\tif ( handleObj.preType === \"mouseenter\" || handleObj.preType === \"mouseleave\" ) {\n\t\t\t\t\tevent.type = handleObj.preType;\n\t\t\t\t\trelated = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];\n\t\t\t\t}\n\n\t\t\t\tif ( !related || related !== elem ) {\n\t\t\t\t\telems.push({ elem: elem, handleObj: handleObj, level: close.level });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfor ( i = 0, l = elems.length; i < l; i++ ) {\n\t\tmatch = elems[i];\n\n\t\tif ( maxLevel && match.level > maxLevel ) {\n\t\t\tbreak;\n\t\t}\n\n\t\tevent.currentTarget = match.elem;\n\t\tevent.data = match.handleObj.data;\n\t\tevent.handleObj = match.handleObj;\n\n\t\tret = match.handleObj.origHandler.apply( match.elem, arguments );\n\n\t\tif ( ret === false || event.isPropagationStopped() ) {\n\t\t\tmaxLevel = match.level;\n\n\t\t\tif ( ret === false ) {\n\t\t\t\tstop = false;\n\t\t\t}\n\t\t\tif ( event.isImmediatePropagationStopped() ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn stop;\n}\n\nfunction liveConvert( type, selector ) {\n\treturn (type && type !== \"*\" ? type + \".\" : \"\") + selector.replace(rperiod, \"`\").replace(rspace, \"&\");\n}\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\tif ( fn == null ) {\n\t\t\tfn = data;\n\t\t\tdata = null;\n\t\t}\n\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.bind( name, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n\n\tif ( jQuery.attrFn ) {\n\t\tjQuery.attrFn[ name ] = true;\n\t}\n});\n\n\n/*!\n * Sizzle CSS Selector Engine\n *  Copyright 2011, The Dojo Foundation\n *  Released under the MIT, BSD, and GPL Licenses.\n *  More information: http://sizzlejs.com/\n */\n(function(){\n\nvar chunker = /((?:\\((?:\\([^()]+\\)|[^()]+)+\\)|\\[(?:\\[[^\\[\\]]*\\]|['\"][^'\"]*['\"]|[^\\[\\]'\"]+)+\\]|\\\\.|[^ >+~,(\\[\\\\]+)+|[>+~])(\\s*,\\s*)?((?:.|\\r|\\n)*)/g,\n\tdone = 0,\n\ttoString = Object.prototype.toString,\n\thasDuplicate = false,\n\tbaseHasDuplicate = true,\n\trBackslash = /\\\\/g,\n\trNonWord = /\\W/;\n\n// Here we check if the JavaScript engine is using some sort of\n// optimization where it does not always call our comparision\n// function. If that is the case, discard the hasDuplicate value.\n//   Thus far that includes Google Chrome.\n[0, 0].sort(function() {\n\tbaseHasDuplicate = false;\n\treturn 0;\n});\n\nvar Sizzle = function( selector, context, results, seed ) {\n\tresults = results || [];\n\tcontext = context || document;\n\n\tvar origContext = context;\n\n\tif ( context.nodeType !== 1 && context.nodeType !== 9 ) {\n\t\treturn [];\n\t}\n\t\n\tif ( !selector || typeof selector !== \"string\" ) {\n\t\treturn results;\n\t}\n\n\tvar m, set, checkSet, extra, ret, cur, pop, i,\n\t\tprune = true,\n\t\tcontextXML = Sizzle.isXML( context ),\n\t\tparts = [],\n\t\tsoFar = selector;\n\t\n\t// Reset the position of the chunker regexp (start from head)\n\tdo {\n\t\tchunker.exec( \"\" );\n\t\tm = chunker.exec( soFar );\n\n\t\tif ( m ) {\n\t\t\tsoFar = m[3];\n\t\t\n\t\t\tparts.push( m[1] );\n\t\t\n\t\t\tif ( m[2] ) {\n\t\t\t\textra = m[3];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} while ( m );\n\n\tif ( parts.length > 1 && origPOS.exec( selector ) ) {\n\n\t\tif ( parts.length === 2 && Expr.relative[ parts[0] ] ) {\n\t\t\tset = posProcess( parts[0] + parts[1], context );\n\n\t\t} else {\n\t\t\tset = Expr.relative[ parts[0] ] ?\n\t\t\t\t[ context ] :\n\t\t\t\tSizzle( parts.shift(), context );\n\n\t\t\twhile ( parts.length ) {\n\t\t\t\tselector = parts.shift();\n\n\t\t\t\tif ( Expr.relative[ selector ] ) {\n\t\t\t\t\tselector += parts.shift();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tset = posProcess( selector, set );\n\t\t\t}\n\t\t}\n\n\t} else {\n\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\t// (but not if it'll be faster if the inner selector is an ID)\n\t\tif ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&\n\t\t\t\tExpr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {\n\n\t\t\tret = Sizzle.find( parts.shift(), context, contextXML );\n\t\t\tcontext = ret.expr ?\n\t\t\t\tSizzle.filter( ret.expr, ret.set )[0] :\n\t\t\t\tret.set[0];\n\t\t}\n\n\t\tif ( context ) {\n\t\t\tret = seed ?\n\t\t\t\t{ expr: parts.pop(), set: makeArray(seed) } :\n\t\t\t\tSizzle.find( parts.pop(), parts.length === 1 && (parts[0] === \"~\" || parts[0] === \"+\") && context.parentNode ? context.parentNode : context, contextXML );\n\n\t\t\tset = ret.expr ?\n\t\t\t\tSizzle.filter( ret.expr, ret.set ) :\n\t\t\t\tret.set;\n\n\t\t\tif ( parts.length > 0 ) {\n\t\t\t\tcheckSet = makeArray( set );\n\n\t\t\t} else {\n\t\t\t\tprune = false;\n\t\t\t}\n\n\t\t\twhile ( parts.length ) {\n\t\t\t\tcur = parts.pop();\n\t\t\t\tpop = cur;\n\n\t\t\t\tif ( !Expr.relative[ cur ] ) {\n\t\t\t\t\tcur = \"\";\n\t\t\t\t} else {\n\t\t\t\t\tpop = parts.pop();\n\t\t\t\t}\n\n\t\t\t\tif ( pop == null ) {\n\t\t\t\t\tpop = context;\n\t\t\t\t}\n\n\t\t\t\tExpr.relative[ cur ]( checkSet, pop, contextXML );\n\t\t\t}\n\n\t\t} else {\n\t\t\tcheckSet = parts = [];\n\t\t}\n\t}\n\n\tif ( !checkSet ) {\n\t\tcheckSet = set;\n\t}\n\n\tif ( !checkSet ) {\n\t\tSizzle.error( cur || selector );\n\t}\n\n\tif ( toString.call(checkSet) === \"[object Array]\" ) {\n\t\tif ( !prune ) {\n\t\t\tresults.push.apply( results, checkSet );\n\n\t\t} else if ( context && context.nodeType === 1 ) {\n\t\t\tfor ( i = 0; checkSet[i] != null; i++ ) {\n\t\t\t\tif ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {\n\t\t\t\t\tresults.push( set[i] );\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\t\t\tfor ( i = 0; checkSet[i] != null; i++ ) {\n\t\t\t\tif ( checkSet[i] && checkSet[i].nodeType === 1 ) {\n\t\t\t\t\tresults.push( set[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t} else {\n\t\tmakeArray( checkSet, results );\n\t}\n\n\tif ( extra ) {\n\t\tSizzle( extra, origContext, results, seed );\n\t\tSizzle.uniqueSort( results );\n\t}\n\n\treturn results;\n};\n\nSizzle.uniqueSort = function( results ) {\n\tif ( sortOrder ) {\n\t\thasDuplicate = baseHasDuplicate;\n\t\tresults.sort( sortOrder );\n\n\t\tif ( hasDuplicate ) {\n\t\t\tfor ( var i = 1; i < results.length; i++ ) {\n\t\t\t\tif ( results[i] === results[ i - 1 ] ) {\n\t\t\t\t\tresults.splice( i--, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn results;\n};\n\nSizzle.matches = function( expr, set ) {\n\treturn Sizzle( expr, null, null, set );\n};\n\nSizzle.matchesSelector = function( node, expr ) {\n\treturn Sizzle( expr, null, null, [node] ).length > 0;\n};\n\nSizzle.find = function( expr, context, isXML ) {\n\tvar set;\n\n\tif ( !expr ) {\n\t\treturn [];\n\t}\n\n\tfor ( var i = 0, l = Expr.order.length; i < l; i++ ) {\n\t\tvar match,\n\t\t\ttype = Expr.order[i];\n\t\t\n\t\tif ( (match = Expr.leftMatch[ type ].exec( expr )) ) {\n\t\t\tvar left = match[1];\n\t\t\tmatch.splice( 1, 1 );\n\n\t\t\tif ( left.substr( left.length - 1 ) !== \"\\\\\" ) {\n\t\t\t\tmatch[1] = (match[1] || \"\").replace( rBackslash, \"\" );\n\t\t\t\tset = Expr.find[ type ]( match, context, isXML );\n\n\t\t\t\tif ( set != null ) {\n\t\t\t\t\texpr = expr.replace( Expr.match[ type ], \"\" );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( !set ) {\n\t\tset = typeof context.getElementsByTagName !== \"undefined\" ?\n\t\t\tcontext.getElementsByTagName( \"*\" ) :\n\t\t\t[];\n\t}\n\n\treturn { set: set, expr: expr };\n};\n\nSizzle.filter = function( expr, set, inplace, not ) {\n\tvar match, anyFound,\n\t\told = expr,\n\t\tresult = [],\n\t\tcurLoop = set,\n\t\tisXMLFilter = set && set[0] && Sizzle.isXML( set[0] );\n\n\twhile ( expr && set.length ) {\n\t\tfor ( var type in Expr.filter ) {\n\t\t\tif ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {\n\t\t\t\tvar found, item,\n\t\t\t\t\tfilter = Expr.filter[ type ],\n\t\t\t\t\tleft = match[1];\n\n\t\t\t\tanyFound = false;\n\n\t\t\t\tmatch.splice(1,1);\n\n\t\t\t\tif ( left.substr( left.length - 1 ) === \"\\\\\" ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif ( curLoop === result ) {\n\t\t\t\t\tresult = [];\n\t\t\t\t}\n\n\t\t\t\tif ( Expr.preFilter[ type ] ) {\n\t\t\t\t\tmatch = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );\n\n\t\t\t\t\tif ( !match ) {\n\t\t\t\t\t\tanyFound = found = true;\n\n\t\t\t\t\t} else if ( match === true ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( match ) {\n\t\t\t\t\tfor ( var i = 0; (item = curLoop[i]) != null; i++ ) {\n\t\t\t\t\t\tif ( item ) {\n\t\t\t\t\t\t\tfound = filter( item, match, i, curLoop );\n\t\t\t\t\t\t\tvar pass = not ^ !!found;\n\n\t\t\t\t\t\t\tif ( inplace && found != null ) {\n\t\t\t\t\t\t\t\tif ( pass ) {\n\t\t\t\t\t\t\t\t\tanyFound = true;\n\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcurLoop[i] = false;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else if ( pass ) {\n\t\t\t\t\t\t\t\tresult.push( item );\n\t\t\t\t\t\t\t\tanyFound = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( found !== undefined ) {\n\t\t\t\t\tif ( !inplace ) {\n\t\t\t\t\t\tcurLoop = result;\n\t\t\t\t\t}\n\n\t\t\t\t\texpr = expr.replace( Expr.match[ type ], \"\" );\n\n\t\t\t\t\tif ( !anyFound ) {\n\t\t\t\t\t\treturn [];\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Improper expression\n\t\tif ( expr === old ) {\n\t\t\tif ( anyFound == null ) {\n\t\t\t\tSizzle.error( expr );\n\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\told = expr;\n\t}\n\n\treturn curLoop;\n};\n\nSizzle.error = function( msg ) {\n\tthrow \"Syntax error, unrecognized expression: \" + msg;\n};\n\nvar Expr = Sizzle.selectors = {\n\torder: [ \"ID\", \"NAME\", \"TAG\" ],\n\n\tmatch: {\n\t\tID: /#((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)/,\n\t\tCLASS: /\\.((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)/,\n\t\tNAME: /\\[name=['\"]*((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)['\"]*\\]/,\n\t\tATTR: /\\[\\s*((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)\\s*(?:(\\S?=)\\s*(?:(['\"])(.*?)\\3|(#?(?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)*)|)|)\\s*\\]/,\n\t\tTAG: /^((?:[\\w\\u00c0-\\uFFFF\\*\\-]|\\\\.)+)/,\n\t\tCHILD: /:(only|nth|last|first)-child(?:\\(\\s*(even|odd|(?:[+\\-]?\\d+|(?:[+\\-]?\\d*)?n\\s*(?:[+\\-]\\s*\\d+)?))\\s*\\))?/,\n\t\tPOS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\))?(?=[^\\-]|$)/,\n\t\tPSEUDO: /:((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)(?:\\((['\"]?)((?:\\([^\\)]+\\)|[^\\(\\)]*)+)\\2\\))?/\n\t},\n\n\tleftMatch: {},\n\n\tattrMap: {\n\t\t\"class\": \"className\",\n\t\t\"for\": \"htmlFor\"\n\t},\n\n\tattrHandle: {\n\t\thref: function( elem ) {\n\t\t\treturn elem.getAttribute( \"href\" );\n\t\t},\n\t\ttype: function( elem ) {\n\t\t\treturn elem.getAttribute( \"type\" );\n\t\t}\n\t},\n\n\trelative: {\n\t\t\"+\": function(checkSet, part){\n\t\t\tvar isPartStr = typeof part === \"string\",\n\t\t\t\tisTag = isPartStr && !rNonWord.test( part ),\n\t\t\t\tisPartStrNotTag = isPartStr && !isTag;\n\n\t\t\tif ( isTag ) {\n\t\t\t\tpart = part.toLowerCase();\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {\n\t\t\t\tif ( (elem = checkSet[i]) ) {\n\t\t\t\t\twhile ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}\n\n\t\t\t\t\tcheckSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?\n\t\t\t\t\t\telem || false :\n\t\t\t\t\t\telem === part;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( isPartStrNotTag ) {\n\t\t\t\tSizzle.filter( part, checkSet, true );\n\t\t\t}\n\t\t},\n\n\t\t\">\": function( checkSet, part ) {\n\t\t\tvar elem,\n\t\t\t\tisPartStr = typeof part === \"string\",\n\t\t\t\ti = 0,\n\t\t\t\tl = checkSet.length;\n\n\t\t\tif ( isPartStr && !rNonWord.test( part ) ) {\n\t\t\t\tpart = part.toLowerCase();\n\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\telem = checkSet[i];\n\n\t\t\t\t\tif ( elem ) {\n\t\t\t\t\t\tvar parent = elem.parentNode;\n\t\t\t\t\t\tcheckSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\telem = checkSet[i];\n\n\t\t\t\t\tif ( elem ) {\n\t\t\t\t\t\tcheckSet[i] = isPartStr ?\n\t\t\t\t\t\t\telem.parentNode :\n\t\t\t\t\t\t\telem.parentNode === part;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( isPartStr ) {\n\t\t\t\t\tSizzle.filter( part, checkSet, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t\"\": function(checkSet, part, isXML){\n\t\t\tvar nodeCheck,\n\t\t\t\tdoneName = done++,\n\t\t\t\tcheckFn = dirCheck;\n\n\t\t\tif ( typeof part === \"string\" && !rNonWord.test( part ) ) {\n\t\t\t\tpart = part.toLowerCase();\n\t\t\t\tnodeCheck = part;\n\t\t\t\tcheckFn = dirNodeCheck;\n\t\t\t}\n\n\t\t\tcheckFn( \"parentNode\", part, doneName, checkSet, nodeCheck, isXML );\n\t\t},\n\n\t\t\"~\": function( checkSet, part, isXML ) {\n\t\t\tvar nodeCheck,\n\t\t\t\tdoneName = done++,\n\t\t\t\tcheckFn = dirCheck;\n\n\t\t\tif ( typeof part === \"string\" && !rNonWord.test( part ) ) {\n\t\t\t\tpart = part.toLowerCase();\n\t\t\t\tnodeCheck = part;\n\t\t\t\tcheckFn = dirNodeCheck;\n\t\t\t}\n\n\t\t\tcheckFn( \"previousSibling\", part, doneName, checkSet, nodeCheck, isXML );\n\t\t}\n\t},\n\n\tfind: {\n\t\tID: function( match, context, isXML ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && !isXML ) {\n\t\t\t\tvar m = context.getElementById(match[1]);\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [m] : [];\n\t\t\t}\n\t\t},\n\n\t\tNAME: function( match, context ) {\n\t\t\tif ( typeof context.getElementsByName !== \"undefined\" ) {\n\t\t\t\tvar ret = [],\n\t\t\t\t\tresults = context.getElementsByName( match[1] );\n\n\t\t\t\tfor ( var i = 0, l = results.length; i < l; i++ ) {\n\t\t\t\t\tif ( results[i].getAttribute(\"name\") === match[1] ) {\n\t\t\t\t\t\tret.push( results[i] );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn ret.length === 0 ? null : ret;\n\t\t\t}\n\t\t},\n\n\t\tTAG: function( match, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( match[1] );\n\t\t\t}\n\t\t}\n\t},\n\tpreFilter: {\n\t\tCLASS: function( match, curLoop, inplace, result, not, isXML ) {\n\t\t\tmatch = \" \" + match[1].replace( rBackslash, \"\" ) + \" \";\n\n\t\t\tif ( isXML ) {\n\t\t\t\treturn match;\n\t\t\t}\n\n\t\t\tfor ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {\n\t\t\t\tif ( elem ) {\n\t\t\t\t\tif ( not ^ (elem.className && (\" \" + elem.className + \" \").replace(/[\\t\\n\\r]/g, \" \").indexOf(match) >= 0) ) {\n\t\t\t\t\t\tif ( !inplace ) {\n\t\t\t\t\t\t\tresult.push( elem );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( inplace ) {\n\t\t\t\t\t\tcurLoop[i] = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t},\n\n\t\tID: function( match ) {\n\t\t\treturn match[1].replace( rBackslash, \"\" );\n\t\t},\n\n\t\tTAG: function( match, curLoop ) {\n\t\t\treturn match[1].replace( rBackslash, \"\" ).toLowerCase();\n\t\t},\n\n\t\tCHILD: function( match ) {\n\t\t\tif ( match[1] === \"nth\" ) {\n\t\t\t\tif ( !match[2] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\tmatch[2] = match[2].replace(/^\\+|\\s*/g, '');\n\n\t\t\t\t// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'\n\t\t\t\tvar test = /(-?)(\\d*)(?:n([+\\-]?\\d*))?/.exec(\n\t\t\t\t\tmatch[2] === \"even\" && \"2n\" || match[2] === \"odd\" && \"2n+1\" ||\n\t\t\t\t\t!/\\D/.test( match[2] ) && \"0n+\" + match[2] || match[2]);\n\n\t\t\t\t// calculate the numbers (first)n+(last) including if they are negative\n\t\t\t\tmatch[2] = (test[1] + (test[2] || 1)) - 0;\n\t\t\t\tmatch[3] = test[3] - 0;\n\t\t\t}\n\t\t\telse if ( match[2] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\t// TODO: Move to normal caching system\n\t\t\tmatch[0] = done++;\n\n\t\t\treturn match;\n\t\t},\n\n\t\tATTR: function( match, curLoop, inplace, result, not, isXML ) {\n\t\t\tvar name = match[1] = match[1].replace( rBackslash, \"\" );\n\t\t\t\n\t\t\tif ( !isXML && Expr.attrMap[name] ) {\n\t\t\t\tmatch[1] = Expr.attrMap[name];\n\t\t\t}\n\n\t\t\t// Handle if an un-quoted value was used\n\t\t\tmatch[4] = ( match[4] || match[5] || \"\" ).replace( rBackslash, \"\" );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[4] = \" \" + match[4] + \" \";\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\tPSEUDO: function( match, curLoop, inplace, result, not ) {\n\t\t\tif ( match[1] === \"not\" ) {\n\t\t\t\t// If we're dealing with a complex expression, or a simple one\n\t\t\t\tif ( ( chunker.exec(match[3]) || \"\" ).length > 1 || /^\\w/.test(match[3]) ) {\n\t\t\t\t\tmatch[3] = Sizzle(match[3], null, null, curLoop);\n\n\t\t\t\t} else {\n\t\t\t\t\tvar ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);\n\n\t\t\t\t\tif ( !inplace ) {\n\t\t\t\t\t\tresult.push.apply( result, ret );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t\n\t\t\treturn match;\n\t\t},\n\n\t\tPOS: function( match ) {\n\t\t\tmatch.unshift( true );\n\n\t\t\treturn match;\n\t\t}\n\t},\n\t\n\tfilters: {\n\t\tenabled: function( elem ) {\n\t\t\treturn elem.disabled === false && elem.type !== \"hidden\";\n\t\t},\n\n\t\tdisabled: function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\tchecked: function( elem ) {\n\t\t\treturn elem.checked === true;\n\t\t},\n\t\t\n\t\tselected: function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\t\t\t\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\tparent: function( elem ) {\n\t\t\treturn !!elem.firstChild;\n\t\t},\n\n\t\tempty: function( elem ) {\n\t\t\treturn !elem.firstChild;\n\t\t},\n\n\t\thas: function( elem, i, match ) {\n\t\t\treturn !!Sizzle( match[3], elem ).length;\n\t\t},\n\n\t\theader: function( elem ) {\n\t\t\treturn (/h\\d/i).test( elem.nodeName );\n\t\t},\n\n\t\ttext: function( elem ) {\n\t\t\t// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) \n\t\t\t// use getAttribute instead to test this case\n\t\t\treturn \"text\" === elem.getAttribute( 'type' );\n\t\t},\n\t\tradio: function( elem ) {\n\t\t\treturn \"radio\" === elem.type;\n\t\t},\n\n\t\tcheckbox: function( elem ) {\n\t\t\treturn \"checkbox\" === elem.type;\n\t\t},\n\n\t\tfile: function( elem ) {\n\t\t\treturn \"file\" === elem.type;\n\t\t},\n\t\tpassword: function( elem ) {\n\t\t\treturn \"password\" === elem.type;\n\t\t},\n\n\t\tsubmit: function( elem ) {\n\t\t\treturn \"submit\" === elem.type;\n\t\t},\n\n\t\timage: function( elem ) {\n\t\t\treturn \"image\" === elem.type;\n\t\t},\n\n\t\treset: function( elem ) {\n\t\t\treturn \"reset\" === elem.type;\n\t\t},\n\n\t\tbutton: function( elem ) {\n\t\t\treturn \"button\" === elem.type || elem.nodeName.toLowerCase() === \"button\";\n\t\t},\n\n\t\tinput: function( elem ) {\n\t\t\treturn (/input|select|textarea|button/i).test( elem.nodeName );\n\t\t}\n\t},\n\tsetFilters: {\n\t\tfirst: function( elem, i ) {\n\t\t\treturn i === 0;\n\t\t},\n\n\t\tlast: function( elem, i, match, array ) {\n\t\t\treturn i === array.length - 1;\n\t\t},\n\n\t\teven: function( elem, i ) {\n\t\t\treturn i % 2 === 0;\n\t\t},\n\n\t\todd: function( elem, i ) {\n\t\t\treturn i % 2 === 1;\n\t\t},\n\n\t\tlt: function( elem, i, match ) {\n\t\t\treturn i < match[3] - 0;\n\t\t},\n\n\t\tgt: function( elem, i, match ) {\n\t\t\treturn i > match[3] - 0;\n\t\t},\n\n\t\tnth: function( elem, i, match ) {\n\t\t\treturn match[3] - 0 === i;\n\t\t},\n\n\t\teq: function( elem, i, match ) {\n\t\t\treturn match[3] - 0 === i;\n\t\t}\n\t},\n\tfilter: {\n\t\tPSEUDO: function( elem, match, i, array ) {\n\t\t\tvar name = match[1],\n\t\t\t\tfilter = Expr.filters[ name ];\n\n\t\t\tif ( filter ) {\n\t\t\t\treturn filter( elem, i, match, array );\n\n\t\t\t} else if ( name === \"contains\" ) {\n\t\t\t\treturn (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || \"\").indexOf(match[3]) >= 0;\n\n\t\t\t} else if ( name === \"not\" ) {\n\t\t\t\tvar not = match[3];\n\n\t\t\t\tfor ( var j = 0, l = not.length; j < l; j++ ) {\n\t\t\t\t\tif ( not[j] === elem ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t} else {\n\t\t\t\tSizzle.error( name );\n\t\t\t}\n\t\t},\n\n\t\tCHILD: function( elem, match ) {\n\t\t\tvar type = match[1],\n\t\t\t\tnode = elem;\n\n\t\t\tswitch ( type ) {\n\t\t\t\tcase \"only\":\n\t\t\t\tcase \"first\":\n\t\t\t\t\twhile ( (node = node.previousSibling) )\t {\n\t\t\t\t\t\tif ( node.nodeType === 1 ) { \n\t\t\t\t\t\t\treturn false; \n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( type === \"first\" ) { \n\t\t\t\t\t\treturn true; \n\t\t\t\t\t}\n\n\t\t\t\t\tnode = elem;\n\n\t\t\t\tcase \"last\":\n\t\t\t\t\twhile ( (node = node.nextSibling) )\t {\n\t\t\t\t\t\tif ( node.nodeType === 1 ) { \n\t\t\t\t\t\t\treturn false; \n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\tcase \"nth\":\n\t\t\t\t\tvar first = match[2],\n\t\t\t\t\t\tlast = match[3];\n\n\t\t\t\t\tif ( first === 1 && last === 0 ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tvar doneName = match[0],\n\t\t\t\t\t\tparent = elem.parentNode;\n\t\n\t\t\t\t\tif ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {\n\t\t\t\t\t\tvar count = 0;\n\t\t\t\t\t\t\n\t\t\t\t\t\tfor ( node = parent.firstChild; node; node = node.nextSibling ) {\n\t\t\t\t\t\t\tif ( node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\tnode.nodeIndex = ++count;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} \n\n\t\t\t\t\t\tparent.sizcache = doneName;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tvar diff = elem.nodeIndex - last;\n\n\t\t\t\t\tif ( first === 0 ) {\n\t\t\t\t\t\treturn diff === 0;\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tID: function( elem, match ) {\n\t\t\treturn elem.nodeType === 1 && elem.getAttribute(\"id\") === match;\n\t\t},\n\n\t\tTAG: function( elem, match ) {\n\t\t\treturn (match === \"*\" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;\n\t\t},\n\t\t\n\t\tCLASS: function( elem, match ) {\n\t\t\treturn (\" \" + (elem.className || elem.getAttribute(\"class\")) + \" \")\n\t\t\t\t.indexOf( match ) > -1;\n\t\t},\n\n\t\tATTR: function( elem, match ) {\n\t\t\tvar name = match[1],\n\t\t\t\tresult = Expr.attrHandle[ name ] ?\n\t\t\t\t\tExpr.attrHandle[ name ]( elem ) :\n\t\t\t\t\telem[ name ] != null ?\n\t\t\t\t\t\telem[ name ] :\n\t\t\t\t\t\telem.getAttribute( name ),\n\t\t\t\tvalue = result + \"\",\n\t\t\t\ttype = match[2],\n\t\t\t\tcheck = match[4];\n\n\t\t\treturn result == null ?\n\t\t\t\ttype === \"!=\" :\n\t\t\t\ttype === \"=\" ?\n\t\t\t\tvalue === check :\n\t\t\t\ttype === \"*=\" ?\n\t\t\t\tvalue.indexOf(check) >= 0 :\n\t\t\t\ttype === \"~=\" ?\n\t\t\t\t(\" \" + value + \" \").indexOf(check) >= 0 :\n\t\t\t\t!check ?\n\t\t\t\tvalue && result !== false :\n\t\t\t\ttype === \"!=\" ?\n\t\t\t\tvalue !== check :\n\t\t\t\ttype === \"^=\" ?\n\t\t\t\tvalue.indexOf(check) === 0 :\n\t\t\t\ttype === \"$=\" ?\n\t\t\t\tvalue.substr(value.length - check.length) === check :\n\t\t\t\ttype === \"|=\" ?\n\t\t\t\tvalue === check || value.substr(0, check.length + 1) === check + \"-\" :\n\t\t\t\tfalse;\n\t\t},\n\n\t\tPOS: function( elem, match, i, array ) {\n\t\t\tvar name = match[2],\n\t\t\t\tfilter = Expr.setFilters[ name ];\n\n\t\t\tif ( filter ) {\n\t\t\t\treturn filter( elem, i, match, array );\n\t\t\t}\n\t\t}\n\t}\n};\n\nvar origPOS = Expr.match.POS,\n\tfescape = function(all, num){\n\t\treturn \"\\\\\" + (num - 0 + 1);\n\t};\n\nfor ( var type in Expr.match ) {\n\tExpr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\\[]*\\])(?![^\\(]*\\))/.source) );\n\tExpr.leftMatch[ type ] = new RegExp( /(^(?:.|\\r|\\n)*?)/.source + Expr.match[ type ].source.replace(/\\\\(\\d+)/g, fescape) );\n}\n\nvar makeArray = function( array, results ) {\n\tarray = Array.prototype.slice.call( array, 0 );\n\n\tif ( results ) {\n\t\tresults.push.apply( results, array );\n\t\treturn results;\n\t}\n\t\n\treturn array;\n};\n\n// Perform a simple check to determine if the browser is capable of\n// converting a NodeList to an array using builtin methods.\n// Also verifies that the returned array holds DOM nodes\n// (which is not the case in the Blackberry browser)\ntry {\n\tArray.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;\n\n// Provide a fallback method if it does not work\n} catch( e ) {\n\tmakeArray = function( array, results ) {\n\t\tvar i = 0,\n\t\t\tret = results || [];\n\n\t\tif ( toString.call(array) === \"[object Array]\" ) {\n\t\t\tArray.prototype.push.apply( ret, array );\n\n\t\t} else {\n\t\t\tif ( typeof array.length === \"number\" ) {\n\t\t\t\tfor ( var l = array.length; i < l; i++ ) {\n\t\t\t\t\tret.push( array[i] );\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tfor ( ; array[i]; i++ ) {\n\t\t\t\t\tret.push( array[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t};\n}\n\nvar sortOrder, siblingCheck;\n\nif ( document.documentElement.compareDocumentPosition ) {\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tif ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {\n\t\t\treturn a.compareDocumentPosition ? -1 : 1;\n\t\t}\n\n\t\treturn a.compareDocumentPosition(b) & 4 ? -1 : 1;\n\t};\n\n} else {\n\tsortOrder = function( a, b ) {\n\t\tvar al, bl,\n\t\t\tap = [],\n\t\t\tbp = [],\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tcur = aup;\n\n\t\t// The nodes are identical, we can exit early\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\n\t\t// If the nodes are siblings (or identical) we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\n\t\t// If no parents were found then the nodes are disconnected\n\t\t} else if ( !aup ) {\n\t\t\treturn -1;\n\n\t\t} else if ( !bup ) {\n\t\t\treturn 1;\n\t\t}\n\n\t\t// Otherwise they're somewhere else in the tree so we need\n\t\t// to build up a full list of the parentNodes for comparison\n\t\twhile ( cur ) {\n\t\t\tap.unshift( cur );\n\t\t\tcur = cur.parentNode;\n\t\t}\n\n\t\tcur = bup;\n\n\t\twhile ( cur ) {\n\t\t\tbp.unshift( cur );\n\t\t\tcur = cur.parentNode;\n\t\t}\n\n\t\tal = ap.length;\n\t\tbl = bp.length;\n\n\t\t// Start walking down the tree looking for a discrepancy\n\t\tfor ( var i = 0; i < al && i < bl; i++ ) {\n\t\t\tif ( ap[i] !== bp[i] ) {\n\t\t\t\treturn siblingCheck( ap[i], bp[i] );\n\t\t\t}\n\t\t}\n\n\t\t// We ended someplace up the tree so do a sibling check\n\t\treturn i === al ?\n\t\t\tsiblingCheck( a, bp[i], -1 ) :\n\t\t\tsiblingCheck( ap[i], b, 1 );\n\t};\n\n\tsiblingCheck = function( a, b, ret ) {\n\t\tif ( a === b ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tvar cur = a.nextSibling;\n\n\t\twhile ( cur ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tcur = cur.nextSibling;\n\t\t}\n\n\t\treturn 1;\n\t};\n}\n\n// Utility function for retreiving the text value of an array of DOM nodes\nSizzle.getText = function( elems ) {\n\tvar ret = \"\", elem;\n\n\tfor ( var i = 0; elems[i]; i++ ) {\n\t\telem = elems[i];\n\n\t\t// Get the text from text nodes and CDATA nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 4 ) {\n\t\t\tret += elem.nodeValue;\n\n\t\t// Traverse everything else, except comment nodes\n\t\t} else if ( elem.nodeType !== 8 ) {\n\t\t\tret += Sizzle.getText( elem.childNodes );\n\t\t}\n\t}\n\n\treturn ret;\n};\n\n// Check to see if the browser returns elements by name when\n// querying by getElementById (and provide a workaround)\n(function(){\n\t// We're going to inject a fake input element with a specified name\n\tvar form = document.createElement(\"div\"),\n\t\tid = \"script\" + (new Date()).getTime(),\n\t\troot = document.documentElement;\n\n\tform.innerHTML = \"<a name='\" + id + \"'/>\";\n\n\t// Inject it into the root element, check its status, and remove it quickly\n\troot.insertBefore( form, root.firstChild );\n\n\t// The workaround has to do additional checks after a getElementById\n\t// Which slows things down for other browsers (hence the branching)\n\tif ( document.getElementById( id ) ) {\n\t\tExpr.find.ID = function( match, context, isXML ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && !isXML ) {\n\t\t\t\tvar m = context.getElementById(match[1]);\n\n\t\t\t\treturn m ?\n\t\t\t\t\tm.id === match[1] || typeof m.getAttributeNode !== \"undefined\" && m.getAttributeNode(\"id\").nodeValue === match[1] ?\n\t\t\t\t\t\t[m] :\n\t\t\t\t\t\tundefined :\n\t\t\t\t\t[];\n\t\t\t}\n\t\t};\n\n\t\tExpr.filter.ID = function( elem, match ) {\n\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n\n\t\t\treturn elem.nodeType === 1 && node && node.nodeValue === match;\n\t\t};\n\t}\n\n\troot.removeChild( form );\n\n\t// release memory in IE\n\troot = form = null;\n})();\n\n(function(){\n\t// Check to see if the browser returns only elements\n\t// when doing getElementsByTagName(\"*\")\n\n\t// Create a fake element\n\tvar div = document.createElement(\"div\");\n\tdiv.appendChild( document.createComment(\"\") );\n\n\t// Make sure no comments are found\n\tif ( div.getElementsByTagName(\"*\").length > 0 ) {\n\t\tExpr.find.TAG = function( match, context ) {\n\t\t\tvar results = context.getElementsByTagName( match[1] );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( match[1] === \"*\" ) {\n\t\t\t\tvar tmp = [];\n\n\t\t\t\tfor ( var i = 0; results[i]; i++ ) {\n\t\t\t\t\tif ( results[i].nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( results[i] );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tresults = tmp;\n\t\t\t}\n\n\t\t\treturn results;\n\t\t};\n\t}\n\n\t// Check to see if an attribute returns normalized href attributes\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\n\tif ( div.firstChild && typeof div.firstChild.getAttribute !== \"undefined\" &&\n\t\t\tdiv.firstChild.getAttribute(\"href\") !== \"#\" ) {\n\n\t\tExpr.attrHandle.href = function( elem ) {\n\t\t\treturn elem.getAttribute( \"href\", 2 );\n\t\t};\n\t}\n\n\t// release memory in IE\n\tdiv = null;\n})();\n\nif ( document.querySelectorAll ) {\n\t(function(){\n\t\tvar oldSizzle = Sizzle,\n\t\t\tdiv = document.createElement(\"div\"),\n\t\t\tid = \"__sizzle__\";\n\n\t\tdiv.innerHTML = \"<p class='TEST'></p>\";\n\n\t\t// Safari can't handle uppercase or unicode characters when\n\t\t// in quirks mode.\n\t\tif ( div.querySelectorAll && div.querySelectorAll(\".TEST\").length === 0 ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tSizzle = function( query, context, extra, seed ) {\n\t\t\tcontext = context || document;\n\n\t\t\t// Only use querySelectorAll on non-XML documents\n\t\t\t// (ID selectors don't work in non-HTML documents)\n\t\t\tif ( !seed && !Sizzle.isXML(context) ) {\n\t\t\t\t// See if we find a selector to speed up\n\t\t\t\tvar match = /^(\\w+$)|^\\.([\\w\\-]+$)|^#([\\w\\-]+$)/.exec( query );\n\t\t\t\t\n\t\t\t\tif ( match && (context.nodeType === 1 || context.nodeType === 9) ) {\n\t\t\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t\t\tif ( match[1] ) {\n\t\t\t\t\t\treturn makeArray( context.getElementsByTagName( query ), extra );\n\t\t\t\t\t\n\t\t\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t\t\t} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {\n\t\t\t\t\t\treturn makeArray( context.getElementsByClassName( match[2] ), extra );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif ( context.nodeType === 9 ) {\n\t\t\t\t\t// Speed-up: Sizzle(\"body\")\n\t\t\t\t\t// The body element only exists once, optimize finding it\n\t\t\t\t\tif ( query === \"body\" && context.body ) {\n\t\t\t\t\t\treturn makeArray( [ context.body ], extra );\n\t\t\t\t\t\t\n\t\t\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\t\t\t} else if ( match && match[3] ) {\n\t\t\t\t\t\tvar elem = context.getElementById( match[3] );\n\n\t\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === match[3] ) {\n\t\t\t\t\t\t\t\treturn makeArray( [ elem ], extra );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn makeArray( [], extra );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn makeArray( context.querySelectorAll(query), extra );\n\t\t\t\t\t} catch(qsaError) {}\n\n\t\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t\t// IE 8 doesn't work on object elements\n\t\t\t\t} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\t\tvar oldContext = context,\n\t\t\t\t\t\told = context.getAttribute( \"id\" ),\n\t\t\t\t\t\tnid = old || id,\n\t\t\t\t\t\thasParent = context.parentNode,\n\t\t\t\t\t\trelativeHierarchySelector = /^\\s*[+~]/.test( query );\n\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnid = nid.replace( /'/g, \"\\\\$&\" );\n\t\t\t\t\t}\n\t\t\t\t\tif ( relativeHierarchySelector && hasParent ) {\n\t\t\t\t\t\tcontext = context.parentNode;\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif ( !relativeHierarchySelector || hasParent ) {\n\t\t\t\t\t\t\treturn makeArray( context.querySelectorAll( \"[id='\" + nid + \"'] \" + query ), extra );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} catch(pseudoError) {\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\t\toldContext.removeAttribute( \"id\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\n\t\t\treturn oldSizzle(query, context, extra, seed);\n\t\t};\n\n\t\tfor ( var prop in oldSizzle ) {\n\t\t\tSizzle[ prop ] = oldSizzle[ prop ];\n\t\t}\n\n\t\t// release memory in IE\n\t\tdiv = null;\n\t})();\n}\n\n(function(){\n\tvar html = document.documentElement,\n\t\tmatches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,\n\t\tpseudoWorks = false;\n\n\ttry {\n\t\t// This should fail with an exception\n\t\t// Gecko does not error, returns false instead\n\t\tmatches.call( document.documentElement, \"[test!='']:sizzle\" );\n\t\n\t} catch( pseudoError ) {\n\t\tpseudoWorks = true;\n\t}\n\n\tif ( matches ) {\n\t\tSizzle.matchesSelector = function( node, expr ) {\n\t\t\t// Make sure that attribute selectors are quoted\n\t\t\texpr = expr.replace(/\\=\\s*([^'\"\\]]*)\\s*\\]/g, \"='$1']\");\n\n\t\t\tif ( !Sizzle.isXML( node ) ) {\n\t\t\t\ttry { \n\t\t\t\t\tif ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {\n\t\t\t\t\t\treturn matches.call( node, expr );\n\t\t\t\t\t}\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\treturn Sizzle(expr, null, null, [node]).length > 0;\n\t\t};\n\t}\n})();\n\n(function(){\n\tvar div = document.createElement(\"div\");\n\n\tdiv.innerHTML = \"<div class='test e'></div><div class='test'></div>\";\n\n\t// Opera can't find a second classname (in 9.6)\n\t// Also, make sure that getElementsByClassName actually exists\n\tif ( !div.getElementsByClassName || div.getElementsByClassName(\"e\").length === 0 ) {\n\t\treturn;\n\t}\n\n\t// Safari caches class attributes, doesn't catch changes (in 3.2)\n\tdiv.lastChild.className = \"e\";\n\n\tif ( div.getElementsByClassName(\"e\").length === 1 ) {\n\t\treturn;\n\t}\n\t\n\tExpr.order.splice(1, 0, \"CLASS\");\n\tExpr.find.CLASS = function( match, context, isXML ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && !isXML ) {\n\t\t\treturn context.getElementsByClassName(match[1]);\n\t\t}\n\t};\n\n\t// release memory in IE\n\tdiv = null;\n})();\n\nfunction dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {\n\tfor ( var i = 0, l = checkSet.length; i < l; i++ ) {\n\t\tvar elem = checkSet[i];\n\n\t\tif ( elem ) {\n\t\t\tvar match = false;\n\n\t\t\telem = elem[dir];\n\n\t\t\twhile ( elem ) {\n\t\t\t\tif ( elem.sizcache === doneName ) {\n\t\t\t\t\tmatch = checkSet[elem.sizset];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( elem.nodeType === 1 && !isXML ){\n\t\t\t\t\telem.sizcache = doneName;\n\t\t\t\t\telem.sizset = i;\n\t\t\t\t}\n\n\t\t\t\tif ( elem.nodeName.toLowerCase() === cur ) {\n\t\t\t\t\tmatch = elem;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\telem = elem[dir];\n\t\t\t}\n\n\t\t\tcheckSet[i] = match;\n\t\t}\n\t}\n}\n\nfunction dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {\n\tfor ( var i = 0, l = checkSet.length; i < l; i++ ) {\n\t\tvar elem = checkSet[i];\n\n\t\tif ( elem ) {\n\t\t\tvar match = false;\n\t\t\t\n\t\t\telem = elem[dir];\n\n\t\t\twhile ( elem ) {\n\t\t\t\tif ( elem.sizcache === doneName ) {\n\t\t\t\t\tmatch = checkSet[elem.sizset];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\tif ( !isXML ) {\n\t\t\t\t\t\telem.sizcache = doneName;\n\t\t\t\t\t\telem.sizset = i;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( typeof cur !== \"string\" ) {\n\t\t\t\t\t\tif ( elem === cur ) {\n\t\t\t\t\t\t\tmatch = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {\n\t\t\t\t\t\tmatch = elem;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\telem = elem[dir];\n\t\t\t}\n\n\t\t\tcheckSet[i] = match;\n\t\t}\n\t}\n}\n\nif ( document.documentElement.contains ) {\n\tSizzle.contains = function( a, b ) {\n\t\treturn a !== b && (a.contains ? a.contains(b) : true);\n\t};\n\n} else if ( document.documentElement.compareDocumentPosition ) {\n\tSizzle.contains = function( a, b ) {\n\t\treturn !!(a.compareDocumentPosition(b) & 16);\n\t};\n\n} else {\n\tSizzle.contains = function() {\n\t\treturn false;\n\t};\n}\n\nSizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833) \n\tvar documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;\n\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\nvar posProcess = function( selector, context ) {\n\tvar match,\n\t\ttmpSet = [],\n\t\tlater = \"\",\n\t\troot = context.nodeType ? [context] : context;\n\n\t// Position selectors must be done after the filter\n\t// And so must :not(positional) so we move all PSEUDOs to the end\n\twhile ( (match = Expr.match.PSEUDO.exec( selector )) ) {\n\t\tlater += match[0];\n\t\tselector = selector.replace( Expr.match.PSEUDO, \"\" );\n\t}\n\n\tselector = Expr.relative[selector] ? selector + \"*\" : selector;\n\n\tfor ( var i = 0, l = root.length; i < l; i++ ) {\n\t\tSizzle( selector, root[i], tmpSet );\n\t}\n\n\treturn Sizzle.filter( later, tmpSet );\n};\n\n// EXPOSE\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.filters;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n})();\n\n\nvar runtil = /Until$/,\n\trparentsprev = /^(?:parents|prevUntil|prevAll)/,\n\t// Note: This RegExp should be improved, or likely pulled from Sizzle\n\trmultiselector = /,/,\n\tisSimple = /^.[^:#\\[\\.,]*$/,\n\tslice = Array.prototype.slice,\n\tPOS = jQuery.expr.match.POS,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar ret = this.pushStack( \"\", \"find\", selector ),\n\t\t\tlength = 0;\n\n\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\tlength = ret.length;\n\t\t\tjQuery.find( selector, this[i], ret );\n\n\t\t\tif ( i > 0 ) {\n\t\t\t\t// Make sure that the results are unique\n\t\t\t\tfor ( var n = length; n < ret.length; n++ ) {\n\t\t\t\t\tfor ( var r = 0; r < length; r++ ) {\n\t\t\t\t\t\tif ( ret[r] === ret[n] ) {\n\t\t\t\t\t\t\tret.splice(n--, 1);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\thas: function( target ) {\n\t\tvar targets = jQuery( target );\n\t\treturn this.filter(function() {\n\t\t\tfor ( var i = 0, l = targets.length; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector, false), \"not\", selector);\n\t},\n\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector, true), \"filter\", selector );\n\t},\n\n\tis: function( selector ) {\n\t\treturn !!selector && jQuery.filter( selector, this ).length > 0;\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar ret = [], i, l, cur = this[0];\n\n\t\tif ( jQuery.isArray( selectors ) ) {\n\t\t\tvar match, selector,\n\t\t\t\tmatches = {},\n\t\t\t\tlevel = 1;\n\n\t\t\tif ( cur && selectors.length ) {\n\t\t\t\tfor ( i = 0, l = selectors.length; i < l; i++ ) {\n\t\t\t\t\tselector = selectors[i];\n\n\t\t\t\t\tif ( !matches[selector] ) {\n\t\t\t\t\t\tmatches[selector] = jQuery.expr.match.POS.test( selector ) ?\n\t\t\t\t\t\t\tjQuery( selector, context || this.context ) :\n\t\t\t\t\t\t\tselector;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\twhile ( cur && cur.ownerDocument && cur !== context ) {\n\t\t\t\t\tfor ( selector in matches ) {\n\t\t\t\t\t\tmatch = matches[selector];\n\n\t\t\t\t\t\tif ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {\n\t\t\t\t\t\t\tret.push({ selector: selector, elem: cur, level: level });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcur = cur.parentNode;\n\t\t\t\t\tlevel++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn ret;\n\t\t}\n\n\t\tvar pos = POS.test( selectors ) ?\n\t\t\tjQuery( selectors, context || this.context ) : null;\n\n\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\tcur = this[i];\n\n\t\t\twhile ( cur ) {\n\t\t\t\tif ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {\n\t\t\t\t\tret.push( cur );\n\t\t\t\t\tbreak;\n\n\t\t\t\t} else {\n\t\t\t\t\tcur = cur.parentNode;\n\t\t\t\t\tif ( !cur || !cur.ownerDocument || cur === context ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tret = ret.length > 1 ? jQuery.unique(ret) : ret;\n\n\t\treturn this.pushStack( ret, \"closest\", selectors );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\t\tif ( !elem || typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0],\n\t\t\t\t// If it receives a string, the selector is used\n\t\t\t\t// If it receives nothing, the siblings are used\n\t\t\t\telem ? jQuery( elem ) : this.parent().children() );\n\t\t}\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\tvar set = typeof selector === \"string\" ?\n\t\t\t\tjQuery( selector, context ) :\n\t\t\t\tjQuery.makeArray( selector ),\n\t\t\tall = jQuery.merge( this.get(), set );\n\n\t\treturn this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?\n\t\t\tall :\n\t\t\tjQuery.unique( all ) );\n\t},\n\n\tandSelf: function() {\n\t\treturn this.add( this.prevObject );\n\t}\n});\n\n// A painfully simple check to see if an element is disconnected\n// from a document (should be improved, where feasible).\nfunction isDisconnected( node ) {\n\treturn !node || !node.parentNode || node.parentNode.nodeType === 11;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn jQuery.nth( elem, 2, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn jQuery.nth( elem, 2, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( elem.parentNode.firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.makeArray( elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until ),\n\t\t\t// The variable 'args' was introduced in\n\t\t\t// https://github.com/jquery/jquery/commit/52a0238\n\t\t\t// to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.\n\t\t\t// http://code.google.com/p/v8/issues/detail?id=1050\n\t\t\targs = slice.call(arguments);\n\n\t\tif ( !runtil.test( name ) ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;\n\n\t\tif ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {\n\t\t\tret = ret.reverse();\n\t\t}\n\n\t\treturn this.pushStack( ret, name, args.join(\",\") );\n\t};\n});\n\njQuery.extend({\n\tfilter: function( expr, elems, not ) {\n\t\tif ( not ) {\n\t\t\texpr = \":not(\" + expr + \")\";\n\t\t}\n\n\t\treturn elems.length === 1 ?\n\t\t\tjQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :\n\t\t\tjQuery.find.matches(expr, elems);\n\t},\n\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tnth: function( cur, result, dir, elem ) {\n\t\tresult = result || 1;\n\t\tvar num = 0;\n\n\t\tfor ( ; cur; cur = cur[dir] ) {\n\t\t\tif ( cur.nodeType === 1 && ++num === result ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn cur;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, keep ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep(elements, function( elem, i ) {\n\t\t\tvar retVal = !!qualifier.call( elem, i, elem );\n\t\t\treturn retVal === keep;\n\t\t});\n\n\t} else if ( qualifier.nodeType ) {\n\t\treturn jQuery.grep(elements, function( elem, i ) {\n\t\t\treturn (elem === qualifier) === keep;\n\t\t});\n\n\t} else if ( typeof qualifier === \"string\" ) {\n\t\tvar filtered = jQuery.grep(elements, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t});\n\n\t\tif ( isSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter(qualifier, filtered, !keep);\n\t\t} else {\n\t\t\tqualifier = jQuery.filter( qualifier, filtered );\n\t\t}\n\t}\n\n\treturn jQuery.grep(elements, function( elem, i ) {\n\t\treturn (jQuery.inArray( elem, qualifier ) >= 0) === keep;\n\t});\n}\n\n\n\n\nvar rinlinejQuery = / jQuery\\d+=\"(?:\\d+|null)\"/g,\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/ig,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnocache = /<(?:script|object|embed|option|style)/i,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\t_default: [ 0, \"\", \"\" ]\n\t};\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// IE can't serialize <link> and <script> tags normally\nif ( !jQuery.support.htmlSerialize ) {\n\twrapMap._default = [ 1, \"div<div>\", \"</div>\" ];\n}\n\njQuery.fn.extend({\n\ttext: function( text ) {\n\t\tif ( jQuery.isFunction(text) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery( this );\n\n\t\t\t\tself.text( text.call(this, i, self.text()) );\n\t\t\t});\n\t\t}\n\n\t\tif ( typeof text !== \"object\" && text !== undefined ) {\n\t\t\treturn this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );\n\t\t}\n\n\t\treturn jQuery.text( this );\n\t},\n\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\t// The elements to wrap the target around\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append(this);\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery( this ).wrapAll( html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip(arguments, true, function( elem ) {\n\t\t\tif ( this.nodeType === 1 ) {\n\t\t\t\tthis.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip(arguments, true, function( elem ) {\n\t\t\tif ( this.nodeType === 1 ) {\n\t\t\t\tthis.insertBefore( elem, this.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\tif ( this[0] && this[0].parentNode ) {\n\t\t\treturn this.domManip(arguments, false, function( elem ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t});\n\t\t} else if ( arguments.length ) {\n\t\t\tvar set = jQuery(arguments[0]);\n\t\t\tset.push.apply( set, this.toArray() );\n\t\t\treturn this.pushStack( set, \"before\", arguments );\n\t\t}\n\t},\n\n\tafter: function() {\n\t\tif ( this[0] && this[0].parentNode ) {\n\t\t\treturn this.domManip(arguments, false, function( elem ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t});\n\t\t} else if ( arguments.length ) {\n\t\t\tvar set = this.pushStack( this, \"after\", arguments );\n\t\t\tset.push.apply( set, jQuery(arguments[0]).toArray() );\n\t\t\treturn set;\n\t\t}\n\t},\n\n\t// keepData is for internal use only--do not document\n\tremove: function( selector, keepData ) {\n\t\tfor ( var i = 0, elem; (elem = this[i]) != null; i++ ) {\n\t\t\tif ( !selector || jQuery.filter( selector, [ elem ] ).length ) {\n\t\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\t\tjQuery.cleanData( elem.getElementsByTagName(\"*\") );\n\t\t\t\t\tjQuery.cleanData( [ elem ] );\n\t\t\t\t}\n\n\t\t\t\tif ( elem.parentNode ) {\n\t\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tfor ( var i = 0, elem; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( elem.getElementsByTagName(\"*\") );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function () {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\tif ( value === undefined ) {\n\t\t\treturn this[0] && this[0].nodeType === 1 ?\n\t\t\t\tthis[0].innerHTML.replace(rinlinejQuery, \"\") :\n\t\t\t\tnull;\n\n\t\t// See if we can take a shortcut and just use innerHTML\n\t\t} else if ( typeof value === \"string\" && !rnocache.test( value ) &&\n\t\t\t(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&\n\t\t\t!wrapMap[ (rtagName.exec( value ) || [\"\", \"\"])[1].toLowerCase() ] ) {\n\n\t\t\tvalue = value.replace(rxhtmlTag, \"<$1></$2>\");\n\n\t\t\ttry {\n\t\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\tif ( this[i].nodeType === 1 ) {\n\t\t\t\t\t\tjQuery.cleanData( this[i].getElementsByTagName(\"*\") );\n\t\t\t\t\t\tthis[i].innerHTML = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t} catch(e) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\n\t\t} else if ( jQuery.isFunction( value ) ) {\n\t\t\tthis.each(function(i){\n\t\t\t\tvar self = jQuery( this );\n\n\t\t\t\tself.html( value.call(this, i, self.html()) );\n\t\t\t});\n\n\t\t} else {\n\t\t\tthis.empty().append( value );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\treplaceWith: function( value ) {\n\t\tif ( this[0] && this[0].parentNode ) {\n\t\t\t// Make sure that the elements are removed from the DOM before they are inserted\n\t\t\t// this can help fix replacing a parent with child elements\n\t\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\t\treturn this.each(function(i) {\n\t\t\t\t\tvar self = jQuery(this), old = self.html();\n\t\t\t\t\tself.replaceWith( value.call( this, i, old ) );\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ( typeof value !== \"string\" ) {\n\t\t\t\tvalue = jQuery( value ).detach();\n\t\t\t}\n\n\t\t\treturn this.each(function() {\n\t\t\t\tvar next = this.nextSibling,\n\t\t\t\t\tparent = this.parentNode;\n\n\t\t\t\tjQuery( this ).remove();\n\n\t\t\t\tif ( next ) {\n\t\t\t\t\tjQuery(next).before( value );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery(parent).append( value );\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\treturn this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), \"replaceWith\", value );\n\t\t}\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, table, callback ) {\n\t\tvar results, first, fragment, parent,\n\t\t\tvalue = args[0],\n\t\t\tscripts = [];\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === \"string\" && rchecked.test( value ) ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery(this).domManip( args, table, callback, true );\n\t\t\t});\n\t\t}\n\n\t\tif ( jQuery.isFunction(value) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery(this);\n\t\t\t\targs[0] = value.call(this, i, table ? self.html() : undefined);\n\t\t\t\tself.domManip( args, table, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\tparent = value && value.parentNode;\n\n\t\t\t// If we're in a fragment, just use that instead of building a new one\n\t\t\tif ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {\n\t\t\t\tresults = { fragment: parent };\n\n\t\t\t} else {\n\t\t\t\tresults = jQuery.buildFragment( args, this, scripts );\n\t\t\t}\n\n\t\t\tfragment = results.fragment;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfirst = fragment = fragment.firstChild;\n\t\t\t} else {\n\t\t\t\tfirst = fragment.firstChild;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\ttable = table && jQuery.nodeName( first, \"tr\" );\n\n\t\t\t\tfor ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {\n\t\t\t\t\tcallback.call(\n\t\t\t\t\t\ttable ?\n\t\t\t\t\t\t\troot(this[i], first) :\n\t\t\t\t\t\t\tthis[i],\n\t\t\t\t\t\t// Make sure that we do not leak memory by inadvertently discarding\n\t\t\t\t\t\t// the original fragment (which might have attached data) instead of\n\t\t\t\t\t\t// using it; in addition, use the original fragment object for the last\n\t\t\t\t\t\t// item instead of first because it can end up being emptied incorrectly\n\t\t\t\t\t\t// in certain situations (Bug #8070).\n\t\t\t\t\t\t// Fragments from the fragment cache must always be cloned and never used\n\t\t\t\t\t\t// in place.\n\t\t\t\t\t\tresults.cacheable || (l > 1 && i < lastIndex) ?\n\t\t\t\t\t\t\tjQuery.clone( fragment, true, true ) :\n\t\t\t\t\t\t\tfragment\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( scripts.length ) {\n\t\t\t\tjQuery.each( scripts, evalScript );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\nfunction root( elem, cur ) {\n\treturn jQuery.nodeName(elem, \"table\") ?\n\t\t(elem.getElementsByTagName(\"tbody\")[0] ||\n\t\telem.appendChild(elem.ownerDocument.createElement(\"tbody\"))) :\n\t\telem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar internalKey = jQuery.expando,\n\t\toldData = jQuery.data( src ),\n\t\tcurData = jQuery.data( dest, oldData );\n\n\t// Switch to use the internal data object, if it exists, for the next\n\t// stage of data copying\n\tif ( (oldData = oldData[ internalKey ]) ) {\n\t\tvar events = oldData.events;\n\t\t\t\tcurData = curData[ internalKey ] = jQuery.extend({}, oldData);\n\n\t\tif ( events ) {\n\t\t\tdelete curData.handle;\n\t\t\tcurData.events = {};\n\n\t\t\tfor ( var type in events ) {\n\t\t\t\tfor ( var i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? \".\" : \"\" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction cloneFixAttributes(src, dest) {\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// clearAttributes removes the attributes, which we don't want,\n\t// but also removes the attachEvent events, which we *do* want\n\tdest.clearAttributes();\n\n\t// mergeAttributes, in contrast, only merges back on the\n\t// original attributes, not the events\n\tdest.mergeAttributes(src);\n\n\t// IE6-8 fail to clone children inside object elements that use\n\t// the proprietary classid attribute value (rather than the type\n\t// attribute) to identify the type of content to display\n\tif ( nodeName === \"object\" ) {\n\t\tdest.outerHTML = src.outerHTML;\n\n\t} else if ( nodeName === \"input\" && (src.type === \"checkbox\" || src.type === \"radio\") ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\t\tif ( src.checked ) {\n\t\t\tdest.defaultChecked = dest.checked = src.checked;\n\t\t}\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n\n\t// Event data gets referenced instead of copied if the expando\n\t// gets copied too\n\tdest.removeAttribute( jQuery.expando );\n}\n\njQuery.buildFragment = function( args, nodes, scripts ) {\n\tvar fragment, cacheable, cacheresults,\n\t\tdoc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);\n\n\t// Only cache \"small\" (1/2 KB) HTML strings that are associated with the main document\n\t// Cloning options loses the selected state, so don't cache them\n\t// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment\n\t// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache\n\tif ( args.length === 1 && typeof args[0] === \"string\" && args[0].length < 512 && doc === document &&\n\t\targs[0].charAt(0) === \"<\" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {\n\n\t\tcacheable = true;\n\t\tcacheresults = jQuery.fragments[ args[0] ];\n\t\tif ( cacheresults ) {\n\t\t\tif ( cacheresults !== 1 ) {\n\t\t\t\tfragment = cacheresults;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( !fragment ) {\n\t\tfragment = doc.createDocumentFragment();\n\t\tjQuery.clean( args, doc, fragment, scripts );\n\t}\n\n\tif ( cacheable ) {\n\t\tjQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;\n\t}\n\n\treturn { fragment: fragment, cacheable: cacheable };\n};\n\njQuery.fragments = {};\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar ret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tparent = this.length === 1 && this[0].parentNode;\n\n\t\tif ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {\n\t\t\tinsert[ original ]( this[0] );\n\t\t\treturn this;\n\n\t\t} else {\n\t\t\tfor ( var i = 0, l = insert.length; i < l; i++ ) {\n\t\t\t\tvar elems = (i > 0 ? this.clone(true) : this).get();\n\t\t\t\tjQuery( insert[i] )[ original ]( elems );\n\t\t\t\tret = ret.concat( elems );\n\t\t\t}\n\n\t\t\treturn this.pushStack( ret, name, insert.selector );\n\t\t}\n\t};\n});\n\nfunction getAll( elem ) {\n\tif ( \"getElementsByTagName\" in elem ) {\n\t\treturn elem.getElementsByTagName( \"*\" );\n\t\n\t} else if ( \"querySelectorAll\" in elem ) {\n\t\treturn elem.querySelectorAll( \"*\" );\n\n\t} else {\n\t\treturn [];\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar clone = elem.cloneNode(true),\n\t\t\t\tsrcElements,\n\t\t\t\tdestElements,\n\t\t\t\ti;\n\n\t\tif ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\t\t\t// IE copies events bound via attachEvent when using cloneNode.\n\t\t\t// Calling detachEvent on the clone will also remove the events\n\t\t\t// from the original. In order to get around this, we use some\n\t\t\t// proprietary methods to clear the events. Thanks to MooTools\n\t\t\t// guys for this hotness.\n\n\t\t\tcloneFixAttributes( elem, clone );\n\n\t\t\t// Using Sizzle here is crazy slow, so we use getElementsByTagName\n\t\t\t// instead\n\t\t\tsrcElements = getAll( elem );\n\t\t\tdestElements = getAll( clone );\n\n\t\t\t// Weird iteration because IE will replace the length property\n\t\t\t// with an element if you are cloning the body and one of the\n\t\t\t// elements on the page has a name or id of \"length\"\n\t\t\tfor ( i = 0; srcElements[i]; ++i ) {\n\t\t\t\tcloneFixAttributes( srcElements[i], destElements[i] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tcloneCopyEvent( elem, clone );\n\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = getAll( elem );\n\t\t\t\tdestElements = getAll( clone );\n\n\t\t\t\tfor ( i = 0; srcElements[i]; ++i ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[i], destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n},\n\tclean: function( elems, context, fragment, scripts ) {\n\t\tcontext = context || document;\n\n\t\t// !context.createElement fails in IE with an error but returns typeof 'object'\n\t\tif ( typeof context.createElement === \"undefined\" ) {\n\t\t\tcontext = context.ownerDocument || context[0] && context[0].ownerDocument || document;\n\t\t}\n\n\t\tvar ret = [];\n\n\t\tfor ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( typeof elem === \"number\" ) {\n\t\t\t\telem += \"\";\n\t\t\t}\n\n\t\t\tif ( !elem ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Convert html string into DOM nodes\n\t\t\tif ( typeof elem === \"string\" && !rhtml.test( elem ) ) {\n\t\t\t\telem = context.createTextNode( elem );\n\n\t\t\t} else if ( typeof elem === \"string\" ) {\n\t\t\t\t// Fix \"XHTML\"-style tags in all browsers\n\t\t\t\telem = elem.replace(rxhtmlTag, \"<$1></$2>\");\n\n\t\t\t\t// Trim whitespace, otherwise indexOf won't work as expected\n\t\t\t\tvar tag = (rtagName.exec( elem ) || [\"\", \"\"])[1].toLowerCase(),\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default,\n\t\t\t\t\tdepth = wrap[0],\n\t\t\t\t\tdiv = context.createElement(\"div\");\n\n\t\t\t\t// Go to html and back, then peel off extra wrappers\n\t\t\t\tdiv.innerHTML = wrap[1] + elem + wrap[2];\n\n\t\t\t\t// Move to the right depth\n\t\t\t\twhile ( depth-- ) {\n\t\t\t\t\tdiv = div.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Remove IE's autoinserted <tbody> from table fragments\n\t\t\t\tif ( !jQuery.support.tbody ) {\n\n\t\t\t\t\t// String was a <table>, *may* have spurious <tbody>\n\t\t\t\t\tvar hasBody = rtbody.test(elem),\n\t\t\t\t\t\ttbody = tag === \"table\" && !hasBody ?\n\t\t\t\t\t\t\tdiv.firstChild && div.firstChild.childNodes :\n\n\t\t\t\t\t\t\t// String was a bare <thead> or <tfoot>\n\t\t\t\t\t\t\twrap[1] === \"<table>\" && !hasBody ?\n\t\t\t\t\t\t\t\tdiv.childNodes :\n\t\t\t\t\t\t\t\t[];\n\n\t\t\t\t\tfor ( var j = tbody.length - 1; j >= 0 ; --j ) {\n\t\t\t\t\t\tif ( jQuery.nodeName( tbody[ j ], \"tbody\" ) && !tbody[ j ].childNodes.length ) {\n\t\t\t\t\t\t\ttbody[ j ].parentNode.removeChild( tbody[ j ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// IE completely kills leading whitespace when innerHTML is used\n\t\t\t\tif ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\tdiv.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );\n\t\t\t\t}\n\n\t\t\t\telem = div.childNodes;\n\t\t\t}\n\n\t\t\tif ( elem.nodeType ) {\n\t\t\t\tret.push( elem );\n\t\t\t} else {\n\t\t\t\tret = jQuery.merge( ret, elem );\n\t\t\t}\n\t\t}\n\n\t\tif ( fragment ) {\n\t\t\tfor ( i = 0; ret[i]; i++ ) {\n\t\t\t\tif ( scripts && jQuery.nodeName( ret[i], \"script\" ) && (!ret[i].type || ret[i].type.toLowerCase() === \"text/javascript\") ) {\n\t\t\t\t\tscripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );\n\n\t\t\t\t} else {\n\t\t\t\t\tif ( ret[i].nodeType === 1 ) {\n\t\t\t\t\t\tret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName(\"script\"))) );\n\t\t\t\t\t}\n\t\t\t\t\tfragment.appendChild( ret[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,\n\t\t\tdeleteExpando = jQuery.support.deleteExpando;\n\n\t\tfor ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tid = elem[ jQuery.expando ];\n\n\t\t\tif ( id ) {\n\t\t\t\tdata = cache[ id ] && cache[ id ][ internalKey ];\n\n\t\t\t\tif ( data && data.events ) {\n\t\t\t\t\tfor ( var type in data.events ) {\n\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Null the DOM reference to avoid IE6/7/8 leak (#7054)\n\t\t\t\t\tif ( data.handle ) {\n\t\t\t\t\t\tdata.handle.elem = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\tdelete elem[ jQuery.expando ];\n\n\t\t\t\t} else if ( elem.removeAttribute ) {\n\t\t\t\t\telem.removeAttribute( jQuery.expando );\n\t\t\t\t}\n\n\t\t\t\tdelete cache[ id ];\n\t\t\t}\n\t\t}\n\t}\n});\n\nfunction evalScript( i, elem ) {\n\tif ( elem.src ) {\n\t\tjQuery.ajax({\n\t\t\turl: elem.src,\n\t\t\tasync: false,\n\t\t\tdataType: \"script\"\n\t\t});\n\t} else {\n\t\tjQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || \"\" );\n\t}\n\n\tif ( elem.parentNode ) {\n\t\telem.parentNode.removeChild( elem );\n\t}\n}\n\n\n\n\nvar ralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity=([^)]*)/,\n\trdashAlpha = /-([a-z])/ig,\n\trupper = /([A-Z])/g,\n\trnumpx = /^-?\\d+(?:px)?$/i,\n\trnum = /^-?\\d/,\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssWidth = [ \"Left\", \"Right\" ],\n\tcssHeight = [ \"Top\", \"Bottom\" ],\n\tcurCSS,\n\n\tgetComputedStyle,\n\tcurrentStyle,\n\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn.css = function( name, value ) {\n\t// Setting 'undefined' is a no-op\n\tif ( arguments.length === 2 && value === undefined ) {\n\t\treturn this;\n\t}\n\n\treturn jQuery.access( this, name, value, true, function( elem, name, value ) {\n\t\treturn value !== undefined ?\n\t\t\tjQuery.style( elem, name, value ) :\n\t\t\tjQuery.css( elem, name );\n\t});\n};\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\", \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\n\t\t\t\t} else {\n\t\t\t\t\treturn elem.style.opacity;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Exclude the following css properties to add px\n\tcssNumber: {\n\t\t\"zIndex\": true,\n\t\t\"fontWeight\": true,\n\t\t\"opacity\": true,\n\t\t\"zoom\": true,\n\t\t\"lineHeight\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": jQuery.support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, origName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style, hooks = jQuery.cssHooks[ origName ];\n\n\t\tname = jQuery.cssProps[ origName ] || origName;\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\t// Make sure that NaN and null values aren't set. See: #7116\n\t\t\tif ( typeof value === \"number\" && isNaN( value ) || value == null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( typeof value === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {\n\t\t\t\t// Wrapped to prevent IE from throwing errors when 'invalid' values are provided\n\t\t\t\t// Fixes bug #5509\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra ) {\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, origName = jQuery.camelCase( name ),\n\t\t\thooks = jQuery.cssHooks[ origName ];\n\n\t\tname = jQuery.cssProps[ origName ] || origName;\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {\n\t\t\treturn ret;\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\t} else if ( curCSS ) {\n\t\t\treturn curCSS( elem, name, origName );\n\t\t}\n\t},\n\n\t// A method for quickly swapping in/out CSS properties to get correct calculations\n\tswap: function( elem, options, callback ) {\n\t\tvar old = {};\n\n\t\t// Remember the old values, and insert the new ones\n\t\tfor ( var name in options ) {\n\t\t\told[ name ] = elem.style[ name ];\n\t\t\telem.style[ name ] = options[ name ];\n\t\t}\n\n\t\tcallback.call( elem );\n\n\t\t// Revert the old values\n\t\tfor ( name in options ) {\n\t\t\telem.style[ name ] = old[ name ];\n\t\t}\n\t},\n\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rdashAlpha, fcamelCase );\n\t}\n});\n\n// DEPRECATED, Use jQuery.css() instead\njQuery.curCSS = jQuery.css;\n\njQuery.each([\"height\", \"width\"], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tvar val;\n\n\t\t\tif ( computed ) {\n\t\t\t\tif ( elem.offsetWidth !== 0 ) {\n\t\t\t\t\tval = getWH( elem, name, extra );\n\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\tval = getWH( elem, name, extra );\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif ( val <= 0 ) {\n\t\t\t\t\tval = curCSS( elem, name, name );\n\n\t\t\t\t\tif ( val === \"0px\" && currentStyle ) {\n\t\t\t\t\t\tval = currentStyle( elem, name, name );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( val != null ) {\n\t\t\t\t\t\t// Should return \"auto\" instead of 0, use 0 for\n\t\t\t\t\t\t// temporary backwards-compat\n\t\t\t\t\t\treturn val === \"\" || val === \"auto\" ? \"0px\" : val;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( val < 0 || val == null ) {\n\t\t\t\t\tval = elem.style[ name ];\n\n\t\t\t\t\t// Should return \"auto\" instead of 0, use 0 for\n\t\t\t\t\t// temporary backwards-compat\n\t\t\t\t\treturn val === \"\" || val === \"auto\" ? \"0px\" : val;\n\t\t\t\t}\n\n\t\t\t\treturn typeof val === \"string\" ? val : val + \"px\";\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tif ( rnumpx.test( value ) ) {\n\t\t\t\t// ignore negative width and height values #1599\n\t\t\t\tvalue = parseFloat(value);\n\n\t\t\t\tif ( value >= 0 ) {\n\t\t\t\t\treturn value + \"px\";\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t};\n});\n\nif ( !jQuery.support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\t// IE uses filters for opacity\n\t\t\treturn ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\") ?\n\t\t\t\t(parseFloat(RegExp.$1) / 100) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style;\n\n\t\t\t// IE has trouble with opacity if it does not have layout\n\t\t\t// Force it by setting the zoom level\n\t\t\tstyle.zoom = 1;\n\n\t\t\t// Set the alpha filter to set the opacity\n\t\t\tvar opacity = jQuery.isNaN(value) ?\n\t\t\t\t\"\" :\n\t\t\t\t\"alpha(opacity=\" + value * 100 + \")\",\n\t\t\t\tfilter = style.filter || \"\";\n\n\t\t\tstyle.filter = ralpha.test(filter) ?\n\t\t\t\tfilter.replace(ralpha, opacity) :\n\t\t\t\tstyle.filter + ' ' + opacity;\n\t\t}\n\t};\n}\n\nif ( document.defaultView && document.defaultView.getComputedStyle ) {\n\tgetComputedStyle = function( elem, newName, name ) {\n\t\tvar ret, defaultView, computedStyle;\n\n\t\tname = name.replace( rupper, \"-$1\" ).toLowerCase();\n\n\t\tif ( !(defaultView = elem.ownerDocument.defaultView) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {\n\t\t\tret = computedStyle.getPropertyValue( name );\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t};\n}\n\nif ( document.documentElement.currentStyle ) {\n\tcurrentStyle = function( elem, name ) {\n\t\tvar left,\n\t\t\tret = elem.currentStyle && elem.currentStyle[ name ],\n\t\t\trsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],\n\t\t\tstyle = elem.style;\n\n\t\t// From the awesome hack by Dean Edwards\n\t\t// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n\t\t// If we're not dealing with a regular pixel number\n\t\t// but a number that has a weird ending, we need to convert it to pixels\n\t\tif ( !rnumpx.test( ret ) && rnum.test( ret ) ) {\n\t\t\t// Remember the original values\n\t\t\tleft = style.left;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tif ( rsLeft ) {\n\t\t\t\telem.runtimeStyle.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : (ret || 0);\n\t\t\tret = style.pixelLeft + \"px\";\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\telem.runtimeStyle.left = rsLeft;\n\t\t\t}\n\t\t}\n\n\t\treturn ret === \"\" ? \"auto\" : ret;\n\t};\n}\n\ncurCSS = getComputedStyle || currentStyle;\n\nfunction getWH( elem, name, extra ) {\n\tvar which = name === \"width\" ? cssWidth : cssHeight,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight;\n\n\tif ( extra === \"border\" ) {\n\t\treturn val;\n\t}\n\n\tjQuery.each( which, function() {\n\t\tif ( !extra ) {\n\t\t\tval -= parseFloat(jQuery.css( elem, \"padding\" + this )) || 0;\n\t\t}\n\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += parseFloat(jQuery.css( elem, \"margin\" + this )) || 0;\n\n\t\t} else {\n\t\t\tval -= parseFloat(jQuery.css( elem, \"border\" + this + \"Width\" )) || 0;\n\t\t}\n\t});\n\n\treturn val;\n}\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.hidden = function( elem ) {\n\t\tvar width = elem.offsetWidth,\n\t\t\theight = elem.offsetHeight;\n\n\t\treturn (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, \"display\" )) === \"none\");\n\t};\n\n\tjQuery.expr.filters.visible = function( elem ) {\n\t\treturn !jQuery.expr.filters.hidden( elem );\n\t};\n}\n\n\n\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trhash = /#.*$/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\trinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /(?:^file|^widget|\\-extension):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trquery = /\\?/,\n\trscript = /<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi,\n\trselectTextarea = /^(?:select|textarea)/i,\n\trspacesAjax = /\\s+/,\n\trts = /([?&])_=[^&]*/,\n\trucHeaders = /(^|\\-)([a-z])/g,\n\trucHeadersFunc = function( _, $1, $2 ) {\n\t\treturn $1 + $2.toUpperCase();\n\t},\n\trurl = /^([\\w\\+\\.\\-]+:)\\/\\/([^\\/?#:]*)(?::(\\d+))?/,\n\n\t// Keep a copy of the old load method\n\t_load = jQuery.fn.load,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Document location\n\tajaxLocation,\n\n\t// Document location segments\n\tajaxLocParts;\n\n// #8138, IE may throw an exception when accessing\n// a field from document.location if document.domain has been set\ntry {\n\tajaxLocation = document.location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() );\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\tvar dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),\n\t\t\t\ti = 0,\n\t\t\t\tlength = dataTypes.length,\n\t\t\t\tdataType,\n\t\t\t\tlist,\n\t\t\t\tplaceBefore;\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\tfor(; i < length; i++ ) {\n\t\t\t\tdataType = dataTypes[ i ];\n\t\t\t\t// We control if we're asked to add before\n\t\t\t\t// any existing element\n\t\t\t\tplaceBefore = /^\\+/.test( dataType );\n\t\t\t\tif ( placeBefore ) {\n\t\t\t\t\tdataType = dataType.substr( 1 ) || \"*\";\n\t\t\t\t}\n\t\t\t\tlist = structure[ dataType ] = structure[ dataType ] || [];\n\t\t\t\t// then we add to the structure accordingly\n\t\t\t\tlist[ placeBefore ? \"unshift\" : \"push\" ]( func );\n\t\t\t}\n\t\t}\n\t};\n}\n\n//Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,\n\t\tdataType /* internal */, inspected /* internal */ ) {\n\n\tdataType = dataType || options.dataTypes[ 0 ];\n\tinspected = inspected || {};\n\n\tinspected[ dataType ] = true;\n\n\tvar list = structure[ dataType ],\n\t\ti = 0,\n\t\tlength = list ? list.length : 0,\n\t\texecuteOnly = ( structure === prefilters ),\n\t\tselection;\n\n\tfor(; i < length && ( executeOnly || !selection ); i++ ) {\n\t\tselection = list[ i ]( options, originalOptions, jqXHR );\n\t\t// If we got redirected to another dataType\n\t\t// we try there if executing only and not done already\n\t\tif ( typeof selection === \"string\" ) {\n\t\t\tif ( !executeOnly || inspected[ selection ] ) {\n\t\t\t\tselection = undefined;\n\t\t\t} else {\n\t\t\t\toptions.dataTypes.unshift( selection );\n\t\t\t\tselection = inspectPrefiltersOrTransports(\n\t\t\t\t\t\tstructure, options, originalOptions, jqXHR, selection, inspected );\n\t\t\t}\n\t\t}\n\t}\n\t// If we're only executing or nothing was selected\n\t// we try the catchall dataType if not done already\n\tif ( ( executeOnly || !selection ) && !inspected[ \"*\" ] ) {\n\t\tselection = inspectPrefiltersOrTransports(\n\t\t\t\tstructure, options, originalOptions, jqXHR, \"*\", inspected );\n\t}\n\t// unnecessary when only executing (prefilters)\n\t// but it'll be ignored by the caller in that case\n\treturn selection;\n}\n\njQuery.fn.extend({\n\tload: function( url, params, callback ) {\n\t\tif ( typeof url !== \"string\" && _load ) {\n\t\t\treturn _load.apply( this, arguments );\n\n\t\t// Don't do a request if no elements are being requested\n\t\t} else if ( !this.length ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tvar off = url.indexOf( \" \" );\n\t\tif ( off >= 0 ) {\n\t\t\tvar selector = url.slice( off, url.length );\n\t\t\turl = url.slice( 0, off );\n\t\t}\n\n\t\t// Default to a GET request\n\t\tvar type = \"GET\";\n\n\t\t// If the second parameter was provided\n\t\tif ( params ) {\n\t\t\t// If it's a function\n\t\t\tif ( jQuery.isFunction( params ) ) {\n\t\t\t\t// We assume that it's the callback\n\t\t\t\tcallback = params;\n\t\t\t\tparams = undefined;\n\n\t\t\t// Otherwise, build a param string\n\t\t\t} else if ( typeof params === \"object\" ) {\n\t\t\t\tparams = jQuery.param( params, jQuery.ajaxSettings.traditional );\n\t\t\t\ttype = \"POST\";\n\t\t\t}\n\t\t}\n\n\t\tvar self = this;\n\n\t\t// Request the remote document\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params,\n\t\t\t// Complete callback (responseText is used internally)\n\t\t\tcomplete: function( jqXHR, status, responseText ) {\n\t\t\t\t// Store the response as specified by the jqXHR object\n\t\t\t\tresponseText = jqXHR.responseText;\n\t\t\t\t// If successful, inject the HTML into all the matched elements\n\t\t\t\tif ( jqXHR.isResolved() ) {\n\t\t\t\t\t// #4825: Get the actual response in case\n\t\t\t\t\t// a dataFilter is present in ajaxSettings\n\t\t\t\t\tjqXHR.done(function( r ) {\n\t\t\t\t\t\tresponseText = r;\n\t\t\t\t\t});\n\t\t\t\t\t// See if a selector was specified\n\t\t\t\t\tself.html( selector ?\n\t\t\t\t\t\t// Create a dummy div to hold the results\n\t\t\t\t\t\tjQuery(\"<div>\")\n\t\t\t\t\t\t\t// inject the contents of the document in, removing the scripts\n\t\t\t\t\t\t\t// to avoid any 'Permission Denied' errors in IE\n\t\t\t\t\t\t\t.append(responseText.replace(rscript, \"\"))\n\n\t\t\t\t\t\t\t// Locate the specified elements\n\t\t\t\t\t\t\t.find(selector) :\n\n\t\t\t\t\t\t// If not, just inject the full result\n\t\t\t\t\t\tresponseText );\n\t\t\t\t}\n\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tself.each( callback, [ responseText, status, jqXHR ] );\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn this;\n\t},\n\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\n\tserializeArray: function() {\n\t\treturn this.map(function(){\n\t\t\treturn this.elements ? jQuery.makeArray( this.elements ) : this;\n\t\t})\n\t\t.filter(function(){\n\t\t\treturn this.name && !this.disabled &&\n\t\t\t\t( this.checked || rselectTextarea.test( this.nodeName ) ||\n\t\t\t\t\trinput.test( this.type ) );\n\t\t})\n\t\t.map(function( i, elem ){\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val, i ){\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( \"ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend\".split( \" \" ), function( i, o ){\n\tjQuery.fn[ o ] = function( f ){\n\t\treturn this.bind( o, f );\n\t};\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\ttype: method,\n\t\t\turl: url,\n\t\t\tdata: data,\n\t\t\tsuccess: callback,\n\t\t\tdataType: type\n\t\t});\n\t};\n} );\n\njQuery.extend({\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function ( target, settings ) {\n\t\tif ( !settings ) {\n\t\t\t// Only one parameter, we extend ajaxSettings\n\t\t\tsettings = target;\n\t\t\ttarget = jQuery.extend( true, jQuery.ajaxSettings, settings );\n\t\t} else {\n\t\t\t// target was provided, we extend into it\n\t\t\tjQuery.extend( true, target, jQuery.ajaxSettings, settings );\n\t\t}\n\t\t// Flatten fields we don't want deep extended\n\t\tfor( var field in { context: 1, url: 1 } ) {\n\t\t\tif ( field in settings ) {\n\t\t\t\ttarget[ field ] = settings[ field ];\n\t\t\t} else if( field in jQuery.ajaxSettings ) {\n\t\t\t\ttarget[ field ] = jQuery.ajaxSettings[ field ];\n\t\t\t}\n\t\t}\n\t\treturn target;\n\t},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\ttype: \"GET\",\n\t\tcontentType: \"application/x-www-form-urlencoded\",\n\t\tprocessData: true,\n\t\tasync: true,\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\tcrossDomain: null,\n\t\t*/\n\n\t\taccepts: {\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\thtml: \"text/html\",\n\t\t\ttext: \"text/plain\",\n\t\t\tjson: \"application/json, text/javascript\",\n\t\t\t\"*\": \"*/*\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\"\n\t\t},\n\n\t\t// List of data converters\n\t\t// 1) key format is \"source_type destination_type\" (a single space in-between)\n\t\t// 2) the catchall symbol \"*\" can be used for source_type\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": window.String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t}\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar // Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events\n\t\t\t// It's the callbackContext if one was provided in the options\n\t\t\t// and if it's a DOM node or a jQuery collection\n\t\t\tglobalEventContext = callbackContext !== s &&\n\t\t\t\t( callbackContext.nodeType || callbackContext instanceof jQuery ) ?\n\t\t\t\t\t\tjQuery( callbackContext ) : jQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery._Deferred(),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// ifModified key\n\t\t\tifModifiedKey,\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\t\t\t// transport\n\t\t\ttransport,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\t\t\t// Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\trequestHeaders[ name.toLowerCase().replace( rucHeaders, rucHeadersFunc ) ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match === undefined ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tstatusText = statusText || \"abort\";\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( statusText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, statusText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Callback for when everything is done\n\t\t// It is defined here because jslint complains if it is declared\n\t\t// at the end of the function (which would be more logical and readable)\n\t\tfunction done( status, statusText, responses, headers ) {\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status ? 4 : 0;\n\n\t\t\tvar isSuccess,\n\t\t\t\tsuccess,\n\t\t\t\terror,\n\t\t\t\tresponse = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,\n\t\t\t\tlastModified,\n\t\t\t\tetag;\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( status >= 200 && status < 300 || status === 304 ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\n\t\t\t\t\tif ( ( lastModified = jqXHR.getResponseHeader( \"Last-Modified\" ) ) ) {\n\t\t\t\t\t\tjQuery.lastModified[ ifModifiedKey ] = lastModified;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ( etag = jqXHR.getResponseHeader( \"Etag\" ) ) ) {\n\t\t\t\t\t\tjQuery.etag[ ifModifiedKey ] = etag;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If not modified\n\t\t\t\tif ( status === 304 ) {\n\n\t\t\t\t\tstatusText = \"notmodified\";\n\t\t\t\t\tisSuccess = true;\n\n\t\t\t\t// If we have data\n\t\t\t\t} else {\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tsuccess = ajaxConvert( s, response );\n\t\t\t\t\t\tstatusText = \"success\";\n\t\t\t\t\t\tisSuccess = true;\n\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t// We have a parsererror\n\t\t\t\t\t\tstatusText = \"parsererror\";\n\t\t\t\t\t\terror = e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif( !statusText || status ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = statusText;\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajax\" + ( isSuccess ? \"Success\" : \"Error\" ),\n\t\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\t\tjqXHR.complete = completeDeferred.done;\n\n\t\t// Status-dependent callbacks\n\t\tjqXHR.statusCode = function( map ) {\n\t\t\tif ( map ) {\n\t\t\t\tvar tmp;\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tfor( tmp in map ) {\n\t\t\t\t\t\tstatusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttmp = map[ jqXHR.status ];\n\t\t\t\t\tjqXHR.then( tmp, tmp );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this;\n\t\t};\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().split( rspacesAjax );\n\n\t\t// Determine if a cross-domain request is in order\n\t\tif ( !s.crossDomain ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? 80 : 443 ) ) !=\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? 80 : 443 ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefiler, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\tfireGlobals = s.global;\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.data;\n\t\t\t}\n\n\t\t\t// Get ifModifiedKey before adding the anti-cache parameter\n\t\t\tifModifiedKey = s.url;\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\n\t\t\t\tvar ts = jQuery.now(),\n\t\t\t\t\t// try replacing _= if it is there\n\t\t\t\t\tret = s.url.replace( rts, \"$1_=\" + ts );\n\n\t\t\t\t// if nothing was replaced, add timestamp to the end\n\t\t\t\ts.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? \"&\" : \"?\" ) + \"_=\" + ts : \"\" );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\trequestHeaders[ \"Content-Type\" ] = s.contentType;\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tifModifiedKey = ifModifiedKey || s.url;\n\t\t\tif ( jQuery.lastModified[ ifModifiedKey ] ) {\n\t\t\t\trequestHeaders[ \"If-Modified-Since\" ] = jQuery.lastModified[ ifModifiedKey ];\n\t\t\t}\n\t\t\tif ( jQuery.etag[ ifModifiedKey ] ) {\n\t\t\t\trequestHeaders[ \"If-None-Match\" ] = jQuery.etag[ ifModifiedKey ];\n\t\t\t}\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\trequestHeaders.Accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", */*; q=0.01\" : \"\" ) :\n\t\t\ts.accepts[ \"*\" ];\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t\t// Abort if not done already\n\t\t\t\tjqXHR.abort();\n\t\t\t\treturn false;\n\n\t\t}\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout( function(){\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch (e) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( status < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.error( e );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\t// Serialize an array of form elements or a set of\n\t// key/values into a query string\n\tparam: function( a, traditional ) {\n\t\tvar s = [],\n\t\t\tadd = function( key, value ) {\n\t\t\t\t// If value is a function, invoke it and return its value\n\t\t\t\tvalue = jQuery.isFunction( value ) ? value() : value;\n\t\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t\t};\n\n\t\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\t\tif ( traditional === undefined ) {\n\t\t\ttraditional = jQuery.ajaxSettings.traditional;\n\t\t}\n\n\t\t// If an array was passed in, assume that it is an array of form elements.\n\t\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t\t// Serialize the form elements\n\t\t\tjQuery.each( a, function() {\n\t\t\t\tadd( this.name, this.value );\n\t\t\t} );\n\n\t\t} else {\n\t\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t\t// did it), otherwise encode params recursively.\n\t\t\tfor ( var prefix in a ) {\n\t\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t\t}\n\t\t}\n\n\t\t// Return the resulting serialization\n\t\treturn s.join( \"&\" ).replace( r20, \"+\" );\n\t}\n});\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tif ( jQuery.isArray( obj ) && obj.length ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// If array item is non-scalar (array or object), encode its\n\t\t\t\t// numeric index to resolve deserialization ambiguity issues.\n\t\t\t\t// Note that rack (as of 1.0.0) can't currently deserialize\n\t\t\t\t// nested arrays properly, and attempting to do so may cause\n\t\t\t\t// a server error. Possible fixes are to modify rack's\n\t\t\t\t// deserialization algorithm or to provide an option or flag\n\t\t\t\t// to force array serialization to be shallow.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" || jQuery.isArray(v) ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && obj != null && typeof obj === \"object\" ) {\n\t\t// If we see an array here, it is empty and should be treated as an empty\n\t\t// object\n\t\tif ( jQuery.isArray( obj ) || jQuery.isEmptyObject( obj ) ) {\n\t\t\tadd( prefix, \"\" );\n\n\t\t// Serialize object item.\n\t\t} else {\n\t\t\tfor ( var name in obj ) {\n\t\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t\t}\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// This is still on the jQuery object... for now\n// Want to move this to jQuery.ajax some day\njQuery.extend({\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {}\n\n});\n\n/* Handles responses to an ajax request:\n * - sets all responseXXX fields accordingly\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar contents = s.contents,\n\t\tdataTypes = s.dataTypes,\n\t\tresponseFields = s.responseFields,\n\t\tct,\n\t\ttype,\n\t\tfinalDataType,\n\t\tfirstDataType;\n\n\t// Fill responseXXX fields\n\tfor( type in responseFields ) {\n\t\tif ( type in responses ) {\n\t\t\tjqXHR[ responseFields[type] ] = responses[ type ];\n\t\t}\n\t}\n\n\t// Remove auto dataType and get content-type in the process\n\twhile( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"content-type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n// Chain conversions given the request and the original response\nfunction ajaxConvert( s, response ) {\n\n\t// Apply the dataFilter if provided\n\tif ( s.dataFilter ) {\n\t\tresponse = s.dataFilter( response, s.dataType );\n\t}\n\n\tvar dataTypes = s.dataTypes,\n\t\tconverters = {},\n\t\ti,\n\t\tkey,\n\t\tlength = dataTypes.length,\n\t\ttmp,\n\t\t// Current and previous dataTypes\n\t\tcurrent = dataTypes[ 0 ],\n\t\tprev,\n\t\t// Conversion expression\n\t\tconversion,\n\t\t// Conversion function\n\t\tconv,\n\t\t// Conversion functions (transitive conversion)\n\t\tconv1,\n\t\tconv2;\n\n\t// For each dataType in the chain\n\tfor( i = 1; i < length; i++ ) {\n\n\t\t// Create converters map\n\t\t// with lowercased keys\n\t\tif ( i === 1 ) {\n\t\t\tfor( key in s.converters ) {\n\t\t\t\tif( typeof key === \"string\" ) {\n\t\t\t\t\tconverters[ key.toLowerCase() ] = s.converters[ key ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Get the dataTypes\n\t\tprev = current;\n\t\tcurrent = dataTypes[ i ];\n\n\t\t// If current is auto dataType, update it to prev\n\t\tif( current === \"*\" ) {\n\t\t\tcurrent = prev;\n\t\t// If no auto and dataTypes are actually different\n\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t// Get the converter\n\t\t\tconversion = prev + \" \" + current;\n\t\t\tconv = converters[ conversion ] || converters[ \"* \" + current ];\n\n\t\t\t// If there is no direct converter, search transitively\n\t\t\tif ( !conv ) {\n\t\t\t\tconv2 = undefined;\n\t\t\t\tfor( conv1 in converters ) {\n\t\t\t\t\ttmp = conv1.split( \" \" );\n\t\t\t\t\tif ( tmp[ 0 ] === prev || tmp[ 0 ] === \"*\" ) {\n\t\t\t\t\t\tconv2 = converters[ tmp[1] + \" \" + current ];\n\t\t\t\t\t\tif ( conv2 ) {\n\t\t\t\t\t\t\tconv1 = converters[ conv1 ];\n\t\t\t\t\t\t\tif ( conv1 === true ) {\n\t\t\t\t\t\t\t\tconv = conv2;\n\t\t\t\t\t\t\t} else if ( conv2 === true ) {\n\t\t\t\t\t\t\t\tconv = conv1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If we found no converter, dispatch an error\n\t\t\tif ( !( conv || conv2 ) ) {\n\t\t\t\tjQuery.error( \"No conversion from \" + conversion.replace(\" \",\" to \") );\n\t\t\t}\n\t\t\t// If found converter is not an equivalence\n\t\t\tif ( conv !== true ) {\n\t\t\t\t// Convert with 1 or 2 converters accordingly\n\t\t\t\tresponse = conv ? conv( response ) : conv2( conv1(response) );\n\t\t\t}\n\t\t}\n\t}\n\treturn response;\n}\n\n\n\n\nvar jsc = jQuery.now(),\n\tjsre = /(\\=)\\?(&|$)|()\\?\\?()/i;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\treturn jQuery.expando + \"_\" + ( jsc++ );\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar dataIsString = ( typeof s.data === \"string\" );\n\n\tif ( s.dataTypes[ 0 ] === \"jsonp\" ||\n\t\toriginalSettings.jsonpCallback ||\n\t\toriginalSettings.jsonp != null ||\n\t\ts.jsonp !== false && ( jsre.test( s.url ) ||\n\t\t\t\tdataIsString && jsre.test( s.data ) ) ) {\n\n\t\tvar responseContainer,\n\t\t\tjsonpCallback = s.jsonpCallback =\n\t\t\t\tjQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,\n\t\t\tprevious = window[ jsonpCallback ],\n\t\t\turl = s.url,\n\t\t\tdata = s.data,\n\t\t\treplace = \"$1\" + jsonpCallback + \"$2\",\n\t\t\tcleanUp = function() {\n\t\t\t\t// Set callback back to previous value\n\t\t\t\twindow[ jsonpCallback ] = previous;\n\t\t\t\t// Call if it was a function and we have a response\n\t\t\t\tif ( responseContainer && jQuery.isFunction( previous ) ) {\n\t\t\t\t\twindow[ jsonpCallback ]( responseContainer[ 0 ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( s.jsonp !== false ) {\n\t\t\turl = url.replace( jsre, replace );\n\t\t\tif ( s.url === url ) {\n\t\t\t\tif ( dataIsString ) {\n\t\t\t\t\tdata = data.replace( jsre, replace );\n\t\t\t\t}\n\t\t\t\tif ( s.data === data ) {\n\t\t\t\t\t// Add callback manually\n\t\t\t\t\turl += (/\\?/.test( url ) ? \"&\" : \"?\") + s.jsonp + \"=\" + jsonpCallback;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ts.url = url;\n\t\ts.data = data;\n\n\t\t// Install callback\n\t\twindow[ jsonpCallback ] = function( response ) {\n\t\t\tresponseContainer = [ response ];\n\t\t};\n\n\t\t// Install cleanUp function\n\t\tjqXHR.then( cleanUp, cleanUp );\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( jsonpCallback + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /javascript|ecmascript/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || document.getElementsByTagName( \"head\" )[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement( \"script\" );\n\n\t\t\t\tscript.async = \"async\";\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\n\t\t\t\t// Attach handlers for all browsers\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t\t\t// Handle memory leak in IE\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\t\t\t\t// Remove the script\n\t\t\t\t\t\tif ( head && script.parentNode ) {\n\t\t\t\t\t\t\thead.removeChild( script );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Dereference the script\n\t\t\t\t\t\tscript = undefined;\n\n\t\t\t\t\t\t// Callback if not abort\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\t// Use insertBefore instead of appendChild  to circumvent an IE6 bug.\n\t\t\t\t// This arises when a base node is used (#2709 and #4378).\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( 0, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar // #5280: next active xhr id and list of active xhrs' callbacks\n\txhrId = jQuery.now(),\n\txhrCallbacks,\n\n\t// XHR used to determine supports properties\n\ttestXHR;\n\n// #5280: Internet Explorer will keep connections alive if we don't abort on unload\nfunction xhrOnUnloadAbort() {\n\tjQuery( window ).unload(function() {\n\t\t// Abort all pending requests\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( 0, 1 );\n\t\t}\n\t});\n}\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n\t} catch( e ) {}\n}\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject ?\n\t/* Microsoft failed to properly\n\t * implement the XMLHttpRequest in IE7 (can't request local files),\n\t * so we use the ActiveXObject when it is available\n\t * Additionally XMLHttpRequest can be disabled in IE7/IE8 so\n\t * we need a fallback.\n\t */\n\tfunction() {\n\t\treturn !this.isLocal && createStandardXHR() || createActiveXHR();\n\t} :\n\t// For all other browsers, use the standard XMLHttpRequest object\n\tcreateStandardXHR;\n\n// Test if we can create an xhr object\ntestXHR = jQuery.ajaxSettings.xhr();\njQuery.support.ajax = !!testXHR;\n\n// Does this browser support crossDomain XHR requests\njQuery.support.cors = testXHR && ( \"withCredentials\" in testXHR );\n\n// No need for the temporary xhr anymore\ntestXHR = undefined;\n\n// Create transport if the browser can provide an xhr\nif ( jQuery.support.ajax ) {\n\n\tjQuery.ajaxTransport(function( s ) {\n\t\t// Cross domain only allowed if supported through XMLHttpRequest\n\t\tif ( !s.crossDomain || jQuery.support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\n\t\t\t\t\t// Get a new xhr\n\t\t\t\t\tvar xhr = s.xhr(),\n\t\t\t\t\t\thandle,\n\t\t\t\t\t\ti;\n\n\t\t\t\t\t// Open the socket\n\t\t\t\t\t// Passing null username, generates a login popup on Opera (#2865)\n\t\t\t\t\tif ( s.username ) {\n\t\t\t\t\t\txhr.open( s.type, s.url, s.async, s.username, s.password );\n\t\t\t\t\t} else {\n\t\t\t\t\t\txhr.open( s.type, s.url, s.async );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Apply custom fields if provided\n\t\t\t\t\tif ( s.xhrFields ) {\n\t\t\t\t\t\tfor ( i in s.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = s.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Override mime type if needed\n\t\t\t\t\tif ( s.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( s.mimeType );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Requested-With header\n\t\t\t\t\t// Not set for crossDomain requests with no content\n\t\t\t\t\t// (see why at http://trac.dojotoolkit.org/ticket/9486)\n\t\t\t\t\t// Won't change header if already provided\n\t\t\t\t\tif ( !( s.crossDomain && !s.hasContent ) && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Need an extra try/catch for cross domain requests in Firefox 3\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch( _ ) {}\n\n\t\t\t\t\t// Do send the request\n\t\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\t\txhr.send( ( s.hasContent && s.data ) || null );\n\n\t\t\t\t\t// Listener\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\n\t\t\t\t\t\tvar status,\n\t\t\t\t\t\t\tstatusText,\n\t\t\t\t\t\t\tresponseHeaders,\n\t\t\t\t\t\t\tresponses,\n\t\t\t\t\t\t\txml;\n\n\t\t\t\t\t\t// Firefox throws exceptions when accessing properties\n\t\t\t\t\t\t// of an xhr when a network error occured\n\t\t\t\t\t\t// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)\n\t\t\t\t\t\ttry {\n\n\t\t\t\t\t\t\t// Was never called and is aborted or complete\n\t\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\n\t\t\t\t\t\t\t\t// Only called once\n\t\t\t\t\t\t\t\tcallback = undefined;\n\n\t\t\t\t\t\t\t\t// Do not keep as active anymore\n\t\t\t\t\t\t\t\tif ( handle ) {\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\t\t\t\t\t\t\t\t\tdelete xhrCallbacks[ handle ];\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// If it's an abort\n\t\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\t\t// Abort it manually if needed\n\t\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tstatus = xhr.status;\n\t\t\t\t\t\t\t\t\tresponseHeaders = xhr.getAllResponseHeaders();\n\t\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\t\txml = xhr.responseXML;\n\n\t\t\t\t\t\t\t\t\t// Construct response list\n\t\t\t\t\t\t\t\t\tif ( xml && xml.documentElement /* #4958 */ ) {\n\t\t\t\t\t\t\t\t\t\tresponses.xml = xml;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\n\t\t\t\t\t\t\t\t\t// Firefox throws an exception when accessing\n\t\t\t\t\t\t\t\t\t// statusText for faulty cross-domain requests\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t\t// We normalize with Webkit giving an empty statusText\n\t\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Filter status for non standard behaviors\n\n\t\t\t\t\t\t\t\t\t// If the request is local and we have data: assume a success\n\t\t\t\t\t\t\t\t\t// (success with no data won't get notified, that's the best we\n\t\t\t\t\t\t\t\t\t// can do given current implementations)\n\t\t\t\t\t\t\t\t\tif ( !status && s.isLocal && !s.crossDomain ) {\n\t\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t\t// IE - #1450: sometimes returns 1223 when it should be 204\n\t\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch( firefoxAccessException ) {\n\t\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\t\tcomplete( -1, firefoxAccessException );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Call complete if needed\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, responseHeaders );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\t// if we're in sync mode or it's in cache\n\t\t\t\t\t// and has been retrieved directly (IE6 & IE7)\n\t\t\t\t\t// we need to manually fire the callback\n\t\t\t\t\tif ( !s.async || xhr.readyState === 4 ) {\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Create the active xhrs callbacks list if needed\n\t\t\t\t\t\t// and attach the unload handler\n\t\t\t\t\t\tif ( !xhrCallbacks ) {\n\t\t\t\t\t\t\txhrCallbacks = {};\n\t\t\t\t\t\t\txhrOnUnloadAbort();\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Add to list of active xhrs callbacks\n\t\t\t\t\t\thandle = xhrId++;\n\t\t\t\t\t\txhr.onreadystatechange = xhrCallbacks[ handle ] = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback(0,1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\n\n\n\n\nvar elemdisplay = {},\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = /^([+\\-]=)?([\\d+.\\-]+)([a-z%]*)$/i,\n\ttimerId,\n\tfxAttrs = [\n\t\t// height animations\n\t\t[ \"height\", \"marginTop\", \"marginBottom\", \"paddingTop\", \"paddingBottom\" ],\n\t\t// width animations\n\t\t[ \"width\", \"marginLeft\", \"marginRight\", \"paddingLeft\", \"paddingRight\" ],\n\t\t// opacity animations\n\t\t[ \"opacity\" ]\n\t];\n\njQuery.fn.extend({\n\tshow: function( speed, easing, callback ) {\n\t\tvar elem, display;\n\n\t\tif ( speed || speed === 0 ) {\n\t\t\treturn this.animate( genFx(\"show\", 3), speed, easing, callback);\n\n\t\t} else {\n\t\t\tfor ( var i = 0, j = this.length; i < j; i++ ) {\n\t\t\t\telem = this[i];\n\t\t\t\tdisplay = elem.style.display;\n\n\t\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t\t// being hidden by cascaded rules or not\n\t\t\t\tif ( !jQuery._data(elem, \"olddisplay\") && display === \"none\" ) {\n\t\t\t\t\tdisplay = elem.style.display = \"\";\n\t\t\t\t}\n\n\t\t\t\t// Set elements which have been overridden with display: none\n\t\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t\t// for such an element\n\t\t\t\tif ( display === \"\" && jQuery.css( elem, \"display\" ) === \"none\" ) {\n\t\t\t\t\tjQuery._data(elem, \"olddisplay\", defaultDisplay(elem.nodeName));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set the display of most of the elements in a second loop\n\t\t\t// to avoid the constant reflow\n\t\t\tfor ( i = 0; i < j; i++ ) {\n\t\t\t\telem = this[i];\n\t\t\t\tdisplay = elem.style.display;\n\n\t\t\t\tif ( display === \"\" || display === \"none\" ) {\n\t\t\t\t\telem.style.display = jQuery._data(elem, \"olddisplay\") || \"\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\t},\n\n\thide: function( speed, easing, callback ) {\n\t\tif ( speed || speed === 0 ) {\n\t\t\treturn this.animate( genFx(\"hide\", 3), speed, easing, callback);\n\n\t\t} else {\n\t\t\tfor ( var i = 0, j = this.length; i < j; i++ ) {\n\t\t\t\tvar display = jQuery.css( this[i], \"display\" );\n\n\t\t\t\tif ( display !== \"none\" && !jQuery._data( this[i], \"olddisplay\" ) ) {\n\t\t\t\t\tjQuery._data( this[i], \"olddisplay\", display );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set the display of the elements in a second loop\n\t\t\t// to avoid the constant reflow\n\t\t\tfor ( i = 0; i < j; i++ ) {\n\t\t\t\tthis[i].style.display = \"none\";\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\t},\n\n\t// Save the old toggle function\n\t_toggle: jQuery.fn.toggle,\n\n\ttoggle: function( fn, fn2, callback ) {\n\t\tvar bool = typeof fn === \"boolean\";\n\n\t\tif ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {\n\t\t\tthis._toggle.apply( this, arguments );\n\n\t\t} else if ( fn == null || bool ) {\n\t\t\tthis.each(function() {\n\t\t\t\tvar state = bool ? fn : jQuery(this).is(\":hidden\");\n\t\t\t\tjQuery(this)[ state ? \"show\" : \"hide\" ]();\n\t\t\t});\n\n\t\t} else {\n\t\t\tthis.animate(genFx(\"toggle\", 3), fn, fn2, callback);\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tfadeTo: function( speed, to, easing, callback ) {\n\t\treturn this.filter(\":hidden\").css(\"opacity\", 0).show().end()\n\t\t\t\t\t.animate({opacity: to}, speed, easing, callback);\n\t},\n\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar optall = jQuery.speed(speed, easing, callback);\n\n\t\tif ( jQuery.isEmptyObject( prop ) ) {\n\t\t\treturn this.each( optall.complete );\n\t\t}\n\n\t\treturn this[ optall.queue === false ? \"each\" : \"queue\" ](function() {\n\t\t\t// XXX 'this' does not always have a nodeName when running the\n\t\t\t// test suite\n\n\t\t\tvar opt = jQuery.extend({}, optall), p,\n\t\t\t\tisElement = this.nodeType === 1,\n\t\t\t\thidden = isElement && jQuery(this).is(\":hidden\"),\n\t\t\t\tself = this;\n\n\t\t\tfor ( p in prop ) {\n\t\t\t\tvar name = jQuery.camelCase( p );\n\n\t\t\t\tif ( p !== name ) {\n\t\t\t\t\tprop[ name ] = prop[ p ];\n\t\t\t\t\tdelete prop[ p ];\n\t\t\t\t\tp = name;\n\t\t\t\t}\n\n\t\t\t\tif ( prop[p] === \"hide\" && hidden || prop[p] === \"show\" && !hidden ) {\n\t\t\t\t\treturn opt.complete.call(this);\n\t\t\t\t}\n\n\t\t\t\tif ( isElement && ( p === \"height\" || p === \"width\" ) ) {\n\t\t\t\t\t// Make sure that nothing sneaks out\n\t\t\t\t\t// Record all 3 overflow attributes because IE does not\n\t\t\t\t\t// change the overflow attribute when overflowX and\n\t\t\t\t\t// overflowY are set to the same value\n\t\t\t\t\topt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];\n\n\t\t\t\t\t// Set display property to inline-block for height/width\n\t\t\t\t\t// animations on inline elements that are having width/height\n\t\t\t\t\t// animated\n\t\t\t\t\tif ( jQuery.css( this, \"display\" ) === \"inline\" &&\n\t\t\t\t\t\t\tjQuery.css( this, \"float\" ) === \"none\" ) {\n\t\t\t\t\t\tif ( !jQuery.support.inlineBlockNeedsLayout ) {\n\t\t\t\t\t\t\tthis.style.display = \"inline-block\";\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvar display = defaultDisplay(this.nodeName);\n\n\t\t\t\t\t\t\t// inline-level elements accept inline-block;\n\t\t\t\t\t\t\t// block-level elements need to be inline with layout\n\t\t\t\t\t\t\tif ( display === \"inline\" ) {\n\t\t\t\t\t\t\t\tthis.style.display = \"inline-block\";\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.style.display = \"inline\";\n\t\t\t\t\t\t\t\tthis.style.zoom = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( jQuery.isArray( prop[p] ) ) {\n\t\t\t\t\t// Create (if needed) and add to specialEasing\n\t\t\t\t\t(opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];\n\t\t\t\t\tprop[p] = prop[p][0];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( opt.overflow != null ) {\n\t\t\t\tthis.style.overflow = \"hidden\";\n\t\t\t}\n\n\t\t\topt.curAnim = jQuery.extend({}, prop);\n\n\t\t\tjQuery.each( prop, function( name, val ) {\n\t\t\t\tvar e = new jQuery.fx( self, opt, name );\n\n\t\t\t\tif ( rfxtypes.test(val) ) {\n\t\t\t\t\te[ val === \"toggle\" ? hidden ? \"show\" : \"hide\" : val ]( prop );\n\n\t\t\t\t} else {\n\t\t\t\t\tvar parts = rfxnum.exec(val),\n\t\t\t\t\t\tstart = e.cur();\n\n\t\t\t\t\tif ( parts ) {\n\t\t\t\t\t\tvar end = parseFloat( parts[2] ),\n\t\t\t\t\t\t\tunit = parts[3] || ( jQuery.cssNumber[ name ] ? \"\" : \"px\" );\n\n\t\t\t\t\t\t// We need to compute starting value\n\t\t\t\t\t\tif ( unit !== \"px\" ) {\n\t\t\t\t\t\t\tjQuery.style( self, name, (end || 1) + unit);\n\t\t\t\t\t\t\tstart = ((end || 1) / e.cur()) * start;\n\t\t\t\t\t\t\tjQuery.style( self, name, start + unit);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\t\t\tif ( parts[1] ) {\n\t\t\t\t\t\t\tend = ((parts[1] === \"-=\" ? -1 : 1) * end) + start;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\te.custom( start, end, unit );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\te.custom( start, val, \"\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// For JS strict compliance\n\t\t\treturn true;\n\t\t});\n\t},\n\n\tstop: function( clearQueue, gotoEnd ) {\n\t\tvar timers = jQuery.timers;\n\n\t\tif ( clearQueue ) {\n\t\t\tthis.queue([]);\n\t\t}\n\n\t\tthis.each(function() {\n\t\t\t// go in reverse order so anything added to the queue during the loop is ignored\n\t\t\tfor ( var i = timers.length - 1; i >= 0; i-- ) {\n\t\t\t\tif ( timers[i].elem === this ) {\n\t\t\t\t\tif (gotoEnd) {\n\t\t\t\t\t\t// force the next step to be the last\n\t\t\t\t\t\ttimers[i](true);\n\t\t\t\t\t}\n\n\t\t\t\t\ttimers.splice(i, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// start the next in the queue if the last step wasn't forced\n\t\tif ( !gotoEnd ) {\n\t\t\tthis.dequeue();\n\t\t}\n\n\t\treturn this;\n\t}\n\n});\n\nfunction genFx( type, num ) {\n\tvar obj = {};\n\n\tjQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {\n\t\tobj[ this ] = type;\n\t});\n\n\treturn obj;\n}\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\", 1),\n\tslideUp: genFx(\"hide\", 1),\n\tslideToggle: genFx(\"toggle\", 1),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.extend({\n\tspeed: function( speed, easing, fn ) {\n\t\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend({}, speed) : {\n\t\t\tcomplete: fn || !fn && easing ||\n\t\t\t\tjQuery.isFunction( speed ) && speed,\n\t\t\tduration: speed,\n\t\t\teasing: fn && easing || easing && !jQuery.isFunction(easing) && easing\n\t\t};\n\n\t\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;\n\n\t\t// Queueing\n\t\topt.old = opt.complete;\n\t\topt.complete = function() {\n\t\t\tif ( opt.queue !== false ) {\n\t\t\t\tjQuery(this).dequeue();\n\t\t\t}\n\t\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\t\topt.old.call( this );\n\t\t\t}\n\t\t};\n\n\t\treturn opt;\n\t},\n\n\teasing: {\n\t\tlinear: function( p, n, firstNum, diff ) {\n\t\t\treturn firstNum + diff * p;\n\t\t},\n\t\tswing: function( p, n, firstNum, diff ) {\n\t\t\treturn ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;\n\t\t}\n\t},\n\n\ttimers: [],\n\n\tfx: function( elem, options, prop ) {\n\t\tthis.options = options;\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\n\t\tif ( !options.orig ) {\n\t\t\toptions.orig = {};\n\t\t}\n\t}\n\n});\n\njQuery.fx.prototype = {\n\t// Simple function for setting a style value\n\tupdate: function() {\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\t(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );\n\t},\n\n\t// Get the current size\n\tcur: function() {\n\t\tif ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {\n\t\t\treturn this.elem[ this.prop ];\n\t\t}\n\n\t\tvar parsed,\n\t\t\tr = jQuery.css( this.elem, this.prop );\n\t\t// Empty strings, null, undefined and \"auto\" are converted to 0,\n\t\t// complex values such as \"rotate(1rad)\" are returned as is,\n\t\t// simple values such as \"10px\" are parsed to Float.\n\t\treturn isNaN( parsed = parseFloat( r ) ) ? !r || r === \"auto\" ? 0 : r : parsed;\n\t},\n\n\t// Start an animation from one number to another\n\tcustom: function( from, to, unit ) {\n\t\tvar self = this,\n\t\t\tfx = jQuery.fx;\n\n\t\tthis.startTime = jQuery.now();\n\t\tthis.start = from;\n\t\tthis.end = to;\n\t\tthis.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? \"\" : \"px\" );\n\t\tthis.now = this.start;\n\t\tthis.pos = this.state = 0;\n\n\t\tfunction t( gotoEnd ) {\n\t\t\treturn self.step(gotoEnd);\n\t\t}\n\n\t\tt.elem = this.elem;\n\n\t\tif ( t() && jQuery.timers.push(t) && !timerId ) {\n\t\t\ttimerId = setInterval(fx.tick, fx.interval);\n\t\t}\n\t},\n\n\t// Simple 'show' function\n\tshow: function() {\n\t\t// Remember where we started, so that we can go back to it later\n\t\tthis.options.orig[this.prop] = jQuery.style( this.elem, this.prop );\n\t\tthis.options.show = true;\n\n\t\t// Begin the animation\n\t\t// Make sure that we start at a small width/height to avoid any\n\t\t// flash of content\n\t\tthis.custom(this.prop === \"width\" || this.prop === \"height\" ? 1 : 0, this.cur());\n\n\t\t// Start by showing the element\n\t\tjQuery( this.elem ).show();\n\t},\n\n\t// Simple 'hide' function\n\thide: function() {\n\t\t// Remember where we started, so that we can go back to it later\n\t\tthis.options.orig[this.prop] = jQuery.style( this.elem, this.prop );\n\t\tthis.options.hide = true;\n\n\t\t// Begin the animation\n\t\tthis.custom(this.cur(), 0);\n\t},\n\n\t// Each step of an animation\n\tstep: function( gotoEnd ) {\n\t\tvar t = jQuery.now(), done = true;\n\n\t\tif ( gotoEnd || t >= this.options.duration + this.startTime ) {\n\t\t\tthis.now = this.end;\n\t\t\tthis.pos = this.state = 1;\n\t\t\tthis.update();\n\n\t\t\tthis.options.curAnim[ this.prop ] = true;\n\n\t\t\tfor ( var i in this.options.curAnim ) {\n\t\t\t\tif ( this.options.curAnim[i] !== true ) {\n\t\t\t\t\tdone = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( done ) {\n\t\t\t\t// Reset the overflow\n\t\t\t\tif ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {\n\t\t\t\t\tvar elem = this.elem,\n\t\t\t\t\t\toptions = this.options;\n\n\t\t\t\t\tjQuery.each( [ \"\", \"X\", \"Y\" ], function (index, value) {\n\t\t\t\t\t\telem.style[ \"overflow\" + value ] = options.overflow[index];\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\t// Hide the element if the \"hide\" operation was done\n\t\t\t\tif ( this.options.hide ) {\n\t\t\t\t\tjQuery(this.elem).hide();\n\t\t\t\t}\n\n\t\t\t\t// Reset the properties, if the item has been hidden or shown\n\t\t\t\tif ( this.options.hide || this.options.show ) {\n\t\t\t\t\tfor ( var p in this.options.curAnim ) {\n\t\t\t\t\t\tjQuery.style( this.elem, p, this.options.orig[p] );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Execute the complete function\n\t\t\t\tthis.options.complete.call( this.elem );\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t} else {\n\t\t\tvar n = t - this.startTime;\n\t\t\tthis.state = n / this.options.duration;\n\n\t\t\t// Perform the easing function, defaults to swing\n\t\t\tvar specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];\n\t\t\tvar defaultEasing = this.options.easing || (jQuery.easing.swing ? \"swing\" : \"linear\");\n\t\t\tthis.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);\n\t\t\tthis.now = this.start + ((this.end - this.start) * this.pos);\n\n\t\t\t// Perform the next step of the animation\n\t\t\tthis.update();\n\t\t}\n\n\t\treturn true;\n\t}\n};\n\njQuery.extend( jQuery.fx, {\n\ttick: function() {\n\t\tvar timers = jQuery.timers;\n\n\t\tfor ( var i = 0; i < timers.length; i++ ) {\n\t\t\tif ( !timers[i]() ) {\n\t\t\t\ttimers.splice(i--, 1);\n\t\t\t}\n\t\t}\n\n\t\tif ( !timers.length ) {\n\t\t\tjQuery.fx.stop();\n\t\t}\n\t},\n\n\tinterval: 13,\n\n\tstop: function() {\n\t\tclearInterval( timerId );\n\t\ttimerId = null;\n\t},\n\n\tspeeds: {\n\t\tslow: 600,\n\t\tfast: 200,\n\t\t// Default speed\n\t\t_default: 400\n\t},\n\n\tstep: {\n\t\topacity: function( fx ) {\n\t\t\tjQuery.style( fx.elem, \"opacity\", fx.now );\n\t\t},\n\n\t\t_default: function( fx ) {\n\t\t\tif ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {\n\t\t\t\tfx.elem.style[ fx.prop ] = (fx.prop === \"width\" || fx.prop === \"height\" ? Math.max(0, fx.now) : fx.now) + fx.unit;\n\t\t\t} else {\n\t\t\t\tfx.elem[ fx.prop ] = fx.now;\n\t\t\t}\n\t\t}\n\t}\n});\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.animated = function( elem ) {\n\t\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\t\treturn elem === fn.elem;\n\t\t}).length;\n\t};\n}\n\nfunction defaultDisplay( nodeName ) {\n\tif ( !elemdisplay[ nodeName ] ) {\n\t\tvar elem = jQuery(\"<\" + nodeName + \">\").appendTo(\"body\"),\n\t\t\tdisplay = elem.css(\"display\");\n\n\t\telem.remove();\n\n\t\tif ( display === \"none\" || display === \"\" ) {\n\t\t\tdisplay = \"block\";\n\t\t}\n\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn elemdisplay[ nodeName ];\n}\n\n\n\n\nvar rtable = /^t(?:able|d|h)$/i,\n\trroot = /^(?:body|html)$/i;\n\nif ( \"getBoundingClientRect\" in document.documentElement ) {\n\tjQuery.fn.offset = function( options ) {\n\t\tvar elem = this[0], box;\n\n\t\tif ( options ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t});\n\t\t}\n\n\t\tif ( !elem || !elem.ownerDocument ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( elem === elem.ownerDocument.body ) {\n\t\t\treturn jQuery.offset.bodyOffset( elem );\n\t\t}\n\n\t\ttry {\n\t\t\tbox = elem.getBoundingClientRect();\n\t\t} catch(e) {}\n\n\t\tvar doc = elem.ownerDocument,\n\t\t\tdocElem = doc.documentElement;\n\n\t\t// Make sure we're not dealing with a disconnected DOM node\n\t\tif ( !box || !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box ? { top: box.top, left: box.left } : { top: 0, left: 0 };\n\t\t}\n\n\t\tvar body = doc.body,\n\t\t\twin = getWindow(doc),\n\t\t\tclientTop  = docElem.clientTop  || body.clientTop  || 0,\n\t\t\tclientLeft = docElem.clientLeft || body.clientLeft || 0,\n\t\t\tscrollTop  = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop ),\n\t\t\tscrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),\n\t\t\ttop  = box.top  + scrollTop  - clientTop,\n\t\t\tleft = box.left + scrollLeft - clientLeft;\n\n\t\treturn { top: top, left: left };\n\t};\n\n} else {\n\tjQuery.fn.offset = function( options ) {\n\t\tvar elem = this[0];\n\n\t\tif ( options ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t});\n\t\t}\n\n\t\tif ( !elem || !elem.ownerDocument ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( elem === elem.ownerDocument.body ) {\n\t\t\treturn jQuery.offset.bodyOffset( elem );\n\t\t}\n\n\t\tjQuery.offset.initialize();\n\n\t\tvar computedStyle,\n\t\t\toffsetParent = elem.offsetParent,\n\t\t\tprevOffsetParent = elem,\n\t\t\tdoc = elem.ownerDocument,\n\t\t\tdocElem = doc.documentElement,\n\t\t\tbody = doc.body,\n\t\t\tdefaultView = doc.defaultView,\n\t\t\tprevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,\n\t\t\ttop = elem.offsetTop,\n\t\t\tleft = elem.offsetLeft;\n\n\t\twhile ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {\n\t\t\tif ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === \"fixed\" ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcomputedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;\n\t\t\ttop  -= elem.scrollTop;\n\t\t\tleft -= elem.scrollLeft;\n\n\t\t\tif ( elem === offsetParent ) {\n\t\t\t\ttop  += elem.offsetTop;\n\t\t\t\tleft += elem.offsetLeft;\n\n\t\t\t\tif ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {\n\t\t\t\t\ttop  += parseFloat( computedStyle.borderTopWidth  ) || 0;\n\t\t\t\t\tleft += parseFloat( computedStyle.borderLeftWidth ) || 0;\n\t\t\t\t}\n\n\t\t\t\tprevOffsetParent = offsetParent;\n\t\t\t\toffsetParent = elem.offsetParent;\n\t\t\t}\n\n\t\t\tif ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== \"visible\" ) {\n\t\t\t\ttop  += parseFloat( computedStyle.borderTopWidth  ) || 0;\n\t\t\t\tleft += parseFloat( computedStyle.borderLeftWidth ) || 0;\n\t\t\t}\n\n\t\t\tprevComputedStyle = computedStyle;\n\t\t}\n\n\t\tif ( prevComputedStyle.position === \"relative\" || prevComputedStyle.position === \"static\" ) {\n\t\t\ttop  += body.offsetTop;\n\t\t\tleft += body.offsetLeft;\n\t\t}\n\n\t\tif ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === \"fixed\" ) {\n\t\t\ttop  += Math.max( docElem.scrollTop, body.scrollTop );\n\t\t\tleft += Math.max( docElem.scrollLeft, body.scrollLeft );\n\t\t}\n\n\t\treturn { top: top, left: left };\n\t};\n}\n\njQuery.offset = {\n\tinitialize: function() {\n\t\tvar body = document.body, container = document.createElement(\"div\"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, \"marginTop\") ) || 0,\n\t\t\thtml = \"<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>\";\n\n\t\tjQuery.extend( container.style, { position: \"absolute\", top: 0, left: 0, margin: 0, border: 0, width: \"1px\", height: \"1px\", visibility: \"hidden\" } );\n\n\t\tcontainer.innerHTML = html;\n\t\tbody.insertBefore( container, body.firstChild );\n\t\tinnerDiv = container.firstChild;\n\t\tcheckDiv = innerDiv.firstChild;\n\t\ttd = innerDiv.nextSibling.firstChild.firstChild;\n\n\t\tthis.doesNotAddBorder = (checkDiv.offsetTop !== 5);\n\t\tthis.doesAddBorderForTableAndCells = (td.offsetTop === 5);\n\n\t\tcheckDiv.style.position = \"fixed\";\n\t\tcheckDiv.style.top = \"20px\";\n\n\t\t// safari subtracts parent border width here which is 5px\n\t\tthis.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);\n\t\tcheckDiv.style.position = checkDiv.style.top = \"\";\n\n\t\tinnerDiv.style.overflow = \"hidden\";\n\t\tinnerDiv.style.position = \"relative\";\n\n\t\tthis.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);\n\n\t\tthis.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);\n\n\t\tbody.removeChild( container );\n\t\tbody = container = innerDiv = checkDiv = table = td = null;\n\t\tjQuery.offset.initialize = jQuery.noop;\n\t},\n\n\tbodyOffset: function( body ) {\n\t\tvar top = body.offsetTop,\n\t\t\tleft = body.offsetLeft;\n\n\t\tjQuery.offset.initialize();\n\n\t\tif ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {\n\t\t\ttop  += parseFloat( jQuery.css(body, \"marginTop\") ) || 0;\n\t\t\tleft += parseFloat( jQuery.css(body, \"marginLeft\") ) || 0;\n\t\t}\n\n\t\treturn { top: top, left: left };\n\t},\n\n\tsetOffset: function( elem, options, i ) {\n\t\tvar position = jQuery.css( elem, \"position\" );\n\n\t\t// set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tvar curElem = jQuery( elem ),\n\t\t\tcurOffset = curElem.offset(),\n\t\t\tcurCSSTop = jQuery.css( elem, \"top\" ),\n\t\t\tcurCSSLeft = jQuery.css( elem, \"left\" ),\n\t\t\tcalculatePosition = (position === \"absolute\" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),\n\t\t\tprops = {}, curPosition = {}, curTop, curLeft;\n\n\t\t// need to be able to calculate position if either top or left is auto and position is absolute\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t}\n\n\t\tcurTop  = calculatePosition ? curPosition.top  : parseInt( curCSSTop,  10 ) || 0;\n\t\tcurLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif (options.top != null) {\n\t\t\tprops.top = (options.top - curOffset.top) + curTop;\n\t\t}\n\t\tif (options.left != null) {\n\t\t\tprops.left = (options.left - curOffset.left) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\n\njQuery.fn.extend({\n\tposition: function() {\n\t\tif ( !this[0] ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar elem = this[0],\n\n\t\t// Get *real* offsetParent\n\t\toffsetParent = this.offsetParent(),\n\n\t\t// Get correct offsets\n\t\toffset       = this.offset(),\n\t\tparentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();\n\n\t\t// Subtract element margins\n\t\t// note: when an element has margin: auto the offsetLeft and marginLeft\n\t\t// are the same in Safari causing offset.left to incorrectly be 0\n\t\toffset.top  -= parseFloat( jQuery.css(elem, \"marginTop\") ) || 0;\n\t\toffset.left -= parseFloat( jQuery.css(elem, \"marginLeft\") ) || 0;\n\n\t\t// Add offsetParent borders\n\t\tparentOffset.top  += parseFloat( jQuery.css(offsetParent[0], \"borderTopWidth\") ) || 0;\n\t\tparentOffset.left += parseFloat( jQuery.css(offsetParent[0], \"borderLeftWidth\") ) || 0;\n\n\t\t// Subtract the two offsets\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top,\n\t\t\tleft: offset.left - parentOffset.left\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || document.body;\n\t\t\twhile ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, \"position\") === \"static\") ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent;\n\t\t});\n\t}\n});\n\n\n// Create scrollLeft and scrollTop methods\njQuery.each( [\"Left\", \"Top\"], function( i, name ) {\n\tvar method = \"scroll\" + name;\n\n\tjQuery.fn[ method ] = function(val) {\n\t\tvar elem = this[0], win;\n\n\t\tif ( !elem ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( val !== undefined ) {\n\t\t\t// Set the scroll offset\n\t\t\treturn this.each(function() {\n\t\t\t\twin = getWindow( this );\n\n\t\t\t\tif ( win ) {\n\t\t\t\t\twin.scrollTo(\n\t\t\t\t\t\t!i ? val : jQuery(win).scrollLeft(),\n\t\t\t\t\t\ti ? val : jQuery(win).scrollTop()\n\t\t\t\t\t);\n\n\t\t\t\t} else {\n\t\t\t\t\tthis[ method ] = val;\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\twin = getWindow( elem );\n\n\t\t\t// Return the scroll offset\n\t\t\treturn win ? (\"pageXOffset\" in win) ? win[ i ? \"pageYOffset\" : \"pageXOffset\" ] :\n\t\t\t\tjQuery.support.boxModel && win.document.documentElement[ method ] ||\n\t\t\t\t\twin.document.body[ method ] :\n\t\t\t\telem[ method ];\n\t\t}\n\t};\n});\n\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n\n\n\n\n// Create innerHeight, innerWidth, outerHeight and outerWidth methods\njQuery.each([ \"Height\", \"Width\" ], function( i, name ) {\n\n\tvar type = name.toLowerCase();\n\n\t// innerHeight and innerWidth\n\tjQuery.fn[\"inner\" + name] = function() {\n\t\treturn this[0] ?\n\t\t\tparseFloat( jQuery.css( this[0], type, \"padding\" ) ) :\n\t\t\tnull;\n\t};\n\n\t// outerHeight and outerWidth\n\tjQuery.fn[\"outer\" + name] = function( margin ) {\n\t\treturn this[0] ?\n\t\t\tparseFloat( jQuery.css( this[0], type, margin ? \"margin\" : \"border\" ) ) :\n\t\t\tnull;\n\t};\n\n\tjQuery.fn[ type ] = function( size ) {\n\t\t// Get window width or height\n\t\tvar elem = this[0];\n\t\tif ( !elem ) {\n\t\t\treturn size == null ? null : this;\n\t\t}\n\n\t\tif ( jQuery.isFunction( size ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tvar self = jQuery( this );\n\t\t\t\tself[ type ]( size.call( this, i, self[ type ]() ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode\n\t\t\t// 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat\n\t\t\tvar docElemProp = elem.document.documentElement[ \"client\" + name ];\n\t\t\treturn elem.document.compatMode === \"CSS1Compat\" && docElemProp ||\n\t\t\t\telem.document.body[ \"client\" + name ] || docElemProp;\n\n\t\t// Get document width or height\n\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t// Either scroll[Width/Height] or offset[Width/Height], whichever is greater\n\t\t\treturn Math.max(\n\t\t\t\telem.documentElement[\"client\" + name],\n\t\t\t\telem.body[\"scroll\" + name], elem.documentElement[\"scroll\" + name],\n\t\t\t\telem.body[\"offset\" + name], elem.documentElement[\"offset\" + name]\n\t\t\t);\n\n\t\t// Get or set width or height on the element\n\t\t} else if ( size === undefined ) {\n\t\t\tvar orig = jQuery.css( elem, type ),\n\t\t\t\tret = parseFloat( orig );\n\n\t\t\treturn jQuery.isNaN( ret ) ? orig : ret;\n\n\t\t// Set the width or height on the element (default to pixels if value is unitless)\n\t\t} else {\n\t\t\treturn this.css( type, typeof size === \"string\" ? size : size + \"px\" );\n\t\t}\n\t};\n\n});\n\n\nwindow.jQuery = window.$ = jQuery;\n})(window);"
  },
  {
    "path": "app/static_dev/js/libs/jquery-1.6.2.js",
    "content": "/*!\n * jQuery JavaScript Library v1.6.2\n * http://jquery.com/\n *\n * Copyright 2011, John Resig\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n * Copyright 2011, The Dojo Foundation\n * Released under the MIT, BSD, and GPL Licenses.\n *\n * Date: Thu Jun 30 14:16:56 2011 -0400\n */\n(function( window, undefined ) {\n\n// Use the correct document accordingly with window argument (sandbox)\nvar document = window.document,\n\tnavigator = window.navigator,\n\tlocation = window.location;\nvar jQuery = (function() {\n\n// Define a local copy of jQuery\nvar jQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\treturn new jQuery.fn.init( selector, context, rootjQuery );\n\t},\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$,\n\n\t// A central reference to the root jQuery(document)\n\trootjQuery,\n\n\t// A simple way to check for HTML strings or ID strings\n\t// (both of which we optimize for)\n\tquickExpr = /^(?:[^<]*(<[\\w\\W]+>)[^>]*$|#([\\w\\-]*)$)/,\n\n\t// Check if a string has a non-whitespace character in it\n\trnotwhite = /\\S/,\n\n\t// Used for trimming whitespace\n\ttrimLeft = /^\\s+/,\n\ttrimRight = /\\s+$/,\n\n\t// Check for digits\n\trdigit = /\\d/,\n\n\t// Match a standalone tag\n\trsingleTag = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>)?$/,\n\n\t// JSON RegExp\n\trvalidchars = /^[\\],:{}\\s]*$/,\n\trvalidescape = /\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g,\n\trvalidtokens = /\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g,\n\trvalidbraces = /(?:^|:|,)(?:\\s*\\[)+/g,\n\n\t// Useragent RegExp\n\trwebkit = /(webkit)[ \\/]([\\w.]+)/,\n\tropera = /(opera)(?:.*version)?[ \\/]([\\w.]+)/,\n\trmsie = /(msie) ([\\w.]+)/,\n\trmozilla = /(mozilla)(?:.*? rv:([\\w.]+))?/,\n\n\t// Matches dashed string for camelizing\n\trdashAlpha = /-([a-z])/ig,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t},\n\n\t// Keep a UserAgent string for use with jQuery.browser\n\tuserAgent = navigator.userAgent,\n\n\t// For matching the engine and version of the browser\n\tbrowserMatch,\n\n\t// The deferred used on DOM ready\n\treadyList,\n\n\t// The ready event handler\n\tDOMContentLoaded,\n\n\t// Save a reference to some core methods\n\ttoString = Object.prototype.toString,\n\thasOwn = Object.prototype.hasOwnProperty,\n\tpush = Array.prototype.push,\n\tslice = Array.prototype.slice,\n\ttrim = String.prototype.trim,\n\tindexOf = Array.prototype.indexOf,\n\n\t// [[Class]] -> type pairs\n\tclass2type = {};\n\njQuery.fn = jQuery.prototype = {\n\tconstructor: jQuery,\n\tinit: function( selector, context, rootjQuery ) {\n\t\tvar match, elem, ret, doc;\n\n\t\t// Handle $(\"\"), $(null), or $(undefined)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle $(DOMElement)\n\t\tif ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\t\t}\n\n\t\t// The body element only exists once, optimize finding it\n\t\tif ( selector === \"body\" && !context && document.body ) {\n\t\t\tthis.context = document;\n\t\t\tthis[0] = document.body;\n\t\t\tthis.selector = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\t// Are we dealing with HTML string or an ID?\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = quickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Verify a match, and that no context was specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\t\t\t\t\tdoc = (context ? context.ownerDocument || context : document);\n\n\t\t\t\t\t// If a single string is passed in and it's a single tag\n\t\t\t\t\t// just do a createElement and skip the rest\n\t\t\t\t\tret = rsingleTag.exec( selector );\n\n\t\t\t\t\tif ( ret ) {\n\t\t\t\t\t\tif ( jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\t\tselector = [ document.createElement( ret[1] ) ];\n\t\t\t\t\t\t\tjQuery.fn.attr.call( selector, context, true );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tselector = [ doc.createElement( ret[1] ) ];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tret = jQuery.buildFragment( [ match[1] ], [ doc ] );\n\t\t\t\t\t\tselector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.merge( this, selector );\n\n\t\t\t\t// HANDLE: $(\"#id\")\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn (context || rootjQuery).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn rootjQuery.ready( selector );\n\t\t}\n\n\t\tif (selector.selector !== undefined) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t},\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The current version of jQuery being used\n\tjquery: \"1.6.2\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\t// The number of elements contained in the matched element set\n\tsize: function() {\n\t\treturn this.length;\n\t},\n\n\ttoArray: function() {\n\t\treturn slice.call( this, 0 );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num == null ?\n\n\t\t\t// Return a 'clean' array\n\t\t\tthis.toArray() :\n\n\t\t\t// Return just the object\n\t\t\t( num < 0 ? this[ this.length + num ] : this[ num ] );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems, name, selector ) {\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = this.constructor();\n\n\t\tif ( jQuery.isArray( elems ) ) {\n\t\t\tpush.apply( ret, elems );\n\n\t\t} else {\n\t\t\tjQuery.merge( ret, elems );\n\t\t}\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\tret.context = this.context;\n\n\t\tif ( name === \"find\" ) {\n\t\t\tret.selector = this.selector + (this.selector ? \" \" : \"\") + selector;\n\t\t} else if ( name ) {\n\t\t\tret.selector = this.selector + \".\" + name + \"(\" + selector + \")\";\n\t\t}\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tready: function( fn ) {\n\t\t// Attach the listeners\n\t\tjQuery.bindReady();\n\n\t\t// Add the callback\n\t\treadyList.done( fn );\n\n\t\treturn this;\n\t},\n\n\teq: function( i ) {\n\t\treturn i === -1 ?\n\t\t\tthis.slice( i ) :\n\t\t\tthis.slice( i, +i + 1 );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ),\n\t\t\t\"slice\", slice.call(arguments).join(\",\") );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: [].sort,\n\tsplice: [].splice\n};\n\n// Give the init function the jQuery prototype for later instantiation\njQuery.fn.init.prototype = jQuery.fn;\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\t\ttarget = arguments[1] || {};\n\t\t// skip the boolean and the target\n\t\ti = 2;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( length === i ) {\n\t\ttarget = this;\n\t\t--i;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\tnoConflict: function( deep ) {\n\t\tif ( window.$ === jQuery ) {\n\t\t\twindow.$ = _$;\n\t\t}\n\n\t\tif ( deep && window.jQuery === jQuery ) {\n\t\t\twindow.jQuery = _jQuery;\n\t\t}\n\n\t\treturn jQuery;\n\t},\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\t\t// Either a released hold or an DOMready/load event and not yet ready\n\t\tif ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {\n\t\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\t\tif ( !document.body ) {\n\t\t\t\treturn setTimeout( jQuery.ready, 1 );\n\t\t\t}\n\n\t\t\t// Remember that the DOM is ready\n\t\t\tjQuery.isReady = true;\n\n\t\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If there are functions bound, to execute\n\t\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t\t// Trigger any bound ready events\n\t\t\tif ( jQuery.fn.trigger ) {\n\t\t\t\tjQuery( document ).trigger( \"ready\" ).unbind( \"ready\" );\n\t\t\t}\n\t\t}\n\t},\n\n\tbindReady: function() {\n\t\tif ( readyList ) {\n\t\t\treturn;\n\t\t}\n\n\t\treadyList = jQuery._Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the\n\t\t// browser event has already occurred.\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\treturn setTimeout( jQuery.ready, 1 );\n\t\t}\n\n\t\t// Mozilla, Opera and webkit nightlies currently support this event\n\t\tif ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", jQuery.ready, false );\n\n\t\t// If IE event model is used\n\t\t} else if ( document.attachEvent ) {\n\t\t\t// ensure firing before onload,\n\t\t\t// maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", DOMContentLoaded );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", jQuery.ready );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar toplevel = false;\n\n\t\t\ttry {\n\t\t\t\ttoplevel = window.frameElement == null;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( document.documentElement.doScroll && toplevel ) {\n\t\t\t\tdoScrollCheck();\n\t\t\t}\n\t\t}\n\t},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\t// A crude way of determining if an object is a window\n\tisWindow: function( obj ) {\n\t\treturn obj && typeof obj === \"object\" && \"setInterval\" in obj;\n\t},\n\n\tisNaN: function( obj ) {\n\t\treturn obj == null || !rdigit.test( obj ) || isNaN( obj );\n\t},\n\n\ttype: function( obj ) {\n\t\treturn obj == null ?\n\t\t\tString( obj ) :\n\t\t\tclass2type[ toString.call(obj) ] || \"object\";\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Not own constructor property must be Object\n\t\tif ( obj.constructor &&\n\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\n\t\tvar key;\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tfor ( var name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\terror: function( msg ) {\n\t\tthrow msg;\n\t},\n\n\tparseJSON: function( data ) {\n\t\tif ( typeof data !== \"string\" || !data ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Make sure leading/trailing whitespace is removed (IE can't handle it)\n\t\tdata = jQuery.trim( data );\n\n\t\t// Attempt to parse using the native JSON parser first\n\t\tif ( window.JSON && window.JSON.parse ) {\n\t\t\treturn window.JSON.parse( data );\n\t\t}\n\n\t\t// Make sure the incoming data is actual JSON\n\t\t// Logic borrowed from http://json.org/json2.js\n\t\tif ( rvalidchars.test( data.replace( rvalidescape, \"@\" )\n\t\t\t.replace( rvalidtokens, \"]\" )\n\t\t\t.replace( rvalidbraces, \"\")) ) {\n\n\t\t\treturn (new Function( \"return \" + data ))();\n\n\t\t}\n\t\tjQuery.error( \"Invalid JSON: \" + data );\n\t},\n\n\t// Cross-browser xml parsing\n\t// (xml & tmp used internally)\n\tparseXML: function( data , xml , tmp ) {\n\n\t\tif ( window.DOMParser ) { // Standard\n\t\t\ttmp = new DOMParser();\n\t\t\txml = tmp.parseFromString( data , \"text/xml\" );\n\t\t} else { // IE\n\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\txml.async = \"false\";\n\t\t\txml.loadXML( data );\n\t\t}\n\n\t\ttmp = xml.documentElement;\n\n\t\tif ( ! tmp || ! tmp.nodeName || tmp.nodeName === \"parsererror\" ) {\n\t\t\tjQuery.error( \"Invalid XML: \" + data );\n\t\t}\n\n\t\treturn xml;\n\t},\n\n\tnoop: function() {},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && rnotwhite.test( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Converts a dashed string to camelCased string;\n\t// Used by both the css and data modules\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( object, callback, args ) {\n\t\tvar name, i = 0,\n\t\t\tlength = object.length,\n\t\t\tisObj = length === undefined || jQuery.isFunction( object );\n\n\t\tif ( args ) {\n\t\t\tif ( isObj ) {\n\t\t\t\tfor ( name in object ) {\n\t\t\t\t\tif ( callback.apply( object[ name ], args ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( ; i < length; ) {\n\t\t\t\t\tif ( callback.apply( object[ i++ ], args ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isObj ) {\n\t\t\t\tfor ( name in object ) {\n\t\t\t\t\tif ( callback.call( object[ name ], name, object[ name ] ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( ; i < length; ) {\n\t\t\t\t\tif ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn object;\n\t},\n\n\t// Use native String.trim function wherever possible\n\ttrim: trim ?\n\t\tfunction( text ) {\n\t\t\treturn text == null ?\n\t\t\t\t\"\" :\n\t\t\t\ttrim.call( text );\n\t\t} :\n\n\t\t// Otherwise use our own trimming functionality\n\t\tfunction( text ) {\n\t\t\treturn text == null ?\n\t\t\t\t\"\" :\n\t\t\t\ttext.toString().replace( trimLeft, \"\" ).replace( trimRight, \"\" );\n\t\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( array, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( array != null ) {\n\t\t\t// The window, strings (and functions) also have 'length'\n\t\t\t// The extra typeof function check is to prevent crashes\n\t\t\t// in Safari 2 (See: #3039)\n\t\t\t// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930\n\t\t\tvar type = jQuery.type( array );\n\n\t\t\tif ( array.length == null || type === \"string\" || type === \"function\" || type === \"regexp\" || jQuery.isWindow( array ) ) {\n\t\t\t\tpush.call( ret, array );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( ret, array );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, array ) {\n\n\t\tif ( indexOf ) {\n\t\t\treturn indexOf.call( array, elem );\n\t\t}\n\n\t\tfor ( var i = 0, length = array.length; i < length; i++ ) {\n\t\t\tif ( array[ i ] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar i = first.length,\n\t\t\tj = 0;\n\n\t\tif ( typeof second.length === \"number\" ) {\n\t\t\tfor ( var l = second.length; j < l; j++ ) {\n\t\t\t\tfirst[ i++ ] = second[ j ];\n\t\t\t}\n\n\t\t} else {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, inv ) {\n\t\tvar ret = [], retVal;\n\t\tinv = !!inv;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( var i = 0, length = elems.length; i < length; i++ ) {\n\t\t\tretVal = !!callback( elems[ i ], i );\n\t\t\tif ( inv !== retVal ) {\n\t\t\t\tret.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value, key, ret = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\t// jquery objects are treated as arrays\n\t\t\tisArray = elems instanceof jQuery || length !== undefined && typeof length === \"number\" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;\n\n\t\t// Go through the array, translating each of the items to their\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret[ ret.length ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( key in elems ) {\n\t\t\t\tvalue = callback( elems[ key ], key, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret[ ret.length ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn ret.concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tif ( typeof context === \"string\" ) {\n\t\t\tvar tmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\tvar args = slice.call( arguments, 2 ),\n\t\t\tproxy = function() {\n\t\t\t\treturn fn.apply( context, args.concat( slice.call( arguments ) ) );\n\t\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\t// Mutifunctional method to get and set values to a collection\n\t// The value/s can optionally be executed if it's a function\n\taccess: function( elems, key, value, exec, fn, pass ) {\n\t\tvar length = elems.length;\n\n\t\t// Setting many attributes\n\t\tif ( typeof key === \"object\" ) {\n\t\t\tfor ( var k in key ) {\n\t\t\t\tjQuery.access( elems, k, key[k], exec, fn, value );\n\t\t\t}\n\t\t\treturn elems;\n\t\t}\n\n\t\t// Setting one attribute\n\t\tif ( value !== undefined ) {\n\t\t\t// Optionally, function values get executed if exec is true\n\t\t\texec = !pass && exec && jQuery.isFunction(value);\n\n\t\t\tfor ( var i = 0; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );\n\t\t\t}\n\n\t\t\treturn elems;\n\t\t}\n\n\t\t// Getting an attribute\n\t\treturn length ? fn( elems[0], key ) : undefined;\n\t},\n\n\tnow: function() {\n\t\treturn (new Date()).getTime();\n\t},\n\n\t// Use of jQuery.browser is frowned upon.\n\t// More details: http://docs.jquery.com/Utilities/jQuery.browser\n\tuaMatch: function( ua ) {\n\t\tua = ua.toLowerCase();\n\n\t\tvar match = rwebkit.exec( ua ) ||\n\t\t\tropera.exec( ua ) ||\n\t\t\trmsie.exec( ua ) ||\n\t\t\tua.indexOf(\"compatible\") < 0 && rmozilla.exec( ua ) ||\n\t\t\t[];\n\n\t\treturn { browser: match[1] || \"\", version: match[2] || \"0\" };\n\t},\n\n\tsub: function() {\n\t\tfunction jQuerySub( selector, context ) {\n\t\t\treturn new jQuerySub.fn.init( selector, context );\n\t\t}\n\t\tjQuery.extend( true, jQuerySub, this );\n\t\tjQuerySub.superclass = this;\n\t\tjQuerySub.fn = jQuerySub.prototype = this();\n\t\tjQuerySub.fn.constructor = jQuerySub;\n\t\tjQuerySub.sub = this.sub;\n\t\tjQuerySub.fn.init = function init( selector, context ) {\n\t\t\tif ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {\n\t\t\t\tcontext = jQuerySub( context );\n\t\t\t}\n\n\t\t\treturn jQuery.fn.init.call( this, selector, context, rootjQuerySub );\n\t\t};\n\t\tjQuerySub.fn.init.prototype = jQuerySub.fn;\n\t\tvar rootjQuerySub = jQuerySub(document);\n\t\treturn jQuerySub;\n\t},\n\n\tbrowser: {}\n});\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nbrowserMatch = jQuery.uaMatch( userAgent );\nif ( browserMatch.browser ) {\n\tjQuery.browser[ browserMatch.browser ] = true;\n\tjQuery.browser.version = browserMatch.version;\n}\n\n// Deprecated, use jQuery.browser.webkit instead\nif ( jQuery.browser.webkit ) {\n\tjQuery.browser.safari = true;\n}\n\n// IE doesn't match non-breaking spaces with \\s\nif ( rnotwhite.test( \"\\xA0\" ) ) {\n\ttrimLeft = /^[\\s\\xA0]+/;\n\ttrimRight = /[\\s\\xA0]+$/;\n}\n\n// All jQuery objects should point back to these\nrootjQuery = jQuery(document);\n\n// Cleanup functions for the document ready method\nif ( document.addEventListener ) {\n\tDOMContentLoaded = function() {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n\t\tjQuery.ready();\n\t};\n\n} else if ( document.attachEvent ) {\n\tDOMContentLoaded = function() {\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\tdocument.detachEvent( \"onreadystatechange\", DOMContentLoaded );\n\t\t\tjQuery.ready();\n\t\t}\n\t};\n}\n\n// The DOM ready check for Internet Explorer\nfunction doScrollCheck() {\n\tif ( jQuery.isReady ) {\n\t\treturn;\n\t}\n\n\ttry {\n\t\t// If IE is used, use the trick by Diego Perini\n\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\tdocument.documentElement.doScroll(\"left\");\n\t} catch(e) {\n\t\tsetTimeout( doScrollCheck, 1 );\n\t\treturn;\n\t}\n\n\t// and execute any waiting functions\n\tjQuery.ready();\n}\n\nreturn jQuery;\n\n})();\n\n\nvar // Promise methods\n\tpromiseMethods = \"done fail isResolved isRejected promise then always pipe\".split( \" \" ),\n\t// Static reference to slice\n\tsliceDeferred = [].slice;\n\njQuery.extend({\n\t// Create a simple deferred (one callbacks list)\n\t_Deferred: function() {\n\t\tvar // callbacks list\n\t\t\tcallbacks = [],\n\t\t\t// stored [ context , args ]\n\t\t\tfired,\n\t\t\t// to avoid firing when already doing so\n\t\t\tfiring,\n\t\t\t// flag to know if the deferred has been cancelled\n\t\t\tcancelled,\n\t\t\t// the deferred itself\n\t\t\tdeferred  = {\n\n\t\t\t\t// done( f1, f2, ...)\n\t\t\t\tdone: function() {\n\t\t\t\t\tif ( !cancelled ) {\n\t\t\t\t\t\tvar args = arguments,\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tlength,\n\t\t\t\t\t\t\telem,\n\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\t_fired;\n\t\t\t\t\t\tif ( fired ) {\n\t\t\t\t\t\t\t_fired = fired;\n\t\t\t\t\t\t\tfired = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor ( i = 0, length = args.length; i < length; i++ ) {\n\t\t\t\t\t\t\telem = args[ i ];\n\t\t\t\t\t\t\ttype = jQuery.type( elem );\n\t\t\t\t\t\t\tif ( type === \"array\" ) {\n\t\t\t\t\t\t\t\tdeferred.done.apply( deferred, elem );\n\t\t\t\t\t\t\t} else if ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tcallbacks.push( elem );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( _fired ) {\n\t\t\t\t\t\t\tdeferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// resolve with given context and args\n\t\t\t\tresolveWith: function( context, args ) {\n\t\t\t\t\tif ( !cancelled && !fired && !firing ) {\n\t\t\t\t\t\t// make sure args are available (#8421)\n\t\t\t\t\t\targs = args || [];\n\t\t\t\t\t\tfiring = 1;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\twhile( callbacks[ 0 ] ) {\n\t\t\t\t\t\t\t\tcallbacks.shift().apply( context, args );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinally {\n\t\t\t\t\t\t\tfired = [ context, args ];\n\t\t\t\t\t\t\tfiring = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// resolve with this as context and given arguments\n\t\t\t\tresolve: function() {\n\t\t\t\t\tdeferred.resolveWith( this, arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Has this deferred been resolved?\n\t\t\t\tisResolved: function() {\n\t\t\t\t\treturn !!( firing || fired );\n\t\t\t\t},\n\n\t\t\t\t// Cancel\n\t\t\t\tcancel: function() {\n\t\t\t\t\tcancelled = 1;\n\t\t\t\t\tcallbacks = [];\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\treturn deferred;\n\t},\n\n\t// Full fledged deferred (two callbacks list)\n\tDeferred: function( func ) {\n\t\tvar deferred = jQuery._Deferred(),\n\t\t\tfailDeferred = jQuery._Deferred(),\n\t\t\tpromise;\n\t\t// Add errorDeferred methods, then and promise\n\t\tjQuery.extend( deferred, {\n\t\t\tthen: function( doneCallbacks, failCallbacks ) {\n\t\t\t\tdeferred.done( doneCallbacks ).fail( failCallbacks );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\talways: function() {\n\t\t\t\treturn deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );\n\t\t\t},\n\t\t\tfail: failDeferred.done,\n\t\t\trejectWith: failDeferred.resolveWith,\n\t\t\treject: failDeferred.resolve,\n\t\t\tisRejected: failDeferred.isResolved,\n\t\t\tpipe: function( fnDone, fnFail ) {\n\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\tjQuery.each( {\n\t\t\t\t\t\tdone: [ fnDone, \"resolve\" ],\n\t\t\t\t\t\tfail: [ fnFail, \"reject\" ]\n\t\t\t\t\t}, function( handler, data ) {\n\t\t\t\t\t\tvar fn = data[ 0 ],\n\t\t\t\t\t\t\taction = data[ 1 ],\n\t\t\t\t\t\t\treturned;\n\t\t\t\t\t\tif ( jQuery.isFunction( fn ) ) {\n\t\t\t\t\t\t\tdeferred[ handler ](function() {\n\t\t\t\t\t\t\t\treturned = fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise().then( newDefer.resolve, newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ action ]( returned );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdeferred[ handler ]( newDefer[ action ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}).promise();\n\t\t\t},\n\t\t\t// Get a promise for this deferred\n\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\tpromise: function( obj ) {\n\t\t\t\tif ( obj == null ) {\n\t\t\t\t\tif ( promise ) {\n\t\t\t\t\t\treturn promise;\n\t\t\t\t\t}\n\t\t\t\t\tpromise = obj = {};\n\t\t\t\t}\n\t\t\t\tvar i = promiseMethods.length;\n\t\t\t\twhile( i-- ) {\n\t\t\t\t\tobj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];\n\t\t\t\t}\n\t\t\t\treturn obj;\n\t\t\t}\n\t\t});\n\t\t// Make sure only one callback list will be used\n\t\tdeferred.done( failDeferred.cancel ).fail( deferred.cancel );\n\t\t// Unexpose cancel\n\t\tdelete deferred.cancel;\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( firstParam ) {\n\t\tvar args = arguments,\n\t\t\ti = 0,\n\t\t\tlength = args.length,\n\t\t\tcount = length,\n\t\t\tdeferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?\n\t\t\t\tfirstParam :\n\t\t\t\tjQuery.Deferred();\n\t\tfunction resolveFunc( i ) {\n\t\t\treturn function( value ) {\n\t\t\t\targs[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\t// Strange bug in FF4:\n\t\t\t\t\t// Values changed onto the arguments object sometimes end up as undefined values\n\t\t\t\t\t// outside the $.when method. Cloning the object into a fresh array solves the issue\n\t\t\t\t\tdeferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\tif ( length > 1 ) {\n\t\t\tfor( ; i < length; i++ ) {\n\t\t\t\tif ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {\n\t\t\t\t\targs[ i ].promise().then( resolveFunc(i), deferred.reject );\n\t\t\t\t} else {\n\t\t\t\t\t--count;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( !count ) {\n\t\t\t\tdeferred.resolveWith( deferred, args );\n\t\t\t}\n\t\t} else if ( deferred !== firstParam ) {\n\t\t\tdeferred.resolveWith( deferred, length ? [ firstParam ] : [] );\n\t\t}\n\t\treturn deferred.promise();\n\t}\n});\n\n\n\njQuery.support = (function() {\n\n\tvar div = document.createElement( \"div\" ),\n\t\tdocumentElement = document.documentElement,\n\t\tall,\n\t\ta,\n\t\tselect,\n\t\topt,\n\t\tinput,\n\t\tmarginDiv,\n\t\tsupport,\n\t\tfragment,\n\t\tbody,\n\t\ttestElementParent,\n\t\ttestElement,\n\t\ttestElementStyle,\n\t\ttds,\n\t\tevents,\n\t\teventName,\n\t\ti,\n\t\tisSupported;\n\n\t// Preliminary tests\n\tdiv.setAttribute(\"className\", \"t\");\n\tdiv.innerHTML = \"   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>\";\n\n\tall = div.getElementsByTagName( \"*\" );\n\ta = div.getElementsByTagName( \"a\" )[ 0 ];\n\n\t// Can't get basic test support\n\tif ( !all || !all.length || !a ) {\n\t\treturn {};\n\t}\n\n\t// First batch of supports tests\n\tselect = document.createElement( \"select\" );\n\topt = select.appendChild( document.createElement(\"option\") );\n\tinput = div.getElementsByTagName( \"input\" )[ 0 ];\n\n\tsupport = {\n\t\t// IE strips leading whitespace when .innerHTML is used\n\t\tleadingWhitespace: ( div.firstChild.nodeType === 3 ),\n\n\t\t// Make sure that tbody elements aren't automatically inserted\n\t\t// IE will insert them into empty tables\n\t\ttbody: !div.getElementsByTagName( \"tbody\" ).length,\n\n\t\t// Make sure that link elements get serialized correctly by innerHTML\n\t\t// This requires a wrapper element in IE\n\t\thtmlSerialize: !!div.getElementsByTagName( \"link\" ).length,\n\n\t\t// Get the style information from getAttribute\n\t\t// (IE uses .cssText instead)\n\t\tstyle: /top/.test( a.getAttribute(\"style\") ),\n\n\t\t// Make sure that URLs aren't manipulated\n\t\t// (IE normalizes it by default)\n\t\threfNormalized: ( a.getAttribute( \"href\" ) === \"/a\" ),\n\n\t\t// Make sure that element opacity exists\n\t\t// (IE uses filter instead)\n\t\t// Use a regex to work around a WebKit issue. See #5145\n\t\topacity: /^0.55$/.test( a.style.opacity ),\n\n\t\t// Verify style float existence\n\t\t// (IE uses styleFloat instead of cssFloat)\n\t\tcssFloat: !!a.style.cssFloat,\n\n\t\t// Make sure that if no value is specified for a checkbox\n\t\t// that it defaults to \"on\".\n\t\t// (WebKit defaults to \"\" instead)\n\t\tcheckOn: ( input.value === \"on\" ),\n\n\t\t// Make sure that a selected-by-default option has a working selected property.\n\t\t// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n\t\toptSelected: opt.selected,\n\n\t\t// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n\t\tgetSetAttribute: div.className !== \"t\",\n\n\t\t// Will be defined later\n\t\tsubmitBubbles: true,\n\t\tchangeBubbles: true,\n\t\tfocusinBubbles: false,\n\t\tdeleteExpando: true,\n\t\tnoCloneEvent: true,\n\t\tinlineBlockNeedsLayout: false,\n\t\tshrinkWrapBlocks: false,\n\t\treliableMarginRight: true\n\t};\n\n\t// Make sure checked status is properly cloned\n\tinput.checked = true;\n\tsupport.noCloneChecked = input.cloneNode( true ).checked;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as disabled)\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Test to see if it's possible to delete an expando from an element\n\t// Fails in Internet Explorer\n\ttry {\n\t\tdelete div.test;\n\t} catch( e ) {\n\t\tsupport.deleteExpando = false;\n\t}\n\n\tif ( !div.addEventListener && div.attachEvent && div.fireEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\t// Cloning a node shouldn't copy over any\n\t\t\t// bound event handlers (IE does this)\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\t\tdiv.cloneNode( true ).fireEvent( \"onclick\" );\n\t}\n\n\t// Check if a radio maintains it's value\n\t// after being appended to the DOM\n\tinput = document.createElement(\"input\");\n\tinput.value = \"t\";\n\tinput.setAttribute(\"type\", \"radio\");\n\tsupport.radioValue = input.value === \"t\";\n\n\tinput.setAttribute(\"checked\", \"checked\");\n\tdiv.appendChild( input );\n\tfragment = document.createDocumentFragment();\n\tfragment.appendChild( div.firstChild );\n\n\t// WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\tdiv.innerHTML = \"\";\n\n\t// Figure out if the W3C box model works as expected\n\tdiv.style.width = div.style.paddingLeft = \"1px\";\n\n\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t// We use our own, invisible, body unless the body is already present\n\t// in which case we use a div (#9239)\n\ttestElement = document.createElement( body ? \"div\" : \"body\" );\n\ttestElementStyle = {\n\t\tvisibility: \"hidden\",\n\t\twidth: 0,\n\t\theight: 0,\n\t\tborder: 0,\n\t\tmargin: 0\n\t};\n\tif ( body ) {\n\t\tjQuery.extend( testElementStyle, {\n\t\t\tposition: \"absolute\",\n\t\t\tleft: -1000,\n\t\t\ttop: -1000\n\t\t});\n\t}\n\tfor ( i in testElementStyle ) {\n\t\ttestElement.style[ i ] = testElementStyle[ i ];\n\t}\n\ttestElement.appendChild( div );\n\ttestElementParent = body || documentElement;\n\ttestElementParent.insertBefore( testElement, testElementParent.firstChild );\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tsupport.appendChecked = input.checked;\n\n\tsupport.boxModel = div.offsetWidth === 2;\n\n\tif ( \"zoom\" in div.style ) {\n\t\t// Check if natively block-level elements act like inline-block\n\t\t// elements when setting their display to 'inline' and giving\n\t\t// them layout\n\t\t// (IE < 8 does this)\n\t\tdiv.style.display = \"inline\";\n\t\tdiv.style.zoom = 1;\n\t\tsupport.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );\n\n\t\t// Check if elements with layout shrink-wrap their children\n\t\t// (IE 6 does this)\n\t\tdiv.style.display = \"\";\n\t\tdiv.innerHTML = \"<div style='width:4px;'></div>\";\n\t\tsupport.shrinkWrapBlocks = ( div.offsetWidth !== 2 );\n\t}\n\n\tdiv.innerHTML = \"<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>\";\n\ttds = div.getElementsByTagName( \"td\" );\n\n\t// Check if table cells still have offsetWidth/Height when they are set\n\t// to display:none and there are still other visible table cells in a\n\t// table row; if so, offsetWidth/Height are not reliable for use when\n\t// determining if an element has been hidden directly using\n\t// display:none (it is still safe to use offsets if a parent element is\n\t// hidden; don safety goggles and see bug #4512 for more information).\n\t// (only IE 8 fails this test)\n\tisSupported = ( tds[ 0 ].offsetHeight === 0 );\n\n\ttds[ 0 ].style.display = \"\";\n\ttds[ 1 ].style.display = \"none\";\n\n\t// Check if empty table cells still have offsetWidth/Height\n\t// (IE < 8 fail this test)\n\tsupport.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );\n\tdiv.innerHTML = \"\";\n\n\t// Check if div with explicit width and no margin-right incorrectly\n\t// gets computed margin-right based on width of container. For more\n\t// info see bug #3333\n\t// Fails in WebKit before Feb 2011 nightlies\n\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\tif ( document.defaultView && document.defaultView.getComputedStyle ) {\n\t\tmarginDiv = document.createElement( \"div\" );\n\t\tmarginDiv.style.width = \"0\";\n\t\tmarginDiv.style.marginRight = \"0\";\n\t\tdiv.appendChild( marginDiv );\n\t\tsupport.reliableMarginRight =\n\t\t\t( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;\n\t}\n\n\t// Remove the body element we added\n\ttestElement.innerHTML = \"\";\n\ttestElementParent.removeChild( testElement );\n\n\t// Technique from Juriy Zaytsev\n\t// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/\n\t// We only care about the case where non-standard event systems\n\t// are used, namely in IE. Short-circuiting here helps us to\n\t// avoid an eval call (in setAttribute) which can cause CSP\n\t// to go haywire. See: https://developer.mozilla.org/en/Security/CSP\n\tif ( div.attachEvent ) {\n\t\tfor( i in {\n\t\t\tsubmit: 1,\n\t\t\tchange: 1,\n\t\t\tfocusin: 1\n\t\t} ) {\n\t\t\teventName = \"on\" + i;\n\t\t\tisSupported = ( eventName in div );\n\t\t\tif ( !isSupported ) {\n\t\t\t\tdiv.setAttribute( eventName, \"return;\" );\n\t\t\t\tisSupported = ( typeof div[ eventName ] === \"function\" );\n\t\t\t}\n\t\t\tsupport[ i + \"Bubbles\" ] = isSupported;\n\t\t}\n\t}\n\n\t// Null connected elements to avoid leaks in IE\n\ttestElement = fragment = select = opt = body = marginDiv = div = input = null;\n\n\treturn support;\n})();\n\n// Keep track of boxModel\njQuery.boxModel = jQuery.support.boxModel;\n\n\n\n\nvar rbrace = /^(?:\\{.*\\}|\\[.*\\])$/,\n\trmultiDash = /([a-z])([A-Z])/g;\n\njQuery.extend({\n\tcache: {},\n\n\t// Please use with caution\n\tuuid: 0,\n\n\t// Unique for each copy of jQuery on the page\n\t// Non-digits removed to match rinlinejQuery\n\texpando: \"jQuery\" + ( jQuery.fn.jquery + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// The following elements throw uncatchable exceptions if you\n\t// attempt to add expando properties to them.\n\tnoData: {\n\t\t\"embed\": true,\n\t\t// Ban all objects except for Flash (which handle expandos)\n\t\t\"object\": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\",\n\t\t\"applet\": true\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data, pvt /* Internal Use Only */ ) {\n\t\tif ( !jQuery.acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar internalKey = jQuery.expando, getByName = typeof name === \"string\", thisCache,\n\n\t\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t\t// can't GC object references properly across the DOM-JS boundary\n\t\t\tisNode = elem.nodeType,\n\n\t\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t\t// attached directly to the object so GC can occur automatically\n\t\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\t\tid = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;\n\n\t\t// Avoid doing any more work than we need to when trying to get data on an\n\t\t// object that has no data at all\n\t\tif ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !id ) {\n\t\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t\t// ends up in the global cache\n\t\t\tif ( isNode ) {\n\t\t\t\telem[ jQuery.expando ] = id = ++jQuery.uuid;\n\t\t\t} else {\n\t\t\t\tid = jQuery.expando;\n\t\t\t}\n\t\t}\n\n\t\tif ( !cache[ id ] ) {\n\t\t\tcache[ id ] = {};\n\n\t\t\t// TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery\n\t\t\t// metadata on plain JS objects when the object is serialized using\n\t\t\t// JSON.stringify\n\t\t\tif ( !isNode ) {\n\t\t\t\tcache[ id ].toJSON = jQuery.noop;\n\t\t\t}\n\t\t}\n\n\t\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t\t// shallow copied over onto the existing cache\n\t\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\t\tif ( pvt ) {\n\t\t\t\tcache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);\n\t\t\t} else {\n\t\t\t\tcache[ id ] = jQuery.extend(cache[ id ], name);\n\t\t\t}\n\t\t}\n\n\t\tthisCache = cache[ id ];\n\n\t\t// Internal jQuery data is stored in a separate object inside the object's data\n\t\t// cache in order to avoid key collisions between internal data and user-defined\n\t\t// data\n\t\tif ( pvt ) {\n\t\t\tif ( !thisCache[ internalKey ] ) {\n\t\t\t\tthisCache[ internalKey ] = {};\n\t\t\t}\n\n\t\t\tthisCache = thisCache[ internalKey ];\n\t\t}\n\n\t\tif ( data !== undefined ) {\n\t\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t\t}\n\n\t\t// TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should\n\t\t// not attempt to inspect the internal events object using jQuery.data, as this\n\t\t// internal data object is undocumented and subject to change.\n\t\tif ( name === \"events\" && !thisCache[name] ) {\n\t\t\treturn thisCache[ internalKey ] && thisCache[ internalKey ].events;\n\t\t}\n\n\t\treturn getByName ? \n\t\t\t// Check for both converted-to-camel and non-converted data property names\n\t\t\tthisCache[ jQuery.camelCase( name ) ] || thisCache[ name ] :\n\t\t\tthisCache;\n\t},\n\n\tremoveData: function( elem, name, pvt /* Internal Use Only */ ) {\n\t\tif ( !jQuery.acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar internalKey = jQuery.expando, isNode = elem.nodeType,\n\n\t\t\t// See jQuery.data for more information\n\t\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t\t// See jQuery.data for more information\n\t\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t\t// If there is already no cache entry for this object, there is no\n\t\t// purpose in continuing\n\t\tif ( !cache[ id ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( name ) {\n\t\t\tvar thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];\n\n\t\t\tif ( thisCache ) {\n\t\t\t\tdelete thisCache[ name ];\n\n\t\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t\t// and let the cache object itself get destroyed\n\t\t\t\tif ( !isEmptyDataObject(thisCache) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// See jQuery.data for more information\n\t\tif ( pvt ) {\n\t\t\tdelete cache[ id ][ internalKey ];\n\n\t\t\t// Don't destroy the parent cache unless the internal data object\n\t\t\t// had been the only thing left in it\n\t\t\tif ( !isEmptyDataObject(cache[ id ]) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tvar internalCache = cache[ id ][ internalKey ];\n\n\t\t// Browsers that fail expando deletion also refuse to delete expandos on\n\t\t// the window, but it will allow it on all other JS objects; other browsers\n\t\t// don't care\n\t\tif ( jQuery.support.deleteExpando || cache != window ) {\n\t\t\tdelete cache[ id ];\n\t\t} else {\n\t\t\tcache[ id ] = null;\n\t\t}\n\n\t\t// We destroyed the entire user cache at once because it's faster than\n\t\t// iterating through each key, but we need to continue to persist internal\n\t\t// data if it existed\n\t\tif ( internalCache ) {\n\t\t\tcache[ id ] = {};\n\t\t\t// TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery\n\t\t\t// metadata on plain JS objects when the object is serialized using\n\t\t\t// JSON.stringify\n\t\t\tif ( !isNode ) {\n\t\t\t\tcache[ id ].toJSON = jQuery.noop;\n\t\t\t}\n\n\t\t\tcache[ id ][ internalKey ] = internalCache;\n\n\t\t// Otherwise, we need to eliminate the expando on the node to avoid\n\t\t// false lookups in the cache for entries that no longer exist\n\t\t} else if ( isNode ) {\n\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t// we must handle all of these cases\n\t\t\tif ( jQuery.support.deleteExpando ) {\n\t\t\t\tdelete elem[ jQuery.expando ];\n\t\t\t} else if ( elem.removeAttribute ) {\n\t\t\t\telem.removeAttribute( jQuery.expando );\n\t\t\t} else {\n\t\t\t\telem[ jQuery.expando ] = null;\n\t\t\t}\n\t\t}\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn jQuery.data( elem, name, data, true );\n\t},\n\n\t// A method for determining if a DOM node can handle the data expando\n\tacceptData: function( elem ) {\n\t\tif ( elem.nodeName ) {\n\t\t\tvar match = jQuery.noData[ elem.nodeName.toLowerCase() ];\n\n\t\t\tif ( match ) {\n\t\t\t\treturn !(match === true || elem.getAttribute(\"classid\") !== match);\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar data = null;\n\n\t\tif ( typeof key === \"undefined\" ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( this[0] );\n\n\t\t\t\tif ( this[0].nodeType === 1 ) {\n\t\t\t    var attr = this[0].attributes, name;\n\t\t\t\t\tfor ( var i = 0, l = attr.length; i < l; i++ ) {\n\t\t\t\t\t\tname = attr[i].name;\n\n\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\tname = jQuery.camelCase( name.substring(5) );\n\n\t\t\t\t\t\t\tdataAttr( this[0], name, data[ name ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t} else if ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\tvar parts = key.split(\".\");\n\t\tparts[1] = parts[1] ? \".\" + parts[1] : \"\";\n\n\t\tif ( value === undefined ) {\n\t\t\tdata = this.triggerHandler(\"getData\" + parts[1] + \"!\", [parts[0]]);\n\n\t\t\t// Try to fetch any internally stored data first\n\t\t\tif ( data === undefined && this.length ) {\n\t\t\t\tdata = jQuery.data( this[0], key );\n\t\t\t\tdata = dataAttr( this[0], key, data );\n\t\t\t}\n\n\t\t\treturn data === undefined && parts[1] ?\n\t\t\t\tthis.data( parts[0] ) :\n\t\t\t\tdata;\n\n\t\t} else {\n\t\t\treturn this.each(function() {\n\t\t\t\tvar $this = jQuery( this ),\n\t\t\t\t\targs = [ parts[0], value ];\n\n\t\t\t\t$this.triggerHandler( \"setData\" + parts[1] + \"!\", args );\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t\t$this.triggerHandler( \"changeData\" + parts[1] + \"!\", args );\n\t\t\t});\n\t\t}\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"$1-$2\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\tdata === \"false\" ? false :\n\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t!jQuery.isNaN( data ) ? parseFloat( data ) :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON\n// property to be considered empty objects; this property always exists in\n// order to make sure JSON.stringify does not expose internal metadata\nfunction isEmptyDataObject( obj ) {\n\tfor ( var name in obj ) {\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n\n\n\nfunction handleQueueMarkDefer( elem, type, src ) {\n\tvar deferDataKey = type + \"defer\",\n\t\tqueueDataKey = type + \"queue\",\n\t\tmarkDataKey = type + \"mark\",\n\t\tdefer = jQuery.data( elem, deferDataKey, undefined, true );\n\tif ( defer &&\n\t\t( src === \"queue\" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&\n\t\t( src === \"mark\" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {\n\t\t// Give room for hard-coded callbacks to fire first\n\t\t// and eventually mark/queue something else on the element\n\t\tsetTimeout( function() {\n\t\t\tif ( !jQuery.data( elem, queueDataKey, undefined, true ) &&\n\t\t\t\t!jQuery.data( elem, markDataKey, undefined, true ) ) {\n\t\t\t\tjQuery.removeData( elem, deferDataKey, true );\n\t\t\t\tdefer.resolve();\n\t\t\t}\n\t\t}, 0 );\n\t}\n}\n\njQuery.extend({\n\n\t_mark: function( elem, type ) {\n\t\tif ( elem ) {\n\t\t\ttype = (type || \"fx\") + \"mark\";\n\t\t\tjQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );\n\t\t}\n\t},\n\n\t_unmark: function( force, elem, type ) {\n\t\tif ( force !== true ) {\n\t\t\ttype = elem;\n\t\t\telem = force;\n\t\t\tforce = false;\n\t\t}\n\t\tif ( elem ) {\n\t\t\ttype = type || \"fx\";\n\t\t\tvar key = type + \"mark\",\n\t\t\t\tcount = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );\n\t\t\tif ( count ) {\n\t\t\t\tjQuery.data( elem, key, count, true );\n\t\t\t} else {\n\t\t\t\tjQuery.removeData( elem, key, true );\n\t\t\t\thandleQueueMarkDefer( elem, type, \"mark\" );\n\t\t\t}\n\t\t}\n\t},\n\n\tqueue: function( elem, type, data ) {\n\t\tif ( elem ) {\n\t\t\ttype = (type || \"fx\") + \"queue\";\n\t\t\tvar q = jQuery.data( elem, type, undefined, true );\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !q || jQuery.isArray(data) ) {\n\t\t\t\t\tq = jQuery.data( elem, type, jQuery.makeArray(data), true );\n\t\t\t\t} else {\n\t\t\t\t\tq.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn q || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tfn = queue.shift(),\n\t\t\tdefer;\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift(\"inprogress\");\n\t\t\t}\n\n\t\t\tfn.call(elem, function() {\n\t\t\t\tjQuery.dequeue(elem, type);\n\t\t\t});\n\t\t}\n\n\t\tif ( !queue.length ) {\n\t\t\tjQuery.removeData( elem, type + \"queue\", true );\n\t\t\thandleQueueMarkDefer( elem, type, \"queue\" );\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t}\n\n\t\tif ( data === undefined ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\t// Based off of the plugin by Clint Helfers, with permission.\n\t// http://blindsignals.com/index.php/2009/07/jquery-delay/\n\tdelay: function( time, type ) {\n\t\ttime = jQuery.fx ? jQuery.fx.speeds[time] || time : time;\n\t\ttype = type || \"fx\";\n\n\t\treturn this.queue( type, function() {\n\t\t\tvar elem = this;\n\t\t\tsetTimeout(function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t}, time );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, object ) {\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobject = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\t\tvar defer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = elements.length,\n\t\t\tcount = 1,\n\t\t\tdeferDataKey = type + \"defer\",\n\t\t\tqueueDataKey = type + \"queue\",\n\t\t\tmarkDataKey = type + \"mark\",\n\t\t\ttmp;\n\t\tfunction resolve() {\n\t\t\tif ( !( --count ) ) {\n\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t}\n\t\t}\n\t\twhile( i-- ) {\n\t\t\tif (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||\n\t\t\t\t\t( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||\n\t\t\t\t\t\tjQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&\n\t\t\t\t\tjQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.done( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise();\n\t}\n});\n\n\n\n\nvar rclass = /[\\n\\t\\r]/g,\n\trspace = /\\s+/,\n\trreturn = /\\r/g,\n\trtype = /^(?:button|input)$/i,\n\trfocusable = /^(?:button|input|object|select|textarea)$/i,\n\trclickable = /^a(?:rea)?$/i,\n\trboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,\n\trinvalidChar = /\\:|^on/,\n\tformHook, boolHook;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn jQuery.access( this, name, value, true, jQuery.attr );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t},\n\t\n\tprop: function( name, value ) {\n\t\treturn jQuery.access( this, name, value, true, jQuery.prop );\n\t},\n\t\n\tremoveProp: function( name ) {\n\t\tname = jQuery.propFix[ name ] || name;\n\t\treturn this.each(function() {\n\t\t\t// try/catch handles cases where IE balks (such as removing a property on window)\n\t\t\ttry {\n\t\t\t\tthis[ name ] = undefined;\n\t\t\t\tdelete this[ name ];\n\t\t\t} catch( e ) {}\n\t\t});\n\t},\n\n\taddClass: function( value ) {\n\t\tvar classNames, i, l, elem,\n\t\t\tsetClass, c, cl;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call(this, j, this.className) );\n\t\t\t});\n\t\t}\n\n\t\tif ( value && typeof value === \"string\" ) {\n\t\t\tclassNames = value.split( rspace );\n\n\t\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\telem = this[ i ];\n\n\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\tif ( !elem.className && classNames.length === 1 ) {\n\t\t\t\t\t\telem.className = value;\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsetClass = \" \" + elem.className + \" \";\n\n\t\t\t\t\t\tfor ( c = 0, cl = classNames.length; c < cl; c++ ) {\n\t\t\t\t\t\t\tif ( !~setClass.indexOf( \" \" + classNames[ c ] + \" \" ) ) {\n\t\t\t\t\t\t\t\tsetClass += classNames[ c ] + \" \";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telem.className = jQuery.trim( setClass );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classNames, i, l, elem, className, c, cl;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call(this, j, this.className) );\n\t\t\t});\n\t\t}\n\n\t\tif ( (value && typeof value === \"string\") || value === undefined ) {\n\t\t\tclassNames = (value || \"\").split( rspace );\n\n\t\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\telem = this[ i ];\n\n\t\t\t\tif ( elem.nodeType === 1 && elem.className ) {\n\t\t\t\t\tif ( value ) {\n\t\t\t\t\t\tclassName = (\" \" + elem.className + \" \").replace( rclass, \" \" );\n\t\t\t\t\t\tfor ( c = 0, cl = classNames.length; c < cl; c++ ) {\n\t\t\t\t\t\t\tclassName = className.replace(\" \" + classNames[ c ] + \" \", \" \");\n\t\t\t\t\t\t}\n\t\t\t\t\t\telem.className = jQuery.trim( className );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\telem.className = \"\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisBool = typeof stateVal === \"boolean\";\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tstate = stateVal,\n\t\t\t\t\tclassNames = value.split( rspace );\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space seperated list\n\t\t\t\t\tstate = isBool ? state : !self.hasClass( className );\n\t\t\t\t\tself[ state ? \"addClass\" : \"removeClass\" ]( className );\n\t\t\t\t}\n\n\t\t\t} else if ( type === \"undefined\" || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// toggle whole className\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \";\n\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\tif ( (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) > -1 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t},\n\n\tval: function( value ) {\n\t\tvar hooks, ret,\n\t\t\telem = this[0];\n\t\t\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ? \n\t\t\t\t\t// handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") : \n\t\t\t\t\t// handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t}\n\n\t\tvar isFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar self = jQuery(this), val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, self.val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map(val, function ( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// attributes.value is undefined in Blackberry 4.7 but\n\t\t\t\t// uses .value. See #6932\n\t\t\t\tvar val = elem.attributes.value;\n\t\t\t\treturn !val || val.specified ? elem.value : elem.text;\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tvalues = [],\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tone = elem.type === \"select-one\";\n\n\t\t\t\t// Nothing was selected\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {\n\t\t\t\t\tvar option = options[ i ];\n\n\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\tif ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null) &&\n\t\t\t\t\t\t\t(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" )) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fixes Bug #2551 -- select.val() broken in IE after form.reset()\n\t\t\t\tif ( one && !values.length && options.length ) {\n\t\t\t\t\treturn jQuery( options[ index ] ).val();\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar values = jQuery.makeArray( value );\n\n\t\t\t\tjQuery(elem).find(\"option\").each(function() {\n\t\t\t\t\tthis.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;\n\t\t\t\t});\n\n\t\t\t\tif ( !values.length ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t},\n\n\tattrFn: {\n\t\tval: true,\n\t\tcss: true,\n\t\thtml: true,\n\t\ttext: true,\n\t\tdata: true,\n\t\twidth: true,\n\t\theight: true,\n\t\toffset: true\n\t},\n\t\n\tattrFix: {\n\t\t// Always normalize to ensure hook usage\n\t\ttabindex: \"tabIndex\"\n\t},\n\t\n\tattr: function( elem, name, value, pass ) {\n\t\tvar nType = elem.nodeType;\n\t\t\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif ( pass && name in jQuery.attrFn ) {\n\t\t\treturn jQuery( elem )[ name ]( value );\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( !(\"getAttribute\" in elem) ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\tvar ret, hooks,\n\t\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\t// Normalize the name if needed\n\t\tif ( notxml ) {\n\t\t\tname = jQuery.attrFix[ name ] || name;\n\n\t\t\thooks = jQuery.attrHooks[ name ];\n\n\t\t\tif ( !hooks ) {\n\t\t\t\t// Use boolHook for boolean attributes\n\t\t\t\tif ( rboolean.test( name ) ) {\n\n\t\t\t\t\thooks = boolHook;\n\n\t\t\t\t// Use formHook for forms and if the name contains certain characters\n\t\t\t\t} else if ( formHook && name !== \"className\" &&\n\t\t\t\t\t(jQuery.nodeName( elem, \"form\" ) || rinvalidChar.test( name )) ) {\n\n\t\t\t\t\thooks = formHook;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn undefined;\n\n\t\t\t} else if ( hooks && \"set\" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, \"\" + value );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\n\t\t\tret = elem.getAttribute( name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret === null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, name ) {\n\t\tvar propName;\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tname = jQuery.attrFix[ name ] || name;\n\t\t\n\t\t\tif ( jQuery.support.getSetAttribute ) {\n\t\t\t\t// Use removeAttribute in browsers that support it\n\t\t\t\telem.removeAttribute( name );\n\t\t\t} else {\n\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\telem.removeAttributeNode( elem.getAttributeNode( name ) );\n\t\t\t}\n\n\t\t\t// Set corresponding property to false for boolean attributes\n\t\t\tif ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {\n\t\t\t\telem[ propName ] = false;\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\t// We can't allow the type property to be changed (since it causes problems in IE)\n\t\t\t\tif ( rtype.test( elem.nodeName ) && elem.parentNode ) {\n\t\t\t\t\tjQuery.error( \"type property can't be changed\" );\n\t\t\t\t} else if ( !jQuery.support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\t// Setting the type on a radio button after the value resets the value in IE6-9\n\t\t\t\t\t// Reset value to it's default in case type is set after value\n\t\t\t\t\t// This is for element creation\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n\t\t\t\t// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\tvar attributeNode = elem.getAttributeNode(\"tabIndex\");\n\n\t\t\t\treturn attributeNode && attributeNode.specified ?\n\t\t\t\t\tparseInt( attributeNode.value, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\tundefined;\n\t\t\t}\n\t\t},\n\t\t// Use the value property for back compat\n\t\t// Use the formHook for button elements in IE6/7 (#1954)\n\t\tvalue: {\n\t\t\tget: function( elem, name ) {\n\t\t\t\tif ( formHook && jQuery.nodeName( elem, \"button\" ) ) {\n\t\t\t\t\treturn formHook.get( elem, name );\n\t\t\t\t}\n\t\t\t\treturn name in elem ?\n\t\t\t\t\telem.value :\n\t\t\t\t\tnull;\n\t\t\t},\n\t\t\tset: function( elem, value, name ) {\n\t\t\t\tif ( formHook && jQuery.nodeName( elem, \"button\" ) ) {\n\t\t\t\t\treturn formHook.set( elem, value, name );\n\t\t\t\t}\n\t\t\t\t// Does not return so that setAttribute is also used\n\t\t\t\telem.value = value;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\ttabindex: \"tabIndex\",\n\t\treadonly: \"readOnly\",\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\",\n\t\tmaxlength: \"maxLength\",\n\t\tcellspacing: \"cellSpacing\",\n\t\tcellpadding: \"cellPadding\",\n\t\trowspan: \"rowSpan\",\n\t\tcolspan: \"colSpan\",\n\t\tusemap: \"useMap\",\n\t\tframeborder: \"frameBorder\",\n\t\tcontenteditable: \"contentEditable\"\n\t},\n\t\n\tprop: function( elem, name, value ) {\n\t\tvar nType = elem.nodeType;\n\n\t\t// don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tvar ret, hooks,\n\t\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\treturn (elem[ name ] = value);\n\t\t\t}\n\n\t\t} else {\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\treturn elem[ name ];\n\t\t\t}\n\t\t}\n\t},\n\t\n\tpropHooks: {}\n});\n\n// Hook for boolean attributes\nboolHook = {\n\tget: function( elem, name ) {\n\t\t// Align boolean attributes with corresponding properties\n\t\treturn jQuery.prop( elem, name ) ?\n\t\t\tname.toLowerCase() :\n\t\t\tundefined;\n\t},\n\tset: function( elem, value, name ) {\n\t\tvar propName;\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\t// value is true since we know at this point it's type boolean and not false\n\t\t\t// Set boolean attributes to the same name and set the DOM property\n\t\t\tpropName = jQuery.propFix[ name ] || name;\n\t\t\tif ( propName in elem ) {\n\t\t\t\t// Only set the IDL specifically if it already exists on the element\n\t\t\t\telem[ propName ] = true;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, name.toLowerCase() );\n\t\t}\n\t\treturn name;\n\t}\n};\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !jQuery.support.getSetAttribute ) {\n\n\t// propFix is more comprehensive and contains all fixes\n\tjQuery.attrFix = jQuery.propFix;\n\t\n\t// Use this for any attribute on a form in IE6/7\n\tformHook = jQuery.attrHooks.name = jQuery.attrHooks.title = jQuery.valHooks.button = {\n\t\tget: function( elem, name ) {\n\t\t\tvar ret;\n\t\t\tret = elem.getAttributeNode( name );\n\t\t\t// Return undefined if nodeValue is empty string\n\t\t\treturn ret && ret.nodeValue !== \"\" ?\n\t\t\t\tret.nodeValue :\n\t\t\t\tundefined;\n\t\t},\n\t\tset: function( elem, value, name ) {\n\t\t\t// Check form objects in IE (multiple bugs related)\n\t\t\t// Only use nodeValue if the attribute node exists on the form\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( ret ) {\n\t\t\t\tret.nodeValue = value;\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t};\n\n\t// Set width and height to auto instead of 0 on empty string( Bug #8150 )\n\t// This is for removals\n\tjQuery.each([ \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\telem.setAttribute( name, \"auto\" );\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n\n// Some attributes require a special call on IE\nif ( !jQuery.support.hrefNormalized ) {\n\tjQuery.each([ \"href\", \"src\", \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar ret = elem.getAttribute( name, 2 );\n\t\t\t\treturn ret === null ? undefined : ret;\n\t\t\t}\n\t\t});\n\t});\n}\n\nif ( !jQuery.support.style ) {\n\tjQuery.attrHooks.style = {\n\t\tget: function( elem ) {\n\t\t\t// Return undefined in the case of empty string\n\t\t\t// Normalize to lowercase since IE uppercases css property names\n\t\t\treturn elem.style.cssText.toLowerCase() || undefined;\n\t\t},\n\t\tset: function( elem, value ) {\n\t\t\treturn (elem.style.cssText = \"\" + value);\n\t\t}\n\t};\n}\n\n// Safari mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !jQuery.support.optSelected ) {\n\tjQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\t// Make sure that it also works with optgroups, see #5701\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n}\n\n// Radios and checkboxes getter/setter\nif ( !jQuery.support.checkOn ) {\n\tjQuery.each([ \"radio\", \"checkbox\" ], function() {\n\t\tjQuery.valHooks[ this ] = {\n\t\t\tget: function( elem ) {\n\t\t\t\t// Handle the case where in Webkit \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t\t}\n\t\t};\n\t});\n}\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);\n\t\t\t}\n\t\t}\n\t});\n});\n\n\n\n\nvar rnamespaces = /\\.(.*)$/,\n\trformElems = /^(?:textarea|input|select)$/i,\n\trperiod = /\\./g,\n\trspaces = / /g,\n\trescape = /[^\\w\\s.|`]/g,\n\tfcleanup = function( nm ) {\n\t\treturn nm.replace(rescape, \"\\\\$&\");\n\t};\n\n/*\n * A number of helper functions used for managing events.\n * Many of the ideas behind this code originated from\n * Dean Edwards' addEvent library.\n */\njQuery.event = {\n\n\t// Bind an event to an element\n\t// Original by Dean Edwards\n\tadd: function( elem, types, handler, data ) {\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( handler === false ) {\n\t\t\thandler = returnFalse;\n\t\t} else if ( !handler ) {\n\t\t\t// Fixes bug #7229. Fix recommended by jdalton\n\t\t\treturn;\n\t\t}\n\n\t\tvar handleObjIn, handleObj;\n\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t}\n\n\t\t// Make sure that the function being executed has a unique ID\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure\n\t\tvar elemData = jQuery._data( elem );\n\n\t\t// If no elemData is found then we must be trying to bind to one of the\n\t\t// banned noData elements\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar events = elemData.events,\n\t\t\teventHandle = elemData.handle;\n\n\t\tif ( !events ) {\n\t\t\telemData.events = events = {};\n\t\t}\n\n\t\tif ( !eventHandle ) {\n\t\t\telemData.handle = eventHandle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.handle.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t}\n\n\t\t// Add elem as a property of the handle function\n\t\t// This is to prevent a memory leak with non-native events in IE.\n\t\teventHandle.elem = elem;\n\n\t\t// Handle multiple events separated by a space\n\t\t// jQuery(...).bind(\"mouseover mouseout\", fn);\n\t\ttypes = types.split(\" \");\n\n\t\tvar type, i = 0, namespaces;\n\n\t\twhile ( (type = types[ i++ ]) ) {\n\t\t\thandleObj = handleObjIn ?\n\t\t\t\tjQuery.extend({}, handleObjIn) :\n\t\t\t\t{ handler: handler, data: data };\n\n\t\t\t// Namespaced event handlers\n\t\t\tif ( type.indexOf(\".\") > -1 ) {\n\t\t\t\tnamespaces = type.split(\".\");\n\t\t\t\ttype = namespaces.shift();\n\t\t\t\thandleObj.namespace = namespaces.slice(0).sort().join(\".\");\n\n\t\t\t} else {\n\t\t\t\tnamespaces = [];\n\t\t\t\thandleObj.namespace = \"\";\n\t\t\t}\n\n\t\t\thandleObj.type = type;\n\t\t\tif ( !handleObj.guid ) {\n\t\t\t\thandleObj.guid = handler.guid;\n\t\t\t}\n\n\t\t\t// Get the current list of functions bound to this event\n\t\t\tvar handlers = events[ type ],\n\t\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// Init the event handler queue\n\t\t\tif ( !handlers ) {\n\t\t\t\thandlers = events[ type ] = [];\n\n\t\t\t\t// Check for a special event handler\n\t\t\t\t// Only use addEventListener/attachEvent if the special\n\t\t\t\t// events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add the function to the element's handler list\n\t\t\thandlers.push( handleObj );\n\n\t\t\t// Keep track of which events have been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\tglobal: {},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, pos ) {\n\t\t// don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( handler === false ) {\n\t\t\thandler = returnFalse;\n\t\t}\n\n\t\tvar ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem ),\n\t\t\tevents = elemData && elemData.events;\n\n\t\tif ( !elemData || !events ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// types is actually an event object here\n\t\tif ( types && types.type ) {\n\t\t\thandler = types.handler;\n\t\t\ttypes = types.type;\n\t\t}\n\n\t\t// Unbind all events for the element\n\t\tif ( !types || typeof types === \"string\" && types.charAt(0) === \".\" ) {\n\t\t\ttypes = types || \"\";\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tjQuery.event.remove( elem, type + types );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\t// jQuery(...).unbind(\"mouseover mouseout\", fn);\n\t\ttypes = types.split(\" \");\n\n\t\twhile ( (type = types[ i++ ]) ) {\n\t\t\torigType = type;\n\t\t\thandleObj = null;\n\t\t\tall = type.indexOf(\".\") < 0;\n\t\t\tnamespaces = [];\n\n\t\t\tif ( !all ) {\n\t\t\t\t// Namespaced event handlers\n\t\t\t\tnamespaces = type.split(\".\");\n\t\t\t\ttype = namespaces.shift();\n\n\t\t\t\tnamespace = new RegExp(\"(^|\\\\.)\" +\n\t\t\t\t\tjQuery.map( namespaces.slice(0).sort(), fcleanup ).join(\"\\\\.(?:.*\\\\.)?\") + \"(\\\\.|$)\");\n\t\t\t}\n\n\t\t\teventType = events[ type ];\n\n\t\t\tif ( !eventType ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( !handler ) {\n\t\t\t\tfor ( j = 0; j < eventType.length; j++ ) {\n\t\t\t\t\thandleObj = eventType[ j ];\n\n\t\t\t\t\tif ( all || namespace.test( handleObj.namespace ) ) {\n\t\t\t\t\t\tjQuery.event.remove( elem, origType, handleObj.handler, j );\n\t\t\t\t\t\teventType.splice( j--, 1 );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\tfor ( j = pos || 0; j < eventType.length; j++ ) {\n\t\t\t\thandleObj = eventType[ j ];\n\n\t\t\t\tif ( handler.guid === handleObj.guid ) {\n\t\t\t\t\t// remove the given handler for the given type\n\t\t\t\t\tif ( all || namespace.test( handleObj.namespace ) ) {\n\t\t\t\t\t\tif ( pos == null ) {\n\t\t\t\t\t\t\teventType.splice( j--, 1 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( pos != null ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// remove generic event handler if no more handlers exist\n\t\t\tif ( eventType.length === 0 || pos != null && eventType.length === 1 ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tret = null;\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tvar handle = elemData.handle;\n\t\t\tif ( handle ) {\n\t\t\t\thandle.elem = null;\n\t\t\t}\n\n\t\t\tdelete elemData.events;\n\t\t\tdelete elemData.handle;\n\n\t\t\tif ( jQuery.isEmptyObject( elemData ) ) {\n\t\t\t\tjQuery.removeData( elem, undefined, true );\n\t\t\t}\n\t\t}\n\t},\n\t\n\t// Events that are safe to short-circuit if no handlers are attached.\n\t// Native DOM events should not be added, they may have inline handlers.\n\tcustomEvent: {\n\t\t\"getData\": true,\n\t\t\"setData\": true,\n\t\t\"changeData\": true\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\t// Event object or event type\n\t\tvar type = event.type || event,\n\t\t\tnamespaces = [],\n\t\t\texclusive;\n\n\t\tif ( type.indexOf(\"!\") >= 0 ) {\n\t\t\t// Exclusive events trigger only for the exact event (no namespaces)\n\t\t\ttype = type.slice(0, -1);\n\t\t\texclusive = true;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\n\t\tif ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {\n\t\t\t// No jQuery handlers for this event type, and it can't have inline handlers\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an Event, Object, or just an event type string\n\t\tevent = typeof event === \"object\" ?\n\t\t\t// jQuery.Event object\n\t\t\tevent[ jQuery.expando ] ? event :\n\t\t\t// Object literal\n\t\t\tnew jQuery.Event( type, event ) :\n\t\t\t// Just the event type (string)\n\t\t\tnew jQuery.Event( type );\n\n\t\tevent.type = type;\n\t\tevent.exclusive = exclusive;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = new RegExp(\"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.)?\") + \"(\\\\.|$)\");\n\t\t\n\t\t// triggerHandler() and global events don't bubble or run the default action\n\t\tif ( onlyHandlers || !elem ) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\n\t\t// Handle a global trigger\n\t\tif ( !elem ) {\n\t\t\t// TODO: Stop taunting the data cache; remove global events and always attach to document\n\t\t\tjQuery.each( jQuery.cache, function() {\n\t\t\t\t// internalKey variable is just used to make it easier to find\n\t\t\t\t// and potentially change this stuff later; currently it just\n\t\t\t\t// points to jQuery.expando\n\t\t\t\tvar internalKey = jQuery.expando,\n\t\t\t\t\tinternalCache = this[ internalKey ];\n\t\t\t\tif ( internalCache && internalCache.events && internalCache.events[ type ] ) {\n\t\t\t\t\tjQuery.event.trigger( event, data, internalCache.handle.elem );\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tevent.target = elem;\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data != null ? jQuery.makeArray( data ) : [];\n\t\tdata.unshift( event );\n\n\t\tvar cur = elem,\n\t\t\t// IE doesn't like method names with a colon (#3533, #8272)\n\t\t\tontype = type.indexOf(\":\") < 0 ? \"on\" + type : \"\";\n\n\t\t// Fire event on the current element, then bubble up the DOM tree\n\t\tdo {\n\t\t\tvar handle = jQuery._data( cur, \"handle\" );\n\n\t\t\tevent.currentTarget = cur;\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Trigger an inline bound script\n\t\t\tif ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {\n\t\t\t\tevent.result = false;\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\n\t\t\t// Bubble up to document, then to window\n\t\t\tcur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;\n\t\t} while ( cur && !event.isPropagationStopped() );\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !event.isDefaultPrevented() ) {\n\t\t\tvar old,\n\t\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\tif ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&\n\t\t\t\t!(type === \"click\" && jQuery.nodeName( elem, \"a\" )) && jQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction)() check here because IE6/7 fails that test.\n\t\t\t\t// IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.\n\t\t\t\ttry {\n\t\t\t\t\tif ( ontype && elem[ type ] ) {\n\t\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\t\told = elem[ ontype ];\n\n\t\t\t\t\t\tif ( old ) {\n\t\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t}\n\t\t\t\t} catch ( ieError ) {}\n\n\t\t\t\tif ( old ) {\n\t\t\t\t\telem[ ontype ] = old;\n\t\t\t\t}\n\n\t\t\t\tjQuery.event.triggered = undefined;\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn event.result;\n\t},\n\n\thandle: function( event ) {\n\t\tevent = jQuery.event.fix( event || window.event );\n\t\t// Snapshot the handlers list since a called handler may add/remove events.\n\t\tvar handlers = ((jQuery._data( this, \"events\" ) || {})[ event.type ] || []).slice(0),\n\t\t\trun_all = !event.exclusive && !event.namespace,\n\t\t\targs = Array.prototype.slice.call( arguments, 0 );\n\n\t\t// Use the fix-ed Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.currentTarget = this;\n\n\t\tfor ( var j = 0, l = handlers.length; j < l; j++ ) {\n\t\t\tvar handleObj = handlers[ j ];\n\n\t\t\t// Triggered event must 1) be non-exclusive and have no namespace, or\n\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event.\n\t\t\tif ( run_all || event.namespace_re.test( handleObj.namespace ) ) {\n\t\t\t\t// Pass in a reference to the handler function itself\n\t\t\t\t// So that we can later remove it\n\t\t\t\tevent.handler = handleObj.handler;\n\t\t\t\tevent.data = handleObj.data;\n\t\t\t\tevent.handleObj = handleObj;\n\n\t\t\t\tvar ret = handleObj.handler.apply( this, args );\n\n\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\tevent.result = ret;\n\t\t\t\t\tif ( ret === false ) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( event.isImmediatePropagationStopped() ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn event.result;\n\t},\n\n\tprops: \"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(\" \"),\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// store a copy of the original event object\n\t\t// and \"clone\" to set read-only properties\n\t\tvar originalEvent = event;\n\t\tevent = jQuery.Event( originalEvent );\n\n\t\tfor ( var i = this.props.length, prop; i; ) {\n\t\t\tprop = this.props[ --i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Fix target property, if necessary\n\t\tif ( !event.target ) {\n\t\t\t// Fixes #1925 where srcElement might not be defined either\n\t\t\tevent.target = event.srcElement || document;\n\t\t}\n\n\t\t// check if target is a textnode (safari)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// Add relatedTarget, if necessary\n\t\tif ( !event.relatedTarget && event.fromElement ) {\n\t\t\tevent.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;\n\t\t}\n\n\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\tif ( event.pageX == null && event.clientX != null ) {\n\t\t\tvar eventDocument = event.target.ownerDocument || document,\n\t\t\t\tdoc = eventDocument.documentElement,\n\t\t\t\tbody = eventDocument.body;\n\n\t\t\tevent.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);\n\t\t\tevent.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);\n\t\t}\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && (event.charCode != null || event.keyCode != null) ) {\n\t\t\tevent.which = event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)\n\t\tif ( !event.metaKey && event.ctrlKey ) {\n\t\t\tevent.metaKey = event.ctrlKey;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t// Note: button is not normalized, so don't use it\n\t\tif ( !event.which && event.button !== undefined ) {\n\t\t\tevent.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));\n\t\t}\n\n\t\treturn event;\n\t},\n\n\t// Deprecated, use jQuery.guid instead\n\tguid: 1E8,\n\n\t// Deprecated, use jQuery.proxy instead\n\tproxy: jQuery.proxy,\n\n\tspecial: {\n\t\tready: {\n\t\t\t// Make sure the ready event is setup\n\t\t\tsetup: jQuery.bindReady,\n\t\t\tteardown: jQuery.noop\n\t\t},\n\n\t\tlive: {\n\t\t\tadd: function( handleObj ) {\n\t\t\t\tjQuery.event.add( this,\n\t\t\t\t\tliveConvert( handleObj.origType, handleObj.selector ),\n\t\t\t\t\tjQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );\n\t\t\t},\n\n\t\t\tremove: function( handleObj ) {\n\t\t\t\tjQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tsetup: function( data, namespaces, eventHandle ) {\n\t\t\t\t// We only want to do this special case on windows\n\t\t\t\tif ( jQuery.isWindow( this ) ) {\n\t\t\t\t\tthis.onbeforeunload = eventHandle;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tteardown: function( namespaces, eventHandle ) {\n\t\t\t\tif ( this.onbeforeunload === eventHandle ) {\n\t\t\t\t\tthis.onbeforeunload = null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.detachEvent ) {\n\t\t\telem.detachEvent( \"on\" + type, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !this.preventDefault ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||\n\t\t\tsrc.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// timeStamp is buggy for some events on Firefox(#3843)\n\t// So we won't rely on the native value\n\tthis.timeStamp = jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\nfunction returnFalse() {\n\treturn false;\n}\nfunction returnTrue() {\n\treturn true;\n}\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tpreventDefault: function() {\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tvar e = this.originalEvent;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// if preventDefault exists run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// otherwise set the returnValue property of the original event to false (IE)\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tvar e = this.originalEvent;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// if stopPropagation exists run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t\t// otherwise set the cancelBubble property of the original event to true (IE)\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\t\tthis.stopPropagation();\n\t},\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse\n};\n\n// Checks if an event happened on an element within another element\n// Used in jQuery.event.special.mouseenter and mouseleave handlers\nvar withinElement = function( event ) {\n\n\t// Check if mouse(over|out) are still within the same parent element\n\tvar related = event.relatedTarget,\n\t\tinside = false,\n\t\teventType = event.type;\n\n\tevent.type = event.data;\n\n\tif ( related !== this ) {\n\n\t\tif ( related ) {\n\t\t\tinside = jQuery.contains( this, related );\n\t\t}\n\n\t\tif ( !inside ) {\n\n\t\t\tjQuery.event.handle.apply( this, arguments );\n\n\t\t\tevent.type = eventType;\n\t\t}\n\t}\n},\n\n// In case of event delegation, we only need to rename the event.type,\n// liveHandler will take care of the rest.\ndelegate = function( event ) {\n\tevent.type = event.data;\n\tjQuery.event.handle.apply( this, arguments );\n};\n\n// Create mouseenter and mouseleave events\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tsetup: function( data ) {\n\t\t\tjQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );\n\t\t},\n\t\tteardown: function( data ) {\n\t\t\tjQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );\n\t\t}\n\t};\n});\n\n// submit delegation\nif ( !jQuery.support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function( data, namespaces ) {\n\t\t\tif ( !jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\tjQuery.event.add(this, \"click.specialSubmit\", function( e ) {\n\t\t\t\t\tvar elem = e.target,\n\t\t\t\t\t\ttype = elem.type;\n\n\t\t\t\t\tif ( (type === \"submit\" || type === \"image\") && jQuery( elem ).closest(\"form\").length ) {\n\t\t\t\t\t\ttrigger( \"submit\", this, arguments );\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tjQuery.event.add(this, \"keypress.specialSubmit\", function( e ) {\n\t\t\t\t\tvar elem = e.target,\n\t\t\t\t\t\ttype = elem.type;\n\n\t\t\t\t\tif ( (type === \"text\" || type === \"password\") && jQuery( elem ).closest(\"form\").length && e.keyCode === 13 ) {\n\t\t\t\t\t\ttrigger( \"submit\", this, arguments );\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\n\t\tteardown: function( namespaces ) {\n\t\t\tjQuery.event.remove( this, \".specialSubmit\" );\n\t\t}\n\t};\n\n}\n\n// change delegation, happens here so we have bind.\nif ( !jQuery.support.changeBubbles ) {\n\n\tvar changeFilters,\n\n\tgetVal = function( elem ) {\n\t\tvar type = elem.type, val = elem.value;\n\n\t\tif ( type === \"radio\" || type === \"checkbox\" ) {\n\t\t\tval = elem.checked;\n\n\t\t} else if ( type === \"select-multiple\" ) {\n\t\t\tval = elem.selectedIndex > -1 ?\n\t\t\t\tjQuery.map( elem.options, function( elem ) {\n\t\t\t\t\treturn elem.selected;\n\t\t\t\t}).join(\"-\") :\n\t\t\t\t\"\";\n\n\t\t} else if ( jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\tval = elem.selectedIndex;\n\t\t}\n\n\t\treturn val;\n\t},\n\n\ttestChange = function testChange( e ) {\n\t\tvar elem = e.target, data, val;\n\n\t\tif ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdata = jQuery._data( elem, \"_change_data\" );\n\t\tval = getVal(elem);\n\n\t\t// the current data will be also retrieved by beforeactivate\n\t\tif ( e.type !== \"focusout\" || elem.type !== \"radio\" ) {\n\t\t\tjQuery._data( elem, \"_change_data\", val );\n\t\t}\n\n\t\tif ( data === undefined || val === data ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( data != null || val ) {\n\t\t\te.type = \"change\";\n\t\t\te.liveFired = undefined;\n\t\t\tjQuery.event.trigger( e, arguments[1], elem );\n\t\t}\n\t};\n\n\tjQuery.event.special.change = {\n\t\tfilters: {\n\t\t\tfocusout: testChange,\n\n\t\t\tbeforedeactivate: testChange,\n\n\t\t\tclick: function( e ) {\n\t\t\t\tvar elem = e.target, type = jQuery.nodeName( elem, \"input\" ) ? elem.type : \"\";\n\n\t\t\t\tif ( type === \"radio\" || type === \"checkbox\" || jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\t\ttestChange.call( this, e );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// Change has to be called before submit\n\t\t\t// Keydown will be called before keypress, which is used in submit-event delegation\n\t\t\tkeydown: function( e ) {\n\t\t\t\tvar elem = e.target, type = jQuery.nodeName( elem, \"input\" ) ? elem.type : \"\";\n\n\t\t\t\tif ( (e.keyCode === 13 && !jQuery.nodeName( elem, \"textarea\" ) ) ||\n\t\t\t\t\t(e.keyCode === 32 && (type === \"checkbox\" || type === \"radio\")) ||\n\t\t\t\t\ttype === \"select-multiple\" ) {\n\t\t\t\t\ttestChange.call( this, e );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// Beforeactivate happens also before the previous element is blurred\n\t\t\t// with this event you can't trigger a change event, but you can store\n\t\t\t// information\n\t\t\tbeforeactivate: function( e ) {\n\t\t\t\tvar elem = e.target;\n\t\t\t\tjQuery._data( elem, \"_change_data\", getVal(elem) );\n\t\t\t}\n\t\t},\n\n\t\tsetup: function( data, namespaces ) {\n\t\t\tif ( this.type === \"file\" ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfor ( var type in changeFilters ) {\n\t\t\t\tjQuery.event.add( this, type + \".specialChange\", changeFilters[type] );\n\t\t\t}\n\n\t\t\treturn rformElems.test( this.nodeName );\n\t\t},\n\n\t\tteardown: function( namespaces ) {\n\t\t\tjQuery.event.remove( this, \".specialChange\" );\n\n\t\t\treturn rformElems.test( this.nodeName );\n\t\t}\n\t};\n\n\tchangeFilters = jQuery.event.special.change.filters;\n\n\t// Handle when the input is .focus()'d\n\tchangeFilters.focus = changeFilters.beforeactivate;\n}\n\nfunction trigger( type, elem, args ) {\n\t// Piggyback on a donor event to simulate a different one.\n\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t// simulated event prevents default then we do the same on the donor.\n\t// Don't pass args or remember liveFired; they apply to the donor event.\n\tvar event = jQuery.extend( {}, args[ 0 ] );\n\tevent.type = type;\n\tevent.originalEvent = {};\n\tevent.liveFired = undefined;\n\tjQuery.event.handle.call( elem, event );\n\tif ( event.isDefaultPrevented() ) {\n\t\targs[ 0 ].preventDefault();\n\t}\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !jQuery.support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler while someone wants focusin/focusout\n\t\tvar attaches = 0;\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tif ( attaches++ === 0 ) {\n\t\t\t\t\tdocument.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tif ( --attaches === 0 ) {\n\t\t\t\t\tdocument.removeEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tfunction handler( donor ) {\n\t\t\t// Donor event is always a native one; fix it and switch its type.\n\t\t\t// Let focusin/out handler cancel the donor focus/blur event.\n\t\t\tvar e = jQuery.event.fix( donor );\n\t\t\te.type = fix;\n\t\t\te.originalEvent = {};\n\t\t\tjQuery.event.trigger( e, null, e.target );\n\t\t\tif ( e.isDefaultPrevented() ) {\n\t\t\t\tdonor.preventDefault();\n\t\t\t}\n\t\t}\n\t});\n}\n\njQuery.each([\"bind\", \"one\"], function( i, name ) {\n\tjQuery.fn[ name ] = function( type, data, fn ) {\n\t\tvar handler;\n\n\t\t// Handle object literals\n\t\tif ( typeof type === \"object\" ) {\n\t\t\tfor ( var key in type ) {\n\t\t\t\tthis[ name ](key, data, type[key], fn);\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( arguments.length === 2 || data === false ) {\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\tif ( name === \"one\" ) {\n\t\t\thandler = function( event ) {\n\t\t\t\tjQuery( this ).unbind( event, handler );\n\t\t\t\treturn fn.apply( this, arguments );\n\t\t\t};\n\t\t\thandler.guid = fn.guid || jQuery.guid++;\n\t\t} else {\n\t\t\thandler = fn;\n\t\t}\n\n\t\tif ( type === \"unload\" && name !== \"one\" ) {\n\t\t\tthis.one( type, data, fn );\n\n\t\t} else {\n\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( this[i], type, handler, data );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n});\n\njQuery.fn.extend({\n\tunbind: function( type, fn ) {\n\t\t// Handle object literals\n\t\tif ( typeof type === \"object\" && !type.preventDefault ) {\n\t\t\tfor ( var key in type ) {\n\t\t\t\tthis.unbind(key, type[key]);\n\t\t\t}\n\n\t\t} else {\n\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\tjQuery.event.remove( this[i], type, fn );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.live( types, data, fn, selector );\n\t},\n\n\tundelegate: function( selector, types, fn ) {\n\t\tif ( arguments.length === 0 ) {\n\t\t\treturn this.unbind( \"live\" );\n\n\t\t} else {\n\t\t\treturn this.die( types, null, fn, selector );\n\t\t}\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\n\ttriggerHandler: function( type, data ) {\n\t\tif ( this[0] ) {\n\t\t\treturn jQuery.event.trigger( type, data, this[0], true );\n\t\t}\n\t},\n\n\ttoggle: function( fn ) {\n\t\t// Save reference to arguments for access in closure\n\t\tvar args = arguments,\n\t\t\tguid = fn.guid || jQuery.guid++,\n\t\t\ti = 0,\n\t\t\ttoggler = function( event ) {\n\t\t\t\t// Figure out which function to execute\n\t\t\t\tvar lastToggle = ( jQuery.data( this, \"lastToggle\" + fn.guid ) || 0 ) % i;\n\t\t\t\tjQuery.data( this, \"lastToggle\" + fn.guid, lastToggle + 1 );\n\n\t\t\t\t// Make sure that clicks stop\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\t// and execute the function\n\t\t\t\treturn args[ lastToggle ].apply( this, arguments ) || false;\n\t\t\t};\n\n\t\t// link all the functions, so any of them can unbind this click handler\n\t\ttoggler.guid = guid;\n\t\twhile ( i < args.length ) {\n\t\t\targs[ i++ ].guid = guid;\n\t\t}\n\n\t\treturn this.click( toggler );\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n});\n\nvar liveMap = {\n\tfocus: \"focusin\",\n\tblur: \"focusout\",\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\"\n};\n\njQuery.each([\"live\", \"die\"], function( i, name ) {\n\tjQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {\n\t\tvar type, i = 0, match, namespaces, preType,\n\t\t\tselector = origSelector || this.selector,\n\t\t\tcontext = origSelector ? this : jQuery( this.context );\n\n\t\tif ( typeof types === \"object\" && !types.preventDefault ) {\n\t\t\tfor ( var key in types ) {\n\t\t\t\tcontext[ name ]( key, data, types[key], selector );\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( name === \"die\" && !types &&\n\t\t\t\t\torigSelector && origSelector.charAt(0) === \".\" ) {\n\n\t\t\tcontext.unbind( origSelector );\n\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data === false || jQuery.isFunction( data ) ) {\n\t\t\tfn = data || returnFalse;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\ttypes = (types || \"\").split(\" \");\n\n\t\twhile ( (type = types[ i++ ]) != null ) {\n\t\t\tmatch = rnamespaces.exec( type );\n\t\t\tnamespaces = \"\";\n\n\t\t\tif ( match )  {\n\t\t\t\tnamespaces = match[0];\n\t\t\t\ttype = type.replace( rnamespaces, \"\" );\n\t\t\t}\n\n\t\t\tif ( type === \"hover\" ) {\n\t\t\t\ttypes.push( \"mouseenter\" + namespaces, \"mouseleave\" + namespaces );\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tpreType = type;\n\n\t\t\tif ( liveMap[ type ] ) {\n\t\t\t\ttypes.push( liveMap[ type ] + namespaces );\n\t\t\t\ttype = type + namespaces;\n\n\t\t\t} else {\n\t\t\t\ttype = (liveMap[ type ] || type) + namespaces;\n\t\t\t}\n\n\t\t\tif ( name === \"live\" ) {\n\t\t\t\t// bind live handler\n\t\t\t\tfor ( var j = 0, l = context.length; j < l; j++ ) {\n\t\t\t\t\tjQuery.event.add( context[j], \"live.\" + liveConvert( type, selector ),\n\t\t\t\t\t\t{ data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\t// unbind live handler\n\t\t\t\tcontext.unbind( \"live.\" + liveConvert( type, selector ), fn );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n});\n\nfunction liveHandler( event ) {\n\tvar stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,\n\t\telems = [],\n\t\tselectors = [],\n\t\tevents = jQuery._data( this, \"events\" );\n\n\t// Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)\n\tif ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === \"click\" ) {\n\t\treturn;\n\t}\n\n\tif ( event.namespace ) {\n\t\tnamespace = new RegExp(\"(^|\\\\.)\" + event.namespace.split(\".\").join(\"\\\\.(?:.*\\\\.)?\") + \"(\\\\.|$)\");\n\t}\n\n\tevent.liveFired = this;\n\n\tvar live = events.live.slice(0);\n\n\tfor ( j = 0; j < live.length; j++ ) {\n\t\thandleObj = live[j];\n\n\t\tif ( handleObj.origType.replace( rnamespaces, \"\" ) === event.type ) {\n\t\t\tselectors.push( handleObj.selector );\n\n\t\t} else {\n\t\t\tlive.splice( j--, 1 );\n\t\t}\n\t}\n\n\tmatch = jQuery( event.target ).closest( selectors, event.currentTarget );\n\n\tfor ( i = 0, l = match.length; i < l; i++ ) {\n\t\tclose = match[i];\n\n\t\tfor ( j = 0; j < live.length; j++ ) {\n\t\t\thandleObj = live[j];\n\n\t\t\tif ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {\n\t\t\t\telem = close.elem;\n\t\t\t\trelated = null;\n\n\t\t\t\t// Those two events require additional checking\n\t\t\t\tif ( handleObj.preType === \"mouseenter\" || handleObj.preType === \"mouseleave\" ) {\n\t\t\t\t\tevent.type = handleObj.preType;\n\t\t\t\t\trelated = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];\n\n\t\t\t\t\t// Make sure not to accidentally match a child element with the same selector\n\t\t\t\t\tif ( related && jQuery.contains( elem, related ) ) {\n\t\t\t\t\t\trelated = elem;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( !related || related !== elem ) {\n\t\t\t\t\telems.push({ elem: elem, handleObj: handleObj, level: close.level });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfor ( i = 0, l = elems.length; i < l; i++ ) {\n\t\tmatch = elems[i];\n\n\t\tif ( maxLevel && match.level > maxLevel ) {\n\t\t\tbreak;\n\t\t}\n\n\t\tevent.currentTarget = match.elem;\n\t\tevent.data = match.handleObj.data;\n\t\tevent.handleObj = match.handleObj;\n\n\t\tret = match.handleObj.origHandler.apply( match.elem, arguments );\n\n\t\tif ( ret === false || event.isPropagationStopped() ) {\n\t\t\tmaxLevel = match.level;\n\n\t\t\tif ( ret === false ) {\n\t\t\t\tstop = false;\n\t\t\t}\n\t\t\tif ( event.isImmediatePropagationStopped() ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn stop;\n}\n\nfunction liveConvert( type, selector ) {\n\treturn (type && type !== \"*\" ? type + \".\" : \"\") + selector.replace(rperiod, \"`\").replace(rspaces, \"&\");\n}\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\tif ( fn == null ) {\n\t\t\tfn = data;\n\t\t\tdata = null;\n\t\t}\n\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.bind( name, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n\n\tif ( jQuery.attrFn ) {\n\t\tjQuery.attrFn[ name ] = true;\n\t}\n});\n\n\n\n/*!\n * Sizzle CSS Selector Engine\n *  Copyright 2011, The Dojo Foundation\n *  Released under the MIT, BSD, and GPL Licenses.\n *  More information: http://sizzlejs.com/\n */\n(function(){\n\nvar chunker = /((?:\\((?:\\([^()]+\\)|[^()]+)+\\)|\\[(?:\\[[^\\[\\]]*\\]|['\"][^'\"]*['\"]|[^\\[\\]'\"]+)+\\]|\\\\.|[^ >+~,(\\[\\\\]+)+|[>+~])(\\s*,\\s*)?((?:.|\\r|\\n)*)/g,\n\tdone = 0,\n\ttoString = Object.prototype.toString,\n\thasDuplicate = false,\n\tbaseHasDuplicate = true,\n\trBackslash = /\\\\/g,\n\trNonWord = /\\W/;\n\n// Here we check if the JavaScript engine is using some sort of\n// optimization where it does not always call our comparision\n// function. If that is the case, discard the hasDuplicate value.\n//   Thus far that includes Google Chrome.\n[0, 0].sort(function() {\n\tbaseHasDuplicate = false;\n\treturn 0;\n});\n\nvar Sizzle = function( selector, context, results, seed ) {\n\tresults = results || [];\n\tcontext = context || document;\n\n\tvar origContext = context;\n\n\tif ( context.nodeType !== 1 && context.nodeType !== 9 ) {\n\t\treturn [];\n\t}\n\t\n\tif ( !selector || typeof selector !== \"string\" ) {\n\t\treturn results;\n\t}\n\n\tvar m, set, checkSet, extra, ret, cur, pop, i,\n\t\tprune = true,\n\t\tcontextXML = Sizzle.isXML( context ),\n\t\tparts = [],\n\t\tsoFar = selector;\n\t\n\t// Reset the position of the chunker regexp (start from head)\n\tdo {\n\t\tchunker.exec( \"\" );\n\t\tm = chunker.exec( soFar );\n\n\t\tif ( m ) {\n\t\t\tsoFar = m[3];\n\t\t\n\t\t\tparts.push( m[1] );\n\t\t\n\t\t\tif ( m[2] ) {\n\t\t\t\textra = m[3];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} while ( m );\n\n\tif ( parts.length > 1 && origPOS.exec( selector ) ) {\n\n\t\tif ( parts.length === 2 && Expr.relative[ parts[0] ] ) {\n\t\t\tset = posProcess( parts[0] + parts[1], context );\n\n\t\t} else {\n\t\t\tset = Expr.relative[ parts[0] ] ?\n\t\t\t\t[ context ] :\n\t\t\t\tSizzle( parts.shift(), context );\n\n\t\t\twhile ( parts.length ) {\n\t\t\t\tselector = parts.shift();\n\n\t\t\t\tif ( Expr.relative[ selector ] ) {\n\t\t\t\t\tselector += parts.shift();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tset = posProcess( selector, set );\n\t\t\t}\n\t\t}\n\n\t} else {\n\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\t// (but not if it'll be faster if the inner selector is an ID)\n\t\tif ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&\n\t\t\t\tExpr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {\n\n\t\t\tret = Sizzle.find( parts.shift(), context, contextXML );\n\t\t\tcontext = ret.expr ?\n\t\t\t\tSizzle.filter( ret.expr, ret.set )[0] :\n\t\t\t\tret.set[0];\n\t\t}\n\n\t\tif ( context ) {\n\t\t\tret = seed ?\n\t\t\t\t{ expr: parts.pop(), set: makeArray(seed) } :\n\t\t\t\tSizzle.find( parts.pop(), parts.length === 1 && (parts[0] === \"~\" || parts[0] === \"+\") && context.parentNode ? context.parentNode : context, contextXML );\n\n\t\t\tset = ret.expr ?\n\t\t\t\tSizzle.filter( ret.expr, ret.set ) :\n\t\t\t\tret.set;\n\n\t\t\tif ( parts.length > 0 ) {\n\t\t\t\tcheckSet = makeArray( set );\n\n\t\t\t} else {\n\t\t\t\tprune = false;\n\t\t\t}\n\n\t\t\twhile ( parts.length ) {\n\t\t\t\tcur = parts.pop();\n\t\t\t\tpop = cur;\n\n\t\t\t\tif ( !Expr.relative[ cur ] ) {\n\t\t\t\t\tcur = \"\";\n\t\t\t\t} else {\n\t\t\t\t\tpop = parts.pop();\n\t\t\t\t}\n\n\t\t\t\tif ( pop == null ) {\n\t\t\t\t\tpop = context;\n\t\t\t\t}\n\n\t\t\t\tExpr.relative[ cur ]( checkSet, pop, contextXML );\n\t\t\t}\n\n\t\t} else {\n\t\t\tcheckSet = parts = [];\n\t\t}\n\t}\n\n\tif ( !checkSet ) {\n\t\tcheckSet = set;\n\t}\n\n\tif ( !checkSet ) {\n\t\tSizzle.error( cur || selector );\n\t}\n\n\tif ( toString.call(checkSet) === \"[object Array]\" ) {\n\t\tif ( !prune ) {\n\t\t\tresults.push.apply( results, checkSet );\n\n\t\t} else if ( context && context.nodeType === 1 ) {\n\t\t\tfor ( i = 0; checkSet[i] != null; i++ ) {\n\t\t\t\tif ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {\n\t\t\t\t\tresults.push( set[i] );\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\t\t\tfor ( i = 0; checkSet[i] != null; i++ ) {\n\t\t\t\tif ( checkSet[i] && checkSet[i].nodeType === 1 ) {\n\t\t\t\t\tresults.push( set[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t} else {\n\t\tmakeArray( checkSet, results );\n\t}\n\n\tif ( extra ) {\n\t\tSizzle( extra, origContext, results, seed );\n\t\tSizzle.uniqueSort( results );\n\t}\n\n\treturn results;\n};\n\nSizzle.uniqueSort = function( results ) {\n\tif ( sortOrder ) {\n\t\thasDuplicate = baseHasDuplicate;\n\t\tresults.sort( sortOrder );\n\n\t\tif ( hasDuplicate ) {\n\t\t\tfor ( var i = 1; i < results.length; i++ ) {\n\t\t\t\tif ( results[i] === results[ i - 1 ] ) {\n\t\t\t\t\tresults.splice( i--, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn results;\n};\n\nSizzle.matches = function( expr, set ) {\n\treturn Sizzle( expr, null, null, set );\n};\n\nSizzle.matchesSelector = function( node, expr ) {\n\treturn Sizzle( expr, null, null, [node] ).length > 0;\n};\n\nSizzle.find = function( expr, context, isXML ) {\n\tvar set;\n\n\tif ( !expr ) {\n\t\treturn [];\n\t}\n\n\tfor ( var i = 0, l = Expr.order.length; i < l; i++ ) {\n\t\tvar match,\n\t\t\ttype = Expr.order[i];\n\t\t\n\t\tif ( (match = Expr.leftMatch[ type ].exec( expr )) ) {\n\t\t\tvar left = match[1];\n\t\t\tmatch.splice( 1, 1 );\n\n\t\t\tif ( left.substr( left.length - 1 ) !== \"\\\\\" ) {\n\t\t\t\tmatch[1] = (match[1] || \"\").replace( rBackslash, \"\" );\n\t\t\t\tset = Expr.find[ type ]( match, context, isXML );\n\n\t\t\t\tif ( set != null ) {\n\t\t\t\t\texpr = expr.replace( Expr.match[ type ], \"\" );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( !set ) {\n\t\tset = typeof context.getElementsByTagName !== \"undefined\" ?\n\t\t\tcontext.getElementsByTagName( \"*\" ) :\n\t\t\t[];\n\t}\n\n\treturn { set: set, expr: expr };\n};\n\nSizzle.filter = function( expr, set, inplace, not ) {\n\tvar match, anyFound,\n\t\told = expr,\n\t\tresult = [],\n\t\tcurLoop = set,\n\t\tisXMLFilter = set && set[0] && Sizzle.isXML( set[0] );\n\n\twhile ( expr && set.length ) {\n\t\tfor ( var type in Expr.filter ) {\n\t\t\tif ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {\n\t\t\t\tvar found, item,\n\t\t\t\t\tfilter = Expr.filter[ type ],\n\t\t\t\t\tleft = match[1];\n\n\t\t\t\tanyFound = false;\n\n\t\t\t\tmatch.splice(1,1);\n\n\t\t\t\tif ( left.substr( left.length - 1 ) === \"\\\\\" ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif ( curLoop === result ) {\n\t\t\t\t\tresult = [];\n\t\t\t\t}\n\n\t\t\t\tif ( Expr.preFilter[ type ] ) {\n\t\t\t\t\tmatch = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );\n\n\t\t\t\t\tif ( !match ) {\n\t\t\t\t\t\tanyFound = found = true;\n\n\t\t\t\t\t} else if ( match === true ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( match ) {\n\t\t\t\t\tfor ( var i = 0; (item = curLoop[i]) != null; i++ ) {\n\t\t\t\t\t\tif ( item ) {\n\t\t\t\t\t\t\tfound = filter( item, match, i, curLoop );\n\t\t\t\t\t\t\tvar pass = not ^ !!found;\n\n\t\t\t\t\t\t\tif ( inplace && found != null ) {\n\t\t\t\t\t\t\t\tif ( pass ) {\n\t\t\t\t\t\t\t\t\tanyFound = true;\n\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcurLoop[i] = false;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else if ( pass ) {\n\t\t\t\t\t\t\t\tresult.push( item );\n\t\t\t\t\t\t\t\tanyFound = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( found !== undefined ) {\n\t\t\t\t\tif ( !inplace ) {\n\t\t\t\t\t\tcurLoop = result;\n\t\t\t\t\t}\n\n\t\t\t\t\texpr = expr.replace( Expr.match[ type ], \"\" );\n\n\t\t\t\t\tif ( !anyFound ) {\n\t\t\t\t\t\treturn [];\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Improper expression\n\t\tif ( expr === old ) {\n\t\t\tif ( anyFound == null ) {\n\t\t\t\tSizzle.error( expr );\n\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\told = expr;\n\t}\n\n\treturn curLoop;\n};\n\nSizzle.error = function( msg ) {\n\tthrow \"Syntax error, unrecognized expression: \" + msg;\n};\n\nvar Expr = Sizzle.selectors = {\n\torder: [ \"ID\", \"NAME\", \"TAG\" ],\n\n\tmatch: {\n\t\tID: /#((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)/,\n\t\tCLASS: /\\.((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)/,\n\t\tNAME: /\\[name=['\"]*((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)['\"]*\\]/,\n\t\tATTR: /\\[\\s*((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)\\s*(?:(\\S?=)\\s*(?:(['\"])(.*?)\\3|(#?(?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)*)|)|)\\s*\\]/,\n\t\tTAG: /^((?:[\\w\\u00c0-\\uFFFF\\*\\-]|\\\\.)+)/,\n\t\tCHILD: /:(only|nth|last|first)-child(?:\\(\\s*(even|odd|(?:[+\\-]?\\d+|(?:[+\\-]?\\d*)?n\\s*(?:[+\\-]\\s*\\d+)?))\\s*\\))?/,\n\t\tPOS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\))?(?=[^\\-]|$)/,\n\t\tPSEUDO: /:((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)(?:\\((['\"]?)((?:\\([^\\)]+\\)|[^\\(\\)]*)+)\\2\\))?/\n\t},\n\n\tleftMatch: {},\n\n\tattrMap: {\n\t\t\"class\": \"className\",\n\t\t\"for\": \"htmlFor\"\n\t},\n\n\tattrHandle: {\n\t\thref: function( elem ) {\n\t\t\treturn elem.getAttribute( \"href\" );\n\t\t},\n\t\ttype: function( elem ) {\n\t\t\treturn elem.getAttribute( \"type\" );\n\t\t}\n\t},\n\n\trelative: {\n\t\t\"+\": function(checkSet, part){\n\t\t\tvar isPartStr = typeof part === \"string\",\n\t\t\t\tisTag = isPartStr && !rNonWord.test( part ),\n\t\t\t\tisPartStrNotTag = isPartStr && !isTag;\n\n\t\t\tif ( isTag ) {\n\t\t\t\tpart = part.toLowerCase();\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {\n\t\t\t\tif ( (elem = checkSet[i]) ) {\n\t\t\t\t\twhile ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}\n\n\t\t\t\t\tcheckSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?\n\t\t\t\t\t\telem || false :\n\t\t\t\t\t\telem === part;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( isPartStrNotTag ) {\n\t\t\t\tSizzle.filter( part, checkSet, true );\n\t\t\t}\n\t\t},\n\n\t\t\">\": function( checkSet, part ) {\n\t\t\tvar elem,\n\t\t\t\tisPartStr = typeof part === \"string\",\n\t\t\t\ti = 0,\n\t\t\t\tl = checkSet.length;\n\n\t\t\tif ( isPartStr && !rNonWord.test( part ) ) {\n\t\t\t\tpart = part.toLowerCase();\n\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\telem = checkSet[i];\n\n\t\t\t\t\tif ( elem ) {\n\t\t\t\t\t\tvar parent = elem.parentNode;\n\t\t\t\t\t\tcheckSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\telem = checkSet[i];\n\n\t\t\t\t\tif ( elem ) {\n\t\t\t\t\t\tcheckSet[i] = isPartStr ?\n\t\t\t\t\t\t\telem.parentNode :\n\t\t\t\t\t\t\telem.parentNode === part;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( isPartStr ) {\n\t\t\t\t\tSizzle.filter( part, checkSet, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t\"\": function(checkSet, part, isXML){\n\t\t\tvar nodeCheck,\n\t\t\t\tdoneName = done++,\n\t\t\t\tcheckFn = dirCheck;\n\n\t\t\tif ( typeof part === \"string\" && !rNonWord.test( part ) ) {\n\t\t\t\tpart = part.toLowerCase();\n\t\t\t\tnodeCheck = part;\n\t\t\t\tcheckFn = dirNodeCheck;\n\t\t\t}\n\n\t\t\tcheckFn( \"parentNode\", part, doneName, checkSet, nodeCheck, isXML );\n\t\t},\n\n\t\t\"~\": function( checkSet, part, isXML ) {\n\t\t\tvar nodeCheck,\n\t\t\t\tdoneName = done++,\n\t\t\t\tcheckFn = dirCheck;\n\n\t\t\tif ( typeof part === \"string\" && !rNonWord.test( part ) ) {\n\t\t\t\tpart = part.toLowerCase();\n\t\t\t\tnodeCheck = part;\n\t\t\t\tcheckFn = dirNodeCheck;\n\t\t\t}\n\n\t\t\tcheckFn( \"previousSibling\", part, doneName, checkSet, nodeCheck, isXML );\n\t\t}\n\t},\n\n\tfind: {\n\t\tID: function( match, context, isXML ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && !isXML ) {\n\t\t\t\tvar m = context.getElementById(match[1]);\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [m] : [];\n\t\t\t}\n\t\t},\n\n\t\tNAME: function( match, context ) {\n\t\t\tif ( typeof context.getElementsByName !== \"undefined\" ) {\n\t\t\t\tvar ret = [],\n\t\t\t\t\tresults = context.getElementsByName( match[1] );\n\n\t\t\t\tfor ( var i = 0, l = results.length; i < l; i++ ) {\n\t\t\t\t\tif ( results[i].getAttribute(\"name\") === match[1] ) {\n\t\t\t\t\t\tret.push( results[i] );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn ret.length === 0 ? null : ret;\n\t\t\t}\n\t\t},\n\n\t\tTAG: function( match, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( match[1] );\n\t\t\t}\n\t\t}\n\t},\n\tpreFilter: {\n\t\tCLASS: function( match, curLoop, inplace, result, not, isXML ) {\n\t\t\tmatch = \" \" + match[1].replace( rBackslash, \"\" ) + \" \";\n\n\t\t\tif ( isXML ) {\n\t\t\t\treturn match;\n\t\t\t}\n\n\t\t\tfor ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {\n\t\t\t\tif ( elem ) {\n\t\t\t\t\tif ( not ^ (elem.className && (\" \" + elem.className + \" \").replace(/[\\t\\n\\r]/g, \" \").indexOf(match) >= 0) ) {\n\t\t\t\t\t\tif ( !inplace ) {\n\t\t\t\t\t\t\tresult.push( elem );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( inplace ) {\n\t\t\t\t\t\tcurLoop[i] = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t},\n\n\t\tID: function( match ) {\n\t\t\treturn match[1].replace( rBackslash, \"\" );\n\t\t},\n\n\t\tTAG: function( match, curLoop ) {\n\t\t\treturn match[1].replace( rBackslash, \"\" ).toLowerCase();\n\t\t},\n\n\t\tCHILD: function( match ) {\n\t\t\tif ( match[1] === \"nth\" ) {\n\t\t\t\tif ( !match[2] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\tmatch[2] = match[2].replace(/^\\+|\\s*/g, '');\n\n\t\t\t\t// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'\n\t\t\t\tvar test = /(-?)(\\d*)(?:n([+\\-]?\\d*))?/.exec(\n\t\t\t\t\tmatch[2] === \"even\" && \"2n\" || match[2] === \"odd\" && \"2n+1\" ||\n\t\t\t\t\t!/\\D/.test( match[2] ) && \"0n+\" + match[2] || match[2]);\n\n\t\t\t\t// calculate the numbers (first)n+(last) including if they are negative\n\t\t\t\tmatch[2] = (test[1] + (test[2] || 1)) - 0;\n\t\t\t\tmatch[3] = test[3] - 0;\n\t\t\t}\n\t\t\telse if ( match[2] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\t// TODO: Move to normal caching system\n\t\t\tmatch[0] = done++;\n\n\t\t\treturn match;\n\t\t},\n\n\t\tATTR: function( match, curLoop, inplace, result, not, isXML ) {\n\t\t\tvar name = match[1] = match[1].replace( rBackslash, \"\" );\n\t\t\t\n\t\t\tif ( !isXML && Expr.attrMap[name] ) {\n\t\t\t\tmatch[1] = Expr.attrMap[name];\n\t\t\t}\n\n\t\t\t// Handle if an un-quoted value was used\n\t\t\tmatch[4] = ( match[4] || match[5] || \"\" ).replace( rBackslash, \"\" );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[4] = \" \" + match[4] + \" \";\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\tPSEUDO: function( match, curLoop, inplace, result, not ) {\n\t\t\tif ( match[1] === \"not\" ) {\n\t\t\t\t// If we're dealing with a complex expression, or a simple one\n\t\t\t\tif ( ( chunker.exec(match[3]) || \"\" ).length > 1 || /^\\w/.test(match[3]) ) {\n\t\t\t\t\tmatch[3] = Sizzle(match[3], null, null, curLoop);\n\n\t\t\t\t} else {\n\t\t\t\t\tvar ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);\n\n\t\t\t\t\tif ( !inplace ) {\n\t\t\t\t\t\tresult.push.apply( result, ret );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t\n\t\t\treturn match;\n\t\t},\n\n\t\tPOS: function( match ) {\n\t\t\tmatch.unshift( true );\n\n\t\t\treturn match;\n\t\t}\n\t},\n\t\n\tfilters: {\n\t\tenabled: function( elem ) {\n\t\t\treturn elem.disabled === false && elem.type !== \"hidden\";\n\t\t},\n\n\t\tdisabled: function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\tchecked: function( elem ) {\n\t\t\treturn elem.checked === true;\n\t\t},\n\t\t\n\t\tselected: function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\t\t\t\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\tparent: function( elem ) {\n\t\t\treturn !!elem.firstChild;\n\t\t},\n\n\t\tempty: function( elem ) {\n\t\t\treturn !elem.firstChild;\n\t\t},\n\n\t\thas: function( elem, i, match ) {\n\t\t\treturn !!Sizzle( match[3], elem ).length;\n\t\t},\n\n\t\theader: function( elem ) {\n\t\t\treturn (/h\\d/i).test( elem.nodeName );\n\t\t},\n\n\t\ttext: function( elem ) {\n\t\t\tvar attr = elem.getAttribute( \"type\" ), type = elem.type;\n\t\t\t// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) \n\t\t\t// use getAttribute instead to test this case\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" && \"text\" === type && ( attr === type || attr === null );\n\t\t},\n\n\t\tradio: function( elem ) {\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" && \"radio\" === elem.type;\n\t\t},\n\n\t\tcheckbox: function( elem ) {\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" && \"checkbox\" === elem.type;\n\t\t},\n\n\t\tfile: function( elem ) {\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" && \"file\" === elem.type;\n\t\t},\n\n\t\tpassword: function( elem ) {\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" && \"password\" === elem.type;\n\t\t},\n\n\t\tsubmit: function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn (name === \"input\" || name === \"button\") && \"submit\" === elem.type;\n\t\t},\n\n\t\timage: function( elem ) {\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" && \"image\" === elem.type;\n\t\t},\n\n\t\treset: function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn (name === \"input\" || name === \"button\") && \"reset\" === elem.type;\n\t\t},\n\n\t\tbutton: function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && \"button\" === elem.type || name === \"button\";\n\t\t},\n\n\t\tinput: function( elem ) {\n\t\t\treturn (/input|select|textarea|button/i).test( elem.nodeName );\n\t\t},\n\n\t\tfocus: function( elem ) {\n\t\t\treturn elem === elem.ownerDocument.activeElement;\n\t\t}\n\t},\n\tsetFilters: {\n\t\tfirst: function( elem, i ) {\n\t\t\treturn i === 0;\n\t\t},\n\n\t\tlast: function( elem, i, match, array ) {\n\t\t\treturn i === array.length - 1;\n\t\t},\n\n\t\teven: function( elem, i ) {\n\t\t\treturn i % 2 === 0;\n\t\t},\n\n\t\todd: function( elem, i ) {\n\t\t\treturn i % 2 === 1;\n\t\t},\n\n\t\tlt: function( elem, i, match ) {\n\t\t\treturn i < match[3] - 0;\n\t\t},\n\n\t\tgt: function( elem, i, match ) {\n\t\t\treturn i > match[3] - 0;\n\t\t},\n\n\t\tnth: function( elem, i, match ) {\n\t\t\treturn match[3] - 0 === i;\n\t\t},\n\n\t\teq: function( elem, i, match ) {\n\t\t\treturn match[3] - 0 === i;\n\t\t}\n\t},\n\tfilter: {\n\t\tPSEUDO: function( elem, match, i, array ) {\n\t\t\tvar name = match[1],\n\t\t\t\tfilter = Expr.filters[ name ];\n\n\t\t\tif ( filter ) {\n\t\t\t\treturn filter( elem, i, match, array );\n\n\t\t\t} else if ( name === \"contains\" ) {\n\t\t\t\treturn (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || \"\").indexOf(match[3]) >= 0;\n\n\t\t\t} else if ( name === \"not\" ) {\n\t\t\t\tvar not = match[3];\n\n\t\t\t\tfor ( var j = 0, l = not.length; j < l; j++ ) {\n\t\t\t\t\tif ( not[j] === elem ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t} else {\n\t\t\t\tSizzle.error( name );\n\t\t\t}\n\t\t},\n\n\t\tCHILD: function( elem, match ) {\n\t\t\tvar type = match[1],\n\t\t\t\tnode = elem;\n\n\t\t\tswitch ( type ) {\n\t\t\t\tcase \"only\":\n\t\t\t\tcase \"first\":\n\t\t\t\t\twhile ( (node = node.previousSibling) )\t {\n\t\t\t\t\t\tif ( node.nodeType === 1 ) { \n\t\t\t\t\t\t\treturn false; \n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( type === \"first\" ) { \n\t\t\t\t\t\treturn true; \n\t\t\t\t\t}\n\n\t\t\t\t\tnode = elem;\n\n\t\t\t\tcase \"last\":\n\t\t\t\t\twhile ( (node = node.nextSibling) )\t {\n\t\t\t\t\t\tif ( node.nodeType === 1 ) { \n\t\t\t\t\t\t\treturn false; \n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\tcase \"nth\":\n\t\t\t\t\tvar first = match[2],\n\t\t\t\t\t\tlast = match[3];\n\n\t\t\t\t\tif ( first === 1 && last === 0 ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tvar doneName = match[0],\n\t\t\t\t\t\tparent = elem.parentNode;\n\t\n\t\t\t\t\tif ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {\n\t\t\t\t\t\tvar count = 0;\n\t\t\t\t\t\t\n\t\t\t\t\t\tfor ( node = parent.firstChild; node; node = node.nextSibling ) {\n\t\t\t\t\t\t\tif ( node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\tnode.nodeIndex = ++count;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} \n\n\t\t\t\t\t\tparent.sizcache = doneName;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tvar diff = elem.nodeIndex - last;\n\n\t\t\t\t\tif ( first === 0 ) {\n\t\t\t\t\t\treturn diff === 0;\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tID: function( elem, match ) {\n\t\t\treturn elem.nodeType === 1 && elem.getAttribute(\"id\") === match;\n\t\t},\n\n\t\tTAG: function( elem, match ) {\n\t\t\treturn (match === \"*\" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;\n\t\t},\n\t\t\n\t\tCLASS: function( elem, match ) {\n\t\t\treturn (\" \" + (elem.className || elem.getAttribute(\"class\")) + \" \")\n\t\t\t\t.indexOf( match ) > -1;\n\t\t},\n\n\t\tATTR: function( elem, match ) {\n\t\t\tvar name = match[1],\n\t\t\t\tresult = Expr.attrHandle[ name ] ?\n\t\t\t\t\tExpr.attrHandle[ name ]( elem ) :\n\t\t\t\t\telem[ name ] != null ?\n\t\t\t\t\t\telem[ name ] :\n\t\t\t\t\t\telem.getAttribute( name ),\n\t\t\t\tvalue = result + \"\",\n\t\t\t\ttype = match[2],\n\t\t\t\tcheck = match[4];\n\n\t\t\treturn result == null ?\n\t\t\t\ttype === \"!=\" :\n\t\t\t\ttype === \"=\" ?\n\t\t\t\tvalue === check :\n\t\t\t\ttype === \"*=\" ?\n\t\t\t\tvalue.indexOf(check) >= 0 :\n\t\t\t\ttype === \"~=\" ?\n\t\t\t\t(\" \" + value + \" \").indexOf(check) >= 0 :\n\t\t\t\t!check ?\n\t\t\t\tvalue && result !== false :\n\t\t\t\ttype === \"!=\" ?\n\t\t\t\tvalue !== check :\n\t\t\t\ttype === \"^=\" ?\n\t\t\t\tvalue.indexOf(check) === 0 :\n\t\t\t\ttype === \"$=\" ?\n\t\t\t\tvalue.substr(value.length - check.length) === check :\n\t\t\t\ttype === \"|=\" ?\n\t\t\t\tvalue === check || value.substr(0, check.length + 1) === check + \"-\" :\n\t\t\t\tfalse;\n\t\t},\n\n\t\tPOS: function( elem, match, i, array ) {\n\t\t\tvar name = match[2],\n\t\t\t\tfilter = Expr.setFilters[ name ];\n\n\t\t\tif ( filter ) {\n\t\t\t\treturn filter( elem, i, match, array );\n\t\t\t}\n\t\t}\n\t}\n};\n\nvar origPOS = Expr.match.POS,\n\tfescape = function(all, num){\n\t\treturn \"\\\\\" + (num - 0 + 1);\n\t};\n\nfor ( var type in Expr.match ) {\n\tExpr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\\[]*\\])(?![^\\(]*\\))/.source) );\n\tExpr.leftMatch[ type ] = new RegExp( /(^(?:.|\\r|\\n)*?)/.source + Expr.match[ type ].source.replace(/\\\\(\\d+)/g, fescape) );\n}\n\nvar makeArray = function( array, results ) {\n\tarray = Array.prototype.slice.call( array, 0 );\n\n\tif ( results ) {\n\t\tresults.push.apply( results, array );\n\t\treturn results;\n\t}\n\t\n\treturn array;\n};\n\n// Perform a simple check to determine if the browser is capable of\n// converting a NodeList to an array using builtin methods.\n// Also verifies that the returned array holds DOM nodes\n// (which is not the case in the Blackberry browser)\ntry {\n\tArray.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;\n\n// Provide a fallback method if it does not work\n} catch( e ) {\n\tmakeArray = function( array, results ) {\n\t\tvar i = 0,\n\t\t\tret = results || [];\n\n\t\tif ( toString.call(array) === \"[object Array]\" ) {\n\t\t\tArray.prototype.push.apply( ret, array );\n\n\t\t} else {\n\t\t\tif ( typeof array.length === \"number\" ) {\n\t\t\t\tfor ( var l = array.length; i < l; i++ ) {\n\t\t\t\t\tret.push( array[i] );\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tfor ( ; array[i]; i++ ) {\n\t\t\t\t\tret.push( array[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t};\n}\n\nvar sortOrder, siblingCheck;\n\nif ( document.documentElement.compareDocumentPosition ) {\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tif ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {\n\t\t\treturn a.compareDocumentPosition ? -1 : 1;\n\t\t}\n\n\t\treturn a.compareDocumentPosition(b) & 4 ? -1 : 1;\n\t};\n\n} else {\n\tsortOrder = function( a, b ) {\n\t\t// The nodes are identical, we can exit early\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\n\t\t// Fallback to using sourceIndex (in IE) if it's available on both nodes\n\t\t} else if ( a.sourceIndex && b.sourceIndex ) {\n\t\t\treturn a.sourceIndex - b.sourceIndex;\n\t\t}\n\n\t\tvar al, bl,\n\t\t\tap = [],\n\t\t\tbp = [],\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tcur = aup;\n\n\t\t// If the nodes are siblings (or identical) we can do a quick check\n\t\tif ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\n\t\t// If no parents were found then the nodes are disconnected\n\t\t} else if ( !aup ) {\n\t\t\treturn -1;\n\n\t\t} else if ( !bup ) {\n\t\t\treturn 1;\n\t\t}\n\n\t\t// Otherwise they're somewhere else in the tree so we need\n\t\t// to build up a full list of the parentNodes for comparison\n\t\twhile ( cur ) {\n\t\t\tap.unshift( cur );\n\t\t\tcur = cur.parentNode;\n\t\t}\n\n\t\tcur = bup;\n\n\t\twhile ( cur ) {\n\t\t\tbp.unshift( cur );\n\t\t\tcur = cur.parentNode;\n\t\t}\n\n\t\tal = ap.length;\n\t\tbl = bp.length;\n\n\t\t// Start walking down the tree looking for a discrepancy\n\t\tfor ( var i = 0; i < al && i < bl; i++ ) {\n\t\t\tif ( ap[i] !== bp[i] ) {\n\t\t\t\treturn siblingCheck( ap[i], bp[i] );\n\t\t\t}\n\t\t}\n\n\t\t// We ended someplace up the tree so do a sibling check\n\t\treturn i === al ?\n\t\t\tsiblingCheck( a, bp[i], -1 ) :\n\t\t\tsiblingCheck( ap[i], b, 1 );\n\t};\n\n\tsiblingCheck = function( a, b, ret ) {\n\t\tif ( a === b ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tvar cur = a.nextSibling;\n\n\t\twhile ( cur ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tcur = cur.nextSibling;\n\t\t}\n\n\t\treturn 1;\n\t};\n}\n\n// Utility function for retreiving the text value of an array of DOM nodes\nSizzle.getText = function( elems ) {\n\tvar ret = \"\", elem;\n\n\tfor ( var i = 0; elems[i]; i++ ) {\n\t\telem = elems[i];\n\n\t\t// Get the text from text nodes and CDATA nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 4 ) {\n\t\t\tret += elem.nodeValue;\n\n\t\t// Traverse everything else, except comment nodes\n\t\t} else if ( elem.nodeType !== 8 ) {\n\t\t\tret += Sizzle.getText( elem.childNodes );\n\t\t}\n\t}\n\n\treturn ret;\n};\n\n// Check to see if the browser returns elements by name when\n// querying by getElementById (and provide a workaround)\n(function(){\n\t// We're going to inject a fake input element with a specified name\n\tvar form = document.createElement(\"div\"),\n\t\tid = \"script\" + (new Date()).getTime(),\n\t\troot = document.documentElement;\n\n\tform.innerHTML = \"<a name='\" + id + \"'/>\";\n\n\t// Inject it into the root element, check its status, and remove it quickly\n\troot.insertBefore( form, root.firstChild );\n\n\t// The workaround has to do additional checks after a getElementById\n\t// Which slows things down for other browsers (hence the branching)\n\tif ( document.getElementById( id ) ) {\n\t\tExpr.find.ID = function( match, context, isXML ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && !isXML ) {\n\t\t\t\tvar m = context.getElementById(match[1]);\n\n\t\t\t\treturn m ?\n\t\t\t\t\tm.id === match[1] || typeof m.getAttributeNode !== \"undefined\" && m.getAttributeNode(\"id\").nodeValue === match[1] ?\n\t\t\t\t\t\t[m] :\n\t\t\t\t\t\tundefined :\n\t\t\t\t\t[];\n\t\t\t}\n\t\t};\n\n\t\tExpr.filter.ID = function( elem, match ) {\n\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n\n\t\t\treturn elem.nodeType === 1 && node && node.nodeValue === match;\n\t\t};\n\t}\n\n\troot.removeChild( form );\n\n\t// release memory in IE\n\troot = form = null;\n})();\n\n(function(){\n\t// Check to see if the browser returns only elements\n\t// when doing getElementsByTagName(\"*\")\n\n\t// Create a fake element\n\tvar div = document.createElement(\"div\");\n\tdiv.appendChild( document.createComment(\"\") );\n\n\t// Make sure no comments are found\n\tif ( div.getElementsByTagName(\"*\").length > 0 ) {\n\t\tExpr.find.TAG = function( match, context ) {\n\t\t\tvar results = context.getElementsByTagName( match[1] );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( match[1] === \"*\" ) {\n\t\t\t\tvar tmp = [];\n\n\t\t\t\tfor ( var i = 0; results[i]; i++ ) {\n\t\t\t\t\tif ( results[i].nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( results[i] );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tresults = tmp;\n\t\t\t}\n\n\t\t\treturn results;\n\t\t};\n\t}\n\n\t// Check to see if an attribute returns normalized href attributes\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\n\tif ( div.firstChild && typeof div.firstChild.getAttribute !== \"undefined\" &&\n\t\t\tdiv.firstChild.getAttribute(\"href\") !== \"#\" ) {\n\n\t\tExpr.attrHandle.href = function( elem ) {\n\t\t\treturn elem.getAttribute( \"href\", 2 );\n\t\t};\n\t}\n\n\t// release memory in IE\n\tdiv = null;\n})();\n\nif ( document.querySelectorAll ) {\n\t(function(){\n\t\tvar oldSizzle = Sizzle,\n\t\t\tdiv = document.createElement(\"div\"),\n\t\t\tid = \"__sizzle__\";\n\n\t\tdiv.innerHTML = \"<p class='TEST'></p>\";\n\n\t\t// Safari can't handle uppercase or unicode characters when\n\t\t// in quirks mode.\n\t\tif ( div.querySelectorAll && div.querySelectorAll(\".TEST\").length === 0 ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tSizzle = function( query, context, extra, seed ) {\n\t\t\tcontext = context || document;\n\n\t\t\t// Only use querySelectorAll on non-XML documents\n\t\t\t// (ID selectors don't work in non-HTML documents)\n\t\t\tif ( !seed && !Sizzle.isXML(context) ) {\n\t\t\t\t// See if we find a selector to speed up\n\t\t\t\tvar match = /^(\\w+$)|^\\.([\\w\\-]+$)|^#([\\w\\-]+$)/.exec( query );\n\t\t\t\t\n\t\t\t\tif ( match && (context.nodeType === 1 || context.nodeType === 9) ) {\n\t\t\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t\t\tif ( match[1] ) {\n\t\t\t\t\t\treturn makeArray( context.getElementsByTagName( query ), extra );\n\t\t\t\t\t\n\t\t\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t\t\t} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {\n\t\t\t\t\t\treturn makeArray( context.getElementsByClassName( match[2] ), extra );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif ( context.nodeType === 9 ) {\n\t\t\t\t\t// Speed-up: Sizzle(\"body\")\n\t\t\t\t\t// The body element only exists once, optimize finding it\n\t\t\t\t\tif ( query === \"body\" && context.body ) {\n\t\t\t\t\t\treturn makeArray( [ context.body ], extra );\n\t\t\t\t\t\t\n\t\t\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\t\t\t} else if ( match && match[3] ) {\n\t\t\t\t\t\tvar elem = context.getElementById( match[3] );\n\n\t\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === match[3] ) {\n\t\t\t\t\t\t\t\treturn makeArray( [ elem ], extra );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn makeArray( [], extra );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn makeArray( context.querySelectorAll(query), extra );\n\t\t\t\t\t} catch(qsaError) {}\n\n\t\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t\t// IE 8 doesn't work on object elements\n\t\t\t\t} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\t\tvar oldContext = context,\n\t\t\t\t\t\told = context.getAttribute( \"id\" ),\n\t\t\t\t\t\tnid = old || id,\n\t\t\t\t\t\thasParent = context.parentNode,\n\t\t\t\t\t\trelativeHierarchySelector = /^\\s*[+~]/.test( query );\n\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnid = nid.replace( /'/g, \"\\\\$&\" );\n\t\t\t\t\t}\n\t\t\t\t\tif ( relativeHierarchySelector && hasParent ) {\n\t\t\t\t\t\tcontext = context.parentNode;\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif ( !relativeHierarchySelector || hasParent ) {\n\t\t\t\t\t\t\treturn makeArray( context.querySelectorAll( \"[id='\" + nid + \"'] \" + query ), extra );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} catch(pseudoError) {\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\t\toldContext.removeAttribute( \"id\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\n\t\t\treturn oldSizzle(query, context, extra, seed);\n\t\t};\n\n\t\tfor ( var prop in oldSizzle ) {\n\t\t\tSizzle[ prop ] = oldSizzle[ prop ];\n\t\t}\n\n\t\t// release memory in IE\n\t\tdiv = null;\n\t})();\n}\n\n(function(){\n\tvar html = document.documentElement,\n\t\tmatches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;\n\n\tif ( matches ) {\n\t\t// Check to see if it's possible to do matchesSelector\n\t\t// on a disconnected node (IE 9 fails this)\n\t\tvar disconnectedMatch = !matches.call( document.createElement( \"div\" ), \"div\" ),\n\t\t\tpseudoWorks = false;\n\n\t\ttry {\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( document.documentElement, \"[test!='']:sizzle\" );\n\t\n\t\t} catch( pseudoError ) {\n\t\t\tpseudoWorks = true;\n\t\t}\n\n\t\tSizzle.matchesSelector = function( node, expr ) {\n\t\t\t// Make sure that attribute selectors are quoted\n\t\t\texpr = expr.replace(/\\=\\s*([^'\"\\]]*)\\s*\\]/g, \"='$1']\");\n\n\t\t\tif ( !Sizzle.isXML( node ) ) {\n\t\t\t\ttry { \n\t\t\t\t\tif ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {\n\t\t\t\t\t\tvar ret = matches.call( node, expr );\n\n\t\t\t\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\t\t\t\tif ( ret || !disconnectedMatch ||\n\t\t\t\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t\t\t\t// fragment in IE 9, so check for that\n\t\t\t\t\t\t\t\tnode.document && node.document.nodeType !== 11 ) {\n\t\t\t\t\t\t\treturn ret;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\treturn Sizzle(expr, null, null, [node]).length > 0;\n\t\t};\n\t}\n})();\n\n(function(){\n\tvar div = document.createElement(\"div\");\n\n\tdiv.innerHTML = \"<div class='test e'></div><div class='test'></div>\";\n\n\t// Opera can't find a second classname (in 9.6)\n\t// Also, make sure that getElementsByClassName actually exists\n\tif ( !div.getElementsByClassName || div.getElementsByClassName(\"e\").length === 0 ) {\n\t\treturn;\n\t}\n\n\t// Safari caches class attributes, doesn't catch changes (in 3.2)\n\tdiv.lastChild.className = \"e\";\n\n\tif ( div.getElementsByClassName(\"e\").length === 1 ) {\n\t\treturn;\n\t}\n\t\n\tExpr.order.splice(1, 0, \"CLASS\");\n\tExpr.find.CLASS = function( match, context, isXML ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && !isXML ) {\n\t\t\treturn context.getElementsByClassName(match[1]);\n\t\t}\n\t};\n\n\t// release memory in IE\n\tdiv = null;\n})();\n\nfunction dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {\n\tfor ( var i = 0, l = checkSet.length; i < l; i++ ) {\n\t\tvar elem = checkSet[i];\n\n\t\tif ( elem ) {\n\t\t\tvar match = false;\n\n\t\t\telem = elem[dir];\n\n\t\t\twhile ( elem ) {\n\t\t\t\tif ( elem.sizcache === doneName ) {\n\t\t\t\t\tmatch = checkSet[elem.sizset];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( elem.nodeType === 1 && !isXML ){\n\t\t\t\t\telem.sizcache = doneName;\n\t\t\t\t\telem.sizset = i;\n\t\t\t\t}\n\n\t\t\t\tif ( elem.nodeName.toLowerCase() === cur ) {\n\t\t\t\t\tmatch = elem;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\telem = elem[dir];\n\t\t\t}\n\n\t\t\tcheckSet[i] = match;\n\t\t}\n\t}\n}\n\nfunction dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {\n\tfor ( var i = 0, l = checkSet.length; i < l; i++ ) {\n\t\tvar elem = checkSet[i];\n\n\t\tif ( elem ) {\n\t\t\tvar match = false;\n\t\t\t\n\t\t\telem = elem[dir];\n\n\t\t\twhile ( elem ) {\n\t\t\t\tif ( elem.sizcache === doneName ) {\n\t\t\t\t\tmatch = checkSet[elem.sizset];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\tif ( !isXML ) {\n\t\t\t\t\t\telem.sizcache = doneName;\n\t\t\t\t\t\telem.sizset = i;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( typeof cur !== \"string\" ) {\n\t\t\t\t\t\tif ( elem === cur ) {\n\t\t\t\t\t\t\tmatch = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {\n\t\t\t\t\t\tmatch = elem;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\telem = elem[dir];\n\t\t\t}\n\n\t\t\tcheckSet[i] = match;\n\t\t}\n\t}\n}\n\nif ( document.documentElement.contains ) {\n\tSizzle.contains = function( a, b ) {\n\t\treturn a !== b && (a.contains ? a.contains(b) : true);\n\t};\n\n} else if ( document.documentElement.compareDocumentPosition ) {\n\tSizzle.contains = function( a, b ) {\n\t\treturn !!(a.compareDocumentPosition(b) & 16);\n\t};\n\n} else {\n\tSizzle.contains = function() {\n\t\treturn false;\n\t};\n}\n\nSizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833) \n\tvar documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;\n\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\nvar posProcess = function( selector, context ) {\n\tvar match,\n\t\ttmpSet = [],\n\t\tlater = \"\",\n\t\troot = context.nodeType ? [context] : context;\n\n\t// Position selectors must be done after the filter\n\t// And so must :not(positional) so we move all PSEUDOs to the end\n\twhile ( (match = Expr.match.PSEUDO.exec( selector )) ) {\n\t\tlater += match[0];\n\t\tselector = selector.replace( Expr.match.PSEUDO, \"\" );\n\t}\n\n\tselector = Expr.relative[selector] ? selector + \"*\" : selector;\n\n\tfor ( var i = 0, l = root.length; i < l; i++ ) {\n\t\tSizzle( selector, root[i], tmpSet );\n\t}\n\n\treturn Sizzle.filter( later, tmpSet );\n};\n\n// EXPOSE\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.filters;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n})();\n\n\nvar runtil = /Until$/,\n\trparentsprev = /^(?:parents|prevUntil|prevAll)/,\n\t// Note: This RegExp should be improved, or likely pulled from Sizzle\n\trmultiselector = /,/,\n\tisSimple = /^.[^:#\\[\\.,]*$/,\n\tslice = Array.prototype.slice,\n\tPOS = jQuery.expr.match.POS,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar self = this,\n\t\t\ti, l;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0, l = self.length; i < l; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tvar ret = this.pushStack( \"\", \"find\", selector ),\n\t\t\tlength, n, r;\n\n\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\tlength = ret.length;\n\t\t\tjQuery.find( selector, this[i], ret );\n\n\t\t\tif ( i > 0 ) {\n\t\t\t\t// Make sure that the results are unique\n\t\t\t\tfor ( n = length; n < ret.length; n++ ) {\n\t\t\t\t\tfor ( r = 0; r < length; r++ ) {\n\t\t\t\t\t\tif ( ret[r] === ret[n] ) {\n\t\t\t\t\t\t\tret.splice(n--, 1);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\thas: function( target ) {\n\t\tvar targets = jQuery( target );\n\t\treturn this.filter(function() {\n\t\t\tfor ( var i = 0, l = targets.length; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector, false), \"not\", selector);\n\t},\n\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector, true), \"filter\", selector );\n\t},\n\n\tis: function( selector ) {\n\t\treturn !!selector && ( typeof selector === \"string\" ?\n\t\t\tjQuery.filter( selector, this ).length > 0 :\n\t\t\tthis.filter( selector ).length > 0 );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar ret = [], i, l, cur = this[0];\n\t\t\n\t\t// Array\n\t\tif ( jQuery.isArray( selectors ) ) {\n\t\t\tvar match, selector,\n\t\t\t\tmatches = {},\n\t\t\t\tlevel = 1;\n\n\t\t\tif ( cur && selectors.length ) {\n\t\t\t\tfor ( i = 0, l = selectors.length; i < l; i++ ) {\n\t\t\t\t\tselector = selectors[i];\n\n\t\t\t\t\tif ( !matches[ selector ] ) {\n\t\t\t\t\t\tmatches[ selector ] = POS.test( selector ) ?\n\t\t\t\t\t\t\tjQuery( selector, context || this.context ) :\n\t\t\t\t\t\t\tselector;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\twhile ( cur && cur.ownerDocument && cur !== context ) {\n\t\t\t\t\tfor ( selector in matches ) {\n\t\t\t\t\t\tmatch = matches[ selector ];\n\n\t\t\t\t\t\tif ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {\n\t\t\t\t\t\t\tret.push({ selector: selector, elem: cur, level: level });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcur = cur.parentNode;\n\t\t\t\t\tlevel++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn ret;\n\t\t}\n\n\t\t// String\n\t\tvar pos = POS.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\tcur = this[i];\n\n\t\t\twhile ( cur ) {\n\t\t\t\tif ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {\n\t\t\t\t\tret.push( cur );\n\t\t\t\t\tbreak;\n\n\t\t\t\t} else {\n\t\t\t\t\tcur = cur.parentNode;\n\t\t\t\t\tif ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tret = ret.length > 1 ? jQuery.unique( ret ) : ret;\n\n\t\treturn this.pushStack( ret, \"closest\", selectors );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\t\tif ( !elem || typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0],\n\t\t\t\t// If it receives a string, the selector is used\n\t\t\t\t// If it receives nothing, the siblings are used\n\t\t\t\telem ? jQuery( elem ) : this.parent().children() );\n\t\t}\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\tvar set = typeof selector === \"string\" ?\n\t\t\t\tjQuery( selector, context ) :\n\t\t\t\tjQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),\n\t\t\tall = jQuery.merge( this.get(), set );\n\n\t\treturn this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?\n\t\t\tall :\n\t\t\tjQuery.unique( all ) );\n\t},\n\n\tandSelf: function() {\n\t\treturn this.add( this.prevObject );\n\t}\n});\n\n// A painfully simple check to see if an element is disconnected\n// from a document (should be improved, where feasible).\nfunction isDisconnected( node ) {\n\treturn !node || !node.parentNode || node.parentNode.nodeType === 11;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn jQuery.nth( elem, 2, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn jQuery.nth( elem, 2, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( elem.parentNode.firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.makeArray( elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until ),\n\t\t\t// The variable 'args' was introduced in\n\t\t\t// https://github.com/jquery/jquery/commit/52a0238\n\t\t\t// to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.\n\t\t\t// http://code.google.com/p/v8/issues/detail?id=1050\n\t\t\targs = slice.call(arguments);\n\n\t\tif ( !runtil.test( name ) ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;\n\n\t\tif ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {\n\t\t\tret = ret.reverse();\n\t\t}\n\n\t\treturn this.pushStack( ret, name, args.join(\",\") );\n\t};\n});\n\njQuery.extend({\n\tfilter: function( expr, elems, not ) {\n\t\tif ( not ) {\n\t\t\texpr = \":not(\" + expr + \")\";\n\t\t}\n\n\t\treturn elems.length === 1 ?\n\t\t\tjQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :\n\t\t\tjQuery.find.matches(expr, elems);\n\t},\n\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tnth: function( cur, result, dir, elem ) {\n\t\tresult = result || 1;\n\t\tvar num = 0;\n\n\t\tfor ( ; cur; cur = cur[dir] ) {\n\t\t\tif ( cur.nodeType === 1 && ++num === result ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn cur;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, keep ) {\n\n\t// Can't pass null or undefined to indexOf in Firefox 4\n\t// Set to 0 to skip string check\n\tqualifier = qualifier || 0;\n\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep(elements, function( elem, i ) {\n\t\t\tvar retVal = !!qualifier.call( elem, i, elem );\n\t\t\treturn retVal === keep;\n\t\t});\n\n\t} else if ( qualifier.nodeType ) {\n\t\treturn jQuery.grep(elements, function( elem, i ) {\n\t\t\treturn (elem === qualifier) === keep;\n\t\t});\n\n\t} else if ( typeof qualifier === \"string\" ) {\n\t\tvar filtered = jQuery.grep(elements, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t});\n\n\t\tif ( isSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter(qualifier, filtered, !keep);\n\t\t} else {\n\t\t\tqualifier = jQuery.filter( qualifier, filtered );\n\t\t}\n\t}\n\n\treturn jQuery.grep(elements, function( elem, i ) {\n\t\treturn (jQuery.inArray( elem, qualifier ) >= 0) === keep;\n\t});\n}\n\n\n\n\nvar rinlinejQuery = / jQuery\\d+=\"(?:\\d+|null)\"/g,\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/ig,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnocache = /<(?:script|object|embed|option|style)/i,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /\\/(java|ecma)script/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|\\-\\-)/,\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\t_default: [ 0, \"\", \"\" ]\n\t};\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// IE can't serialize <link> and <script> tags normally\nif ( !jQuery.support.htmlSerialize ) {\n\twrapMap._default = [ 1, \"div<div>\", \"</div>\" ];\n}\n\njQuery.fn.extend({\n\ttext: function( text ) {\n\t\tif ( jQuery.isFunction(text) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery( this );\n\n\t\t\t\tself.text( text.call(this, i, self.text()) );\n\t\t\t});\n\t\t}\n\n\t\tif ( typeof text !== \"object\" && text !== undefined ) {\n\t\t\treturn this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );\n\t\t}\n\n\t\treturn jQuery.text( this );\n\t},\n\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\t// The elements to wrap the target around\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery( this ).wrapAll( html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip(arguments, true, function( elem ) {\n\t\t\tif ( this.nodeType === 1 ) {\n\t\t\t\tthis.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip(arguments, true, function( elem ) {\n\t\t\tif ( this.nodeType === 1 ) {\n\t\t\t\tthis.insertBefore( elem, this.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\tif ( this[0] && this[0].parentNode ) {\n\t\t\treturn this.domManip(arguments, false, function( elem ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t});\n\t\t} else if ( arguments.length ) {\n\t\t\tvar set = jQuery(arguments[0]);\n\t\t\tset.push.apply( set, this.toArray() );\n\t\t\treturn this.pushStack( set, \"before\", arguments );\n\t\t}\n\t},\n\n\tafter: function() {\n\t\tif ( this[0] && this[0].parentNode ) {\n\t\t\treturn this.domManip(arguments, false, function( elem ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t});\n\t\t} else if ( arguments.length ) {\n\t\t\tvar set = this.pushStack( this, \"after\", arguments );\n\t\t\tset.push.apply( set, jQuery(arguments[0]).toArray() );\n\t\t\treturn set;\n\t\t}\n\t},\n\n\t// keepData is for internal use only--do not document\n\tremove: function( selector, keepData ) {\n\t\tfor ( var i = 0, elem; (elem = this[i]) != null; i++ ) {\n\t\t\tif ( !selector || jQuery.filter( selector, [ elem ] ).length ) {\n\t\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\t\tjQuery.cleanData( elem.getElementsByTagName(\"*\") );\n\t\t\t\t\tjQuery.cleanData( [ elem ] );\n\t\t\t\t}\n\n\t\t\t\tif ( elem.parentNode ) {\n\t\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tfor ( var i = 0, elem; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( elem.getElementsByTagName(\"*\") );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function () {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\tif ( value === undefined ) {\n\t\t\treturn this[0] && this[0].nodeType === 1 ?\n\t\t\t\tthis[0].innerHTML.replace(rinlinejQuery, \"\") :\n\t\t\t\tnull;\n\n\t\t// See if we can take a shortcut and just use innerHTML\n\t\t} else if ( typeof value === \"string\" && !rnocache.test( value ) &&\n\t\t\t(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&\n\t\t\t!wrapMap[ (rtagName.exec( value ) || [\"\", \"\"])[1].toLowerCase() ] ) {\n\n\t\t\tvalue = value.replace(rxhtmlTag, \"<$1></$2>\");\n\n\t\t\ttry {\n\t\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\tif ( this[i].nodeType === 1 ) {\n\t\t\t\t\t\tjQuery.cleanData( this[i].getElementsByTagName(\"*\") );\n\t\t\t\t\t\tthis[i].innerHTML = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t} catch(e) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\n\t\t} else if ( jQuery.isFunction( value ) ) {\n\t\t\tthis.each(function(i){\n\t\t\t\tvar self = jQuery( this );\n\n\t\t\t\tself.html( value.call(this, i, self.html()) );\n\t\t\t});\n\n\t\t} else {\n\t\t\tthis.empty().append( value );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\treplaceWith: function( value ) {\n\t\tif ( this[0] && this[0].parentNode ) {\n\t\t\t// Make sure that the elements are removed from the DOM before they are inserted\n\t\t\t// this can help fix replacing a parent with child elements\n\t\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\t\treturn this.each(function(i) {\n\t\t\t\t\tvar self = jQuery(this), old = self.html();\n\t\t\t\t\tself.replaceWith( value.call( this, i, old ) );\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ( typeof value !== \"string\" ) {\n\t\t\t\tvalue = jQuery( value ).detach();\n\t\t\t}\n\n\t\t\treturn this.each(function() {\n\t\t\t\tvar next = this.nextSibling,\n\t\t\t\t\tparent = this.parentNode;\n\n\t\t\t\tjQuery( this ).remove();\n\n\t\t\t\tif ( next ) {\n\t\t\t\t\tjQuery(next).before( value );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery(parent).append( value );\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\treturn this.length ?\n\t\t\t\tthis.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), \"replaceWith\", value ) :\n\t\t\t\tthis;\n\t\t}\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, table, callback ) {\n\t\tvar results, first, fragment, parent,\n\t\t\tvalue = args[0],\n\t\t\tscripts = [];\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === \"string\" && rchecked.test( value ) ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery(this).domManip( args, table, callback, true );\n\t\t\t});\n\t\t}\n\n\t\tif ( jQuery.isFunction(value) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery(this);\n\t\t\t\targs[0] = value.call(this, i, table ? self.html() : undefined);\n\t\t\t\tself.domManip( args, table, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\tparent = value && value.parentNode;\n\n\t\t\t// If we're in a fragment, just use that instead of building a new one\n\t\t\tif ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {\n\t\t\t\tresults = { fragment: parent };\n\n\t\t\t} else {\n\t\t\t\tresults = jQuery.buildFragment( args, this, scripts );\n\t\t\t}\n\n\t\t\tfragment = results.fragment;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfirst = fragment = fragment.firstChild;\n\t\t\t} else {\n\t\t\t\tfirst = fragment.firstChild;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\ttable = table && jQuery.nodeName( first, \"tr\" );\n\n\t\t\t\tfor ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {\n\t\t\t\t\tcallback.call(\n\t\t\t\t\t\ttable ?\n\t\t\t\t\t\t\troot(this[i], first) :\n\t\t\t\t\t\t\tthis[i],\n\t\t\t\t\t\t// Make sure that we do not leak memory by inadvertently discarding\n\t\t\t\t\t\t// the original fragment (which might have attached data) instead of\n\t\t\t\t\t\t// using it; in addition, use the original fragment object for the last\n\t\t\t\t\t\t// item instead of first because it can end up being emptied incorrectly\n\t\t\t\t\t\t// in certain situations (Bug #8070).\n\t\t\t\t\t\t// Fragments from the fragment cache must always be cloned and never used\n\t\t\t\t\t\t// in place.\n\t\t\t\t\t\tresults.cacheable || (l > 1 && i < lastIndex) ?\n\t\t\t\t\t\t\tjQuery.clone( fragment, true, true ) :\n\t\t\t\t\t\t\tfragment\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( scripts.length ) {\n\t\t\t\tjQuery.each( scripts, evalScript );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\nfunction root( elem, cur ) {\n\treturn jQuery.nodeName(elem, \"table\") ?\n\t\t(elem.getElementsByTagName(\"tbody\")[0] ||\n\t\telem.appendChild(elem.ownerDocument.createElement(\"tbody\"))) :\n\t\telem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar internalKey = jQuery.expando,\n\t\toldData = jQuery.data( src ),\n\t\tcurData = jQuery.data( dest, oldData );\n\n\t// Switch to use the internal data object, if it exists, for the next\n\t// stage of data copying\n\tif ( (oldData = oldData[ internalKey ]) ) {\n\t\tvar events = oldData.events;\n\t\t\t\tcurData = curData[ internalKey ] = jQuery.extend({}, oldData);\n\n\t\tif ( events ) {\n\t\t\tdelete curData.handle;\n\t\t\tcurData.events = {};\n\n\t\t\tfor ( var type in events ) {\n\t\t\t\tfor ( var i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? \".\" : \"\" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction cloneFixAttributes( src, dest ) {\n\tvar nodeName;\n\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// clearAttributes removes the attributes, which we don't want,\n\t// but also removes the attachEvent events, which we *do* want\n\tif ( dest.clearAttributes ) {\n\t\tdest.clearAttributes();\n\t}\n\n\t// mergeAttributes, in contrast, only merges back on the\n\t// original attributes, not the events\n\tif ( dest.mergeAttributes ) {\n\t\tdest.mergeAttributes( src );\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\n\t// IE6-8 fail to clone children inside object elements that use\n\t// the proprietary classid attribute value (rather than the type\n\t// attribute) to identify the type of content to display\n\tif ( nodeName === \"object\" ) {\n\t\tdest.outerHTML = src.outerHTML;\n\n\t} else if ( nodeName === \"input\" && (src.type === \"checkbox\" || src.type === \"radio\") ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\t\tif ( src.checked ) {\n\t\t\tdest.defaultChecked = dest.checked = src.checked;\n\t\t}\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n\n\t// Event data gets referenced instead of copied if the expando\n\t// gets copied too\n\tdest.removeAttribute( jQuery.expando );\n}\n\njQuery.buildFragment = function( args, nodes, scripts ) {\n\tvar fragment, cacheable, cacheresults, doc;\n\n  // nodes may contain either an explicit document object,\n  // a jQuery collection or context object.\n  // If nodes[0] contains a valid object to assign to doc\n  if ( nodes && nodes[0] ) {\n    doc = nodes[0].ownerDocument || nodes[0];\n  }\n\n  // Ensure that an attr object doesn't incorrectly stand in as a document object\n\t// Chrome and Firefox seem to allow this to occur and will throw exception\n\t// Fixes #8950\n\tif ( !doc.createDocumentFragment ) {\n\t\tdoc = document;\n\t}\n\n\t// Only cache \"small\" (1/2 KB) HTML strings that are associated with the main document\n\t// Cloning options loses the selected state, so don't cache them\n\t// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment\n\t// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache\n\tif ( args.length === 1 && typeof args[0] === \"string\" && args[0].length < 512 && doc === document &&\n\t\targs[0].charAt(0) === \"<\" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {\n\n\t\tcacheable = true;\n\n\t\tcacheresults = jQuery.fragments[ args[0] ];\n\t\tif ( cacheresults && cacheresults !== 1 ) {\n\t\t\tfragment = cacheresults;\n\t\t}\n\t}\n\n\tif ( !fragment ) {\n\t\tfragment = doc.createDocumentFragment();\n\t\tjQuery.clean( args, doc, fragment, scripts );\n\t}\n\n\tif ( cacheable ) {\n\t\tjQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;\n\t}\n\n\treturn { fragment: fragment, cacheable: cacheable };\n};\n\njQuery.fragments = {};\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar ret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tparent = this.length === 1 && this[0].parentNode;\n\n\t\tif ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {\n\t\t\tinsert[ original ]( this[0] );\n\t\t\treturn this;\n\n\t\t} else {\n\t\t\tfor ( var i = 0, l = insert.length; i < l; i++ ) {\n\t\t\t\tvar elems = (i > 0 ? this.clone(true) : this).get();\n\t\t\t\tjQuery( insert[i] )[ original ]( elems );\n\t\t\t\tret = ret.concat( elems );\n\t\t\t}\n\n\t\t\treturn this.pushStack( ret, name, insert.selector );\n\t\t}\n\t};\n});\n\nfunction getAll( elem ) {\n\tif ( \"getElementsByTagName\" in elem ) {\n\t\treturn elem.getElementsByTagName( \"*\" );\n\n\t} else if ( \"querySelectorAll\" in elem ) {\n\t\treturn elem.querySelectorAll( \"*\" );\n\n\t} else {\n\t\treturn [];\n\t}\n}\n\n// Used in clean, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n\tif ( elem.type === \"checkbox\" || elem.type === \"radio\" ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\n// Finds all inputs and passes them to fixDefaultChecked\nfunction findInputs( elem ) {\n\tif ( jQuery.nodeName( elem, \"input\" ) ) {\n\t\tfixDefaultChecked( elem );\n\t} else if ( \"getElementsByTagName\" in elem ) {\n\t\tjQuery.grep( elem.getElementsByTagName(\"input\"), fixDefaultChecked );\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar clone = elem.cloneNode(true),\n\t\t\t\tsrcElements,\n\t\t\t\tdestElements,\n\t\t\t\ti;\n\n\t\tif ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\t\t\t// IE copies events bound via attachEvent when using cloneNode.\n\t\t\t// Calling detachEvent on the clone will also remove the events\n\t\t\t// from the original. In order to get around this, we use some\n\t\t\t// proprietary methods to clear the events. Thanks to MooTools\n\t\t\t// guys for this hotness.\n\n\t\t\tcloneFixAttributes( elem, clone );\n\n\t\t\t// Using Sizzle here is crazy slow, so we use getElementsByTagName\n\t\t\t// instead\n\t\t\tsrcElements = getAll( elem );\n\t\t\tdestElements = getAll( clone );\n\n\t\t\t// Weird iteration because IE will replace the length property\n\t\t\t// with an element if you are cloning the body and one of the\n\t\t\t// elements on the page has a name or id of \"length\"\n\t\t\tfor ( i = 0; srcElements[i]; ++i ) {\n\t\t\t\tcloneFixAttributes( srcElements[i], destElements[i] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tcloneCopyEvent( elem, clone );\n\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = getAll( elem );\n\t\t\t\tdestElements = getAll( clone );\n\n\t\t\t\tfor ( i = 0; srcElements[i]; ++i ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[i], destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsrcElements = destElements = null;\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tclean: function( elems, context, fragment, scripts ) {\n\t\tvar checkScriptType;\n\n\t\tcontext = context || document;\n\n\t\t// !context.createElement fails in IE with an error but returns typeof 'object'\n\t\tif ( typeof context.createElement === \"undefined\" ) {\n\t\t\tcontext = context.ownerDocument || context[0] && context[0].ownerDocument || document;\n\t\t}\n\n\t\tvar ret = [], j;\n\n\t\tfor ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( typeof elem === \"number\" ) {\n\t\t\t\telem += \"\";\n\t\t\t}\n\n\t\t\tif ( !elem ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Convert html string into DOM nodes\n\t\t\tif ( typeof elem === \"string\" ) {\n\t\t\t\tif ( !rhtml.test( elem ) ) {\n\t\t\t\t\telem = context.createTextNode( elem );\n\t\t\t\t} else {\n\t\t\t\t\t// Fix \"XHTML\"-style tags in all browsers\n\t\t\t\t\telem = elem.replace(rxhtmlTag, \"<$1></$2>\");\n\n\t\t\t\t\t// Trim whitespace, otherwise indexOf won't work as expected\n\t\t\t\t\tvar tag = (rtagName.exec( elem ) || [\"\", \"\"])[1].toLowerCase(),\n\t\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default,\n\t\t\t\t\t\tdepth = wrap[0],\n\t\t\t\t\t\tdiv = context.createElement(\"div\");\n\n\t\t\t\t\t// Go to html and back, then peel off extra wrappers\n\t\t\t\t\tdiv.innerHTML = wrap[1] + elem + wrap[2];\n\n\t\t\t\t\t// Move to the right depth\n\t\t\t\t\twhile ( depth-- ) {\n\t\t\t\t\t\tdiv = div.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove IE's autoinserted <tbody> from table fragments\n\t\t\t\t\tif ( !jQuery.support.tbody ) {\n\n\t\t\t\t\t\t// String was a <table>, *may* have spurious <tbody>\n\t\t\t\t\t\tvar hasBody = rtbody.test(elem),\n\t\t\t\t\t\t\ttbody = tag === \"table\" && !hasBody ?\n\t\t\t\t\t\t\t\tdiv.firstChild && div.firstChild.childNodes :\n\n\t\t\t\t\t\t\t\t// String was a bare <thead> or <tfoot>\n\t\t\t\t\t\t\t\twrap[1] === \"<table>\" && !hasBody ?\n\t\t\t\t\t\t\t\t\tdiv.childNodes :\n\t\t\t\t\t\t\t\t\t[];\n\n\t\t\t\t\t\tfor ( j = tbody.length - 1; j >= 0 ; --j ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( tbody[ j ], \"tbody\" ) && !tbody[ j ].childNodes.length ) {\n\t\t\t\t\t\t\t\ttbody[ j ].parentNode.removeChild( tbody[ j ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// IE completely kills leading whitespace when innerHTML is used\n\t\t\t\t\tif ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tdiv.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );\n\t\t\t\t\t}\n\n\t\t\t\t\telem = div.childNodes;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Resets defaultChecked for any radios and checkboxes\n\t\t\t// about to be appended to the DOM in IE 6/7 (#8060)\n\t\t\tvar len;\n\t\t\tif ( !jQuery.support.appendChecked ) {\n\t\t\t\tif ( elem[0] && typeof (len = elem.length) === \"number\" ) {\n\t\t\t\t\tfor ( j = 0; j < len; j++ ) {\n\t\t\t\t\t\tfindInputs( elem[j] );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfindInputs( elem );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( elem.nodeType ) {\n\t\t\t\tret.push( elem );\n\t\t\t} else {\n\t\t\t\tret = jQuery.merge( ret, elem );\n\t\t\t}\n\t\t}\n\n\t\tif ( fragment ) {\n\t\t\tcheckScriptType = function( elem ) {\n\t\t\t\treturn !elem.type || rscriptType.test( elem.type );\n\t\t\t};\n\t\t\tfor ( i = 0; ret[i]; i++ ) {\n\t\t\t\tif ( scripts && jQuery.nodeName( ret[i], \"script\" ) && (!ret[i].type || ret[i].type.toLowerCase() === \"text/javascript\") ) {\n\t\t\t\t\tscripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );\n\n\t\t\t\t} else {\n\t\t\t\t\tif ( ret[i].nodeType === 1 ) {\n\t\t\t\t\t\tvar jsTags = jQuery.grep( ret[i].getElementsByTagName( \"script\" ), checkScriptType );\n\n\t\t\t\t\t\tret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );\n\t\t\t\t\t}\n\t\t\t\t\tfragment.appendChild( ret[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,\n\t\t\tdeleteExpando = jQuery.support.deleteExpando;\n\n\t\tfor ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tid = elem[ jQuery.expando ];\n\n\t\t\tif ( id ) {\n\t\t\t\tdata = cache[ id ] && cache[ id ][ internalKey ];\n\n\t\t\t\tif ( data && data.events ) {\n\t\t\t\t\tfor ( var type in data.events ) {\n\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Null the DOM reference to avoid IE6/7/8 leak (#7054)\n\t\t\t\t\tif ( data.handle ) {\n\t\t\t\t\t\tdata.handle.elem = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\tdelete elem[ jQuery.expando ];\n\n\t\t\t\t} else if ( elem.removeAttribute ) {\n\t\t\t\t\telem.removeAttribute( jQuery.expando );\n\t\t\t\t}\n\n\t\t\t\tdelete cache[ id ];\n\t\t\t}\n\t\t}\n\t}\n});\n\nfunction evalScript( i, elem ) {\n\tif ( elem.src ) {\n\t\tjQuery.ajax({\n\t\t\turl: elem.src,\n\t\t\tasync: false,\n\t\t\tdataType: \"script\"\n\t\t});\n\t} else {\n\t\tjQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || \"\" ).replace( rcleanScript, \"/*$0*/\" ) );\n\t}\n\n\tif ( elem.parentNode ) {\n\t\telem.parentNode.removeChild( elem );\n\t}\n}\n\n\n\nvar ralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity=([^)]*)/,\n\t// fixed for IE9, see #8346\n\trupper = /([A-Z]|^ms)/g,\n\trnumpx = /^-?\\d+(?:px)?$/i,\n\trnum = /^-?\\d/,\n\trrelNum = /^[+\\-]=/,\n\trrelNumFilter = /[^+\\-\\.\\de]+/g,\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssWidth = [ \"Left\", \"Right\" ],\n\tcssHeight = [ \"Top\", \"Bottom\" ],\n\tcurCSS,\n\n\tgetComputedStyle,\n\tcurrentStyle;\n\njQuery.fn.css = function( name, value ) {\n\t// Setting 'undefined' is a no-op\n\tif ( arguments.length === 2 && value === undefined ) {\n\t\treturn this;\n\t}\n\n\treturn jQuery.access( this, name, value, true, function( elem, name, value ) {\n\t\treturn value !== undefined ?\n\t\t\tjQuery.style( elem, name, value ) :\n\t\t\tjQuery.css( elem, name );\n\t});\n};\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\", \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\n\t\t\t\t} else {\n\t\t\t\t\treturn elem.style.opacity;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Exclude the following css properties to add px\n\tcssNumber: {\n\t\t\"fillOpacity\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": jQuery.support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, origName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style, hooks = jQuery.cssHooks[ origName ];\n\n\t\tname = jQuery.cssProps[ origName ] || origName;\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Make sure that NaN and null values aren't set. See: #7116\n\t\t\tif ( type === \"number\" && isNaN( value ) || value == null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && rrelNum.test( value ) ) {\n\t\t\t\tvalue = +value.replace( rrelNumFilter, \"\" ) + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {\n\t\t\t\t// Wrapped to prevent IE from throwing errors when 'invalid' values are provided\n\t\t\t\t// Fixes bug #5509\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra ) {\n\t\tvar ret, hooks;\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.camelCase( name );\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tname = jQuery.cssProps[ name ] || name;\n\n\t\t// cssFloat needs a special treatment\n\t\tif ( name === \"cssFloat\" ) {\n\t\t\tname = \"float\";\n\t\t}\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {\n\t\t\treturn ret;\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\t} else if ( curCSS ) {\n\t\t\treturn curCSS( elem, name );\n\t\t}\n\t},\n\n\t// A method for quickly swapping in/out CSS properties to get correct calculations\n\tswap: function( elem, options, callback ) {\n\t\tvar old = {};\n\n\t\t// Remember the old values, and insert the new ones\n\t\tfor ( var name in options ) {\n\t\t\told[ name ] = elem.style[ name ];\n\t\t\telem.style[ name ] = options[ name ];\n\t\t}\n\n\t\tcallback.call( elem );\n\n\t\t// Revert the old values\n\t\tfor ( name in options ) {\n\t\t\telem.style[ name ] = old[ name ];\n\t\t}\n\t}\n});\n\n// DEPRECATED, Use jQuery.css() instead\njQuery.curCSS = jQuery.css;\n\njQuery.each([\"height\", \"width\"], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tvar val;\n\n\t\t\tif ( computed ) {\n\t\t\t\tif ( elem.offsetWidth !== 0 ) {\n\t\t\t\t\treturn getWH( elem, name, extra );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\tval = getWH( elem, name, extra );\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn val;\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tif ( rnumpx.test( value ) ) {\n\t\t\t\t// ignore negative width and height values #1599\n\t\t\t\tvalue = parseFloat( value );\n\n\t\t\t\tif ( value >= 0 ) {\n\t\t\t\t\treturn value + \"px\";\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t};\n});\n\nif ( !jQuery.support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\t// IE uses filters for opacity\n\t\t\treturn ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n\t\t\t\t( parseFloat( RegExp.$1 ) / 100 ) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style,\n\t\t\t\tcurrentStyle = elem.currentStyle;\n\n\t\t\t// IE has trouble with opacity if it does not have layout\n\t\t\t// Force it by setting the zoom level\n\t\t\tstyle.zoom = 1;\n\n\t\t\t// Set the alpha filter to set the opacity\n\t\t\tvar opacity = jQuery.isNaN( value ) ?\n\t\t\t\t\"\" :\n\t\t\t\t\"alpha(opacity=\" + value * 100 + \")\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n\t\t\tstyle.filter = ralpha.test( filter ) ?\n\t\t\t\tfilter.replace( ralpha, opacity ) :\n\t\t\t\tfilter + \" \" + opacity;\n\t\t}\n\t};\n}\n\njQuery(function() {\n\t// This hook cannot be added until DOM ready because the support test\n\t// for it is not run until after DOM ready\n\tif ( !jQuery.support.reliableMarginRight ) {\n\t\tjQuery.cssHooks.marginRight = {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t\t// Work around by temporarily setting element display to inline-block\n\t\t\t\tvar ret;\n\t\t\t\tjQuery.swap( elem, { \"display\": \"inline-block\" }, function() {\n\t\t\t\t\tif ( computed ) {\n\t\t\t\t\t\tret = curCSS( elem, \"margin-right\", \"marginRight\" );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tret = elem.style.marginRight;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t};\n\t}\n});\n\nif ( document.defaultView && document.defaultView.getComputedStyle ) {\n\tgetComputedStyle = function( elem, name ) {\n\t\tvar ret, defaultView, computedStyle;\n\n\t\tname = name.replace( rupper, \"-$1\" ).toLowerCase();\n\n\t\tif ( !(defaultView = elem.ownerDocument.defaultView) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {\n\t\t\tret = computedStyle.getPropertyValue( name );\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t};\n}\n\nif ( document.documentElement.currentStyle ) {\n\tcurrentStyle = function( elem, name ) {\n\t\tvar left,\n\t\t\tret = elem.currentStyle && elem.currentStyle[ name ],\n\t\t\trsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],\n\t\t\tstyle = elem.style;\n\n\t\t// From the awesome hack by Dean Edwards\n\t\t// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n\t\t// If we're not dealing with a regular pixel number\n\t\t// but a number that has a weird ending, we need to convert it to pixels\n\t\tif ( !rnumpx.test( ret ) && rnum.test( ret ) ) {\n\t\t\t// Remember the original values\n\t\t\tleft = style.left;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tif ( rsLeft ) {\n\t\t\t\telem.runtimeStyle.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : (ret || 0);\n\t\t\tret = style.pixelLeft + \"px\";\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\telem.runtimeStyle.left = rsLeft;\n\t\t\t}\n\t\t}\n\n\t\treturn ret === \"\" ? \"auto\" : ret;\n\t};\n}\n\ncurCSS = getComputedStyle || currentStyle;\n\nfunction getWH( elem, name, extra ) {\n\n\t// Start with offset property\n\tvar val = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\twhich = name === \"width\" ? cssWidth : cssHeight;\n\n\tif ( val > 0 ) {\n\t\tif ( extra !== \"border\" ) {\n\t\t\tjQuery.each( which, function() {\n\t\t\t\tif ( !extra ) {\n\t\t\t\t\tval -= parseFloat( jQuery.css( elem, \"padding\" + this ) ) || 0;\n\t\t\t\t}\n\t\t\t\tif ( extra === \"margin\" ) {\n\t\t\t\t\tval += parseFloat( jQuery.css( elem, extra + this ) ) || 0;\n\t\t\t\t} else {\n\t\t\t\t\tval -= parseFloat( jQuery.css( elem, \"border\" + this + \"Width\" ) ) || 0;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn val + \"px\";\n\t}\n\n\t// Fall back to computed then uncomputed css if necessary\n\tval = curCSS( elem, name, name );\n\tif ( val < 0 || val == null ) {\n\t\tval = elem.style[ name ] || 0;\n\t}\n\t// Normalize \"\", auto, and prepare for extra\n\tval = parseFloat( val ) || 0;\n\n\t// Add padding, border, margin\n\tif ( extra ) {\n\t\tjQuery.each( which, function() {\n\t\t\tval += parseFloat( jQuery.css( elem, \"padding\" + this ) ) || 0;\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += parseFloat( jQuery.css( elem, \"border\" + this + \"Width\" ) ) || 0;\n\t\t\t}\n\t\t\tif ( extra === \"margin\" ) {\n\t\t\t\tval += parseFloat( jQuery.css( elem, extra + this ) ) || 0;\n\t\t\t}\n\t\t});\n\t}\n\n\treturn val + \"px\";\n}\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.hidden = function( elem ) {\n\t\tvar width = elem.offsetWidth,\n\t\t\theight = elem.offsetHeight;\n\n\t\treturn (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, \"display\" )) === \"none\");\n\t};\n\n\tjQuery.expr.filters.visible = function( elem ) {\n\t\treturn !jQuery.expr.filters.hidden( elem );\n\t};\n}\n\n\n\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trhash = /#.*$/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\trinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app\\-storage|.+\\-extension|file|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trquery = /\\?/,\n\trscript = /<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi,\n\trselectTextarea = /^(?:select|textarea)/i,\n\trspacesAjax = /\\s+/,\n\trts = /([?&])_=[^&]*/,\n\trurl = /^([\\w\\+\\.\\-]+:)(?:\\/\\/([^\\/?#:]*)(?::(\\d+))?)?/,\n\n\t// Keep a copy of the old load method\n\t_load = jQuery.fn.load,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Document location\n\tajaxLocation,\n\n\t// Document location segments\n\tajaxLocParts;\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\tvar dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),\n\t\t\t\ti = 0,\n\t\t\t\tlength = dataTypes.length,\n\t\t\t\tdataType,\n\t\t\t\tlist,\n\t\t\t\tplaceBefore;\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\tfor(; i < length; i++ ) {\n\t\t\t\tdataType = dataTypes[ i ];\n\t\t\t\t// We control if we're asked to add before\n\t\t\t\t// any existing element\n\t\t\t\tplaceBefore = /^\\+/.test( dataType );\n\t\t\t\tif ( placeBefore ) {\n\t\t\t\t\tdataType = dataType.substr( 1 ) || \"*\";\n\t\t\t\t}\n\t\t\t\tlist = structure[ dataType ] = structure[ dataType ] || [];\n\t\t\t\t// then we add to the structure accordingly\n\t\t\t\tlist[ placeBefore ? \"unshift\" : \"push\" ]( func );\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,\n\t\tdataType /* internal */, inspected /* internal */ ) {\n\n\tdataType = dataType || options.dataTypes[ 0 ];\n\tinspected = inspected || {};\n\n\tinspected[ dataType ] = true;\n\n\tvar list = structure[ dataType ],\n\t\ti = 0,\n\t\tlength = list ? list.length : 0,\n\t\texecuteOnly = ( structure === prefilters ),\n\t\tselection;\n\n\tfor(; i < length && ( executeOnly || !selection ); i++ ) {\n\t\tselection = list[ i ]( options, originalOptions, jqXHR );\n\t\t// If we got redirected to another dataType\n\t\t// we try there if executing only and not done already\n\t\tif ( typeof selection === \"string\" ) {\n\t\t\tif ( !executeOnly || inspected[ selection ] ) {\n\t\t\t\tselection = undefined;\n\t\t\t} else {\n\t\t\t\toptions.dataTypes.unshift( selection );\n\t\t\t\tselection = inspectPrefiltersOrTransports(\n\t\t\t\t\t\tstructure, options, originalOptions, jqXHR, selection, inspected );\n\t\t\t}\n\t\t}\n\t}\n\t// If we're only executing or nothing was selected\n\t// we try the catchall dataType if not done already\n\tif ( ( executeOnly || !selection ) && !inspected[ \"*\" ] ) {\n\t\tselection = inspectPrefiltersOrTransports(\n\t\t\t\tstructure, options, originalOptions, jqXHR, \"*\", inspected );\n\t}\n\t// unnecessary when only executing (prefilters)\n\t// but it'll be ignored by the caller in that case\n\treturn selection;\n}\n\njQuery.fn.extend({\n\tload: function( url, params, callback ) {\n\t\tif ( typeof url !== \"string\" && _load ) {\n\t\t\treturn _load.apply( this, arguments );\n\n\t\t// Don't do a request if no elements are being requested\n\t\t} else if ( !this.length ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tvar off = url.indexOf( \" \" );\n\t\tif ( off >= 0 ) {\n\t\t\tvar selector = url.slice( off, url.length );\n\t\t\turl = url.slice( 0, off );\n\t\t}\n\n\t\t// Default to a GET request\n\t\tvar type = \"GET\";\n\n\t\t// If the second parameter was provided\n\t\tif ( params ) {\n\t\t\t// If it's a function\n\t\t\tif ( jQuery.isFunction( params ) ) {\n\t\t\t\t// We assume that it's the callback\n\t\t\t\tcallback = params;\n\t\t\t\tparams = undefined;\n\n\t\t\t// Otherwise, build a param string\n\t\t\t} else if ( typeof params === \"object\" ) {\n\t\t\t\tparams = jQuery.param( params, jQuery.ajaxSettings.traditional );\n\t\t\t\ttype = \"POST\";\n\t\t\t}\n\t\t}\n\n\t\tvar self = this;\n\n\t\t// Request the remote document\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params,\n\t\t\t// Complete callback (responseText is used internally)\n\t\t\tcomplete: function( jqXHR, status, responseText ) {\n\t\t\t\t// Store the response as specified by the jqXHR object\n\t\t\t\tresponseText = jqXHR.responseText;\n\t\t\t\t// If successful, inject the HTML into all the matched elements\n\t\t\t\tif ( jqXHR.isResolved() ) {\n\t\t\t\t\t// #4825: Get the actual response in case\n\t\t\t\t\t// a dataFilter is present in ajaxSettings\n\t\t\t\t\tjqXHR.done(function( r ) {\n\t\t\t\t\t\tresponseText = r;\n\t\t\t\t\t});\n\t\t\t\t\t// See if a selector was specified\n\t\t\t\t\tself.html( selector ?\n\t\t\t\t\t\t// Create a dummy div to hold the results\n\t\t\t\t\t\tjQuery(\"<div>\")\n\t\t\t\t\t\t\t// inject the contents of the document in, removing the scripts\n\t\t\t\t\t\t\t// to avoid any 'Permission Denied' errors in IE\n\t\t\t\t\t\t\t.append(responseText.replace(rscript, \"\"))\n\n\t\t\t\t\t\t\t// Locate the specified elements\n\t\t\t\t\t\t\t.find(selector) :\n\n\t\t\t\t\t\t// If not, just inject the full result\n\t\t\t\t\t\tresponseText );\n\t\t\t\t}\n\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tself.each( callback, [ responseText, status, jqXHR ] );\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn this;\n\t},\n\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\n\tserializeArray: function() {\n\t\treturn this.map(function(){\n\t\t\treturn this.elements ? jQuery.makeArray( this.elements ) : this;\n\t\t})\n\t\t.filter(function(){\n\t\t\treturn this.name && !this.disabled &&\n\t\t\t\t( this.checked || rselectTextarea.test( this.nodeName ) ||\n\t\t\t\t\trinput.test( this.type ) );\n\t\t})\n\t\t.map(function( i, elem ){\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val, i ){\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( \"ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend\".split( \" \" ), function( i, o ){\n\tjQuery.fn[ o ] = function( f ){\n\t\treturn this.bind( o, f );\n\t};\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\ttype: method,\n\t\t\turl: url,\n\t\t\tdata: data,\n\t\t\tsuccess: callback,\n\t\t\tdataType: type\n\t\t});\n\t};\n});\n\njQuery.extend({\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function ( target, settings ) {\n\t\tif ( !settings ) {\n\t\t\t// Only one parameter, we extend ajaxSettings\n\t\t\tsettings = target;\n\t\t\ttarget = jQuery.extend( true, jQuery.ajaxSettings, settings );\n\t\t} else {\n\t\t\t// target was provided, we extend into it\n\t\t\tjQuery.extend( true, target, jQuery.ajaxSettings, settings );\n\t\t}\n\t\t// Flatten fields we don't want deep extended\n\t\tfor( var field in { context: 1, url: 1 } ) {\n\t\t\tif ( field in settings ) {\n\t\t\t\ttarget[ field ] = settings[ field ];\n\t\t\t} else if( field in jQuery.ajaxSettings ) {\n\t\t\t\ttarget[ field ] = jQuery.ajaxSettings[ field ];\n\t\t\t}\n\t\t}\n\t\treturn target;\n\t},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\ttype: \"GET\",\n\t\tcontentType: \"application/x-www-form-urlencoded\",\n\t\tprocessData: true,\n\t\tasync: true,\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\thtml: \"text/html\",\n\t\t\ttext: \"text/plain\",\n\t\t\tjson: \"application/json, text/javascript\",\n\t\t\t\"*\": \"*/*\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\"\n\t\t},\n\n\t\t// List of data converters\n\t\t// 1) key format is \"source_type destination_type\" (a single space in-between)\n\t\t// 2) the catchall symbol \"*\" can be used for source_type\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": window.String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t}\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar // Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events\n\t\t\t// It's the callbackContext if one was provided in the options\n\t\t\t// and if it's a DOM node or a jQuery collection\n\t\t\tglobalEventContext = callbackContext !== s &&\n\t\t\t\t( callbackContext.nodeType || callbackContext instanceof jQuery ) ?\n\t\t\t\t\t\tjQuery( callbackContext ) : jQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery._Deferred(),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// ifModified key\n\t\t\tifModifiedKey,\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\t\t\t// transport\n\t\t\ttransport,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\t\t\t// Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match === undefined ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tstatusText = statusText || \"abort\";\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( statusText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, statusText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Callback for when everything is done\n\t\t// It is defined here because jslint complains if it is declared\n\t\t// at the end of the function (which would be more logical and readable)\n\t\tfunction done( status, statusText, responses, headers ) {\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status ? 4 : 0;\n\n\t\t\tvar isSuccess,\n\t\t\t\tsuccess,\n\t\t\t\terror,\n\t\t\t\tresponse = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,\n\t\t\t\tlastModified,\n\t\t\t\tetag;\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( status >= 200 && status < 300 || status === 304 ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\n\t\t\t\t\tif ( ( lastModified = jqXHR.getResponseHeader( \"Last-Modified\" ) ) ) {\n\t\t\t\t\t\tjQuery.lastModified[ ifModifiedKey ] = lastModified;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ( etag = jqXHR.getResponseHeader( \"Etag\" ) ) ) {\n\t\t\t\t\t\tjQuery.etag[ ifModifiedKey ] = etag;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If not modified\n\t\t\t\tif ( status === 304 ) {\n\n\t\t\t\t\tstatusText = \"notmodified\";\n\t\t\t\t\tisSuccess = true;\n\n\t\t\t\t// If we have data\n\t\t\t\t} else {\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tsuccess = ajaxConvert( s, response );\n\t\t\t\t\t\tstatusText = \"success\";\n\t\t\t\t\t\tisSuccess = true;\n\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t// We have a parsererror\n\t\t\t\t\t\tstatusText = \"parsererror\";\n\t\t\t\t\t\terror = e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif( !statusText || status ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = statusText;\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajax\" + ( isSuccess ? \"Success\" : \"Error\" ),\n\t\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\t\tjqXHR.complete = completeDeferred.done;\n\n\t\t// Status-dependent callbacks\n\t\tjqXHR.statusCode = function( map ) {\n\t\t\tif ( map ) {\n\t\t\t\tvar tmp;\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tfor( tmp in map ) {\n\t\t\t\t\t\tstatusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttmp = map[ jqXHR.status ];\n\t\t\t\t\tjqXHR.then( tmp, tmp );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this;\n\t\t};\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().split( rspacesAjax );\n\n\t\t// Determine if a cross-domain request is in order\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? 80 : 443 ) ) !=\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? 80 : 443 ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefiler, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\tfireGlobals = s.global;\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.data;\n\t\t\t}\n\n\t\t\t// Get ifModifiedKey before adding the anti-cache parameter\n\t\t\tifModifiedKey = s.url;\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\n\t\t\t\tvar ts = jQuery.now(),\n\t\t\t\t\t// try replacing _= if it is there\n\t\t\t\t\tret = s.url.replace( rts, \"$1_=\" + ts );\n\n\t\t\t\t// if nothing was replaced, add timestamp to the end\n\t\t\t\ts.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? \"&\" : \"?\" ) + \"_=\" + ts : \"\" );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tifModifiedKey = ifModifiedKey || s.url;\n\t\t\tif ( jQuery.lastModified[ ifModifiedKey ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ ifModifiedKey ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ ifModifiedKey ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ ifModifiedKey ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", */*; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t\t// Abort if not done already\n\t\t\t\tjqXHR.abort();\n\t\t\t\treturn false;\n\n\t\t}\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout( function(){\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch (e) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( status < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.error( e );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\t// Serialize an array of form elements or a set of\n\t// key/values into a query string\n\tparam: function( a, traditional ) {\n\t\tvar s = [],\n\t\t\tadd = function( key, value ) {\n\t\t\t\t// If value is a function, invoke it and return its value\n\t\t\t\tvalue = jQuery.isFunction( value ) ? value() : value;\n\t\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t\t};\n\n\t\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\t\tif ( traditional === undefined ) {\n\t\t\ttraditional = jQuery.ajaxSettings.traditional;\n\t\t}\n\n\t\t// If an array was passed in, assume that it is an array of form elements.\n\t\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t\t// Serialize the form elements\n\t\t\tjQuery.each( a, function() {\n\t\t\t\tadd( this.name, this.value );\n\t\t\t});\n\n\t\t} else {\n\t\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t\t// did it), otherwise encode params recursively.\n\t\t\tfor ( var prefix in a ) {\n\t\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t\t}\n\t\t}\n\n\t\t// Return the resulting serialization\n\t\treturn s.join( \"&\" ).replace( r20, \"+\" );\n\t}\n});\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// If array item is non-scalar (array or object), encode its\n\t\t\t\t// numeric index to resolve deserialization ambiguity issues.\n\t\t\t\t// Note that rack (as of 1.0.0) can't currently deserialize\n\t\t\t\t// nested arrays properly, and attempting to do so may cause\n\t\t\t\t// a server error. Possible fixes are to modify rack's\n\t\t\t\t// deserialization algorithm or to provide an option or flag\n\t\t\t\t// to force array serialization to be shallow.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" || jQuery.isArray(v) ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && obj != null && typeof obj === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( var name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// This is still on the jQuery object... for now\n// Want to move this to jQuery.ajax some day\njQuery.extend({\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {}\n\n});\n\n/* Handles responses to an ajax request:\n * - sets all responseXXX fields accordingly\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar contents = s.contents,\n\t\tdataTypes = s.dataTypes,\n\t\tresponseFields = s.responseFields,\n\t\tct,\n\t\ttype,\n\t\tfinalDataType,\n\t\tfirstDataType;\n\n\t// Fill responseXXX fields\n\tfor( type in responseFields ) {\n\t\tif ( type in responses ) {\n\t\t\tjqXHR[ responseFields[type] ] = responses[ type ];\n\t\t}\n\t}\n\n\t// Remove auto dataType and get content-type in the process\n\twhile( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"content-type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n// Chain conversions given the request and the original response\nfunction ajaxConvert( s, response ) {\n\n\t// Apply the dataFilter if provided\n\tif ( s.dataFilter ) {\n\t\tresponse = s.dataFilter( response, s.dataType );\n\t}\n\n\tvar dataTypes = s.dataTypes,\n\t\tconverters = {},\n\t\ti,\n\t\tkey,\n\t\tlength = dataTypes.length,\n\t\ttmp,\n\t\t// Current and previous dataTypes\n\t\tcurrent = dataTypes[ 0 ],\n\t\tprev,\n\t\t// Conversion expression\n\t\tconversion,\n\t\t// Conversion function\n\t\tconv,\n\t\t// Conversion functions (transitive conversion)\n\t\tconv1,\n\t\tconv2;\n\n\t// For each dataType in the chain\n\tfor( i = 1; i < length; i++ ) {\n\n\t\t// Create converters map\n\t\t// with lowercased keys\n\t\tif ( i === 1 ) {\n\t\t\tfor( key in s.converters ) {\n\t\t\t\tif( typeof key === \"string\" ) {\n\t\t\t\t\tconverters[ key.toLowerCase() ] = s.converters[ key ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Get the dataTypes\n\t\tprev = current;\n\t\tcurrent = dataTypes[ i ];\n\n\t\t// If current is auto dataType, update it to prev\n\t\tif( current === \"*\" ) {\n\t\t\tcurrent = prev;\n\t\t// If no auto and dataTypes are actually different\n\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t// Get the converter\n\t\t\tconversion = prev + \" \" + current;\n\t\t\tconv = converters[ conversion ] || converters[ \"* \" + current ];\n\n\t\t\t// If there is no direct converter, search transitively\n\t\t\tif ( !conv ) {\n\t\t\t\tconv2 = undefined;\n\t\t\t\tfor( conv1 in converters ) {\n\t\t\t\t\ttmp = conv1.split( \" \" );\n\t\t\t\t\tif ( tmp[ 0 ] === prev || tmp[ 0 ] === \"*\" ) {\n\t\t\t\t\t\tconv2 = converters[ tmp[1] + \" \" + current ];\n\t\t\t\t\t\tif ( conv2 ) {\n\t\t\t\t\t\t\tconv1 = converters[ conv1 ];\n\t\t\t\t\t\t\tif ( conv1 === true ) {\n\t\t\t\t\t\t\t\tconv = conv2;\n\t\t\t\t\t\t\t} else if ( conv2 === true ) {\n\t\t\t\t\t\t\t\tconv = conv1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If we found no converter, dispatch an error\n\t\t\tif ( !( conv || conv2 ) ) {\n\t\t\t\tjQuery.error( \"No conversion from \" + conversion.replace(\" \",\" to \") );\n\t\t\t}\n\t\t\t// If found converter is not an equivalence\n\t\t\tif ( conv !== true ) {\n\t\t\t\t// Convert with 1 or 2 converters accordingly\n\t\t\t\tresponse = conv ? conv( response ) : conv2( conv1(response) );\n\t\t\t}\n\t\t}\n\t}\n\treturn response;\n}\n\n\n\n\nvar jsc = jQuery.now(),\n\tjsre = /(\\=)\\?(&|$)|\\?\\?/i;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\treturn jQuery.expando + \"_\" + ( jsc++ );\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar inspectData = s.contentType === \"application/x-www-form-urlencoded\" &&\n\t\t( typeof s.data === \"string\" );\n\n\tif ( s.dataTypes[ 0 ] === \"jsonp\" ||\n\t\ts.jsonp !== false && ( jsre.test( s.url ) ||\n\t\t\t\tinspectData && jsre.test( s.data ) ) ) {\n\n\t\tvar responseContainer,\n\t\t\tjsonpCallback = s.jsonpCallback =\n\t\t\t\tjQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,\n\t\t\tprevious = window[ jsonpCallback ],\n\t\t\turl = s.url,\n\t\t\tdata = s.data,\n\t\t\treplace = \"$1\" + jsonpCallback + \"$2\";\n\n\t\tif ( s.jsonp !== false ) {\n\t\t\turl = url.replace( jsre, replace );\n\t\t\tif ( s.url === url ) {\n\t\t\t\tif ( inspectData ) {\n\t\t\t\t\tdata = data.replace( jsre, replace );\n\t\t\t\t}\n\t\t\t\tif ( s.data === data ) {\n\t\t\t\t\t// Add callback manually\n\t\t\t\t\turl += (/\\?/.test( url ) ? \"&\" : \"?\") + s.jsonp + \"=\" + jsonpCallback;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ts.url = url;\n\t\ts.data = data;\n\n\t\t// Install callback\n\t\twindow[ jsonpCallback ] = function( response ) {\n\t\t\tresponseContainer = [ response ];\n\t\t};\n\n\t\t// Clean-up function\n\t\tjqXHR.always(function() {\n\t\t\t// Set callback back to previous value\n\t\t\twindow[ jsonpCallback ] = previous;\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( previous ) ) {\n\t\t\t\twindow[ jsonpCallback ]( responseContainer[ 0 ] );\n\t\t\t}\n\t\t});\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( jsonpCallback + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\n\n\n\n\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /javascript|ecmascript/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || document.getElementsByTagName( \"head\" )[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement( \"script\" );\n\n\t\t\t\tscript.async = \"async\";\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\n\t\t\t\t// Attach handlers for all browsers\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t\t\t// Handle memory leak in IE\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\t\t\t\t// Remove the script\n\t\t\t\t\t\tif ( head && script.parentNode ) {\n\t\t\t\t\t\t\thead.removeChild( script );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Dereference the script\n\t\t\t\t\t\tscript = undefined;\n\n\t\t\t\t\t\t// Callback if not abort\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\t// Use insertBefore instead of appendChild  to circumvent an IE6 bug.\n\t\t\t\t// This arises when a base node is used (#2709 and #4378).\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( 0, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n\n\n\nvar // #5280: Internet Explorer will keep connections alive if we don't abort on unload\n\txhrOnUnloadAbort = window.ActiveXObject ? function() {\n\t\t// Abort all pending requests\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( 0, 1 );\n\t\t}\n\t} : false,\n\txhrId = 0,\n\txhrCallbacks;\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n\t} catch( e ) {}\n}\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject ?\n\t/* Microsoft failed to properly\n\t * implement the XMLHttpRequest in IE7 (can't request local files),\n\t * so we use the ActiveXObject when it is available\n\t * Additionally XMLHttpRequest can be disabled in IE7/IE8 so\n\t * we need a fallback.\n\t */\n\tfunction() {\n\t\treturn !this.isLocal && createStandardXHR() || createActiveXHR();\n\t} :\n\t// For all other browsers, use the standard XMLHttpRequest object\n\tcreateStandardXHR;\n\n// Determine support properties\n(function( xhr ) {\n\tjQuery.extend( jQuery.support, {\n\t\tajax: !!xhr,\n\t\tcors: !!xhr && ( \"withCredentials\" in xhr )\n\t});\n})( jQuery.ajaxSettings.xhr() );\n\n// Create transport if the browser can provide an xhr\nif ( jQuery.support.ajax ) {\n\n\tjQuery.ajaxTransport(function( s ) {\n\t\t// Cross domain only allowed if supported through XMLHttpRequest\n\t\tif ( !s.crossDomain || jQuery.support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\n\t\t\t\t\t// Get a new xhr\n\t\t\t\t\tvar xhr = s.xhr(),\n\t\t\t\t\t\thandle,\n\t\t\t\t\t\ti;\n\n\t\t\t\t\t// Open the socket\n\t\t\t\t\t// Passing null username, generates a login popup on Opera (#2865)\n\t\t\t\t\tif ( s.username ) {\n\t\t\t\t\t\txhr.open( s.type, s.url, s.async, s.username, s.password );\n\t\t\t\t\t} else {\n\t\t\t\t\t\txhr.open( s.type, s.url, s.async );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Apply custom fields if provided\n\t\t\t\t\tif ( s.xhrFields ) {\n\t\t\t\t\t\tfor ( i in s.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = s.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Override mime type if needed\n\t\t\t\t\tif ( s.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( s.mimeType );\n\t\t\t\t\t}\n\n\t\t\t\t\t// X-Requested-With header\n\t\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\t\tif ( !s.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Need an extra try/catch for cross domain requests in Firefox 3\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch( _ ) {}\n\n\t\t\t\t\t// Do send the request\n\t\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\t\txhr.send( ( s.hasContent && s.data ) || null );\n\n\t\t\t\t\t// Listener\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\n\t\t\t\t\t\tvar status,\n\t\t\t\t\t\t\tstatusText,\n\t\t\t\t\t\t\tresponseHeaders,\n\t\t\t\t\t\t\tresponses,\n\t\t\t\t\t\t\txml;\n\n\t\t\t\t\t\t// Firefox throws exceptions when accessing properties\n\t\t\t\t\t\t// of an xhr when a network error occured\n\t\t\t\t\t\t// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)\n\t\t\t\t\t\ttry {\n\n\t\t\t\t\t\t\t// Was never called and is aborted or complete\n\t\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\n\t\t\t\t\t\t\t\t// Only called once\n\t\t\t\t\t\t\t\tcallback = undefined;\n\n\t\t\t\t\t\t\t\t// Do not keep as active anymore\n\t\t\t\t\t\t\t\tif ( handle ) {\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\t\t\t\t\t\t\t\t\tif ( xhrOnUnloadAbort ) {\n\t\t\t\t\t\t\t\t\t\tdelete xhrCallbacks[ handle ];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// If it's an abort\n\t\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\t\t// Abort it manually if needed\n\t\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tstatus = xhr.status;\n\t\t\t\t\t\t\t\t\tresponseHeaders = xhr.getAllResponseHeaders();\n\t\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\t\txml = xhr.responseXML;\n\n\t\t\t\t\t\t\t\t\t// Construct response list\n\t\t\t\t\t\t\t\t\tif ( xml && xml.documentElement /* #4958 */ ) {\n\t\t\t\t\t\t\t\t\t\tresponses.xml = xml;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\n\t\t\t\t\t\t\t\t\t// Firefox throws an exception when accessing\n\t\t\t\t\t\t\t\t\t// statusText for faulty cross-domain requests\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t\t// We normalize with Webkit giving an empty statusText\n\t\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Filter status for non standard behaviors\n\n\t\t\t\t\t\t\t\t\t// If the request is local and we have data: assume a success\n\t\t\t\t\t\t\t\t\t// (success with no data won't get notified, that's the best we\n\t\t\t\t\t\t\t\t\t// can do given current implementations)\n\t\t\t\t\t\t\t\t\tif ( !status && s.isLocal && !s.crossDomain ) {\n\t\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t\t// IE - #1450: sometimes returns 1223 when it should be 204\n\t\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch( firefoxAccessException ) {\n\t\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\t\tcomplete( -1, firefoxAccessException );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Call complete if needed\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, responseHeaders );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\t// if we're in sync mode or it's in cache\n\t\t\t\t\t// and has been retrieved directly (IE6 & IE7)\n\t\t\t\t\t// we need to manually fire the callback\n\t\t\t\t\tif ( !s.async || xhr.readyState === 4 ) {\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else {\n\t\t\t\t\t\thandle = ++xhrId;\n\t\t\t\t\t\tif ( xhrOnUnloadAbort ) {\n\t\t\t\t\t\t\t// Create the active xhrs callbacks list if needed\n\t\t\t\t\t\t\t// and attach the unload handler\n\t\t\t\t\t\t\tif ( !xhrCallbacks ) {\n\t\t\t\t\t\t\t\txhrCallbacks = {};\n\t\t\t\t\t\t\t\tjQuery( window ).unload( xhrOnUnloadAbort );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Add to list of active xhrs callbacks\n\t\t\t\t\t\t\txhrCallbacks[ handle ] = callback;\n\t\t\t\t\t\t}\n\t\t\t\t\t\txhr.onreadystatechange = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback(0,1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\n\n\n\n\nvar elemdisplay = {},\n\tiframe, iframeDoc,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = /^([+\\-]=)?([\\d+.\\-]+)([a-z%]*)$/i,\n\ttimerId,\n\tfxAttrs = [\n\t\t// height animations\n\t\t[ \"height\", \"marginTop\", \"marginBottom\", \"paddingTop\", \"paddingBottom\" ],\n\t\t// width animations\n\t\t[ \"width\", \"marginLeft\", \"marginRight\", \"paddingLeft\", \"paddingRight\" ],\n\t\t// opacity animations\n\t\t[ \"opacity\" ]\n\t],\n\tfxNow,\n\trequestAnimationFrame = window.webkitRequestAnimationFrame ||\n\t\twindow.mozRequestAnimationFrame ||\n\t\twindow.oRequestAnimationFrame;\n\njQuery.fn.extend({\n\tshow: function( speed, easing, callback ) {\n\t\tvar elem, display;\n\n\t\tif ( speed || speed === 0 ) {\n\t\t\treturn this.animate( genFx(\"show\", 3), speed, easing, callback);\n\n\t\t} else {\n\t\t\tfor ( var i = 0, j = this.length; i < j; i++ ) {\n\t\t\t\telem = this[i];\n\n\t\t\t\tif ( elem.style ) {\n\t\t\t\t\tdisplay = elem.style.display;\n\n\t\t\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t\t\t// being hidden by cascaded rules or not\n\t\t\t\t\tif ( !jQuery._data(elem, \"olddisplay\") && display === \"none\" ) {\n\t\t\t\t\t\tdisplay = elem.style.display = \"\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set elements which have been overridden with display: none\n\t\t\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t\t\t// for such an element\n\t\t\t\t\tif ( display === \"\" && jQuery.css( elem, \"display\" ) === \"none\" ) {\n\t\t\t\t\t\tjQuery._data(elem, \"olddisplay\", defaultDisplay(elem.nodeName));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set the display of most of the elements in a second loop\n\t\t\t// to avoid the constant reflow\n\t\t\tfor ( i = 0; i < j; i++ ) {\n\t\t\t\telem = this[i];\n\n\t\t\t\tif ( elem.style ) {\n\t\t\t\t\tdisplay = elem.style.display;\n\n\t\t\t\t\tif ( display === \"\" || display === \"none\" ) {\n\t\t\t\t\t\telem.style.display = jQuery._data(elem, \"olddisplay\") || \"\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\t},\n\n\thide: function( speed, easing, callback ) {\n\t\tif ( speed || speed === 0 ) {\n\t\t\treturn this.animate( genFx(\"hide\", 3), speed, easing, callback);\n\n\t\t} else {\n\t\t\tfor ( var i = 0, j = this.length; i < j; i++ ) {\n\t\t\t\tif ( this[i].style ) {\n\t\t\t\t\tvar display = jQuery.css( this[i], \"display\" );\n\n\t\t\t\t\tif ( display !== \"none\" && !jQuery._data( this[i], \"olddisplay\" ) ) {\n\t\t\t\t\t\tjQuery._data( this[i], \"olddisplay\", display );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set the display of the elements in a second loop\n\t\t\t// to avoid the constant reflow\n\t\t\tfor ( i = 0; i < j; i++ ) {\n\t\t\t\tif ( this[i].style ) {\n\t\t\t\t\tthis[i].style.display = \"none\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\t},\n\n\t// Save the old toggle function\n\t_toggle: jQuery.fn.toggle,\n\n\ttoggle: function( fn, fn2, callback ) {\n\t\tvar bool = typeof fn === \"boolean\";\n\n\t\tif ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {\n\t\t\tthis._toggle.apply( this, arguments );\n\n\t\t} else if ( fn == null || bool ) {\n\t\t\tthis.each(function() {\n\t\t\t\tvar state = bool ? fn : jQuery(this).is(\":hidden\");\n\t\t\t\tjQuery(this)[ state ? \"show\" : \"hide\" ]();\n\t\t\t});\n\n\t\t} else {\n\t\t\tthis.animate(genFx(\"toggle\", 3), fn, fn2, callback);\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tfadeTo: function( speed, to, easing, callback ) {\n\t\treturn this.filter(\":hidden\").css(\"opacity\", 0).show().end()\n\t\t\t\t\t.animate({opacity: to}, speed, easing, callback);\n\t},\n\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar optall = jQuery.speed(speed, easing, callback);\n\n\t\tif ( jQuery.isEmptyObject( prop ) ) {\n\t\t\treturn this.each( optall.complete, [ false ] );\n\t\t}\n\n\t\t// Do not change referenced properties as per-property easing will be lost\n\t\tprop = jQuery.extend( {}, prop );\n\n\t\treturn this[ optall.queue === false ? \"each\" : \"queue\" ](function() {\n\t\t\t// XXX 'this' does not always have a nodeName when running the\n\t\t\t// test suite\n\n\t\t\tif ( optall.queue === false ) {\n\t\t\t\tjQuery._mark( this );\n\t\t\t}\n\n\t\t\tvar opt = jQuery.extend( {}, optall ),\n\t\t\t\tisElement = this.nodeType === 1,\n\t\t\t\thidden = isElement && jQuery(this).is(\":hidden\"),\n\t\t\t\tname, val, p,\n\t\t\t\tdisplay, e,\n\t\t\t\tparts, start, end, unit;\n\n\t\t\t// will store per property easing and be used to determine when an animation is complete\n\t\t\topt.animatedProperties = {};\n\n\t\t\tfor ( p in prop ) {\n\n\t\t\t\t// property name normalization\n\t\t\t\tname = jQuery.camelCase( p );\n\t\t\t\tif ( p !== name ) {\n\t\t\t\t\tprop[ name ] = prop[ p ];\n\t\t\t\t\tdelete prop[ p ];\n\t\t\t\t}\n\n\t\t\t\tval = prop[ name ];\n\n\t\t\t\t// easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)\n\t\t\t\tif ( jQuery.isArray( val ) ) {\n\t\t\t\t\topt.animatedProperties[ name ] = val[ 1 ];\n\t\t\t\t\tval = prop[ name ] = val[ 0 ];\n\t\t\t\t} else {\n\t\t\t\t\topt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';\n\t\t\t\t}\n\n\t\t\t\tif ( val === \"hide\" && hidden || val === \"show\" && !hidden ) {\n\t\t\t\t\treturn opt.complete.call( this );\n\t\t\t\t}\n\n\t\t\t\tif ( isElement && ( name === \"height\" || name === \"width\" ) ) {\n\t\t\t\t\t// Make sure that nothing sneaks out\n\t\t\t\t\t// Record all 3 overflow attributes because IE does not\n\t\t\t\t\t// change the overflow attribute when overflowX and\n\t\t\t\t\t// overflowY are set to the same value\n\t\t\t\t\topt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];\n\n\t\t\t\t\t// Set display property to inline-block for height/width\n\t\t\t\t\t// animations on inline elements that are having width/height\n\t\t\t\t\t// animated\n\t\t\t\t\tif ( jQuery.css( this, \"display\" ) === \"inline\" &&\n\t\t\t\t\t\t\tjQuery.css( this, \"float\" ) === \"none\" ) {\n\t\t\t\t\t\tif ( !jQuery.support.inlineBlockNeedsLayout ) {\n\t\t\t\t\t\t\tthis.style.display = \"inline-block\";\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdisplay = defaultDisplay( this.nodeName );\n\n\t\t\t\t\t\t\t// inline-level elements accept inline-block;\n\t\t\t\t\t\t\t// block-level elements need to be inline with layout\n\t\t\t\t\t\t\tif ( display === \"inline\" ) {\n\t\t\t\t\t\t\t\tthis.style.display = \"inline-block\";\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.style.display = \"inline\";\n\t\t\t\t\t\t\t\tthis.style.zoom = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( opt.overflow != null ) {\n\t\t\t\tthis.style.overflow = \"hidden\";\n\t\t\t}\n\n\t\t\tfor ( p in prop ) {\n\t\t\t\te = new jQuery.fx( this, opt, p );\n\t\t\t\tval = prop[ p ];\n\n\t\t\t\tif ( rfxtypes.test(val) ) {\n\t\t\t\t\te[ val === \"toggle\" ? hidden ? \"show\" : \"hide\" : val ]();\n\n\t\t\t\t} else {\n\t\t\t\t\tparts = rfxnum.exec( val );\n\t\t\t\t\tstart = e.cur();\n\n\t\t\t\t\tif ( parts ) {\n\t\t\t\t\t\tend = parseFloat( parts[2] );\n\t\t\t\t\t\tunit = parts[3] || ( jQuery.cssNumber[ p ] ? \"\" : \"px\" );\n\n\t\t\t\t\t\t// We need to compute starting value\n\t\t\t\t\t\tif ( unit !== \"px\" ) {\n\t\t\t\t\t\t\tjQuery.style( this, p, (end || 1) + unit);\n\t\t\t\t\t\t\tstart = ((end || 1) / e.cur()) * start;\n\t\t\t\t\t\t\tjQuery.style( this, p, start + unit);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\t\t\tif ( parts[1] ) {\n\t\t\t\t\t\t\tend = ( (parts[ 1 ] === \"-=\" ? -1 : 1) * end ) + start;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\te.custom( start, end, unit );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\te.custom( start, val, \"\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// For JS strict compliance\n\t\t\treturn true;\n\t\t});\n\t},\n\n\tstop: function( clearQueue, gotoEnd ) {\n\t\tif ( clearQueue ) {\n\t\t\tthis.queue([]);\n\t\t}\n\n\t\tthis.each(function() {\n\t\t\tvar timers = jQuery.timers,\n\t\t\t\ti = timers.length;\n\t\t\t// clear marker counters if we know they won't be\n\t\t\tif ( !gotoEnd ) {\n\t\t\t\tjQuery._unmark( true, this );\n\t\t\t}\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( timers[i].elem === this ) {\n\t\t\t\t\tif (gotoEnd) {\n\t\t\t\t\t\t// force the next step to be the last\n\t\t\t\t\t\ttimers[i](true);\n\t\t\t\t\t}\n\n\t\t\t\t\ttimers.splice(i, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// start the next in the queue if the last step wasn't forced\n\t\tif ( !gotoEnd ) {\n\t\t\tthis.dequeue();\n\t\t}\n\n\t\treturn this;\n\t}\n\n});\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout( clearFxNow, 0 );\n\treturn ( fxNow = jQuery.now() );\n}\n\nfunction clearFxNow() {\n\tfxNow = undefined;\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, num ) {\n\tvar obj = {};\n\n\tjQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {\n\t\tobj[ this ] = type;\n\t});\n\n\treturn obj;\n}\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\", 1),\n\tslideUp: genFx(\"hide\", 1),\n\tslideToggle: genFx(\"toggle\", 1),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.extend({\n\tspeed: function( speed, easing, fn ) {\n\t\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend({}, speed) : {\n\t\t\tcomplete: fn || !fn && easing ||\n\t\t\t\tjQuery.isFunction( speed ) && speed,\n\t\t\tduration: speed,\n\t\t\teasing: fn && easing || easing && !jQuery.isFunction(easing) && easing\n\t\t};\n\n\t\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;\n\n\t\t// Queueing\n\t\topt.old = opt.complete;\n\t\topt.complete = function( noUnmark ) {\n\t\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\t\topt.old.call( this );\n\t\t\t}\n\n\t\t\tif ( opt.queue !== false ) {\n\t\t\t\tjQuery.dequeue( this );\n\t\t\t} else if ( noUnmark !== false ) {\n\t\t\t\tjQuery._unmark( this );\n\t\t\t}\n\t\t};\n\n\t\treturn opt;\n\t},\n\n\teasing: {\n\t\tlinear: function( p, n, firstNum, diff ) {\n\t\t\treturn firstNum + diff * p;\n\t\t},\n\t\tswing: function( p, n, firstNum, diff ) {\n\t\t\treturn ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;\n\t\t}\n\t},\n\n\ttimers: [],\n\n\tfx: function( elem, options, prop ) {\n\t\tthis.options = options;\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\n\t\toptions.orig = options.orig || {};\n\t}\n\n});\n\njQuery.fx.prototype = {\n\t// Simple function for setting a style value\n\tupdate: function() {\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\t(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );\n\t},\n\n\t// Get the current size\n\tcur: function() {\n\t\tif ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {\n\t\t\treturn this.elem[ this.prop ];\n\t\t}\n\n\t\tvar parsed,\n\t\t\tr = jQuery.css( this.elem, this.prop );\n\t\t// Empty strings, null, undefined and \"auto\" are converted to 0,\n\t\t// complex values such as \"rotate(1rad)\" are returned as is,\n\t\t// simple values such as \"10px\" are parsed to Float.\n\t\treturn isNaN( parsed = parseFloat( r ) ) ? !r || r === \"auto\" ? 0 : r : parsed;\n\t},\n\n\t// Start an animation from one number to another\n\tcustom: function( from, to, unit ) {\n\t\tvar self = this,\n\t\t\tfx = jQuery.fx,\n\t\t\traf;\n\n\t\tthis.startTime = fxNow || createFxNow();\n\t\tthis.start = from;\n\t\tthis.end = to;\n\t\tthis.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? \"\" : \"px\" );\n\t\tthis.now = this.start;\n\t\tthis.pos = this.state = 0;\n\n\t\tfunction t( gotoEnd ) {\n\t\t\treturn self.step(gotoEnd);\n\t\t}\n\n\t\tt.elem = this.elem;\n\n\t\tif ( t() && jQuery.timers.push(t) && !timerId ) {\n\t\t\t// Use requestAnimationFrame instead of setInterval if available\n\t\t\tif ( requestAnimationFrame ) {\n\t\t\t\ttimerId = true;\n\t\t\t\traf = function() {\n\t\t\t\t\t// When timerId gets set to null at any point, this stops\n\t\t\t\t\tif ( timerId ) {\n\t\t\t\t\t\trequestAnimationFrame( raf );\n\t\t\t\t\t\tfx.tick();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\trequestAnimationFrame( raf );\n\t\t\t} else {\n\t\t\t\ttimerId = setInterval( fx.tick, fx.interval );\n\t\t\t}\n\t\t}\n\t},\n\n\t// Simple 'show' function\n\tshow: function() {\n\t\t// Remember where we started, so that we can go back to it later\n\t\tthis.options.orig[this.prop] = jQuery.style( this.elem, this.prop );\n\t\tthis.options.show = true;\n\n\t\t// Begin the animation\n\t\t// Make sure that we start at a small width/height to avoid any\n\t\t// flash of content\n\t\tthis.custom(this.prop === \"width\" || this.prop === \"height\" ? 1 : 0, this.cur());\n\n\t\t// Start by showing the element\n\t\tjQuery( this.elem ).show();\n\t},\n\n\t// Simple 'hide' function\n\thide: function() {\n\t\t// Remember where we started, so that we can go back to it later\n\t\tthis.options.orig[this.prop] = jQuery.style( this.elem, this.prop );\n\t\tthis.options.hide = true;\n\n\t\t// Begin the animation\n\t\tthis.custom(this.cur(), 0);\n\t},\n\n\t// Each step of an animation\n\tstep: function( gotoEnd ) {\n\t\tvar t = fxNow || createFxNow(),\n\t\t\tdone = true,\n\t\t\telem = this.elem,\n\t\t\toptions = this.options,\n\t\t\ti, n;\n\n\t\tif ( gotoEnd || t >= options.duration + this.startTime ) {\n\t\t\tthis.now = this.end;\n\t\t\tthis.pos = this.state = 1;\n\t\t\tthis.update();\n\n\t\t\toptions.animatedProperties[ this.prop ] = true;\n\n\t\t\tfor ( i in options.animatedProperties ) {\n\t\t\t\tif ( options.animatedProperties[i] !== true ) {\n\t\t\t\t\tdone = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( done ) {\n\t\t\t\t// Reset the overflow\n\t\t\t\tif ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {\n\n\t\t\t\t\tjQuery.each( [ \"\", \"X\", \"Y\" ], function (index, value) {\n\t\t\t\t\t\telem.style[ \"overflow\" + value ] = options.overflow[index];\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Hide the element if the \"hide\" operation was done\n\t\t\t\tif ( options.hide ) {\n\t\t\t\t\tjQuery(elem).hide();\n\t\t\t\t}\n\n\t\t\t\t// Reset the properties, if the item has been hidden or shown\n\t\t\t\tif ( options.hide || options.show ) {\n\t\t\t\t\tfor ( var p in options.animatedProperties ) {\n\t\t\t\t\t\tjQuery.style( elem, p, options.orig[p] );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Execute the complete function\n\t\t\t\toptions.complete.call( elem );\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t} else {\n\t\t\t// classical easing cannot be used with an Infinity duration\n\t\t\tif ( options.duration == Infinity ) {\n\t\t\t\tthis.now = t;\n\t\t\t} else {\n\t\t\t\tn = t - this.startTime;\n\t\t\t\tthis.state = n / options.duration;\n\n\t\t\t\t// Perform the easing function, defaults to swing\n\t\t\t\tthis.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );\n\t\t\t\tthis.now = this.start + ((this.end - this.start) * this.pos);\n\t\t\t}\n\t\t\t// Perform the next step of the animation\n\t\t\tthis.update();\n\t\t}\n\n\t\treturn true;\n\t}\n};\n\njQuery.extend( jQuery.fx, {\n\ttick: function() {\n\t\tfor ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {\n\t\t\tif ( !timers[i]() ) {\n\t\t\t\ttimers.splice(i--, 1);\n\t\t\t}\n\t\t}\n\n\t\tif ( !timers.length ) {\n\t\t\tjQuery.fx.stop();\n\t\t}\n\t},\n\n\tinterval: 13,\n\n\tstop: function() {\n\t\tclearInterval( timerId );\n\t\ttimerId = null;\n\t},\n\n\tspeeds: {\n\t\tslow: 600,\n\t\tfast: 200,\n\t\t// Default speed\n\t\t_default: 400\n\t},\n\n\tstep: {\n\t\topacity: function( fx ) {\n\t\t\tjQuery.style( fx.elem, \"opacity\", fx.now );\n\t\t},\n\n\t\t_default: function( fx ) {\n\t\t\tif ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {\n\t\t\t\tfx.elem.style[ fx.prop ] = (fx.prop === \"width\" || fx.prop === \"height\" ? Math.max(0, fx.now) : fx.now) + fx.unit;\n\t\t\t} else {\n\t\t\t\tfx.elem[ fx.prop ] = fx.now;\n\t\t\t}\n\t\t}\n\t}\n});\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.animated = function( elem ) {\n\t\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\t\treturn elem === fn.elem;\n\t\t}).length;\n\t};\n}\n\n// Try to restore the default display value of an element\nfunction defaultDisplay( nodeName ) {\n\n\tif ( !elemdisplay[ nodeName ] ) {\n\n\t\tvar body = document.body,\n\t\t\telem = jQuery( \"<\" + nodeName + \">\" ).appendTo( body ),\n\t\t\tdisplay = elem.css( \"display\" );\n\n\t\telem.remove();\n\n\t\t// If the simple way fails,\n\t\t// get element's real default display by attaching it to a temp iframe\n\t\tif ( display === \"none\" || display === \"\" ) {\n\t\t\t// No iframe to use yet, so create it\n\t\t\tif ( !iframe ) {\n\t\t\t\tiframe = document.createElement( \"iframe\" );\n\t\t\t\tiframe.frameBorder = iframe.width = iframe.height = 0;\n\t\t\t}\n\n\t\t\tbody.appendChild( iframe );\n\n\t\t\t// Create a cacheable copy of the iframe document on first call.\n\t\t\t// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML\n\t\t\t// document to it; WebKit & Firefox won't allow reusing the iframe document.\n\t\t\tif ( !iframeDoc || !iframe.createElement ) {\n\t\t\t\tiframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;\n\t\t\t\tiframeDoc.write( ( document.compatMode === \"CSS1Compat\" ? \"<!doctype html>\" : \"\" ) + \"<html><body>\" );\n\t\t\t\tiframeDoc.close();\n\t\t\t}\n\n\t\t\telem = iframeDoc.createElement( nodeName );\n\n\t\t\tiframeDoc.body.appendChild( elem );\n\n\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\n\t\t\tbody.removeChild( iframe );\n\t\t}\n\n\t\t// Store the correct default display\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn elemdisplay[ nodeName ];\n}\n\n\n\n\nvar rtable = /^t(?:able|d|h)$/i,\n\trroot = /^(?:body|html)$/i;\n\nif ( \"getBoundingClientRect\" in document.documentElement ) {\n\tjQuery.fn.offset = function( options ) {\n\t\tvar elem = this[0], box;\n\n\t\tif ( options ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t});\n\t\t}\n\n\t\tif ( !elem || !elem.ownerDocument ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( elem === elem.ownerDocument.body ) {\n\t\t\treturn jQuery.offset.bodyOffset( elem );\n\t\t}\n\n\t\ttry {\n\t\t\tbox = elem.getBoundingClientRect();\n\t\t} catch(e) {}\n\n\t\tvar doc = elem.ownerDocument,\n\t\t\tdocElem = doc.documentElement;\n\n\t\t// Make sure we're not dealing with a disconnected DOM node\n\t\tif ( !box || !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box ? { top: box.top, left: box.left } : { top: 0, left: 0 };\n\t\t}\n\n\t\tvar body = doc.body,\n\t\t\twin = getWindow(doc),\n\t\t\tclientTop  = docElem.clientTop  || body.clientTop  || 0,\n\t\t\tclientLeft = docElem.clientLeft || body.clientLeft || 0,\n\t\t\tscrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,\n\t\t\tscrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,\n\t\t\ttop  = box.top  + scrollTop  - clientTop,\n\t\t\tleft = box.left + scrollLeft - clientLeft;\n\n\t\treturn { top: top, left: left };\n\t};\n\n} else {\n\tjQuery.fn.offset = function( options ) {\n\t\tvar elem = this[0];\n\n\t\tif ( options ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t});\n\t\t}\n\n\t\tif ( !elem || !elem.ownerDocument ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( elem === elem.ownerDocument.body ) {\n\t\t\treturn jQuery.offset.bodyOffset( elem );\n\t\t}\n\n\t\tjQuery.offset.initialize();\n\n\t\tvar computedStyle,\n\t\t\toffsetParent = elem.offsetParent,\n\t\t\tprevOffsetParent = elem,\n\t\t\tdoc = elem.ownerDocument,\n\t\t\tdocElem = doc.documentElement,\n\t\t\tbody = doc.body,\n\t\t\tdefaultView = doc.defaultView,\n\t\t\tprevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,\n\t\t\ttop = elem.offsetTop,\n\t\t\tleft = elem.offsetLeft;\n\n\t\twhile ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {\n\t\t\tif ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === \"fixed\" ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcomputedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;\n\t\t\ttop  -= elem.scrollTop;\n\t\t\tleft -= elem.scrollLeft;\n\n\t\t\tif ( elem === offsetParent ) {\n\t\t\t\ttop  += elem.offsetTop;\n\t\t\t\tleft += elem.offsetLeft;\n\n\t\t\t\tif ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {\n\t\t\t\t\ttop  += parseFloat( computedStyle.borderTopWidth  ) || 0;\n\t\t\t\t\tleft += parseFloat( computedStyle.borderLeftWidth ) || 0;\n\t\t\t\t}\n\n\t\t\t\tprevOffsetParent = offsetParent;\n\t\t\t\toffsetParent = elem.offsetParent;\n\t\t\t}\n\n\t\t\tif ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== \"visible\" ) {\n\t\t\t\ttop  += parseFloat( computedStyle.borderTopWidth  ) || 0;\n\t\t\t\tleft += parseFloat( computedStyle.borderLeftWidth ) || 0;\n\t\t\t}\n\n\t\t\tprevComputedStyle = computedStyle;\n\t\t}\n\n\t\tif ( prevComputedStyle.position === \"relative\" || prevComputedStyle.position === \"static\" ) {\n\t\t\ttop  += body.offsetTop;\n\t\t\tleft += body.offsetLeft;\n\t\t}\n\n\t\tif ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === \"fixed\" ) {\n\t\t\ttop  += Math.max( docElem.scrollTop, body.scrollTop );\n\t\t\tleft += Math.max( docElem.scrollLeft, body.scrollLeft );\n\t\t}\n\n\t\treturn { top: top, left: left };\n\t};\n}\n\njQuery.offset = {\n\tinitialize: function() {\n\t\tvar body = document.body, container = document.createElement(\"div\"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, \"marginTop\") ) || 0,\n\t\t\thtml = \"<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>\";\n\n\t\tjQuery.extend( container.style, { position: \"absolute\", top: 0, left: 0, margin: 0, border: 0, width: \"1px\", height: \"1px\", visibility: \"hidden\" } );\n\n\t\tcontainer.innerHTML = html;\n\t\tbody.insertBefore( container, body.firstChild );\n\t\tinnerDiv = container.firstChild;\n\t\tcheckDiv = innerDiv.firstChild;\n\t\ttd = innerDiv.nextSibling.firstChild.firstChild;\n\n\t\tthis.doesNotAddBorder = (checkDiv.offsetTop !== 5);\n\t\tthis.doesAddBorderForTableAndCells = (td.offsetTop === 5);\n\n\t\tcheckDiv.style.position = \"fixed\";\n\t\tcheckDiv.style.top = \"20px\";\n\n\t\t// safari subtracts parent border width here which is 5px\n\t\tthis.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);\n\t\tcheckDiv.style.position = checkDiv.style.top = \"\";\n\n\t\tinnerDiv.style.overflow = \"hidden\";\n\t\tinnerDiv.style.position = \"relative\";\n\n\t\tthis.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);\n\n\t\tthis.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);\n\n\t\tbody.removeChild( container );\n\t\tjQuery.offset.initialize = jQuery.noop;\n\t},\n\n\tbodyOffset: function( body ) {\n\t\tvar top = body.offsetTop,\n\t\t\tleft = body.offsetLeft;\n\n\t\tjQuery.offset.initialize();\n\n\t\tif ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {\n\t\t\ttop  += parseFloat( jQuery.css(body, \"marginTop\") ) || 0;\n\t\t\tleft += parseFloat( jQuery.css(body, \"marginLeft\") ) || 0;\n\t\t}\n\n\t\treturn { top: top, left: left };\n\t},\n\n\tsetOffset: function( elem, options, i ) {\n\t\tvar position = jQuery.css( elem, \"position\" );\n\n\t\t// set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tvar curElem = jQuery( elem ),\n\t\t\tcurOffset = curElem.offset(),\n\t\t\tcurCSSTop = jQuery.css( elem, \"top\" ),\n\t\t\tcurCSSLeft = jQuery.css( elem, \"left\" ),\n\t\t\tcalculatePosition = (position === \"absolute\" || position === \"fixed\") && jQuery.inArray(\"auto\", [curCSSTop, curCSSLeft]) > -1,\n\t\t\tprops = {}, curPosition = {}, curTop, curLeft;\n\n\t\t// need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif (options.top != null) {\n\t\t\tprops.top = (options.top - curOffset.top) + curTop;\n\t\t}\n\t\tif (options.left != null) {\n\t\t\tprops.left = (options.left - curOffset.left) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\n\njQuery.fn.extend({\n\tposition: function() {\n\t\tif ( !this[0] ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar elem = this[0],\n\n\t\t// Get *real* offsetParent\n\t\toffsetParent = this.offsetParent(),\n\n\t\t// Get correct offsets\n\t\toffset       = this.offset(),\n\t\tparentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();\n\n\t\t// Subtract element margins\n\t\t// note: when an element has margin: auto the offsetLeft and marginLeft\n\t\t// are the same in Safari causing offset.left to incorrectly be 0\n\t\toffset.top  -= parseFloat( jQuery.css(elem, \"marginTop\") ) || 0;\n\t\toffset.left -= parseFloat( jQuery.css(elem, \"marginLeft\") ) || 0;\n\n\t\t// Add offsetParent borders\n\t\tparentOffset.top  += parseFloat( jQuery.css(offsetParent[0], \"borderTopWidth\") ) || 0;\n\t\tparentOffset.left += parseFloat( jQuery.css(offsetParent[0], \"borderLeftWidth\") ) || 0;\n\n\t\t// Subtract the two offsets\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top,\n\t\t\tleft: offset.left - parentOffset.left\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || document.body;\n\t\t\twhile ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, \"position\") === \"static\") ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent;\n\t\t});\n\t}\n});\n\n\n// Create scrollLeft and scrollTop methods\njQuery.each( [\"Left\", \"Top\"], function( i, name ) {\n\tvar method = \"scroll\" + name;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\tvar elem, win;\n\n\t\tif ( val === undefined ) {\n\t\t\telem = this[ 0 ];\n\n\t\t\tif ( !elem ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\twin = getWindow( elem );\n\n\t\t\t// Return the scroll offset\n\t\t\treturn win ? (\"pageXOffset\" in win) ? win[ i ? \"pageYOffset\" : \"pageXOffset\" ] :\n\t\t\t\tjQuery.support.boxModel && win.document.documentElement[ method ] ||\n\t\t\t\t\twin.document.body[ method ] :\n\t\t\t\telem[ method ];\n\t\t}\n\n\t\t// Set the scroll offset\n\t\treturn this.each(function() {\n\t\t\twin = getWindow( this );\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!i ? val : jQuery( win ).scrollLeft(),\n\t\t\t\t\t i ? val : jQuery( win ).scrollTop()\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\tthis[ method ] = val;\n\t\t\t}\n\t\t});\n\t};\n});\n\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n\n\n\n\n// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods\njQuery.each([ \"Height\", \"Width\" ], function( i, name ) {\n\n\tvar type = name.toLowerCase();\n\n\t// innerHeight and innerWidth\n\tjQuery.fn[ \"inner\" + name ] = function() {\n\t\tvar elem = this[0];\n\t\treturn elem && elem.style ?\n\t\t\tparseFloat( jQuery.css( elem, type, \"padding\" ) ) :\n\t\t\tnull;\n\t};\n\n\t// outerHeight and outerWidth\n\tjQuery.fn[ \"outer\" + name ] = function( margin ) {\n\t\tvar elem = this[0];\n\t\treturn elem && elem.style ?\n\t\t\tparseFloat( jQuery.css( elem, type, margin ? \"margin\" : \"border\" ) ) :\n\t\t\tnull;\n\t};\n\n\tjQuery.fn[ type ] = function( size ) {\n\t\t// Get window width or height\n\t\tvar elem = this[0];\n\t\tif ( !elem ) {\n\t\t\treturn size == null ? null : this;\n\t\t}\n\n\t\tif ( jQuery.isFunction( size ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tvar self = jQuery( this );\n\t\t\t\tself[ type ]( size.call( this, i, self[ type ]() ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode\n\t\t\t// 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat\n\t\t\tvar docElemProp = elem.document.documentElement[ \"client\" + name ];\n\t\t\treturn elem.document.compatMode === \"CSS1Compat\" && docElemProp ||\n\t\t\t\telem.document.body[ \"client\" + name ] || docElemProp;\n\n\t\t// Get document width or height\n\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t// Either scroll[Width/Height] or offset[Width/Height], whichever is greater\n\t\t\treturn Math.max(\n\t\t\t\telem.documentElement[\"client\" + name],\n\t\t\t\telem.body[\"scroll\" + name], elem.documentElement[\"scroll\" + name],\n\t\t\t\telem.body[\"offset\" + name], elem.documentElement[\"offset\" + name]\n\t\t\t);\n\n\t\t// Get or set width or height on the element\n\t\t} else if ( size === undefined ) {\n\t\t\tvar orig = jQuery.css( elem, type ),\n\t\t\t\tret = parseFloat( orig );\n\n\t\t\treturn jQuery.isNaN( ret ) ? orig : ret;\n\n\t\t// Set the width or height on the element (default to pixels if value is unitless)\n\t\t} else {\n\t\t\treturn this.css( type, typeof size === \"string\" ? size : size + \"px\" );\n\t\t}\n\t};\n\n});\n\n\n// Expose jQuery to the global object\nwindow.jQuery = window.$ = jQuery;\n})(window);\n"
  },
  {
    "path": "app/static_dev/js/mylibs/.gitignore",
    "content": "!.gitignore\n\n"
  },
  {
    "path": "app/static_dev/js/mylibs/openid-en.js",
    "content": "\n/*\n\tSimple OpenID Plugin\n\thttp://code.google.com/p/openid-selector/\n\t\n\tThis code is licensed under the New BSD License.\n*/\n\nvar providers;\nvar openid;\n(function ($) {\nopenid = {\n\tversion : '1.3', // version constant\n\tdemo : false,\n\tdemo_text : null,\n\tcookie_expires : 6 * 30, // 6 months.\n\tcookie_name : 'openid_provider',\n\tcookie_path : '/',\n\n\timg_path : '/img/',\n\tlocale : null, // is set in openid-<locale>.js\n\tsprite : null, // usually equals to locale, is set in\n\t// openid-<locale>.js\n\tsignin_text : null, // text on submit button on the form\n\tall_small : false, // output large providers w/ small icons\n\tno_sprite : false, // don't use sprite image\n\timage_title : '{provider}', // for image title\n\n\tinput_id : null,\n\tprovider_url : null,\n\tprovider_id : null,\n\n\t/**\n\t * Class constructor\n\t * \n\t * @return {Void}\n\t */\n\tinit : function(input_id) {\n\t\tproviders = $.extend({}, providers_large, providers_small);\n\t\tvar openid_btns = $('#openid_btns');\n\t\tthis.input_id = input_id;\n\t\t$('#openid_choice').show();\n\t\t$('#openid_input_area').empty();\n\t\tvar i = 0;\n\t\t// add box for each provider\n\t\tfor (id in providers_large) {\n\t\t\tbox = this.getBoxHTML(id, providers_large[id], (this.all_small ? 'small' : 'large'), i++);\n\t\t\topenid_btns.append(box);\n\t\t}\n\t\tif (providers_small) {\n\t\t\topenid_btns.append('<br/>');\n\t\t\tfor (id in providers_small) {\n\t\t\t\tbox = this.getBoxHTML(id, providers_small[id], 'small', i++);\n\t\t\t\topenid_btns.append(box);\n\t\t\t}\n\t\t}\n\t\t$('#openid_form').submit(this.submit);\n\t\tvar box_id = this.readCookie();\n\t\tif (box_id) {\n\t\t\tthis.signin(box_id, true);\n\t\t}\n\t},\n\n\t/**\n\t * @return {String}\n\t */\n\tgetBoxHTML : function(box_id, provider, box_size, index) {\n\t\tif (this.no_sprite) {\n\t\t\tvar image_ext = box_size == 'small' ? '.ico.gif' : '.gif';\n\t\t\treturn '<a title=\"' + this.image_title.replace('{provider}', provider[\"name\"]) + '\" href=\"javascript:openid.signin(\\'' + box_id + '\\');\"'\n\t\t\t\t\t+ ' style=\"background: #FFF url(' + this.img_path + '../images.' + box_size + '/' + box_id + image_ext + ') no-repeat center center\" '\n\t\t\t\t\t+ 'class=\"' + box_id + ' openid_' + box_size + '_btn\"></a>';\n\t\t}\n\t\tvar x = box_size == 'small' ? -index * 24 : -index * 100;\n\t\tvar y = box_size == 'small' ? -60 : 0;\n\t\treturn '<a title=\"' + this.image_title.replace('{provider}', provider[\"name\"]) + '\" href=\"javascript:openid.signin(\\'' + box_id + '\\');\"'\n\t\t\t\t+ ' style=\"background: #FFF url(' + this.img_path + 'openid-providers-' + this.sprite + '.png); background-position: ' + x + 'px ' + y + 'px\" '\n\t\t\t\t+ 'class=\"' + box_id + ' openid_' + box_size + '_btn\"></a>';\n\t},\n\n\t/**\n\t * Provider image click\n\t * \n\t * @return {Void}\n\t */\n\tsignin : function(box_id, onload) {\n\t\tvar provider = providers[box_id];\n\t\tif (!provider) {\n\t\t\treturn;\n\t\t}\n\t\tthis.highlight(box_id);\n\t\tthis.setCookie(box_id);\n\t\tthis.provider_id = box_id;\n\t\tthis.provider_url = provider['url'];\n\t\t// prompt user for input?\n\t\tif (provider['label']) {\n\t\t\tthis.useInputBox(provider);\n\t\t} else {\n\t\t\t$('#openid_input_area').empty();\n\t\t\tif (!onload) {\n\t\t\t\t$('#openid_form').submit();\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Sign-in button click\n\t * \n\t * @return {Boolean}\n\t */\n\tsubmit : function() {\n\t\tvar url = openid.provider_url;\n\t\tif (url) {\n\t\t\turl = url.replace('{username}', $('#openid_username').val());\n\t\t\topenid.setOpenIdUrl(url);\n\t\t}\n\t\tif (openid.demo) {\n\t\t\talert(openid.demo_text + \"\\r\\n\" + document.getElementById(openid.input_id).value);\n\t\t\treturn false;\n\t\t}\n\t\tif (url.indexOf(\"javascript:\") == 0) {\n\t\t\turl = url.substr(\"javascript:\".length);\n\t\t\teval(url);\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t/**\n\t * @return {Void}\n\t */\n\tsetOpenIdUrl : function(url) {\n\t\tvar hidden = document.getElementById(this.input_id);\n\t\tif (hidden != null) {\n\t\t\thidden.value = url;\n\t\t} else {\n\t\t\t$('#openid_form').append('<input type=\"hidden\" id=\"' + this.input_id + '\" name=\"' + this.input_id + '\" value=\"' + url + '\"/>');\n\t\t}\n\t},\n\n\t/**\n\t * @return {Void}\n\t */\n\thighlight : function(box_id) {\n\t\t// remove previous highlight.\n\t\tvar highlight = $('#openid_highlight');\n\t\tif (highlight) {\n\t\t\thighlight.replaceWith($('#openid_highlight a')[0]);\n\t\t}\n\t\t// add new highlight.\n\t\t$('.' + box_id).wrap('<div id=\"openid_highlight\"></div>');\n\t},\n\n\tsetCookie : function(value) {\n\t\tvar date = new Date();\n\t\tdate.setTime(date.getTime() + (this.cookie_expires * 24 * 60 * 60 * 1000));\n\t\tvar expires = \"; expires=\" + date.toGMTString();\n\t\tdocument.cookie = this.cookie_name + \"=\" + value + expires + \"; path=\" + this.cookie_path;\n\t},\n\n\treadCookie : function() {\n\t\tvar nameEQ = this.cookie_name + \"=\";\n\t\tvar ca = document.cookie.split(';');\n\t\tfor ( var i = 0; i < ca.length; i++) {\n\t\t\tvar c = ca[i];\n\t\t\twhile (c.charAt(0) == ' ')\n\t\t\t\tc = c.substring(1, c.length);\n\t\t\tif (c.indexOf(nameEQ) == 0)\n\t\t\t\treturn c.substring(nameEQ.length, c.length);\n\t\t}\n\t\treturn null;\n\t},\n\n\t/**\n\t * @return {Void}\n\t */\n\tuseInputBox : function(provider) {\n\t\tvar input_area = $('#openid_input_area');\n\t\tvar html = '';\n\t\tvar id = 'openid_username';\n\t\tvar value = '';\n\t\tvar label = provider['label'];\n\t\tvar style = '';\n\t\tif (label) {\n\t\t\thtml = '<p>' + label + '</p>';\n\t\t}\n\t\tif (provider['name'] == 'OpenID') {\n\t\t\tid = this.input_id;\n\t\t\tvalue = 'http://';\n\t\t\tstyle = 'background: #FFF url(' + this.img_path + 'openid-inputicon.gif) no-repeat scroll 0 50%; padding-left:18px;';\n\t\t}\n\t\thtml += '<input id=\"' + id + '\" type=\"text\" style=\"' + style + '\" name=\"' + id + '\" value=\"' + value + '\" />'\n\t\t\t\t+ '<input id=\"openid_submit\" type=\"submit\" value=\"' + this.signin_text + '\"/>';\n\t\tinput_area.empty();\n\t\tinput_area.append(html);\n\t\t$('#' + id).focus();\n\t},\n\n\tsetDemoMode : function(demoMode) {\n\t\tthis.demo = demoMode;\n\t}\n};\n})(jQuery);\n\n\n/*\n\tSimple OpenID Plugin\n\thttp://code.google.com/p/openid-selector/\n\t\n\tThis code is licensed under the New BSD License.\n*/\n\nvar providers_large = {\n\tgoogle : {\n\t\tname : 'Google',\n\t\turl : 'https://www.google.com/accounts/o8/id'\n\t},\n\tyahoo : {\n\t\tname : 'Yahoo',\n\t\turl : 'http://me.yahoo.com/'\n\t},\n\taol : {\n\t\tname : 'AOL',\n\t\tlabel : 'Enter your AOL screenname.',\n\t\turl : 'http://openid.aol.com/{username}'\n\t},\n\tmyopenid : {\n\t\tname : 'MyOpenID',\n\t\tlabel : 'Enter your MyOpenID username.',\n\t\turl : 'http://{username}.myopenid.com/'\n\t},\n\topenid : {\n\t\tname : 'OpenID',\n\t\tlabel : 'Enter your OpenID.',\n\t\turl : null\n\t}\n};\n\nvar providers_small = {\n\tlivejournal : {\n\t\tname : 'LiveJournal',\n\t\tlabel : 'Enter your Livejournal username.',\n\t\turl : 'http://{username}.livejournal.com/'\n\t},\n\t/* flickr: {\n\t\tname: 'Flickr',        \n\t\tlabel: 'Enter your Flickr username.',\n\t\turl: 'http://flickr.com/{username}/'\n\t}, */\n\t/* technorati: {\n\t\tname: 'Technorati',\n\t\tlabel: 'Enter your Technorati username.',\n\t\turl: 'http://technorati.com/people/technorati/{username}/'\n\t}, */\n\twordpress : {\n\t\tname : 'Wordpress',\n\t\tlabel : 'Enter your Wordpress.com username.',\n\t\turl : 'http://{username}.wordpress.com/'\n\t},\n\tblogger : {\n\t\tname : 'Blogger',\n\t\tlabel : 'Your Blogger account',\n\t\turl : 'http://{username}.blogspot.com/'\n\t},\n\tverisign : {\n\t\tname : 'Verisign',\n\t\tlabel : 'Your Verisign username',\n\t\turl : 'http://{username}.pip.verisignlabs.com/'\n\t},\n\t/* vidoop: {\n\t\tname: 'Vidoop',\n\t\tlabel: 'Your Vidoop username',\n\t\turl: 'http://{username}.myvidoop.com/'\n\t}, */\n\t/* launchpad: {\n\t\tname: 'Launchpad',\n\t\tlabel: 'Your Launchpad username',\n\t\turl: 'https://launchpad.net/~{username}'\n\t}, */\n\tclaimid : {\n\t\tname : 'ClaimID',\n\t\tlabel : 'Your ClaimID username',\n\t\turl : 'http://claimid.com/{username}'\n\t},\n\tclickpass : {\n\t\tname : 'ClickPass',\n\t\tlabel : 'Enter your ClickPass username',\n\t\turl : 'http://clickpass.com/public/{username}'\n\t},\n\tgoogle_profile : {\n\t\tname : 'Google Profile',\n\t\tlabel : 'Enter your Google Profile username',\n\t\turl : 'http://www.google.com/profiles/{username}'\n\t}\n};\n\nopenid.locale = 'en';\nopenid.sprite = 'en'; // reused in german& japan localization\nopenid.demo_text = 'In client demo mode. Normally would have submitted OpenID:';\nopenid.signin_text = 'Sign-In';\nopenid.image_title = 'log in with {provider}';"
  },
  {
    "path": "app/static_dev/js/plugins.js",
    "content": "\n// usage: log('inside coolFunc', this, arguments);\n// paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/\nwindow.log = function(){\n  log.history = log.history || [];   // store logs to an array for reference\n  log.history.push(arguments);\n  if(this.console) {\n    arguments.callee = arguments.callee.caller;\n    var newarr = [].slice.call(arguments);\n    (typeof console.log === 'object' ? log.apply.call(console.log, console, newarr) : console.log.apply(console, newarr));\n  }\n};\n\n// make it safe to use console.log always\n(function(b){function c(){}for(var d=\"assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn\".split(\",\"),a;a=d.pop();){b[a]=b[a]||c}})((function(){try\n{console.log();return window.console;}catch(err){return window.console={};}})());\n\n\n// place any jQuery/helper plugins in here, instead of separate, slower script files.\n\n"
  },
  {
    "path": "app/static_dev/js/script.js",
    "content": "/* Author: \n\n*/\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "app/static_dev/robots.txt",
    "content": "# www.robotstxt.org/\n# www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449\n\nUser-agent: *\n\n"
  },
  {
    "path": "app/static_dev/test/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\t<title>QUnit Tests</title>\n\t<link rel=\"stylesheet\" href=\"qunit/qunit.css\" media=\"screen\">\n\n<!-- reference your own javascript files here -->\n\n  <script src=\"../js/libs/modernizr-2.0.6.min.js\"></script>\n  \n  <script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js\"></script> \n  <script src=\"../js/plugins.js\"></script> \n  <script src=\"../js/script.js\"></script> \n\n\n<!-- test runner files -->\n\t<script src=\"qunit/qunit.js\"></script>\n\t<script src=\"tests.js\"></script>\n\n\n\n</head>\n<body class=\"flora\">\n\t<h1 id=\"qunit-header\">QUnit Test Suite</h1>\n\t<h2 id=\"qunit-banner\"></h2>\n\t<div id=\"qunit-testrunner-toolbar\"></div>\n\t<h2 id=\"qunit-userAgent\"></h2>\n\t<ol id=\"qunit-tests\"></ol>\n\t<div id=\"qunit-fixture\">test markup</div>\n\t</body>\n</html>\n"
  },
  {
    "path": "app/static_dev/test/qunit/qunit.css",
    "content": "/** Font Family and Sizes */\n\n#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {\n\tfont-family: \"Helvetica Neue Light\", \"HelveticaNeue-Light\", \"Helvetica Neue\", Calibri, Helvetica, Arial;\n}\n\n#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }\n#qunit-tests { font-size: smaller; }\n\n\n/** Resets */\n\n#qunit-tests, #qunit-tests li ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {\n\tmargin: 0;\n\tpadding: 0;\n}\n\n\n/** Header */\n\n#qunit-header {\n\tpadding: 0.5em 0 0.5em 1em;\n\t\n\tcolor: #fff;\n\ttext-shadow: rgba(0, 0, 0, 0.5) 4px 4px 1px;\n\tbackground-color: #0d3349;\n\t\n\tborder-radius: 15px 15px 0 0;\n\t-moz-border-radius: 15px 15px 0 0;\n\t-webkit-border-top-right-radius: 15px;\n\t-webkit-border-top-left-radius: 15px;\n}\n\n#qunit-banner {\n\theight: 5px;\n}\n\n#qunit-testrunner-toolbar {\n\tpadding: 0em 0 0.5em 2em;\n}\n\n#qunit-userAgent {\n\tpadding: 0.5em 0 0.5em 2.5em;\n\tbackground-color: #2b81af;\n\tcolor: #fff;\n\ttext-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;\n}\n\n\n/** Tests: Pass/Fail */\n\n#qunit-tests {\n\tlist-style-position: inside;\n}\n\n#qunit-tests li {\n\tpadding: 0.4em 0.5em 0.4em 2.5em;\n\tborder-bottom: 1px solid #fff;\n\tlist-style-position: inside;\n}\n\n#qunit-tests li strong {\n\tcursor: pointer;\n}\n\n#qunit-tests li ol {\n\tmargin-top: 0.5em;\n\tpadding: 0.5em;\n\t\n\tbackground-color: #fff;\n\t\n\tborder-radius: 15px;\n\t-moz-border-radius: 15px;\n\t-webkit-border-radius: 15px;\n\t\n\tbox-shadow: inset 0px 2px 13px #999;\n\t-moz-box-shadow: inset 0px 2px 13px #999;\n\t-webkit-box-shadow: inset 0px 2px 13px #999;\n}\n\n#qunit-tests li li {\n\tmargin: 0.5em;\n\tpadding: 0.4em 0.5em 0.4em 0.5em;\n\tbackground-color: #fff;\n\tborder-bottom: none;\n\tlist-style-position: inside;\n}\n\n/*** Passing Styles */\n\n#qunit-tests li li.pass {\n\tcolor: #5E740B;\n\tbackground-color: #fff;\n\tborder-left: 26px solid #C6E746;\n}\n\n#qunit-tests li.pass                        { color: #528CE0; background-color: #D2E0E6; }\n#qunit-tests li.pass span.test-name         { color: #366097; }\n \n#qunit-tests li li.pass span.test-actual,\n#qunit-tests li li.pass span.test-expected  { color: #999999; }\n\nstrong b.pass                               { color: #5E740B; }\n\n#qunit-banner.qunit-pass                    { background-color: #C6E746; }\n\n/*** Failing Styles */\n\n#qunit-tests li li.fail {\n\tcolor: #710909;\n\tbackground-color: #fff;\n\tborder-left: 26px solid #EE5757;\n}\n\n#qunit-tests li.fail                        { color: #000000; background-color: #EE5757; }\n#qunit-tests li.fail span.test-name,\n#qunit-tests li.fail span.module-name       { color: #000000; }\n\n#qunit-tests li li.fail span.test-actual    { color: #EE5757; }\n#qunit-tests li li.fail span.test-expected  { color: green;   }\n\nstrong b.fail                               { color: #710909; }\n\n#qunit-banner.qunit-fail, \n#qunit-testrunner-toolbar                   { background-color: #EE5757; }\n\n\n/** Footer */\n\n#qunit-testresult {\n\tpadding: 0.5em 0.5em 0.5em 2.5em;\n\t\n\tcolor: #2b81af;\n\tbackground-color: #D2E0E6;\n\n\tborder-radius: 0 0 15px 15px;\n\t-moz-border-radius: 0 0 15px 15px;\n\t-webkit-border-bottom-right-radius: 15px;\n\t-webkit-border-bottom-left-radius: 15px;\t\n}\n\n/** Fixture */\n\n#qunit-fixture {\n\tposition: absolute;\n\ttop: -10000px;\n\tleft: -10000px;\n}\n"
  },
  {
    "path": "app/static_dev/test/qunit/qunit.js",
    "content": "/*\n * QUnit - A JavaScript Unit Testing Framework\n * \n * http://docs.jquery.com/QUnit\n *\n * Copyright (c) 2009 John Resig, Jörn Zaefferer\n * Dual licensed under the MIT (MIT-LICENSE.txt)\n * and GPL (GPL-LICENSE.txt) licenses.\n */\n\n(function(window) {\n\nvar QUnit = {\n\n\t// call on start of module test to prepend name to all tests\n\tmodule: function(name, testEnvironment) {\n\t\tconfig.currentModule = name;\n\n\t\tsynchronize(function() {\n\t\t\tif ( config.currentModule ) {\n\t\t\t\tQUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );\n\t\t\t}\n\n\t\t\tconfig.currentModule = name;\n\t\t\tconfig.moduleTestEnvironment = testEnvironment;\n\t\t\tconfig.moduleStats = { all: 0, bad: 0 };\n\n\t\t\tQUnit.moduleStart( name, testEnvironment );\n\t\t});\n\t},\n\n\tasyncTest: function(testName, expected, callback) {\n\t\tif ( arguments.length === 2 ) {\n\t\t\tcallback = expected;\n\t\t\texpected = 0;\n\t\t}\n\n\t\tQUnit.test(testName, expected, callback, true);\n\t},\n\t\n\ttest: function(testName, expected, callback, async) {\n\t\tvar name = '<span class=\"test-name\">' + testName + '</span>', testEnvironment, testEnvironmentArg;\n\n\t\tif ( arguments.length === 2 ) {\n\t\t\tcallback = expected;\n\t\t\texpected = null;\n\t\t}\n\t\t// is 2nd argument a testEnvironment?\n\t\tif ( expected && typeof expected === 'object') {\n\t\t\ttestEnvironmentArg =  expected;\n\t\t\texpected = null;\n\t\t}\n\n\t\tif ( config.currentModule ) {\n\t\t\tname = '<span class=\"module-name\">' + config.currentModule + \"</span>: \" + name;\n\t\t}\n\n\t\tif ( !validTest(config.currentModule + \": \" + testName) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tsynchronize(function() {\n\n\t\t\ttestEnvironment = extend({\n\t\t\t\tsetup: function() {},\n\t\t\t\tteardown: function() {}\n\t\t\t}, config.moduleTestEnvironment);\n\t\t\tif (testEnvironmentArg) {\n\t\t\t\textend(testEnvironment,testEnvironmentArg);\n\t\t\t}\n\n\t\t\tQUnit.testStart( testName, testEnvironment );\n\n\t\t\t// allow utility functions to access the current test environment\n\t\t\tQUnit.current_testEnvironment = testEnvironment;\n\t\t\t\n\t\t\tconfig.assertions = [];\n\t\t\tconfig.expected = expected;\n\t\t\t\n\t\t\tvar tests = id(\"qunit-tests\");\n\t\t\tif (tests) {\n\t\t\t\tvar b = document.createElement(\"strong\");\n\t\t\t\t\tb.innerHTML = \"Running \" + name;\n\t\t\t\tvar li = document.createElement(\"li\");\n\t\t\t\t\tli.appendChild( b );\n\t\t\t\t\tli.id = \"current-test-output\";\n\t\t\t\ttests.appendChild( li )\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tif ( !config.pollution ) {\n\t\t\t\t\tsaveGlobal();\n\t\t\t\t}\n\n\t\t\t\ttestEnvironment.setup.call(testEnvironment);\n\t\t\t} catch(e) {\n\t\t\t\tQUnit.ok( false, \"Setup failed on \" + name + \": \" + e.message );\n\t\t\t}\n\t    });\n\t\n\t    synchronize(function() {\n\t\t\tif ( async ) {\n\t\t\t\tQUnit.stop();\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcallback.call(testEnvironment);\n\t\t\t} catch(e) {\n\t\t\t\tfail(\"Test \" + name + \" died, exception and test follows\", e, callback);\n\t\t\t\tQUnit.ok( false, \"Died on test #\" + (config.assertions.length + 1) + \": \" + e.message );\n\t\t\t\t// else next test will carry the responsibility\n\t\t\t\tsaveGlobal();\n\n\t\t\t\t// Restart the tests if they're blocking\n\t\t\t\tif ( config.blocking ) {\n\t\t\t\t\tstart();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tsynchronize(function() {\n\t\t\ttry {\n\t\t\t\tcheckPollution();\n\t\t\t\ttestEnvironment.teardown.call(testEnvironment);\n\t\t\t} catch(e) {\n\t\t\t\tQUnit.ok( false, \"Teardown failed on \" + name + \": \" + e.message );\n\t\t\t}\n\t    });\n\t\n\t    synchronize(function() {\n\t\t\ttry {\n\t\t\t\tQUnit.reset();\n\t\t\t} catch(e) {\n\t\t\t\tfail(\"reset() failed, following Test \" + name + \", exception and reset fn follows\", e, reset);\n\t\t\t}\n\n\t\t\tif ( config.expected && config.expected != config.assertions.length ) {\n\t\t\t\tQUnit.ok( false, \"Expected \" + config.expected + \" assertions, but \" + config.assertions.length + \" were run\" );\n\t\t\t}\n\n\t\t\tvar good = 0, bad = 0,\n\t\t\t\ttests = id(\"qunit-tests\");\n\n\t\t\tconfig.stats.all += config.assertions.length;\n\t\t\tconfig.moduleStats.all += config.assertions.length;\n\n\t\t\tif ( tests ) {\n\t\t\t\tvar ol  = document.createElement(\"ol\");\n\n\t\t\t\tfor ( var i = 0; i < config.assertions.length; i++ ) {\n\t\t\t\t\tvar assertion = config.assertions[i];\n\n\t\t\t\t\tvar li = document.createElement(\"li\");\n\t\t\t\t\tli.className = assertion.result ? \"pass\" : \"fail\";\n\t\t\t\t\tli.innerHTML = assertion.message || \"(no message)\";\n\t\t\t\t\tol.appendChild( li );\n\n\t\t\t\t\tif ( assertion.result ) {\n\t\t\t\t\t\tgood++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbad++;\n\t\t\t\t\t\tconfig.stats.bad++;\n\t\t\t\t\t\tconfig.moduleStats.bad++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (bad == 0) {\n\t\t\t\t\tol.style.display = \"none\";\n\t\t\t\t}\n\n\t\t\t\tvar b = document.createElement(\"strong\");\n\t\t\t\tb.innerHTML = name + \" <b style='color:black;'>(<b class='fail'>\" + bad + \"</b>, <b class='pass'>\" + good + \"</b>, \" + config.assertions.length + \")</b>\";\n\t\t\t\t\n\t\t\t\taddEvent(b, \"click\", function() {\n\t\t\t\t\tvar next = b.nextSibling, display = next.style.display;\n\t\t\t\t\tnext.style.display = display === \"none\" ? \"block\" : \"none\";\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\taddEvent(b, \"dblclick\", function(e) {\n\t\t\t\t\tvar target = e && e.target ? e.target : window.event.srcElement;\n\t\t\t\t\tif ( target.nodeName.toLowerCase() == \"span\" || target.nodeName.toLowerCase() == \"b\" ) {\n\t\t\t\t\t\ttarget = target.parentNode;\n\t\t\t\t\t}\n\t\t\t\t\tif ( window.location && target.nodeName.toLowerCase() === \"strong\" ) {\n\t\t\t\t\t\twindow.location.search = \"?\" + encodeURIComponent(getText([target]).replace(/\\(.+\\)$/, \"\").replace(/(^\\s*|\\s*$)/g, \"\"));\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tvar li = id(\"current-test-output\");\n\t\t\t\tli.id = \"\";\n\t\t\t\tli.className = bad ? \"fail\" : \"pass\";\n\t\t\t\tli.removeChild( li.firstChild );\n\t\t\t\tli.appendChild( b );\n\t\t\t\tli.appendChild( ol );\n\n\t\t\t\tif ( bad ) {\n\t\t\t\t\tvar toolbar = id(\"qunit-testrunner-toolbar\");\n\t\t\t\t\tif ( toolbar ) {\n\t\t\t\t\t\ttoolbar.style.display = \"block\";\n\t\t\t\t\t\tid(\"qunit-filter-pass\").disabled = null;\n\t\t\t\t\t\tid(\"qunit-filter-missing\").disabled = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tfor ( var i = 0; i < config.assertions.length; i++ ) {\n\t\t\t\t\tif ( !config.assertions[i].result ) {\n\t\t\t\t\t\tbad++;\n\t\t\t\t\t\tconfig.stats.bad++;\n\t\t\t\t\t\tconfig.moduleStats.bad++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tQUnit.testDone( testName, bad, config.assertions.length );\n\n\t\t\tif ( !window.setTimeout && !config.queue.length ) {\n\t\t\t\tdone();\n\t\t\t}\n\t\t});\n\n\t\tif ( window.setTimeout && !config.doneTimer ) {\n\t\t\tconfig.doneTimer = window.setTimeout(function(){\n\t\t\t\tif ( !config.queue.length ) {\n\t\t\t\t\tdone();\n\t\t\t\t} else {\n\t\t\t\t\tsynchronize( done );\n\t\t\t\t}\n\t\t\t}, 13);\n\t\t}\n\t},\n\t\n\t/**\n\t * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.\n\t */\n\texpect: function(asserts) {\n\t\tconfig.expected = asserts;\n\t},\n\n\t/**\n\t * Asserts true.\n\t * @example ok( \"asdfasdf\".length > 5, \"There must be at least 5 chars\" );\n\t */\n\tok: function(a, msg) {\n\t\tmsg = escapeHtml(msg);\n\t\tQUnit.log(a, msg);\n\n\t\tconfig.assertions.push({\n\t\t\tresult: !!a,\n\t\t\tmessage: msg\n\t\t});\n\t},\n\n\t/**\n\t * Checks that the first two arguments are equal, with an optional message.\n\t * Prints out both actual and expected values.\n\t *\n\t * Prefered to ok( actual == expected, message )\n\t *\n\t * @example equal( format(\"Received {0} bytes.\", 2), \"Received 2 bytes.\" );\n\t *\n\t * @param Object actual\n\t * @param Object expected\n\t * @param String message (optional)\n\t */\n\tequal: function(actual, expected, message) {\n\t\tpush(expected == actual, actual, expected, message);\n\t},\n\n\tnotEqual: function(actual, expected, message) {\n\t\tpush(expected != actual, actual, expected, message);\n\t},\n\t\n\tdeepEqual: function(actual, expected, message) {\n\t\tpush(QUnit.equiv(actual, expected), actual, expected, message);\n\t},\n\n\tnotDeepEqual: function(actual, expected, message) {\n\t\tpush(!QUnit.equiv(actual, expected), actual, expected, message);\n\t},\n\n\tstrictEqual: function(actual, expected, message) {\n\t\tpush(expected === actual, actual, expected, message);\n\t},\n\n\tnotStrictEqual: function(actual, expected, message) {\n\t\tpush(expected !== actual, actual, expected, message);\n\t},\n\n\traises: function(fn,  message) {\n\t\ttry {\n\t\t\tfn();\n\t\t\tok( false, message );\n\t\t}\n\t\tcatch (e) {\n\t\t\tok( true, message );\n\t\t}\n\t},\n\n\tstart: function() {\n\t\t// A slight delay, to avoid any current callbacks\n\t\tif ( window.setTimeout ) {\n\t\t\twindow.setTimeout(function() {\n\t\t\t\tif ( config.timeout ) {\n\t\t\t\t\tclearTimeout(config.timeout);\n\t\t\t\t}\n\n\t\t\t\tconfig.blocking = false;\n\t\t\t\tprocess();\n\t\t\t}, 13);\n\t\t} else {\n\t\t\tconfig.blocking = false;\n\t\t\tprocess();\n\t\t}\n\t},\n\t\n\tstop: function(timeout) {\n\t\tconfig.blocking = true;\n\n\t\tif ( timeout && window.setTimeout ) {\n\t\t\tconfig.timeout = window.setTimeout(function() {\n\t\t\t\tQUnit.ok( false, \"Test timed out\" );\n\t\t\t\tQUnit.start();\n\t\t\t}, timeout);\n\t\t}\n\t}\n\n};\n\n// Backwards compatibility, deprecated\nQUnit.equals = QUnit.equal;\nQUnit.same = QUnit.deepEqual;\n\n// Maintain internal state\nvar config = {\n\t// The queue of tests to run\n\tqueue: [],\n\n\t// block until document ready\n\tblocking: true\n};\n\n// Load paramaters\n(function() {\n\tvar location = window.location || { search: \"\", protocol: \"file:\" },\n\t\tGETParams = location.search.slice(1).split('&');\n\n\tfor ( var i = 0; i < GETParams.length; i++ ) {\n\t\tGETParams[i] = decodeURIComponent( GETParams[i] );\n\t\tif ( GETParams[i] === \"noglobals\" ) {\n\t\t\tGETParams.splice( i, 1 );\n\t\t\ti--;\n\t\t\tconfig.noglobals = true;\n\t\t} else if ( GETParams[i].search('=') > -1 ) {\n\t\t\tGETParams.splice( i, 1 );\n\t\t\ti--;\n\t\t}\n\t}\n\t\n\t// restrict modules/tests by get parameters\n\tconfig.filters = GETParams;\n\t\n\t// Figure out if we're running the tests from a server or not\n\tQUnit.isLocal = !!(location.protocol === 'file:');\n})();\n\n// Expose the API as global variables, unless an 'exports'\n// object exists, in that case we assume we're in CommonJS\nif ( typeof exports === \"undefined\" || typeof require === \"undefined\" ) {\n\textend(window, QUnit);\n\twindow.QUnit = QUnit;\n} else {\n\textend(exports, QUnit);\n\texports.QUnit = QUnit;\n}\n\n// define these after exposing globals to keep them in these QUnit namespace only\nextend(QUnit, {\n\tconfig: config,\n\n\t// Initialize the configuration options\n\tinit: function() {\n\t\textend(config, {\n\t\t\tstats: { all: 0, bad: 0 },\n\t\t\tmoduleStats: { all: 0, bad: 0 },\n\t\t\tstarted: +new Date,\n\t\t\tupdateRate: 1000,\n\t\t\tblocking: false,\n\t\t\tautostart: true,\n\t\t\tautorun: false,\n\t\t\tassertions: [],\n\t\t\tfilters: [],\n\t\t\tqueue: []\n\t\t});\n\n\t\tvar tests = id(\"qunit-tests\"),\n\t\t\tbanner = id(\"qunit-banner\"),\n\t\t\tresult = id(\"qunit-testresult\");\n\n\t\tif ( tests ) {\n\t\t\ttests.innerHTML = \"\";\n\t\t}\n\n\t\tif ( banner ) {\n\t\t\tbanner.className = \"\";\n\t\t}\n\n\t\tif ( result ) {\n\t\t\tresult.parentNode.removeChild( result );\n\t\t}\n\t},\n\t\n\t/**\n\t * Resets the test setup. Useful for tests that modify the DOM.\n\t */\n\treset: function() {\n\t\tif ( window.jQuery ) {\n\t\t\tjQuery(\"#main, #qunit-fixture\").html( config.fixture );\n\t\t}\n\t},\n\t\n\t/**\n\t * Trigger an event on an element.\n\t *\n\t * @example triggerEvent( document.body, \"click\" );\n\t *\n\t * @param DOMElement elem\n\t * @param String type\n\t */\n\ttriggerEvent: function( elem, type, event ) {\n\t\tif ( document.createEvent ) {\n\t\t\tevent = document.createEvent(\"MouseEvents\");\n\t\t\tevent.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,\n\t\t\t\t0, 0, 0, 0, 0, false, false, false, false, 0, null);\n\t\t\telem.dispatchEvent( event );\n\n\t\t} else if ( elem.fireEvent ) {\n\t\t\telem.fireEvent(\"on\"+type);\n\t\t}\n\t},\n\t\n\t// Safe object type checking\n\tis: function( type, obj ) {\n\t\treturn QUnit.objectType( obj ) == type;\n\t},\n\t\n\tobjectType: function( obj ) {\n\t\tif (typeof obj === \"undefined\") {\n\t\t\t\treturn \"undefined\";\n\n\t\t// consider: typeof null === object\n\t\t}\n\t\tif (obj === null) {\n\t\t\t\treturn \"null\";\n\t\t}\n\n\t\tvar type = Object.prototype.toString.call( obj )\n\t\t\t.match(/^\\[object\\s(.*)\\]$/)[1] || '';\n\n\t\tswitch (type) {\n\t\t\t\tcase 'Number':\n\t\t\t\t\t\tif (isNaN(obj)) {\n\t\t\t\t\t\t\t\treturn \"nan\";\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn \"number\";\n\t\t\t\t\t\t}\n\t\t\t\tcase 'String':\n\t\t\t\tcase 'Boolean':\n\t\t\t\tcase 'Array':\n\t\t\t\tcase 'Date':\n\t\t\t\tcase 'RegExp':\n\t\t\t\tcase 'Function':\n\t\t\t\t\t\treturn type.toLowerCase();\n\t\t}\n\t\tif (typeof obj === \"object\") {\n\t\t\t\treturn \"object\";\n\t\t}\n\t\treturn undefined;\n\t},\n\t\n\t// Logging callbacks\n\tbegin: function() {},\n\tdone: function(failures, total) {},\n\tlog: function(result, message) {},\n\ttestStart: function(name, testEnvironment) {},\n\ttestDone: function(name, failures, total) {},\n\tmoduleStart: function(name, testEnvironment) {},\n\tmoduleDone: function(name, failures, total) {}\n});\n\nif ( typeof document === \"undefined\" || document.readyState === \"complete\" ) {\n\tconfig.autorun = true;\n}\n\naddEvent(window, \"load\", function() {\n\tQUnit.begin();\n\t\n\t// Initialize the config, saving the execution queue\n\tvar oldconfig = extend({}, config);\n\tQUnit.init();\n\textend(config, oldconfig);\n\n\tconfig.blocking = false;\n\n\tvar userAgent = id(\"qunit-userAgent\");\n\tif ( userAgent ) {\n\t\tuserAgent.innerHTML = navigator.userAgent;\n\t}\n\t\n\tvar toolbar = id(\"qunit-testrunner-toolbar\");\n\tif ( toolbar ) {\n\t\ttoolbar.style.display = \"none\";\n\t\t\n\t\tvar filter = document.createElement(\"input\");\n\t\tfilter.type = \"checkbox\";\n\t\tfilter.id = \"qunit-filter-pass\";\n\t\tfilter.disabled = true;\n\t\taddEvent( filter, \"click\", function() {\n\t\t\tvar li = document.getElementsByTagName(\"li\");\n\t\t\tfor ( var i = 0; i < li.length; i++ ) {\n\t\t\t\tif ( li[i].className.indexOf(\"pass\") > -1 ) {\n\t\t\t\t\tli[i].style.display = filter.checked ? \"none\" : \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\ttoolbar.appendChild( filter );\n\n\t\tvar label = document.createElement(\"label\");\n\t\tlabel.setAttribute(\"for\", \"qunit-filter-pass\");\n\t\tlabel.innerHTML = \"Hide passed tests\";\n\t\ttoolbar.appendChild( label );\n\n\t\tvar missing = document.createElement(\"input\");\n\t\tmissing.type = \"checkbox\";\n\t\tmissing.id = \"qunit-filter-missing\";\n\t\tmissing.disabled = true;\n\t\taddEvent( missing, \"click\", function() {\n\t\t\tvar li = document.getElementsByTagName(\"li\");\n\t\t\tfor ( var i = 0; i < li.length; i++ ) {\n\t\t\t\tif ( li[i].className.indexOf(\"fail\") > -1 && li[i].innerHTML.indexOf('missing test - untested code is broken code') > - 1 ) {\n\t\t\t\t\tli[i].parentNode.parentNode.style.display = missing.checked ? \"none\" : \"block\";\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\ttoolbar.appendChild( missing );\n\n\t\tlabel = document.createElement(\"label\");\n\t\tlabel.setAttribute(\"for\", \"qunit-filter-missing\");\n\t\tlabel.innerHTML = \"Hide missing tests (untested code is broken code)\";\n\t\ttoolbar.appendChild( label );\n\t}\n\n\tvar main = id('main') || id('qunit-fixture');\n\tif ( main ) {\n\t\tconfig.fixture = main.innerHTML;\n\t}\n\n\tif (config.autostart) {\n\t\tQUnit.start();\n\t}\n});\n\nfunction done() {\n\tif ( config.doneTimer && window.clearTimeout ) {\n\t\twindow.clearTimeout( config.doneTimer );\n\t\tconfig.doneTimer = null;\n\t}\n\n\tif ( config.queue.length ) {\n\t\tconfig.doneTimer = window.setTimeout(function(){\n\t\t\tif ( !config.queue.length ) {\n\t\t\t\tdone();\n\t\t\t} else {\n\t\t\t\tsynchronize( done );\n\t\t\t}\n\t\t}, 13);\n\n\t\treturn;\n\t}\n\n\tconfig.autorun = true;\n\n\t// Log the last module results\n\tif ( config.currentModule ) {\n\t\tQUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );\n\t}\n\n\tvar banner = id(\"qunit-banner\"),\n\t\ttests = id(\"qunit-tests\"),\n\t\thtml = ['Tests completed in ',\n\t\t+new Date - config.started, ' milliseconds.<br/>',\n\t\t'<span class=\"passed\">', config.stats.all - config.stats.bad, '</span> tests of <span class=\"total\">', config.stats.all, '</span> passed, <span class=\"failed\">', config.stats.bad,'</span> failed.'].join('');\n\n\tif ( banner ) {\n\t\tbanner.className = (config.stats.bad ? \"qunit-fail\" : \"qunit-pass\");\n\t}\n\n\tif ( tests ) {\t\n\t\tvar result = id(\"qunit-testresult\");\n\n\t\tif ( !result ) {\n\t\t\tresult = document.createElement(\"p\");\n\t\t\tresult.id = \"qunit-testresult\";\n\t\t\tresult.className = \"result\";\n\t\t\ttests.parentNode.insertBefore( result, tests.nextSibling );\n\t\t}\n\n\t\tresult.innerHTML = html;\n\t}\n\n\tQUnit.done( config.stats.bad, config.stats.all );\n}\n\nfunction validTest( name ) {\n\tvar i = config.filters.length,\n\t\trun = false;\n\n\tif ( !i ) {\n\t\treturn true;\n\t}\n\t\n\twhile ( i-- ) {\n\t\tvar filter = config.filters[i],\n\t\t\tnot = filter.charAt(0) == '!';\n\n\t\tif ( not ) {\n\t\t\tfilter = filter.slice(1);\n\t\t}\n\n\t\tif ( name.indexOf(filter) !== -1 ) {\n\t\t\treturn !not;\n\t\t}\n\n\t\tif ( not ) {\n\t\t\trun = true;\n\t\t}\n\t}\n\n\treturn run;\n}\n\nfunction escapeHtml(s) {\n\ts = s === null ? \"\" : s + \"\";\n\treturn s.replace(/[\\&\"<>\\\\]/g, function(s) {\n\t\tswitch(s) {\n\t\t\tcase \"&\": return \"&amp;\";\n\t\t\tcase \"\\\\\": return \"\\\\\\\\\";\n\t\t\tcase '\"': return '\\\"';\n\t\t\tcase \"<\": return \"&lt;\";\n\t\t\tcase \">\": return \"&gt;\";\n\t\t\tdefault: return s;\n\t\t}\n\t});\n}\n\nfunction push(result, actual, expected, message) {\n\tmessage = escapeHtml(message) || (result ? \"okay\" : \"failed\");\n\tmessage = '<span class=\"test-message\">' + message + \"</span>\";\n\texpected = escapeHtml(QUnit.jsDump.parse(expected));\n\tactual = escapeHtml(QUnit.jsDump.parse(actual));\n\tvar output = message + ', expected: <span class=\"test-expected\">' + expected + '</span>';\n\tif (actual != expected) {\n\t\toutput += ' result: <span class=\"test-actual\">' + actual + '</span>, diff: ' + QUnit.diff(expected, actual);\n\t}\n\t\n\t// can't use ok, as that would double-escape messages\n\tQUnit.log(result, output);\n\tconfig.assertions.push({\n\t\tresult: !!result,\n\t\tmessage: output\n\t});\n}\n\nfunction synchronize( callback ) {\n\tconfig.queue.push( callback );\n\n\tif ( config.autorun && !config.blocking ) {\n\t\tprocess();\n\t}\n}\n\nfunction process() {\n\tvar start = (new Date()).getTime();\n\n\twhile ( config.queue.length && !config.blocking ) {\n\t\tif ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) {\n\t\t\tconfig.queue.shift()();\n\n\t\t} else {\n\t\t\tsetTimeout( process, 13 );\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nfunction saveGlobal() {\n\tconfig.pollution = [];\n\t\n\tif ( config.noglobals ) {\n\t\tfor ( var key in window ) {\n\t\t\tconfig.pollution.push( key );\n\t\t}\n\t}\n}\n\nfunction checkPollution( name ) {\n\tvar old = config.pollution;\n\tsaveGlobal();\n\t\n\tvar newGlobals = diff( old, config.pollution );\n\tif ( newGlobals.length > 0 ) {\n\t\tok( false, \"Introduced global variable(s): \" + newGlobals.join(\", \") );\n\t\tconfig.expected++;\n\t}\n\n\tvar deletedGlobals = diff( config.pollution, old );\n\tif ( deletedGlobals.length > 0 ) {\n\t\tok( false, \"Deleted global variable(s): \" + deletedGlobals.join(\", \") );\n\t\tconfig.expected++;\n\t}\n}\n\n// returns a new Array with the elements that are in a but not in b\nfunction diff( a, b ) {\n\tvar result = a.slice();\n\tfor ( var i = 0; i < result.length; i++ ) {\n\t\tfor ( var j = 0; j < b.length; j++ ) {\n\t\t\tif ( result[i] === b[j] ) {\n\t\t\t\tresult.splice(i, 1);\n\t\t\t\ti--;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction fail(message, exception, callback) {\n\tif ( typeof console !== \"undefined\" && console.error && console.warn ) {\n\t\tconsole.error(message);\n\t\tconsole.error(exception);\n\t\tconsole.warn(callback.toString());\n\n\t} else if ( window.opera && opera.postError ) {\n\t\topera.postError(message, exception, callback.toString);\n\t}\n}\n\nfunction extend(a, b) {\n\tfor ( var prop in b ) {\n\t\ta[prop] = b[prop];\n\t}\n\n\treturn a;\n}\n\nfunction addEvent(elem, type, fn) {\n\tif ( elem.addEventListener ) {\n\t\telem.addEventListener( type, fn, false );\n\t} else if ( elem.attachEvent ) {\n\t\telem.attachEvent( \"on\" + type, fn );\n\t} else {\n\t\tfn();\n\t}\n}\n\nfunction id(name) {\n\treturn !!(typeof document !== \"undefined\" && document && document.getElementById) &&\n\t\tdocument.getElementById( name );\n}\n\n// Test for equality any JavaScript type.\n// Discussions and reference: http://philrathe.com/articles/equiv\n// Test suites: http://philrathe.com/tests/equiv\n// Author: Philippe Rathé <prathe@gmail.com>\nQUnit.equiv = function () {\n\n    var innerEquiv; // the real equiv function\n    var callers = []; // stack to decide between skip/abort functions\n    var parents = []; // stack to avoiding loops from circular referencing\n\n    // Call the o related callback with the given arguments.\n    function bindCallbacks(o, callbacks, args) {\n        var prop = QUnit.objectType(o);\n        if (prop) {\n            if (QUnit.objectType(callbacks[prop]) === \"function\") {\n                return callbacks[prop].apply(callbacks, args);\n            } else {\n                return callbacks[prop]; // or undefined\n            }\n        }\n    }\n    \n    var callbacks = function () {\n\n        // for string, boolean, number and null\n        function useStrictEquality(b, a) {\n            if (b instanceof a.constructor || a instanceof b.constructor) {\n                // to catch short annotaion VS 'new' annotation of a declaration\n                // e.g. var i = 1;\n                //      var j = new Number(1);\n                return a == b;\n            } else {\n                return a === b;\n            }\n        }\n\n        return {\n            \"string\": useStrictEquality,\n            \"boolean\": useStrictEquality,\n            \"number\": useStrictEquality,\n            \"null\": useStrictEquality,\n            \"undefined\": useStrictEquality,\n\n            \"nan\": function (b) {\n                return isNaN(b);\n            },\n\n            \"date\": function (b, a) {\n                return QUnit.objectType(b) === \"date\" && a.valueOf() === b.valueOf();\n            },\n\n            \"regexp\": function (b, a) {\n                return QUnit.objectType(b) === \"regexp\" &&\n                    a.source === b.source && // the regex itself\n                    a.global === b.global && // and its modifers (gmi) ...\n                    a.ignoreCase === b.ignoreCase &&\n                    a.multiline === b.multiline;\n            },\n\n            // - skip when the property is a method of an instance (OOP)\n            // - abort otherwise,\n            //   initial === would have catch identical references anyway\n            \"function\": function () {\n                var caller = callers[callers.length - 1];\n                return caller !== Object &&\n                        typeof caller !== \"undefined\";\n            },\n\n            \"array\": function (b, a) {\n                var i, j, loop;\n                var len;\n\n                // b could be an object literal here\n                if ( ! (QUnit.objectType(b) === \"array\")) {\n                    return false;\n                }   \n                \n                len = a.length;\n                if (len !== b.length) { // safe and faster\n                    return false;\n                }\n                \n                //track reference to avoid circular references\n                parents.push(a);\n                for (i = 0; i < len; i++) {\n                    loop = false;\n                    for(j=0;j<parents.length;j++){\n                        if(parents[j] === a[i]){\n                            loop = true;//dont rewalk array\n                        }\n                    }\n                    if (!loop && ! innerEquiv(a[i], b[i])) {\n                        parents.pop();\n                        return false;\n                    }\n                }\n                parents.pop();\n                return true;\n            },\n\n            \"object\": function (b, a) {\n                var i, j, loop;\n                var eq = true; // unless we can proove it\n                var aProperties = [], bProperties = []; // collection of strings\n\n                // comparing constructors is more strict than using instanceof\n                if ( a.constructor !== b.constructor) {\n                    return false;\n                }\n\n                // stack constructor before traversing properties\n                callers.push(a.constructor);\n                //track reference to avoid circular references\n                parents.push(a);\n                \n                for (i in a) { // be strict: don't ensures hasOwnProperty and go deep\n                    loop = false;\n                    for(j=0;j<parents.length;j++){\n                        if(parents[j] === a[i])\n                            loop = true; //don't go down the same path twice\n                    }\n                    aProperties.push(i); // collect a's properties\n\n                    if (!loop && ! innerEquiv(a[i], b[i])) {\n                        eq = false;\n                        break;\n                    }\n                }\n\n                callers.pop(); // unstack, we are done\n                parents.pop();\n\n                for (i in b) {\n                    bProperties.push(i); // collect b's properties\n                }\n\n                // Ensures identical properties name\n                return eq && innerEquiv(aProperties.sort(), bProperties.sort());\n            }\n        };\n    }();\n\n    innerEquiv = function () { // can take multiple arguments\n        var args = Array.prototype.slice.apply(arguments);\n        if (args.length < 2) {\n            return true; // end transition\n        }\n\n        return (function (a, b) {\n            if (a === b) {\n                return true; // catch the most you can\n            } else if (a === null || b === null || typeof a === \"undefined\" || typeof b === \"undefined\" || QUnit.objectType(a) !== QUnit.objectType(b)) {\n                return false; // don't lose time with error prone cases\n            } else {\n                return bindCallbacks(a, callbacks, [b, a]);\n            }\n\n        // apply transition with (1..n) arguments\n        })(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length -1));\n    };\n\n    return innerEquiv;\n\n}();\n\n/**\n * jsDump\n * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com\n * Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php)\n * Date: 5/15/2008\n * @projectDescription Advanced and extensible data dumping for Javascript.\n * @version 1.0.0\n * @author Ariel Flesler\n * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}\n */\nQUnit.jsDump = (function() {\n\tfunction quote( str ) {\n\t\treturn '\"' + str.toString().replace(/\"/g, '\\\\\"') + '\"';\n\t};\n\tfunction literal( o ) {\n\t\treturn o + '';\t\n\t};\n\tfunction join( pre, arr, post ) {\n\t\tvar s = jsDump.separator(),\n\t\t\tbase = jsDump.indent(),\n\t\t\tinner = jsDump.indent(1);\n\t\tif ( arr.join )\n\t\t\tarr = arr.join( ',' + s + inner );\n\t\tif ( !arr )\n\t\t\treturn pre + post;\n\t\treturn [ pre, inner + arr, base + post ].join(s);\n\t};\n\tfunction array( arr ) {\n\t\tvar i = arr.length,\tret = Array(i);\t\t\t\t\t\n\t\tthis.up();\n\t\twhile ( i-- )\n\t\t\tret[i] = this.parse( arr[i] );\t\t\t\t\n\t\tthis.down();\n\t\treturn join( '[', ret, ']' );\n\t};\n\t\n\tvar reName = /^function (\\w+)/;\n\t\n\tvar jsDump = {\n\t\tparse:function( obj, type ) { //type is used mostly internally, you can fix a (custom)type in advance\n\t\t\tvar\tparser = this.parsers[ type || this.typeOf(obj) ];\n\t\t\ttype = typeof parser;\t\t\t\n\t\t\t\n\t\t\treturn type == 'function' ? parser.call( this, obj ) :\n\t\t\t\t   type == 'string' ? parser :\n\t\t\t\t   this.parsers.error;\n\t\t},\n\t\ttypeOf:function( obj ) {\n\t\t\tvar type;\n\t\t\tif ( obj === null ) {\n\t\t\t\ttype = \"null\";\n\t\t\t} else if (typeof obj === \"undefined\") {\n\t\t\t\ttype = \"undefined\";\n\t\t\t} else if (QUnit.is(\"RegExp\", obj)) {\n\t\t\t\ttype = \"regexp\";\n\t\t\t} else if (QUnit.is(\"Date\", obj)) {\n\t\t\t\ttype = \"date\";\n\t\t\t} else if (QUnit.is(\"Function\", obj)) {\n\t\t\t\ttype = \"function\";\n\t\t\t} else if (obj.setInterval && obj.document && !obj.nodeType) {\n\t\t\t\ttype = \"window\";\n\t\t\t} else if (obj.nodeType === 9) {\n\t\t\t\ttype = \"document\";\n\t\t\t} else if (obj.nodeType) {\n\t\t\t\ttype = \"node\";\n\t\t\t} else if (typeof obj === \"object\" && typeof obj.length === \"number\" && obj.length >= 0) {\n\t\t\t\ttype = \"array\";\n\t\t\t} else {\n\t\t\t\ttype = typeof obj;\n\t\t\t}\n\t\t\treturn type;\n\t\t},\n\t\tseparator:function() {\n\t\t\treturn this.multiline ?\tthis.HTML ? '<br />' : '\\n' : this.HTML ? '&nbsp;' : ' ';\n\t\t},\n\t\tindent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing\n\t\t\tif ( !this.multiline )\n\t\t\t\treturn '';\n\t\t\tvar chr = this.indentChar;\n\t\t\tif ( this.HTML )\n\t\t\t\tchr = chr.replace(/\\t/g,'   ').replace(/ /g,'&nbsp;');\n\t\t\treturn Array( this._depth_ + (extra||0) ).join(chr);\n\t\t},\n\t\tup:function( a ) {\n\t\t\tthis._depth_ += a || 1;\n\t\t},\n\t\tdown:function( a ) {\n\t\t\tthis._depth_ -= a || 1;\n\t\t},\n\t\tsetParser:function( name, parser ) {\n\t\t\tthis.parsers[name] = parser;\n\t\t},\n\t\t// The next 3 are exposed so you can use them\n\t\tquote:quote, \n\t\tliteral:literal,\n\t\tjoin:join,\n\t\t//\n\t\t_depth_: 1,\n\t\t// This is the list of parsers, to modify them, use jsDump.setParser\n\t\tparsers:{\n\t\t\twindow: '[Window]',\n\t\t\tdocument: '[Document]',\n\t\t\terror:'[ERROR]', //when no parser is found, shouldn't happen\n\t\t\tunknown: '[Unknown]',\n\t\t\t'null':'null',\n\t\t\tundefined:'undefined',\n\t\t\t'function':function( fn ) {\n\t\t\t\tvar ret = 'function',\n\t\t\t\t\tname = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE\n\t\t\t\tif ( name )\n\t\t\t\t\tret += ' ' + name;\n\t\t\t\tret += '(';\n\t\t\t\t\n\t\t\t\tret = [ ret, this.parse( fn, 'functionArgs' ), '){'].join('');\n\t\t\t\treturn join( ret, this.parse(fn,'functionCode'), '}' );\n\t\t\t},\n\t\t\tarray: array,\n\t\t\tnodelist: array,\n\t\t\targuments: array,\n\t\t\tobject:function( map ) {\n\t\t\t\tvar ret = [ ];\n\t\t\t\tthis.up();\n\t\t\t\tfor ( var key in map )\n\t\t\t\t\tret.push( this.parse(key,'key') + ': ' + this.parse(map[key]) );\n\t\t\t\tthis.down();\n\t\t\t\treturn join( '{', ret, '}' );\n\t\t\t},\n\t\t\tnode:function( node ) {\n\t\t\t\tvar open = this.HTML ? '&lt;' : '<',\n\t\t\t\t\tclose = this.HTML ? '&gt;' : '>';\n\t\t\t\t\t\n\t\t\t\tvar tag = node.nodeName.toLowerCase(),\n\t\t\t\t\tret = open + tag;\n\t\t\t\t\t\n\t\t\t\tfor ( var a in this.DOMAttrs ) {\n\t\t\t\t\tvar val = node[this.DOMAttrs[a]];\n\t\t\t\t\tif ( val )\n\t\t\t\t\t\tret += ' ' + a + '=' + this.parse( val, 'attribute' );\n\t\t\t\t}\n\t\t\t\treturn ret + close + open + '/' + tag + close;\n\t\t\t},\n\t\t\tfunctionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function\n\t\t\t\tvar l = fn.length;\n\t\t\t\tif ( !l ) return '';\t\t\t\t\n\t\t\t\t\n\t\t\t\tvar args = Array(l);\n\t\t\t\twhile ( l-- )\n\t\t\t\t\targs[l] = String.fromCharCode(97+l);//97 is 'a'\n\t\t\t\treturn ' ' + args.join(', ') + ' ';\n\t\t\t},\n\t\t\tkey:quote, //object calls it internally, the key part of an item in a map\n\t\t\tfunctionCode:'[code]', //function calls it internally, it's the content of the function\n\t\t\tattribute:quote, //node calls it internally, it's an html attribute value\n\t\t\tstring:quote,\n\t\t\tdate:quote,\n\t\t\tregexp:literal, //regex\n\t\t\tnumber:literal,\n\t\t\t'boolean':literal\n\t\t},\n\t\tDOMAttrs:{//attributes to dump from nodes, name=>realName\n\t\t\tid:'id',\n\t\t\tname:'name',\n\t\t\t'class':'className'\n\t\t},\n\t\tHTML:false,//if true, entities are escaped ( <, >, \\t, space and \\n )\n\t\tindentChar:'   ',//indentation unit\n\t\tmultiline:false //if true, items in a collection, are separated by a \\n, else just a space.\n\t};\n\n\treturn jsDump;\n})();\n\n// from Sizzle.js\nfunction getText( elems ) {\n\tvar ret = \"\", elem;\n\n\tfor ( var i = 0; elems[i]; i++ ) {\n\t\telem = elems[i];\n\n\t\t// Get the text from text nodes and CDATA nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 4 ) {\n\t\t\tret += elem.nodeValue;\n\n\t\t// Traverse everything else, except comment nodes\n\t\t} else if ( elem.nodeType !== 8 ) {\n\t\t\tret += getText( elem.childNodes );\n\t\t}\n\t}\n\n\treturn ret;\n};\n\n/*\n * Javascript Diff Algorithm\n *  By John Resig (http://ejohn.org/)\n *  Modified by Chu Alan \"sprite\"\n *\n * Released under the MIT license.\n *\n * More Info:\n *  http://ejohn.org/projects/javascript-diff-algorithm/\n *  \n * Usage: QUnit.diff(expected, actual)\n * \n * QUnit.diff(\"the quick brown fox jumped over\", \"the quick fox jumps over\") == \"the  quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over\"\n */\nQUnit.diff = (function() {\n\tfunction diff(o, n){\n\t\tvar ns = new Object();\n\t\tvar os = new Object();\n\t\t\n\t\tfor (var i = 0; i < n.length; i++) {\n\t\t\tif (ns[n[i]] == null) \n\t\t\t\tns[n[i]] = {\n\t\t\t\t\trows: new Array(),\n\t\t\t\t\to: null\n\t\t\t\t};\n\t\t\tns[n[i]].rows.push(i);\n\t\t}\n\t\t\n\t\tfor (var i = 0; i < o.length; i++) {\n\t\t\tif (os[o[i]] == null) \n\t\t\t\tos[o[i]] = {\n\t\t\t\t\trows: new Array(),\n\t\t\t\t\tn: null\n\t\t\t\t};\n\t\t\tos[o[i]].rows.push(i);\n\t\t}\n\t\t\n\t\tfor (var i in ns) {\n\t\t\tif (ns[i].rows.length == 1 && typeof(os[i]) != \"undefined\" && os[i].rows.length == 1) {\n\t\t\t\tn[ns[i].rows[0]] = {\n\t\t\t\t\ttext: n[ns[i].rows[0]],\n\t\t\t\t\trow: os[i].rows[0]\n\t\t\t\t};\n\t\t\t\to[os[i].rows[0]] = {\n\t\t\t\t\ttext: o[os[i].rows[0]],\n\t\t\t\t\trow: ns[i].rows[0]\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\t\n\t\tfor (var i = 0; i < n.length - 1; i++) {\n\t\t\tif (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null &&\n\t\t\tn[i + 1] == o[n[i].row + 1]) {\n\t\t\t\tn[i + 1] = {\n\t\t\t\t\ttext: n[i + 1],\n\t\t\t\t\trow: n[i].row + 1\n\t\t\t\t};\n\t\t\t\to[n[i].row + 1] = {\n\t\t\t\t\ttext: o[n[i].row + 1],\n\t\t\t\t\trow: i + 1\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\t\n\t\tfor (var i = n.length - 1; i > 0; i--) {\n\t\t\tif (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null &&\n\t\t\tn[i - 1] == o[n[i].row - 1]) {\n\t\t\t\tn[i - 1] = {\n\t\t\t\t\ttext: n[i - 1],\n\t\t\t\t\trow: n[i].row - 1\n\t\t\t\t};\n\t\t\t\to[n[i].row - 1] = {\n\t\t\t\t\ttext: o[n[i].row - 1],\n\t\t\t\t\trow: i - 1\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn {\n\t\t\to: o,\n\t\t\tn: n\n\t\t};\n\t}\n\t\n\treturn function(o, n){\n\t\to = o.replace(/\\s+$/, '');\n\t\tn = n.replace(/\\s+$/, '');\n\t\tvar out = diff(o == \"\" ? [] : o.split(/\\s+/), n == \"\" ? [] : n.split(/\\s+/));\n\n\t\tvar str = \"\";\n\t\t\n\t\tvar oSpace = o.match(/\\s+/g);\n\t\tif (oSpace == null) {\n\t\t\toSpace = [\" \"];\n\t\t}\n\t\telse {\n\t\t\toSpace.push(\" \");\n\t\t}\n\t\tvar nSpace = n.match(/\\s+/g);\n\t\tif (nSpace == null) {\n\t\t\tnSpace = [\" \"];\n\t\t}\n\t\telse {\n\t\t\tnSpace.push(\" \");\n\t\t}\n\t\t\n\t\tif (out.n.length == 0) {\n\t\t\tfor (var i = 0; i < out.o.length; i++) {\n\t\t\t\tstr += '<del>' + out.o[i] + oSpace[i] + \"</del>\";\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tif (out.n[0].text == null) {\n\t\t\t\tfor (n = 0; n < out.o.length && out.o[n].text == null; n++) {\n\t\t\t\t\tstr += '<del>' + out.o[n] + oSpace[n] + \"</del>\";\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tfor (var i = 0; i < out.n.length; i++) {\n\t\t\t\tif (out.n[i].text == null) {\n\t\t\t\t\tstr += '<ins>' + out.n[i] + nSpace[i] + \"</ins>\";\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tvar pre = \"\";\n\t\t\t\t\t\n\t\t\t\t\tfor (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) {\n\t\t\t\t\t\tpre += '<del>' + out.o[n] + oSpace[n] + \"</del>\";\n\t\t\t\t\t}\n\t\t\t\t\tstr += \" \" + out.n[i].text + nSpace[i] + pre;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn str;\n\t}\n})();\n\n})(this);\n"
  },
  {
    "path": "app/static_dev/test/tests.js",
    "content": "\n// documentation on writing tests here: http://docs.jquery.com/QUnit\n// example tests: https://github.com/jquery/qunit/blob/master/test/same.js\n\n// below are some general tests but feel free to delete them.\n\nmodule(\"example tests\");\ntest(\"HTML5 Boilerplate is sweet\",function(){\n  expect(1);\n  equals(\"boilerplate\".replace(\"boilerplate\",\"sweet\"),\"sweet\",\"Yes. HTML5 Boilerplate is, in fact, sweet\");\n  \n})\n\n// these test things from plugins.js\ntest(\"Environment is good\",function(){\n  expect(3);\n  ok( !!window.log, \"log function present\");\n  \n  var history = log.history && log.history.length || 0;\n  log(\"logging from the test suite.\")\n  equals( log.history.length - history, 1, \"log history keeps track\" )\n  \n  ok( !!window.Modernizr, \"Modernizr global is present\")\n})\n\n\n\n"
  },
  {
    "path": "app/templates/account.html",
    "content": "{% extends \"base.html\" %}\n\n{% block main %}\n<h2>Account</h2>\n\n\n<form action=\"/account/setup\" method=\"post\">\n    <input type=\"hidden\" name=\"continue\" value=\"{{ target_url }}\" />\n    <input type=\"hidden\" name=\"subscribe\" value=\"{% if prefs.subscribed_to_newsletter %}on{% endif %}\" />\n    <table border=\"0\">\n        <tr><td>Username:</td> <td><input type=\"text\" name=\"username\" value=\"{{ prefs.nickname }}\" /></td></tr>\n        <tr><td>Email:</td> <td><input type=\"text\" name=\"email\" value=\"{{ prefs.email }}\" /></td></tr>\n        <tr><td></td><td><br><input type=\"submit\" class=\"button\" value=\"ok\" />{% if target_url %}<br><small>Continue to {{ target_url }}</small>{% endif %}</td></tr>\n    </table>\n</form>\n\n{% endblock %}\n"
  },
  {
    "path": "app/templates/account_setup.html",
    "content": "{% extends \"base.html\" %}\n\n{% block main %}\n<h2>Account Setup</h2>\n\n<form action=\"/account/setup\" method=\"post\">\n    <input type=\"hidden\" name=\"continue\" value=\"{{ target_url }}\" />\n    <table border=\"0\">\n        <tr><td>Username:</td> <td><input type=\"text\" name=\"username\" value=\"{{ prefs.nickname }}\" /></td></tr>\n        <tr><td>Email:</td> <td><input type=\"text\" name=\"email\" value=\"{{ prefs.email }}\" /></td></tr>\n        <tr><td><input type=\"checkbox\" name=\"subscribe\" id=\"subscribe\" checked /></td> <td><label for=\"subscribe\">Receive our newsletter</label></td></tr>\n        <tr><td></td><td><br><input type=\"submit\" class=\"button\" value=\"ok\" /><br><small>Continue to {{ target_url }}</small></td></tr>\n    </table>\n</form>\n\n{% endblock %}\n"
  },
  {
    "path": "app/templates/footer.html",
    "content": ""
  },
  {
    "path": "app/templates/header.html",
    "content": "<h1><a href=\"/\">App Engine <i>★</i> Boilerplate</a></h1> \n \n"
  },
  {
    "path": "app/templates/index.html",
    "content": "{% extends \"base.html\" %}\n\n{% block title %}App Engine Boilerplate - A rock-solid default template for App Engine{% endblock %}\n\n{% block main %}\n    <a rel=\"nofollow\" class=\"fork\" href=\"https://github.com/metachris/appengine-boilerplate\"> \n        <img src=\"/img/forkme-badge.png\" alt=\"Fork me on GitHub\"> \n    </a> \n\n    <p>App Engine Boilerplate is a fast, robust and future-proof base template to get your project off the ground quickly and right-footed. </p> \n\n    <h2>What does it include?</h2> \n        <img src=\"/img/h5bp-logo.png\" class=\"logo_right\" />\n        <img src=\"/img/appengine-logo.png\" class=\"logo_right\" />\n\n   <ul> \n        <li><a rel=\"nofollow\" href=\"http://www.html5boilerplate.com\">HTML5 Boilerplate 2.0</a></li> \n        <li>Build script to optimize images, js and css files</li> \n        <li>OpenID authentication with a beautiful interface</li> \n        <li>User preferences model with caching and Gravatar link</li> \n        <li>Optimal caching and compression rules</li> \n        <li>Best practice site configuration defaults</li>\n        <li>MailChimp integration, @login_required decorator</li>\n        <li>Minimal code, detailed comments</li> \n    </ul> \n    \n    {% if prefs %}<h2>Welcome, {{ prefs.nickname }}</h2>{% endif %}\n    \n    <div class=\"demo\"> \n        <a rel=\"nofollow\" class=\"button\" href=\"https://github.com/metachris/appengine-boilerplate\">Visit on Github</a> \n         &nbsp;\n         {% if prefs %}\n            <a class=\"button\" href=\"/account\">Account</a>\n            &nbsp;\n            <a class=\"button\" href=\"/logout\">Log Out</a>\n         {% else %}\n            <a class=\"button\" href=\"/login?continue=/\">Test the Login</a>\n         {% endif %}\n    </div> \n\n    <p>App Engine Boilerplate just contains the things you need to get started. Take a look at the files and start building your idea!\n    </p><p>\n    The code is freely available under the BSD license so you can use it to build anything you want!\n    </p>            \n\n    <h2>How do I get started?</h2> \n    <p>Visit the <a rel=\"nofollow\" href=\"https://github.com/metachris/appengine-boilerplate\">GitHub repo</a> or download it in either <a rel=\"nofollow\" href=\"https://github.com/metachris/appengine-boilerplate/zipball/master\">zip</a> or <a rel=\"nofollow\" href=\"https://github.com/metachris/appengine-boilerplate/tarball/master\">tar</a> format. \n    Here is a quick guide for the first steps:</p> \n    <pre># Clone the repository\n$ git clone git@github.com:metachris/appengine-boilerplate.git\n$ cd appengine-boilerplate\n\n# Start the app engine devserver\n$ &lt;GAE_DIR>/dev_appserver.py app\n\n# You can now visit the site via localhost:8080\n$ google-chrome http://localhost:8080\n\n# To build and preview the site before uploading\n$ ./upload_to_appengine.sh \nBuild the project with 'ant minify' now? [yN]y\n... lots of build output ...\nSetting /static to /static_dev/publish\nYou can now test the latest build. Do you wish to upload this version? [yN]n\nSetting /static back to /static_dev</pre>\n \n<p><br><small>Tip: HTML5 Boilerplate is located in <tt>/static_dev</tt>.</small></p>\n \n \n    <h2>How can I contribute?</h2>\n    <p>If you have ideas for changes to the project, join us on Github and file a ticket, or send over a pull request if you have working code!</p>\n\n    <div class=\"share-bar\"> \n        <div class=\"share-opt\"> \n            <a rel=\"nofollow\" class=\"twitter-share-button\" \n               href=\"http://twitter.com/share\" \n               data-count=\"vertical\" \n               data-text=\"Checking out App Engine Boilerplate\"></a> \n        </div> \n        \n        <div class=\"share-opt\"> \n            <g:plusone size=\"tall\"></g:plusone> \n        </div> \n\n        <div class=\"share-opt\"> \n            <fb:like href=\"\" send=\"false\" layout=\"box_count\" width=\"40\" show_faces=\"false\" font=\"\"></fb:like> \n            <div id=\"fb-root\"></div> \n        </div> \n    </div> \n    \n    \n    <div class=\"footer\"> \n        <p><small>Contributions by <a rel=\"nofollow\" href=\"http://twitter.com/metachris\">Chris Hager</a> <small>★</small> <a rel=\"nofollow\" href=\"https://github.com/foamdino\">Kev Jackson</a> <small>★</small> <a rel=\"nofollow\" href=\"https://github.com/raultorres88\">raultorres88</a></small></p> \n    </div> \n\n    <script> \n        (function(w,d){\n            Modernizr.load({load: '//connect.facebook.net/en_US/all.js#xfbml=1'});\n            Modernizr.load({load: '//platform.twitter.com/widgets.js'});\n            Modernizr.load({load: 'https://apis.google.com/js/plusone.js'});\n        }(this,document));\n    </script>  \n{% endblock %}\n"
  },
  {
    "path": "app/templates/login.html",
    "content": "{% extends \"base.html\" %}\n\n{% block scripts %}\n\t<script> \n        $(document).ready(function() {\n        \topenid.init('openid_identifier');\n        });\n\t</script>\n{% endblock %}\n\n{% block main %}\n\t<!-- Simple OpenID Selector --> \n\t<form action=\"/login\" method=\"get\" id=\"openid_form\"> \n\t\t<input type=\"hidden\" name=\"action\" value=\"verify\" /> \n\t\t{% if continue_to %}<input type=\"hidden\" name=\"continue\" value=\"{{ continue_to }}\" />{% endif %}\t\t\n\t\t<fieldset> \n\t\t\t<legend>Sign-in or Create New Account</legend> \n\t\t\t<div id=\"openid_choice\"> \n\t\t\t\t<p>Please click your account provider:</p> \n\t\t\t\t<div id=\"openid_btns\"></div> \n\t\t\t</div> \n\t\t\t<div id=\"openid_input_area\"> \n\t\t\t\t<input id=\"openid_identifier\" name=\"openid_identifier\" type=\"text\" value=\"http://\" /> \n\t\t\t\t<input id=\"openid_submit\" type=\"submit\" value=\"Sign-In\"/> \n\t\t\t</div> \n\t\t\t<noscript> \n\t\t\t\t<p>OpenID is service that allows you to log-on to many different websites using a single indentity.\n\t\t\t\tFind out <a href=\"http://openid.net/what/\">more about OpenID</a> and <a href=\"http://openid.net/get/\">how to get an OpenID enabled account</a>.</p>\n\t\t\t</noscript> \n\t\t</fieldset> \n\t</form> \n\t<!-- /Simple OpenID Selector --> \n\t\n{% endblock %}\n"
  },
  {
    "path": "app/tools/__init__.py",
    "content": ""
  },
  {
    "path": "app/tools/common.py",
    "content": "# -*- coding: utf-8 -*-\nimport re\nimport logging\nimport unicodedata\nfrom os import environ\n\n\ndef is_testenv():\n    \"\"\"\n    True if devserver, False if appengine server\n\n    Appengine uses 'Google App Engine/<version>',\n    Devserver uses 'Development/<version>'\n    \"\"\"\n    return environ.get('SERVER_SOFTWARE', '').startswith('Development')\n\n\ndef decode(var):\n    \"\"\"Safely decode form input\"\"\"\n    if not var:\n        return var\n    return unicode(var, 'utf-8') if isinstance(var, str) else unicode(var)\n\n\ndef slugify(value):\n    \"\"\"\n    Normalizes string, converts to lowercase, removes non-ascii characters,\n    and converts spaces to hyphens.\n\n    From Django's \"django/template/defaultfilters.py\".\n    \"\"\"\n    _slugify_strip_re = re.compile(r'[^\\w\\s-]')\n    _slugify_hyphenate_re = re.compile(r'[-\\s]+')\n\n    if not isinstance(value, unicode):\n        value = unicode(value)\n    value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')\n    value = unicode(_slugify_strip_re.sub('', value).strip().lower())\n    return _slugify_hyphenate_re.sub('-', value)\n"
  },
  {
    "path": "app/tools/decorators.py",
    "content": "# -*- coding: utf-8 -*-\nfrom google.appengine.api import users\n\n\ndef login_required(func):\n    \"\"\"You can use the @login_required decorator to disallow access to specific\n    BaseRequestHandler methods (eg. get(), post()). Example:\n\n        class Secrets(BaseRequestHandler):\n            @login_required\n            def post(self):\n                self.render(\"secrets.html\")\n\n    \"\"\"\n    def _wrapper(request, *args, **kw):\n        if request.userprefs:\n            return func(request, *args, **kw)\n        else:\n            return request.redirect( \\\n                    users.create_login_url(request.request.uri))\n\n    return _wrapper\n"
  },
  {
    "path": "app/tools/mailchimp.py",
    "content": "import logging\nimport urllib2\nimport settings\n\ntry:\n    import simplejson as json\nexcept ImportError:\n    import json\n\n\ndef mailchimp_subscribe(email, list_id=None, double_optin=True):\n    \"\"\"\n    Subscribes this email to your mailchimp newsletter. If list_id is not\n    set it will default to settings.MAILCHIMP_LIST_ID.\n    \"\"\"\n    ms = MailSnake(settings.MAILCHIMP_API_KEY)\n    list_id = list_id or settings.MAILCHIMP_LIST_ID\n    res = ms.listSubscribe(id=list_id, email_address=email, \\\n            double_optin=double_optin)\n    logging.info(\"MailChimp: Subscribed user %s to list %s. Result: %s\", email,\n            list_id, res)\n\n\ndef mailchimp_unsubscribe(email, list_id=None, delete_member=False,\n        send_goodbye=True, send_notify=True):\n    \"\"\"\n    Unsubscribes this email from your mailchimp newsletter. If list_id is not\n    set it will default to settings.MAILCHIMP_LIST_ID.\n    \"\"\"\n    ms = MailSnake(settings.MAILCHIMP_API_KEY)\n    list_id = list_id or settings.MAILCHIMP_LIST_ID\n    res = ms.listUnsubscribe(id=list_id, email_address=email,\n            delete_member=delete_member, send_goodbye=send_goodbye,\n            send_notify=send_notify)\n\n    logging.info(\"MailChimp: Unsubscribed user %s from list %s. Result: %s\",\n            email, list_id, res)\n\n\nclass MailSnake(object):\n    \"\"\"\n    MailSnake is a simple MailChimp API Wrapper.\n    - URL: https://github.com/leftium/mailsnake\n    - Author: John-Kim Murphy (https://github.com/leftium)\n    \"\"\"\n    def __init__(self, apikey='', extra_params={}):\n        if not apikey:\n            raise ValueError(\"MailChimp API Key not valid. Set in settings.py\")\n\n        self.apikey = apikey\n\n        self.default_params = {'apikey': apikey}\n        self.default_params.update(extra_params)\n\n        dc = 'us1'  # Overwritten if part of the API key\n        if '-' in self.apikey:\n            dc = self.apikey.split('-')[1]\n        self.base_api_url = 'https://%s.api.mailchimp.com/1.3/?method=' % dc\n\n    def call(self, method, params={}):\n        url = self.base_api_url + method\n        params.update(self.default_params)\n\n        post_data = json.dumps(params)\n        headers = {'Content-Type': 'application/json'}\n        request = urllib2.Request(url, post_data, headers)\n        response = urllib2.urlopen(request)\n\n        return json.loads(response.read())\n\n    def __getattr__(self, method_name):\n        def get(self, *args, **kwargs):\n            params = dict((i, j) for (i, j) in enumerate(args))\n            params.update(kwargs)\n            return self.call(method_name, params)\n\n        return get.__get__(self)\n"
  },
  {
    "path": "upload_to_appengine.sh",
    "content": "#!/bin/bash\n\n# Point CMD_APPCFG to your local appengine-sdk/appcfg.py\nCMD_APPCFG=\"\"\n\n# Cache current directory\nDIR=$( pwd )\n\nfunction static_revert {\n  # Set /static back to dev environment\n  set -e\n  echo \"Setting /static back to /static_dev\"\n  cd app\n  rm static\n  ln -s static_dev static\n  cd \"$DIR\"\n  set +e\n}\n\nfunction static_toprod {\n  # Set build script results as /static\n  set -e\n  echo \"Setting /static to /static_dev/publish\"\n  cd app\n  rm static\n  ln -s static_dev/publish static\n  cd \"$DIR\"\n  set +e\n}\n\nfunction upload {\n    # Upload to appengine\n    if [ $CMD_APPCFG ]; then\n        $CMD_APPCFG update app    \n    else\n        echo \"Error: You need to edit upload_to_appengine.sh: point CMD_APPCFG to your local appengine's appcfg.py\"\n    fi\n}\n\nfunction build {\n  cd app/static_dev/build\n  ant minify\n  cd \"$DIR\"\n}\n\nread -p \"Build the project with 'ant minify' now? [yN]\" yn\ncase $yn in\n    [Yy]* ) build;;\n    [Nn]* ) ;;\nesac\n\nstatic_toprod\n\nread -p \"You can now test the latest build. Do you wish to upload this version? [yN]\" yn\ncase $yn in\n    [Yy]* ) upload;;\n    [Nn]* ) ;;\nesac\n\nstatic_revert\n\n\n"
  }
]