commit dcf525dcd2b67b46883d821882d4c9e54787f7a3 Author: Petr Viktorin Date: Sat Nov 19 01:36:39 2011 +0200 sphinx build 2011-11-19 01:36:39+02:00 diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 0000000..dbfd181 --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 20fbb3c1f25faf227aa89dc7ec78651b +tags: fbb0d17656682115ca4d033fb2f83ba1 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/_sources/index.txt b/_sources/index.txt new file mode 100644 index 0000000..a525f6f --- /dev/null +++ b/_sources/index.txt @@ -0,0 +1,25 @@ +.. pokedex documentation master file, created by + sphinx-quickstart on Tue Apr 12 17:43:05 2011. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +The pokedex documentation +========================= + +Jump right in! + +Contents: + +.. toctree:: + :maxdepth: 2 + + installing + usage + schema + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` + diff --git a/_sources/installing.txt b/_sources/installing.txt new file mode 100644 index 0000000..4fd24b5 --- /dev/null +++ b/_sources/installing.txt @@ -0,0 +1,157 @@ +Installing the pokedex library +============================== + +Quick startup with Ubuntu/Debian-like systems +--------------------------------------------- + +Run the following from an empty directory:: + + $ sudo apt-get install git python python-pip python-sqlalchemy + $ git clone git://git.veekun.com/pokedex.git + $ pip install -E env -e pokedex + $ source env/bin/activate + (env)$ pokedex setup -v + (env)$ pokedex lookup eevee + +If it all goes smoothly, you can now use ``env/bin/pokedex``, the command-line +tool, and ``env/bin/python``, a Python interpreter configured to use the +pokedex library. + +That is all you need. Feel free to skip the rest of this chapter if you're not +interested in the details. + +Prerequisites +------------- + +Linux +^^^^^ + +Ubuntu/Debian users should run the following:: + + $ sudo apt-get install git python python-pip + +With other Linuxes, install the packages for git, python (2.6 or 2.7, +*not* 3.x), and python-pip. + +If you succeeded, skip the Detailed instructions. + +Detailed instructions +^^^^^^^^^^^^^^^^^^^^^ + +You should know what a command line is and how to work with it. +The here we assume you're using Linux [#]_, if that's not the case, make +sure you have enough computer knowledge to translate the instructions to your +operating system. + +Pokedex is distributed via Git_. So, get Git. + +You will also need Python_ 2; the language pokedex is written in. Be sure to get +version **2.6** or **2.7**. Pokedex does not work with Python 3.x yet, and it +most likely won't work with 2.5 or earlier. + +Next, get pip_, a tool to install Python packages. Experts can use another +tool, of course. + +Make sure git and pip are on your path. + +Optionally you can install SQLAlchemy_, `Python markdown`_, Whoosh_, +or construct_. If you don't, pip will atuomatically download and install a copy +for you, but some are pretty big so you might want to install it system-wide. +(Unfortunately, many distros have outdated versions of these libraries, so pip +will install pokedex's own copy anyway.) + +Getting and installing pokedex +------------------------------ + +Run the following from an empty directory:: + + $ git clone git://git.veekun.com/pokedex.git + $ pip install -E env -e pokedex + +This will give you two directories: pokedex (containing the source code and +data), and env (a virtualenv_). + +In env/bin, there are three interesting files: + +* pokedex: The pokedex program +* python: A copy of Python that knows about pokedex and its prerequisites. + Using the system python won't work. +* activate: Typing ``source env/bin/activate`` in a shell will put + pokedex and our bin/python on the $PATH, and generally set things up to work + with them. Your prompt will change to let you know of this. You can end such + a session by typing ``deactivate``. + +This documentation will assume that you've activated the virtualenv, so +``pokedex`` means ``env/bin/pokedex``. + +Advanced +^^^^^^^^ + +You can of course install into an existing virtualenv, by either using its pip +and leaving out the ``-E env``, or running the setup script directly:: + + (anotherenv)$ cd pokedex + (anotherenv)pokedex$ python setup.py develop + +It is also possible to install pokedex system-wide. There are problems with +that. Don't do it. The only time you need ``sudo`` is for getting the +prerequisites. + +Loading the database +-------------------- + +Before you can do anything useful with pokedex, you need to load the database:: + + $ pokedex setup -v + +This will load the data into a default SQLite database and create a default +Whoosh index. + +Advanced +^^^^^^^^ + +If you want to use another database, make sure you have the corresponding +`SQLAlchemy engine`_ for it and either use the ``-e`` switch, (e.g. +``-e postgresql://@/pokedex``), or set the ``POKEDEX_DB_ENGINE`` environment +variable. + +To use another lookup index directory, specify it with ``-i`` or the +``POKEDEX_INDEX_DIR`` variable. + +Make sure you always use the same options whenever you use pokedex. + +If you're confused about what pokedex thinks its settings are, check +``pokedex status``. + +See ``pokedex help`` for even more options. + +All done +-------- + +To verify that all went smoothly, check that the pokedex tool finds your +favorite pokémon:: + + $ pokedex lookup eevee + +Yes, that was a bit anti-climatic. The command-line tool doesn't do much, +currently. + + + + + + +.. _Git: http://git-scm.com/ +.. _Python: http://www.python.org/ +.. _pip: http://pypi.python.org/pypi/pip +.. _SQLAlchemy: www.sqlalchemy.org/ +.. _`Python markdown`: http://www.freewisdom.org/projects/python-markdown/ +.. _Whoosh: http://whoosh.ca/ +.. _construct: pypi.python.org/pypi/construct +.. _virtualenv: http://www.virtualenv.org/en/latest/ +.. _`SQLAlchemy engine`: http://www.sqlalchemy.org/docs/core/engines.html + +.. rubric:: Footnotes +.. [#] If you write instructions for another OS, well be happy to include them + here. The reason your OS is not listed here is because the author doesn't + use it, so naturally he can't write instructions for it. diff --git a/_sources/main-tables.txt b/_sources/main-tables.txt new file mode 100644 index 0000000..5da1e90 --- /dev/null +++ b/_sources/main-tables.txt @@ -0,0 +1,172 @@ +The pokédex tables +================== + +.. module:: pokedex.db.tables + +All the tables listed here are classes defined with SQLAlchemy's +:mod:`~sqlalchemy.ext.declarative` extension. + +.. data:: metadata + + The SQLAlchemy :class:`~sqlalchemy.schema.MetaData` containing all the + tables. + +.. data:: mapped_classes + + A list of all the classes you see below. + +Each of these classes has a ``translation_classes`` attribute: a potentially +empty list of translation classes. See :mod:`pokedex.db.multilang` for how +these work. + +Many tables have these columns: + +- **id**: An integer primary key. Sometimes it's semantically meaningful, most + often it isn't. +- **identifier**: A string identifier of the class, and the preferred way to + access individual items. +- **name**: A name (uses the multilang functionality) + +Pokémon +------- + +.. dex-table:: PokemonSpecies +.. dex-table:: Pokemon +.. dex-table:: PokemonForm +.. dex-table:: EvolutionChain +.. dex-table:: PokemonEvolution + +Moves +----- + +.. dex-table:: Move +.. dex-table:: MoveEffect +.. dex-table:: MoveMeta +.. dex-table:: MoveVersion + +Items +----- + +.. dex-table:: Item +.. dex-table:: Berry + +Types +----- + +.. dex-table:: Type + +Abilities +--------- + +.. dex-table:: Ability + +Language +-------- + +.. dex-table:: Language + +Version stuff +------------- + +.. dex-table:: Generation +.. dex-table:: VersionGroup +.. dex-table:: Version +.. dex-table:: Pokedex +.. dex-table:: Region + +Encounters +---------- + +.. dex-table:: Location +.. dex-table:: LocationArea +.. dex-table:: LocationAreaEncounterRate +.. dex-table:: Encounter +.. dex-table:: EncounterCondition +.. dex-table:: EncounterConditionValue +.. dex-table:: EncounterMethod +.. dex-table:: EncounterSlot + + +Contests +-------- + +.. dex-table:: ContestCombo +.. dex-table:: ContestEffect +.. dex-table:: SuperContestCombo +.. dex-table:: SuperContestEffect + +Enum tables +----------- + +.. dex-table:: BerryFirmness +.. dex-table:: ContestType +.. dex-table:: EggGroup +.. dex-table:: EvolutionTrigger +.. dex-table:: GrowthRate +.. dex-table:: ItemCategory +.. dex-table:: ItemFlag +.. dex-table:: ItemFlingEffect +.. dex-table:: ItemPocket +.. dex-table:: MoveBattleStyle +.. dex-table:: MoveDamageClass +.. dex-table:: MoveMetaAilment +.. dex-table:: MoveMetaCategory +.. dex-table:: MoveTarget +.. dex-table:: Nature +.. dex-table:: PokemonColor +.. dex-table:: PokemonMoveMethod +.. dex-table:: PokemonShape +.. dex-table:: Stat + +Changelogs +---------- + +.. dex-table:: AbilityChangelog +.. dex-table:: MoveEffectChangelog + +Flavor text +----------- + +.. dex-table:: ItemFlavorText +.. dex-table:: AbilityFlavorText +.. dex-table:: MoveFlavorText +.. dex-table:: PokemonSpeciesFlavorText + +Association tables +------------------ + +.. dex-table:: BerryFlavor +.. dex-table:: EncounterConditionValueMap +.. dex-table:: ItemFlagMap +.. dex-table:: Machine +.. dex-table:: MoveFlag +.. dex-table:: MoveFlagMap +.. dex-table:: MoveMetaStatChange +.. dex-table:: NatureBattleStylePreference +.. dex-table:: NaturePokeathlonStat +.. dex-table:: PokeathlonStat +.. dex-table:: PokemonAbility +.. dex-table:: PokemonEggGroup +.. dex-table:: PokemonFormPokeathlonStat +.. dex-table:: PokemonHabitat +.. dex-table:: PokemonMove +.. dex-table:: PokemonStat +.. dex-table:: PokemonItem +.. dex-table:: PokemonType +.. dex-table:: TypeEfficacy +.. dex-table:: VersionGroupRegion + +Index maps +---------- + +.. dex-table:: ItemGameIndex +.. dex-table:: LocationGameIndex +.. dex-table:: PokemonDexNumber +.. dex-table:: PokemonGameIndex + +Mics tables +----------- + +.. dex-table:: Experience +.. dex-table:: StatHint + diff --git a/_sources/schema.txt b/_sources/schema.txt new file mode 100644 index 0000000..3743604 --- /dev/null +++ b/_sources/schema.txt @@ -0,0 +1,8 @@ +The database schema +=================== + +.. toctree:: + + main-tables + enumerations + associations diff --git a/_sources/usage.txt b/_sources/usage.txt new file mode 100644 index 0000000..facd962 --- /dev/null +++ b/_sources/usage.txt @@ -0,0 +1,275 @@ +Using pokedex +============= + +The pokédex is, first and foremost, a Python library. To get the most of it, +you'll need to learn `Python`_ and `SQLAlchemy`_. + +Here is a small example of using pokedex: + +.. testcode:: + + from pokedex.db import connect, tables, util + session = connect() + pokemon = util.get(session, tables.PokemonSpecies, 'bulbasaur') + print u'{0.name}, the {0.genus} Pokemon'.format(pokemon) + +Running this will give you some Bulbasaur info: + +.. testoutput:: + + Bulbasaur, the Seed Pokemon + +Connecting +---------- + +To get information out of the Pokédex, you will need to create a +:class:`Session `. To do that, use +:func:`pokedex.db.connect`. For simple uses, you don't need to give it any +arguments: it the database that ``pokedex load`` fills up by default. If you +need to select another database, give its URI as the first argument. + +The object :func:`~pokedex.db.connect` gives you is actually a +:class:`SQLAlchemy session `, giving you the +full power of SQLAlchemy for working with the data. We'll cover some basics +here, but if you intend to do some serious work, do read SQLAlchemy's docs. + +XXX: write the rest of this + +..:: + + Pokédex tables + -------------- + + Data in the pokédex is organized in tables, defined in + :mod:`pokedex.db.tables`. + There is quite a few or them. To get you started, here are a few common ones: + + * :class:`~pokedex.db.tables.Pokemon` (includes some alternate forms) + * :class:`~pokedex.db.tables.Move` + * :class:`~pokedex.db.tables.Item` + * :class:`~pokedex.db.tables.Type` + + Getting things + -------------- + + If you know what you want from the pokédex, you can use the + :func:`pokedex.db.util.get` function. It looks up a thing in a table, based on + its identifier, name, or ID, and returns it. + + .. testcode:: + + def print_pokemon(pokemon): + print u'{0.name}, the {0.genus} Pokemon'.format(pokemon) + + print_pokemon(util.get(session, tables.PokemonSpecies, identifier='eevee')) + print_pokemon(util.get(session, tables.PokemonSpecies, name=u'Ho-Oh')) + print_pokemon(util.get(session, tables.PokemonSpecies, id=50)) + + def print_item(item): + print u'{0.name}: ${0.cost}'.format(item) + + print_item(util.get(session, tables.Item, identifier='great-ball')) + print_item(util.get(session, tables.Item, name='Potion')) + print_item(util.get(session, tables.Item, id=30)) + + .. testoutput:: + + Eevee, the Evolution Pokemon + Ho-Oh, the Rainbow Pokemon + Diglett, the Mole Pokemon + Great Ball: $600 + Potion: $300 + Fresh Water: $200 + + .. : + Simple lists + ------------ + + .. note:: + + These functions are only included for convenience in experiments and simple + scripts. + If you want to do something specific, please query the pokédex as explained + in the following sections. + + If you want to get a simple list of pokémon without needing to worry about + things like the different forms and sorting the list, you can use the + :func:`pokedex.util.simple.pokemon` function. + + .. testcode:: + + from pokedex.util import simple + for pokemon in simple.pokemon(session): + print u'{0.name}, the {0.species} Pokemon'.format(pokemon) + + .. testoutput:: + + Bulbasaur, the Seed Pokemon + Ivysaur, the Seed Pokemon + ... + Meloetta, the Melody Pokemon + Genesect, the Paleozoic Pokemon + + Similar functions exist for :func:`~pokedex.util.simple.moves`, + :func:`~pokedex.util.simple.items` and :func:`~pokedex.util.simple.types`. + + All of these give you quick simple lists, basically something a pokédex would + show you. They filter out things you probably won't need (such as Shadow moves + or duplicate Pokémon moves), and sort the results in some sane way, but they + can't guess your needs exactly, and their guesses might change in future + versions. + If you want to do some serious work with the pokédex, read on. + + Querying + -------- + + So, how do you get data from the session? You use the session's + :meth:`~sqlalchemy.orm.session.Session.query` method, and give it a pokédex + Table as an argument. This will give you a :class:`SQLAlchemy query + `. + + To get you started, we'll cover some common query operations below. If you + need to do more, consult the `SQLAlchemy documentation`_. + + Ordering + ^^^^^^^^ + + As always with SQL, you should not rely on query results being in some + particular order – unless you have ordered the query first. This means that + you'll likely want to sort every query you will make. + + For example, you can get a list of all pokémon, sorted by their + :attr:`~pokedex.db.tables.Pokemon.order`, like so: + + .. testcode:: + + for pokemon in session.query(tables.Pokemon).order_by(tables.Pokemon.order): + print pokemon.name + + .. testoutput:: + + Bulbasaur + Ivysaur + Venusaur + Charmander + Charmeleon + ... + Pichu + Pikachu + Raichu + ... + Keldeo + Aria Meloetta + Pirouette Meloetta + Genesect + + Ordering by name + **************** + + Since the pokédex can be used in other languages than English, working with + texts such as names is sometimes tricky. + + The “name” attribute is actually a relation that uses the connection's + default language to select an appropriate translation. It usually works the + same way as a normal attribute, but ordering is an exception to this: + + .. testcode:: + + for pokemon in session.query(tables.Pokemon).order_by(tables.Pokemon.name): + print pokemon.name + + .. testoutput:: + + Traceback (most recent call last): + ... + ArgumentError: SQL expression object or string expected. + + This means that to order by name, you either have to explicitly join the + translation table and sort by that, or use + :func:`pokedex.db.util.order_by_name`: + + + .. testcode:: + + from pokedex.db import util + for pokemon in util.order_by_name(session.query(tables.Pokemon), tables.Pokemon): + print pokemon.name + + .. testoutput:: + + Abomasnow + ... + Zweilous + + Filtering + ^^^^^^^^^ + + Another major operation on queries is filtering, using the query's + :meth:`~sqlalchemy.orm.query.Query.filter` or + :meth:`~sqlalchemy.orm.query.Query.filter_by` methods: + + .. testcode:: + + for move in session.query(tables.Move).filter(tables.Move.power > 200): + print move.name + + .. testoutput:: + + Explosion + + Joining + ^^^^^^^ + + The final operation we'll cover here is joining other tables to the query, + using the query's :meth:`~sqlalchemy.orm.query.Query.join`. + You will usually want to join on a relationship, such as in the following + example: + + .. testcode:: + + query = session.query(tables.Move) + query = query.join(tables.Move.type) + query = query.filter(tables.Type.identifier == 'grass') + query = query.filter(tables.Move.power >= 100) + query = query.order_by(tables.Move.power) + query = util.order_by_name(query, tables.Move) + + print 'The most powerful Grass moves:' + for move in query: + print u'{0.name} ({0.power})'.format(move) + + .. testoutput:: + + The most powerful Grass moves: + Petal Dance (120) + Power Whip (120) + Seed Flare (120) + SolarBeam (120) + Wood Hammer (120) + Leaf Storm (140) + Frenzy Plant (150) + + + API documentation + ----------------- + + .. autofunction:: pokedex.db.connect + + See :class:`sqlalchemy.orm.session.Session` for more documentation on the + returned object. + + .. autofunction:: pokedex.db.util.get + .. autofunction:: pokedex.db.util.order_by_name + + Simple lists + ^^^^^^^^^^^^ + + .. autofunction:: pokedex.util.simple.pokemon + .. autofunction:: pokedex.util.simple.moves + .. autofunction:: pokedex.util.simple.items + .. autofunction:: pokedex.util.simple.types + + + .. _Python: http://www.python.org + .. _SQLAlchemy: http://www.sqlalchemy.org + .. _`SQLAlchemy documentation`: http://www.sqlalchemy.org/docs/orm/tutorial.html diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 0000000..69f30d4 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,509 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +img { + border: 0; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +.align-left { + text-align: left; +} + +.align-center { + clear: both; + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.refcount { + color: #060; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} diff --git a/_static/default.css b/_static/default.css new file mode 100644 index 0000000..b30cb79 --- /dev/null +++ b/_static/default.css @@ -0,0 +1,255 @@ +/* + * default.css_t + * ~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- default theme. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: sans-serif; + font-size: 100%; + background-color: #11303d; + color: #000; + margin: 0; + padding: 0; +} + +div.document { + background-color: #1c4e63; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +div.body { + background-color: #ffffff; + color: #000000; + padding: 0 20px 30px 20px; +} + +div.footer { + color: #ffffff; + width: 100%; + padding: 9px 0 9px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #ffffff; + text-decoration: underline; +} + +div.related { + background-color: #133f52; + line-height: 30px; + color: #ffffff; +} + +div.related a { + color: #ffffff; +} + +div.sphinxsidebar { +} + +div.sphinxsidebar h3 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.4em; + font-weight: normal; + margin: 0; + padding: 0; +} + +div.sphinxsidebar h3 a { + color: #ffffff; +} + +div.sphinxsidebar h4 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.3em; + font-weight: normal; + margin: 5px 0 0 0; + padding: 0; +} + +div.sphinxsidebar p { + color: #ffffff; +} + +div.sphinxsidebar p.topless { + margin: 5px 10px 10px 10px; +} + +div.sphinxsidebar ul { + margin: 10px; + padding: 0; + color: #ffffff; +} + +div.sphinxsidebar a { + color: #98dbcc; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + + +/* -- hyperlink styles ------------------------------------------------------ */ + +a { + color: #355f7c; + text-decoration: none; +} + +a:visited { + color: #355f7c; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + + + +/* -- body styles ----------------------------------------------------------- */ + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: 'Trebuchet MS', sans-serif; + background-color: #f2f2f2; + font-weight: normal; + color: #20435c; + border-bottom: 1px solid #ccc; + margin: 20px -20px 10px -20px; + padding: 3px 0 3px 10px; +} + +div.body h1 { margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 160%; } +div.body h3 { font-size: 140%; } +div.body h4 { font-size: 120%; } +div.body h5 { font-size: 110%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + text-align: justify; + line-height: 130%; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.admonition p { + margin-bottom: 5px; +} + +div.admonition pre { + margin-bottom: 5px; +} + +div.admonition ul, div.admonition ol { + margin-bottom: 5px; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 5px; + background-color: #eeffcc; + color: #333333; + line-height: 120%; + border: 1px solid #ac9; + border-left: none; + border-right: none; +} + +tt { + background-color: #ecf0f3; + padding: 0 1px 0 1px; + font-size: 0.95em; +} + +th { + background-color: #ede; +} + +.warning tt { + background: #efc2c2; +} + +.note tt { + background: #d6d6d6; +} + +.viewcode-back { + font-family: sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} \ No newline at end of file diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 0000000..eeea95e --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,247 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilties for all documentation. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +} + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s == 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * small function to check if an array contains + * a given item. + */ +jQuery.contains = function(arr, item) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] == item) + return true; + } + return false; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node) { + if (node.nodeType == 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span = document.createElement("span"); + span.className = className; + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated == 'undefined') + return string; + return (typeof translated == 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated == 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('.sidebar .this-page-menu')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('.sidebar .this-page-menu li.highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 0000000..d18082e Binary files /dev/null and b/_static/file.png differ diff --git a/_static/jquery.js b/_static/jquery.js new file mode 100644 index 0000000..5c99a8d --- /dev/null +++ b/_static/jquery.js @@ -0,0 +1,8176 @@ +/*! + * jQuery JavaScript Library v1.5 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Mon Jan 31 08:31:29 2011 -0500 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // (both of which we optimize for) + quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Check for digits + rdigit = /\d/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // Has the ready events already been bound? + readyBound = false, + + // The deferred used on DOM ready + readyList, + + // Promise methods + promiseMethods = "then done fail isResolved isRejected promise".split( " " ), + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = "body"; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + match = quickExpr.exec( selector ); + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = (context ? context.ownerDocument || context : document); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return (context || rootjQuery).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if (selector.selector !== undefined) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.5", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + (this.selector ? " " : "") + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.done( fn ); + + return this; + }, + + eq: function( i ) { + return i === -1 ? + this.slice( i ) : + this.slice( i, +i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + window.$ = _$; + + if ( deep ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + // A third-party is pushing the ready event forwards + if ( wait === true ) { + jQuery.readyWait--; + } + + // Make sure that the DOM is not already loaded + if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).unbind( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyBound ) { + return; + } + + readyBound = true; + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent("onreadystatechange", DOMContentLoaded); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + // A crude way of determining if an object is a window + isWindow: function( obj ) { + return obj && typeof obj === "object" && "setInterval" in obj; + }, + + isNaN: function( obj ) { + return obj == null || !rdigit.test( obj ) || isNaN( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw msg; + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test(data.replace(rvalidescape, "@") + .replace(rvalidtokens, "]") + .replace(rvalidbraces, "")) ) { + + // Try to use the native JSON parser first + return window.JSON && window.JSON.parse ? + window.JSON.parse( data ) : + (new Function("return " + data))(); + + } else { + jQuery.error( "Invalid JSON: " + data ); + } + }, + + // Cross-browser xml parsing + // (xml & tmp used internally) + parseXML: function( data , xml , tmp ) { + + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + + tmp = xml.documentElement; + + if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) { + jQuery.error( "Invalid XML: " + data ); + } + + return xml; + }, + + noop: function() {}, + + // Evalulates a script in a global context + globalEval: function( data ) { + if ( data && rnotwhite.test(data) ) { + // Inspired by code by Andrea Giammarchi + // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html + var head = document.getElementsByTagName("head")[0] || document.documentElement, + script = document.createElement("script"); + + script.type = "text/javascript"; + + if ( jQuery.support.scriptEval() ) { + script.appendChild( document.createTextNode( data ) ); + } else { + script.text = data; + } + + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709). + head.insertBefore( script, head.firstChild ); + head.removeChild( script ); + } + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction(object); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( var value = object[0]; + i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // The extra typeof function check is to prevent crashes + // in Safari 2 (See: #3039) + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type(array); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array ) { + if ( array.indexOf ) { + return array.indexOf( elem ); + } + + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[ i ] === elem ) { + return i; + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var ret = [], value; + + // Go through the array, translating each of the items to their + // new value (or values). + for ( var i = 0, length = elems.length; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + proxy: function( fn, proxy, thisObject ) { + if ( arguments.length === 2 ) { + if ( typeof proxy === "string" ) { + thisObject = fn; + fn = thisObject[ proxy ]; + proxy = undefined; + + } else if ( proxy && !jQuery.isFunction( proxy ) ) { + thisObject = proxy; + proxy = undefined; + } + } + + if ( !proxy && fn ) { + proxy = function() { + return fn.apply( thisObject || this, arguments ); + }; + } + + // Set the guid of unique handler to the same of original handler, so it can be removed + if ( fn ) { + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + } + + // So proxy can be declared as an argument + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can be optionally by executed if its a function + access: function( elems, key, value, exec, fn, pass ) { + var length = elems.length; + + // Setting many attributes + if ( typeof key === "object" ) { + for ( var k in key ) { + jQuery.access( elems, k, key[k], exec, fn, value ); + } + return elems; + } + + // Setting one attribute + if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = !pass && exec && jQuery.isFunction(value); + + for ( var i = 0; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + + return elems; + } + + // Getting an attribute + return length ? fn( elems[0], key ) : undefined; + }, + + now: function() { + return (new Date()).getTime(); + }, + + // Create a simple deferred (one callbacks list) + _Deferred: function() { + var // callbacks list + callbacks = [], + // stored [ context , args ] + fired, + // to avoid firing when already doing so + firing, + // flag to know if the deferred has been cancelled + cancelled, + // the deferred itself + deferred = { + + // done( f1, f2, ...) + done: function() { + if ( !cancelled ) { + var args = arguments, + i, + length, + elem, + type, + _fired; + if ( fired ) { + _fired = fired; + fired = 0; + } + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + deferred.done.apply( deferred, elem ); + } else if ( type === "function" ) { + callbacks.push( elem ); + } + } + if ( _fired ) { + deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); + } + } + return this; + }, + + // resolve with given context and args + resolveWith: function( context, args ) { + if ( !cancelled && !fired && !firing ) { + firing = 1; + try { + while( callbacks[ 0 ] ) { + callbacks.shift().apply( context, args ); + } + } + finally { + fired = [ context, args ]; + firing = 0; + } + } + return this; + }, + + // resolve with this as context and given arguments + resolve: function() { + deferred.resolveWith( jQuery.isFunction( this.promise ) ? this.promise() : this, arguments ); + return this; + }, + + // Has this deferred been resolved? + isResolved: function() { + return !!( firing || fired ); + }, + + // Cancel + cancel: function() { + cancelled = 1; + callbacks = []; + return this; + } + }; + + return deferred; + }, + + // Full fledged deferred (two callbacks list) + Deferred: function( func ) { + var deferred = jQuery._Deferred(), + failDeferred = jQuery._Deferred(), + promise; + // Add errorDeferred methods, then and promise + jQuery.extend( deferred, { + then: function( doneCallbacks, failCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ); + return this; + }, + fail: failDeferred.done, + rejectWith: failDeferred.resolveWith, + reject: failDeferred.resolve, + isRejected: failDeferred.isResolved, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj , i /* internal */ ) { + if ( obj == null ) { + if ( promise ) { + return promise; + } + promise = obj = {}; + } + i = promiseMethods.length; + while( i-- ) { + obj[ promiseMethods[ i ] ] = deferred[ promiseMethods[ i ] ]; + } + return obj; + } + } ); + // Make sure only one callback list will be used + deferred.then( failDeferred.cancel, deferred.cancel ); + // Unexpose cancel + delete deferred.cancel; + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + return deferred; + }, + + // Deferred helper + when: function( object ) { + var args = arguments, + length = args.length, + deferred = length <= 1 && object && jQuery.isFunction( object.promise ) ? + object : + jQuery.Deferred(), + promise = deferred.promise(), + resolveArray; + + if ( length > 1 ) { + resolveArray = new Array( length ); + jQuery.each( args, function( index, element ) { + jQuery.when( element ).then( function( value ) { + resolveArray[ index ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value; + if( ! --length ) { + deferred.resolveWith( promise, resolveArray ); + } + }, deferred.reject ); + } ); + } else if ( deferred !== object ) { + deferred.resolve( object ); + } + return promise; + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySubclass( selector, context ) { + return new jQuerySubclass.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySubclass, this ); + jQuerySubclass.superclass = this; + jQuerySubclass.fn = jQuerySubclass.prototype = this(); + jQuerySubclass.fn.constructor = jQuerySubclass; + jQuerySubclass.subclass = this.subclass; + jQuerySubclass.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySubclass) ) { + context = jQuerySubclass(context); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass ); + }; + jQuerySubclass.fn.init.prototype = jQuerySubclass.fn; + var rootjQuerySubclass = jQuerySubclass(document); + return jQuerySubclass; + }, + + browser: {} +}); + +// Create readyList deferred +readyList = jQuery._Deferred(); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +if ( indexOf ) { + jQuery.inArray = function( elem, array ) { + return indexOf.call( array, elem ); + }; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +// Expose jQuery to the global object +return (window.jQuery = window.$ = jQuery); + +})(); + + +(function() { + + jQuery.support = {}; + + var div = document.createElement("div"); + + div.style.display = "none"; + div.innerHTML = "
a"; + + var all = div.getElementsByTagName("*"), + a = div.getElementsByTagName("a")[0], + select = document.createElement("select"), + opt = select.appendChild( document.createElement("option") ); + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return; + } + + jQuery.support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: div.firstChild.nodeType === 3, + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText insted) + style: /red/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: a.getAttribute("href") === "/a", + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55$/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: div.getElementsByTagName("input")[0].value === "on", + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Will be defined later + deleteExpando: true, + optDisabled: false, + checkClone: false, + _scriptEval: null, + noCloneEvent: true, + boxModel: null, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableHiddenOffsets: true + }; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as diabled) + select.disabled = true; + jQuery.support.optDisabled = !opt.disabled; + + jQuery.support.scriptEval = function() { + if ( jQuery.support._scriptEval === null ) { + var root = document.documentElement, + script = document.createElement("script"), + id = "script" + jQuery.now(); + + script.type = "text/javascript"; + try { + script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); + } catch(e) {} + + root.insertBefore( script, root.firstChild ); + + // Make sure that the execution of code works by injecting a script + // tag with appendChild/createTextNode + // (IE doesn't support this, fails, and uses .text instead) + if ( window[ id ] ) { + jQuery.support._scriptEval = true; + delete window[ id ]; + } else { + jQuery.support._scriptEval = false; + } + + root.removeChild( script ); + // release memory in IE + root = script = id = null; + } + + return jQuery.support._scriptEval; + }; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + + } catch(e) { + jQuery.support.deleteExpando = false; + } + + if ( div.attachEvent && div.fireEvent ) { + div.attachEvent("onclick", function click() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + jQuery.support.noCloneEvent = false; + div.detachEvent("onclick", click); + }); + div.cloneNode(true).fireEvent("onclick"); + } + + div = document.createElement("div"); + div.innerHTML = ""; + + var fragment = document.createDocumentFragment(); + fragment.appendChild( div.firstChild ); + + // WebKit doesn't clone checked state correctly in fragments + jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; + + // Figure out if the W3C box model works as expected + // document.body must exist before we can do this + jQuery(function() { + var div = document.createElement("div"), + body = document.getElementsByTagName("body")[0]; + + // Frameset documents with no body should not run this code + if ( !body ) { + return; + } + + div.style.width = div.style.paddingLeft = "1px"; + body.appendChild( div ); + jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; + + if ( "zoom" in div.style ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2; + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
"; + jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2; + } + + div.innerHTML = "
t
"; + var tds = div.getElementsByTagName("td"); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0; + + tds[0].style.display = ""; + tds[1].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE < 8 fail this test) + jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0; + div.innerHTML = ""; + + body.removeChild( div ).style.display = "none"; + div = tds = null; + }); + + // Technique from Juriy Zaytsev + // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ + var eventSupported = function( eventName ) { + var el = document.createElement("div"); + eventName = "on" + eventName; + + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( !el.attachEvent ) { + return true; + } + + var isSupported = (eventName in el); + if ( !isSupported ) { + el.setAttribute(eventName, "return;"); + isSupported = typeof el[eventName] === "function"; + } + el = null; + + return isSupported; + }; + + jQuery.support.submitBubbles = eventSupported("submit"); + jQuery.support.changeBubbles = eventSupported("change"); + + // release memory in IE + div = all = a = null; +})(); + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + + return !!elem && !jQuery.isEmptyObject(elem); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ jQuery.expando ] = id = ++jQuery.uuid; + } else { + id = jQuery.expando; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" ) { + if ( pvt ) { + cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name); + } else { + cache[ id ] = jQuery.extend(cache[ id ], name); + } + } + + thisCache = cache[ id ]; + + // Internal jQuery data is stored in a separate object inside the object's data + // cache in order to avoid key collisions between internal data and user-defined + // data + if ( pvt ) { + if ( !thisCache[ internalKey ] ) { + thisCache[ internalKey ] = {}; + } + + thisCache = thisCache[ internalKey ]; + } + + if ( data !== undefined ) { + thisCache[ name ] = data; + } + + // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should + // not attempt to inspect the internal events object using jQuery.data, as this + // internal data object is undocumented and subject to change. + if ( name === "events" && !thisCache[name] ) { + return thisCache[ internalKey ] && thisCache[ internalKey ].events; + } + + return getByName ? thisCache[ name ] : thisCache; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var internalKey = jQuery.expando, isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ]; + + if ( thisCache ) { + delete thisCache[ name ]; + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( pvt ) { + delete cache[ id ][ internalKey ]; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !jQuery.isEmptyObject(cache[ id ]) ) { + return; + } + } + + var internalCache = cache[ id ][ internalKey ]; + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + if ( jQuery.support.deleteExpando || cache != window ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the entire user cache at once because it's faster than + // iterating through each key, but we need to continue to persist internal + // data if it existed + if ( internalCache ) { + cache[ id ] = {}; + cache[ id ][ internalKey ] = internalCache; + + // Otherwise, we need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + } else if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ jQuery.expando ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( jQuery.expando ); + } else { + elem[ jQuery.expando ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var data = null; + + if ( typeof key === "undefined" ) { + if ( this.length ) { + data = jQuery.data( this[0] ); + + if ( this[0].nodeType === 1 ) { + var attr = this[0].attributes, name; + for ( var i = 0, l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = name.substr( 5 ); + dataAttr( this[0], name, data[ name ] ); + } + } + } + } + + return data; + + } else if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + var parts = key.split("."); + parts[1] = parts[1] ? "." + parts[1] : ""; + + if ( value === undefined ) { + data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + + // Try to fetch any internally stored data first + if ( data === undefined && this.length ) { + data = jQuery.data( this[0], key ); + data = dataAttr( this[0], key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + + } else { + return this.each(function() { + var $this = jQuery( this ), + args = [ parts[0], value ]; + + $this.triggerHandler( "setData" + parts[1] + "!", args ); + jQuery.data( this, key, value ); + $this.triggerHandler( "changeData" + parts[1] + "!", args ); + }); + } + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + data = elem.getAttribute( "data-" + key ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + !jQuery.isNaN( data ) ? parseFloat( data ) : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + + + + +jQuery.extend({ + queue: function( elem, type, data ) { + if ( !elem ) { + return; + } + + type = (type || "fx") + "queue"; + var q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( !data ) { + return q || []; + } + + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + + } else { + q.push( data ); + } + + return q; + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(); + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift("inprogress"); + } + + fn.call(elem, function() { + jQuery.dequeue(elem, type); + }); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue", true ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + } + + if ( data === undefined ) { + return jQuery.queue( this[0], type ); + } + return this.each(function( i ) { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; + type = type || "fx"; + + return this.queue( type, function() { + var elem = this; + setTimeout(function() { + jQuery.dequeue( elem, type ); + }, time ); + }); + }, + + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspaces = /\s+/, + rreturn = /\r/g, + rspecialurl = /^(?:href|src|style)$/, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rradiocheck = /^(?:radio|checkbox)$/i; + +jQuery.props = { + "for": "htmlFor", + "class": "className", + readonly: "readOnly", + maxlength: "maxLength", + cellspacing: "cellSpacing", + rowspan: "rowSpan", + colspan: "colSpan", + tabindex: "tabIndex", + usemap: "useMap", + frameborder: "frameBorder" +}; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.attr ); + }, + + removeAttr: function( name, fn ) { + return this.each(function(){ + jQuery.attr( this, name, "" ); + if ( this.nodeType === 1 ) { + this.removeAttribute( name ); + } + }); + }, + + addClass: function( value ) { + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + self.addClass( value.call(this, i, self.attr("class")) ); + }); + } + + if ( value && typeof value === "string" ) { + var classNames = (value || "").split( rspaces ); + + for ( var i = 0, l = this.length; i < l; i++ ) { + var elem = this[i]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className ) { + elem.className = value; + + } else { + var className = " " + elem.className + " ", + setClass = elem.className; + + for ( var c = 0, cl = classNames.length; c < cl; c++ ) { + if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { + setClass += " " + classNames[c]; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + self.removeClass( value.call(this, i, self.attr("class")) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + var classNames = (value || "").split( rspaces ); + + for ( var i = 0, l = this.length; i < l; i++ ) { + var elem = this[i]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + var className = (" " + elem.className + " ").replace(rclass, " "); + for ( var c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[c] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this); + self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspaces ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " "; + for ( var i = 0, l = this.length; i < l; i++ ) { + if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + if ( !arguments.length ) { + var elem = this[0]; + + if ( elem ) { + if ( jQuery.nodeName( elem, "option" ) ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + + // We need to handle select boxes special + if ( jQuery.nodeName( elem, "select" ) ) { + var index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { + var option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery(option).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + } + + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { + return elem.getAttribute("value") === null ? "on" : elem.value; + } + + // Everything else, we just grab the value + return (elem.value || "").replace(rreturn, ""); + + } + + return undefined; + } + + var isFunction = jQuery.isFunction(value); + + return this.each(function(i) { + var self = jQuery(this), val = value; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call(this, i, self.val()); + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray(val) ) { + val = jQuery.map(val, function (value) { + return value == null ? "" : value + ""; + }); + } + + if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { + this.checked = jQuery.inArray( self.val(), val ) >= 0; + + } else if ( jQuery.nodeName( this, "select" ) ) { + var values = jQuery.makeArray(val); + + jQuery( "option", this ).each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + this.selectedIndex = -1; + } + + } else { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) { + return undefined; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery(elem)[name](value); + } + + var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), + // Whether we are setting (or getting) + set = value !== undefined; + + // Try to normalize/fix the name + name = notxml && jQuery.props[ name ] || name; + + // Only do all the following if this is a node (faster for style) + if ( elem.nodeType === 1 ) { + // These attributes require special treatment + var special = rspecialurl.test( name ); + + // Safari mis-reports the default selected property of an option + // Accessing the parent's selectedIndex property fixes it + if ( name === "selected" && !jQuery.support.optSelected ) { + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + + // If applicable, access the attribute via the DOM 0 way + // 'in' checks fail in Blackberry 4.7 #6931 + if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) { + if ( set ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } + + if ( value === null ) { + if ( elem.nodeType === 1 ) { + elem.removeAttribute( name ); + } + + } else { + elem[ name ] = value; + } + } + + // browsers index elements by id/name on forms, give priority to attributes. + if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { + return elem.getAttributeNode( name ).nodeValue; + } + + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + if ( name === "tabIndex" ) { + var attributeNode = elem.getAttributeNode( "tabIndex" ); + + return attributeNode && attributeNode.specified ? + attributeNode.value : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + + return elem[ name ]; + } + + if ( !jQuery.support.style && notxml && name === "style" ) { + if ( set ) { + elem.style.cssText = "" + value; + } + + return elem.style.cssText; + } + + if ( set ) { + // convert the value to a string (all browsers do this but IE) see #1070 + elem.setAttribute( name, "" + value ); + } + + // Ensure that missing attributes return undefined + // Blackberry 4.7 returns "" from getAttribute #6938 + if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) { + return undefined; + } + + var attr = !jQuery.support.hrefNormalized && notxml && special ? + // Some attributes require a special call on IE + elem.getAttribute( name, 2 ) : + elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return attr === null ? undefined : attr; + } + // Handle everything which isn't a DOM element node + if ( set ) { + elem[ name ] = value; + } + return elem[ name ]; + } +}); + + + + +var rnamespaces = /\.(.*)$/, + rformElems = /^(?:textarea|input|select)$/i, + rperiod = /\./g, + rspace = / /g, + rescape = /[^\w\s.|`]/g, + fcleanup = function( nm ) { + return nm.replace(rescape, "\\$&"); + }, + eventKey = "events"; + +/* + * A number of helper functions used for managing events. + * Many of the ideas behind this code originated from + * Dean Edwards' addEvent library. + */ +jQuery.event = { + + // Bind an event to an element + // Original by Dean Edwards + add: function( elem, types, handler, data ) { + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // For whatever reason, IE has trouble passing the window object + // around, causing it to be cloned in the process + if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) { + elem = window; + } + + if ( handler === false ) { + handler = returnFalse; + } else if ( !handler ) { + // Fixes bug #7229. Fix recommended by jdalton + return; + } + + var handleObjIn, handleObj; + + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + } + + // Make sure that the function being executed has a unique ID + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure + var elemData = jQuery._data( elem ); + + // If no elemData is found then we must be trying to bind to one of the + // banned noData elements + if ( !elemData ) { + return; + } + + var events = elemData[ eventKey ], + eventHandle = elemData.handle; + + if ( typeof events === "function" ) { + // On plain objects events is a fn that holds the the data + // which prevents this data from being JSON serialized + // the function does not need to be called, it just contains the data + eventHandle = events.handle; + events = events.events; + + } else if ( !events ) { + if ( !elem.nodeType ) { + // On plain objects, create a fn that acts as the holder + // of the values to avoid JSON serialization of event data + elemData[ eventKey ] = elemData = function(){}; + } + + elemData.events = events = {}; + } + + if ( !eventHandle ) { + elemData.handle = eventHandle = function() { + // Handle the second event of a trigger and when + // an event is called after a page has unloaded + return typeof jQuery !== "undefined" && !jQuery.event.triggered ? + jQuery.event.handle.apply( eventHandle.elem, arguments ) : + undefined; + }; + } + + // Add elem as a property of the handle function + // This is to prevent a memory leak with non-native events in IE. + eventHandle.elem = elem; + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = types.split(" "); + + var type, i = 0, namespaces; + + while ( (type = types[ i++ ]) ) { + handleObj = handleObjIn ? + jQuery.extend({}, handleObjIn) : + { handler: handler, data: data }; + + // Namespaced event handlers + if ( type.indexOf(".") > -1 ) { + namespaces = type.split("."); + type = namespaces.shift(); + handleObj.namespace = namespaces.slice(0).sort().join("."); + + } else { + namespaces = []; + handleObj.namespace = ""; + } + + handleObj.type = type; + if ( !handleObj.guid ) { + handleObj.guid = handler.guid; + } + + // Get the current list of functions bound to this event + var handlers = events[ type ], + special = jQuery.event.special[ type ] || {}; + + // Init the event handler queue + if ( !handlers ) { + handlers = events[ type ] = []; + + // Check for a special event handler + // Only use addEventListener/attachEvent if the special + // events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add the function to the element's handler list + handlers.push( handleObj ); + + // Keep track of which events have been used, for global triggering + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, pos ) { + // don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + if ( handler === false ) { + handler = returnFalse; + } + + var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + events = elemData && elemData[ eventKey ]; + + if ( !elemData || !events ) { + return; + } + + if ( typeof events === "function" ) { + elemData = events; + events = events.events; + } + + // types is actually an event object here + if ( types && types.type ) { + handler = types.handler; + types = types.type; + } + + // Unbind all events for the element + if ( !types || typeof types === "string" && types.charAt(0) === "." ) { + types = types || ""; + + for ( type in events ) { + jQuery.event.remove( elem, type + types ); + } + + return; + } + + // Handle multiple events separated by a space + // jQuery(...).unbind("mouseover mouseout", fn); + types = types.split(" "); + + while ( (type = types[ i++ ]) ) { + origType = type; + handleObj = null; + all = type.indexOf(".") < 0; + namespaces = []; + + if ( !all ) { + // Namespaced event handlers + namespaces = type.split("."); + type = namespaces.shift(); + + namespace = new RegExp("(^|\\.)" + + jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)"); + } + + eventType = events[ type ]; + + if ( !eventType ) { + continue; + } + + if ( !handler ) { + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( all || namespace.test( handleObj.namespace ) ) { + jQuery.event.remove( elem, origType, handleObj.handler, j ); + eventType.splice( j--, 1 ); + } + } + + continue; + } + + special = jQuery.event.special[ type ] || {}; + + for ( j = pos || 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( handler.guid === handleObj.guid ) { + // remove the given handler for the given type + if ( all || namespace.test( handleObj.namespace ) ) { + if ( pos == null ) { + eventType.splice( j--, 1 ); + } + + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + + if ( pos != null ) { + break; + } + } + } + + // remove generic event handler if no more handlers exist + if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + ret = null; + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + var handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + delete elemData.events; + delete elemData.handle; + + if ( typeof elemData === "function" ) { + jQuery.removeData( elem, eventKey, true ); + + } else if ( jQuery.isEmptyObject( elemData ) ) { + jQuery.removeData( elem, undefined, true ); + } + } + }, + + // bubbling is internal + trigger: function( event, data, elem /*, bubbling */ ) { + // Event object or event type + var type = event.type || event, + bubbling = arguments[3]; + + if ( !bubbling ) { + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + jQuery.extend( jQuery.Event(type), event ) : + // Just the event type (string) + jQuery.Event(type); + + if ( type.indexOf("!") >= 0 ) { + event.type = type = type.slice(0, -1); + event.exclusive = true; + } + + // Handle a global trigger + if ( !elem ) { + // Don't bubble custom events when global (to avoid too much overhead) + event.stopPropagation(); + + // Only trigger if we've ever bound an event for it + if ( jQuery.event.global[ type ] ) { + // XXX This code smells terrible. event.js should not be directly + // inspecting the data cache + jQuery.each( jQuery.cache, function() { + // internalKey variable is just used to make it easier to find + // and potentially change this stuff later; currently it just + // points to jQuery.expando + var internalKey = jQuery.expando, + internalCache = this[ internalKey ]; + if ( internalCache && internalCache.events && internalCache.events[type] ) { + jQuery.event.trigger( event, data, internalCache.handle.elem ); + } + }); + } + } + + // Handle triggering a single element + + // don't do events on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { + return undefined; + } + + // Clean up in case it is reused + event.result = undefined; + event.target = elem; + + // Clone the incoming data, if any + data = jQuery.makeArray( data ); + data.unshift( event ); + } + + event.currentTarget = elem; + + // Trigger the event, it is assumed that "handle" is a function + var handle = elem.nodeType ? + jQuery._data( elem, "handle" ) : + (jQuery._data( elem, eventKey ) || {}).handle; + + if ( handle ) { + handle.apply( elem, data ); + } + + var parent = elem.parentNode || elem.ownerDocument; + + // Trigger an inline bound script + try { + if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { + if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { + event.result = false; + event.preventDefault(); + } + } + + // prevent IE from throwing an error for some elements with some event types, see #3533 + } catch (inlineError) {} + + if ( !event.isPropagationStopped() && parent ) { + jQuery.event.trigger( event, data, parent, true ); + + } else if ( !event.isDefaultPrevented() ) { + var old, + target = event.target, + targetType = type.replace( rnamespaces, "" ), + isClick = jQuery.nodeName( target, "a" ) && targetType === "click", + special = jQuery.event.special[ targetType ] || {}; + + if ( (!special._default || special._default.call( elem, event ) === false) && + !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { + + try { + if ( target[ targetType ] ) { + // Make sure that we don't accidentally re-trigger the onFOO events + old = target[ "on" + targetType ]; + + if ( old ) { + target[ "on" + targetType ] = null; + } + + jQuery.event.triggered = true; + target[ targetType ](); + } + + // prevent IE from throwing an error for some elements with some event types, see #3533 + } catch (triggerError) {} + + if ( old ) { + target[ "on" + targetType ] = old; + } + + jQuery.event.triggered = false; + } + } + }, + + handle: function( event ) { + var all, handlers, namespaces, namespace_re, events, + namespace_sort = [], + args = jQuery.makeArray( arguments ); + + event = args[0] = jQuery.event.fix( event || window.event ); + event.currentTarget = this; + + // Namespaced event handlers + all = event.type.indexOf(".") < 0 && !event.exclusive; + + if ( !all ) { + namespaces = event.type.split("."); + event.type = namespaces.shift(); + namespace_sort = namespaces.slice(0).sort(); + namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)"); + } + + event.namespace = event.namespace || namespace_sort.join("."); + + events = jQuery._data(this, eventKey); + + if ( typeof events === "function" ) { + events = events.events; + } + + handlers = (events || {})[ event.type ]; + + if ( events && handlers ) { + // Clone the handlers to prevent manipulation + handlers = handlers.slice(0); + + for ( var j = 0, l = handlers.length; j < l; j++ ) { + var handleObj = handlers[ j ]; + + // Filter the functions by class + if ( all || namespace_re.test( handleObj.namespace ) ) { + // Pass in a reference to the handler function itself + // So that we can later remove it + event.handler = handleObj.handler; + event.data = handleObj.data; + event.handleObj = handleObj; + + var ret = handleObj.handler.apply( this, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + + if ( event.isImmediatePropagationStopped() ) { + break; + } + } + } + } + + return event.result; + }, + + props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // store a copy of the original event object + // and "clone" to set read-only properties + var originalEvent = event; + event = jQuery.Event( originalEvent ); + + for ( var i = this.props.length, prop; i; ) { + prop = this.props[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary + if ( !event.target ) { + // Fixes #1925 where srcElement might not be defined either + event.target = event.srcElement || document; + } + + // check if target is a textnode (safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && event.fromElement ) { + event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; + } + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && event.clientX != null ) { + var doc = document.documentElement, + body = document.body; + + event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); + event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); + } + + // Add which for key events + if ( event.which == null && (event.charCode != null || event.keyCode != null) ) { + event.which = event.charCode != null ? event.charCode : event.keyCode; + } + + // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) + if ( !event.metaKey && event.ctrlKey ) { + event.metaKey = event.ctrlKey; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && event.button !== undefined ) { + event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); + } + + return event; + }, + + // Deprecated, use jQuery.guid instead + guid: 1E8, + + // Deprecated, use jQuery.proxy instead + proxy: jQuery.proxy, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady, + teardown: jQuery.noop + }, + + live: { + add: function( handleObj ) { + jQuery.event.add( this, + liveConvert( handleObj.origType, handleObj.selector ), + jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); + }, + + remove: function( handleObj ) { + jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj ); + } + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src ) { + // Allow instantiation without the 'new' keyword + if ( !this.preventDefault ) { + return new jQuery.Event( src ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // timeStamp is buggy for some events on Firefox(#3843) + // So we won't rely on the native value + this.timeStamp = jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Checks if an event happened on an element within another element +// Used in jQuery.event.special.mouseenter and mouseleave handlers +var withinElement = function( event ) { + // Check if mouse(over|out) are still within the same parent element + var parent = event.relatedTarget; + + // Firefox sometimes assigns relatedTarget a XUL element + // which we cannot access the parentNode property of + try { + // Traverse up the tree + while ( parent && parent !== this ) { + parent = parent.parentNode; + } + + if ( parent !== this ) { + // set the correct event type + event.type = event.data; + + // handle event if we actually just moused on to a non sub-element + jQuery.event.handle.apply( this, arguments ); + } + + // assuming we've left the element since we most likely mousedover a xul element + } catch(e) { } +}, + +// In case of event delegation, we only need to rename the event.type, +// liveHandler will take care of the rest. +delegate = function( event ) { + event.type = event.data; + jQuery.event.handle.apply( this, arguments ); +}; + +// Create mouseenter and mouseleave events +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + setup: function( data ) { + jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); + }, + teardown: function( data ) { + jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); + } + }; +}); + +// submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function( data, namespaces ) { + if ( this.nodeName && this.nodeName.toLowerCase() !== "form" ) { + jQuery.event.add(this, "click.specialSubmit", function( e ) { + var elem = e.target, + type = elem.type; + + if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { + e.liveFired = undefined; + return trigger( "submit", this, arguments ); + } + }); + + jQuery.event.add(this, "keypress.specialSubmit", function( e ) { + var elem = e.target, + type = elem.type; + + if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { + e.liveFired = undefined; + return trigger( "submit", this, arguments ); + } + }); + + } else { + return false; + } + }, + + teardown: function( namespaces ) { + jQuery.event.remove( this, ".specialSubmit" ); + } + }; + +} + +// change delegation, happens here so we have bind. +if ( !jQuery.support.changeBubbles ) { + + var changeFilters, + + getVal = function( elem ) { + var type = elem.type, val = elem.value; + + if ( type === "radio" || type === "checkbox" ) { + val = elem.checked; + + } else if ( type === "select-multiple" ) { + val = elem.selectedIndex > -1 ? + jQuery.map( elem.options, function( elem ) { + return elem.selected; + }).join("-") : + ""; + + } else if ( elem.nodeName.toLowerCase() === "select" ) { + val = elem.selectedIndex; + } + + return val; + }, + + testChange = function testChange( e ) { + var elem = e.target, data, val; + + if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) { + return; + } + + data = jQuery._data( elem, "_change_data" ); + val = getVal(elem); + + // the current data will be also retrieved by beforeactivate + if ( e.type !== "focusout" || elem.type !== "radio" ) { + jQuery._data( elem, "_change_data", val ); + } + + if ( data === undefined || val === data ) { + return; + } + + if ( data != null || val ) { + e.type = "change"; + e.liveFired = undefined; + return jQuery.event.trigger( e, arguments[1], elem ); + } + }; + + jQuery.event.special.change = { + filters: { + focusout: testChange, + + beforedeactivate: testChange, + + click: function( e ) { + var elem = e.target, type = elem.type; + + if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { + return testChange.call( this, e ); + } + }, + + // Change has to be called before submit + // Keydown will be called before keypress, which is used in submit-event delegation + keydown: function( e ) { + var elem = e.target, type = elem.type; + + if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || + (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || + type === "select-multiple" ) { + return testChange.call( this, e ); + } + }, + + // Beforeactivate happens also before the previous element is blurred + // with this event you can't trigger a change event, but you can store + // information + beforeactivate: function( e ) { + var elem = e.target; + jQuery._data( elem, "_change_data", getVal(elem) ); + } + }, + + setup: function( data, namespaces ) { + if ( this.type === "file" ) { + return false; + } + + for ( var type in changeFilters ) { + jQuery.event.add( this, type + ".specialChange", changeFilters[type] ); + } + + return rformElems.test( this.nodeName ); + }, + + teardown: function( namespaces ) { + jQuery.event.remove( this, ".specialChange" ); + + return rformElems.test( this.nodeName ); + } + }; + + changeFilters = jQuery.event.special.change.filters; + + // Handle when the input is .focus()'d + changeFilters.focus = changeFilters.beforeactivate; +} + +function trigger( type, elem, args ) { + args[0].type = type; + return jQuery.event.handle.apply( elem, args ); +} + +// Create "bubbling" focus and blur events +if ( document.addEventListener ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + jQuery.event.special[ fix ] = { + setup: function() { + this.addEventListener( orig, handler, true ); + }, + teardown: function() { + this.removeEventListener( orig, handler, true ); + } + }; + + function handler( e ) { + e = jQuery.event.fix( e ); + e.type = fix; + return jQuery.event.handle.call( this, e ); + } + }); +} + +jQuery.each(["bind", "one"], function( i, name ) { + jQuery.fn[ name ] = function( type, data, fn ) { + // Handle object literals + if ( typeof type === "object" ) { + for ( var key in type ) { + this[ name ](key, data, type[key], fn); + } + return this; + } + + if ( jQuery.isFunction( data ) || data === false ) { + fn = data; + data = undefined; + } + + var handler = name === "one" ? jQuery.proxy( fn, function( event ) { + jQuery( this ).unbind( event, handler ); + return fn.apply( this, arguments ); + }) : fn; + + if ( type === "unload" && name !== "one" ) { + this.one( type, data, fn ); + + } else { + for ( var i = 0, l = this.length; i < l; i++ ) { + jQuery.event.add( this[i], type, handler, data ); + } + } + + return this; + }; +}); + +jQuery.fn.extend({ + unbind: function( type, fn ) { + // Handle object literals + if ( typeof type === "object" && !type.preventDefault ) { + for ( var key in type ) { + this.unbind(key, type[key]); + } + + } else { + for ( var i = 0, l = this.length; i < l; i++ ) { + jQuery.event.remove( this[i], type, fn ); + } + } + + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.live( types, data, fn, selector ); + }, + + undelegate: function( selector, types, fn ) { + if ( arguments.length === 0 ) { + return this.unbind( "live" ); + + } else { + return this.die( types, null, fn, selector ); + } + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + + triggerHandler: function( type, data ) { + if ( this[0] ) { + var event = jQuery.Event( type ); + event.preventDefault(); + event.stopPropagation(); + jQuery.event.trigger( event, data, this[0] ); + return event.result; + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + i = 1; + + // link all the functions, so any of them can unbind this click handler + while ( i < args.length ) { + jQuery.proxy( fn, args[ i++ ] ); + } + + return this.click( jQuery.proxy( fn, function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + })); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +var liveMap = { + focus: "focusin", + blur: "focusout", + mouseenter: "mouseover", + mouseleave: "mouseout" +}; + +jQuery.each(["live", "die"], function( i, name ) { + jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) { + var type, i = 0, match, namespaces, preType, + selector = origSelector || this.selector, + context = origSelector ? this : jQuery( this.context ); + + if ( typeof types === "object" && !types.preventDefault ) { + for ( var key in types ) { + context[ name ]( key, data, types[key], selector ); + } + + return this; + } + + if ( jQuery.isFunction( data ) ) { + fn = data; + data = undefined; + } + + types = (types || "").split(" "); + + while ( (type = types[ i++ ]) != null ) { + match = rnamespaces.exec( type ); + namespaces = ""; + + if ( match ) { + namespaces = match[0]; + type = type.replace( rnamespaces, "" ); + } + + if ( type === "hover" ) { + types.push( "mouseenter" + namespaces, "mouseleave" + namespaces ); + continue; + } + + preType = type; + + if ( type === "focus" || type === "blur" ) { + types.push( liveMap[ type ] + namespaces ); + type = type + namespaces; + + } else { + type = (liveMap[ type ] || type) + namespaces; + } + + if ( name === "live" ) { + // bind live handler + for ( var j = 0, l = context.length; j < l; j++ ) { + jQuery.event.add( context[j], "live." + liveConvert( type, selector ), + { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } ); + } + + } else { + // unbind live handler + context.unbind( "live." + liveConvert( type, selector ), fn ); + } + } + + return this; + }; +}); + +function liveHandler( event ) { + var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret, + elems = [], + selectors = [], + events = jQuery._data( this, eventKey ); + + if ( typeof events === "function" ) { + events = events.events; + } + + // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911) + if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) { + return; + } + + if ( event.namespace ) { + namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)"); + } + + event.liveFired = this; + + var live = events.live.slice(0); + + for ( j = 0; j < live.length; j++ ) { + handleObj = live[j]; + + if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) { + selectors.push( handleObj.selector ); + + } else { + live.splice( j--, 1 ); + } + } + + match = jQuery( event.target ).closest( selectors, event.currentTarget ); + + for ( i = 0, l = match.length; i < l; i++ ) { + close = match[i]; + + for ( j = 0; j < live.length; j++ ) { + handleObj = live[j]; + + if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) { + elem = close.elem; + related = null; + + // Those two events require additional checking + if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { + event.type = handleObj.preType; + related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; + } + + if ( !related || related !== elem ) { + elems.push({ elem: elem, handleObj: handleObj, level: close.level }); + } + } + } + } + + for ( i = 0, l = elems.length; i < l; i++ ) { + match = elems[i]; + + if ( maxLevel && match.level > maxLevel ) { + break; + } + + event.currentTarget = match.elem; + event.data = match.handleObj.data; + event.handleObj = match.handleObj; + + ret = match.handleObj.origHandler.apply( match.elem, arguments ); + + if ( ret === false || event.isPropagationStopped() ) { + maxLevel = match.level; + + if ( ret === false ) { + stop = false; + } + if ( event.isImmediatePropagationStopped() ) { + break; + } + } + } + + return stop; +} + +function liveConvert( type, selector ) { + return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&"); +} + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.bind( name, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } +}); + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set; + + if ( !expr ) { + return []; + } + + for ( var i = 0, l = Expr.order.length; i < l; i++ ) { + var match, + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + var left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace(/\\/g, ""); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( var type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + var found, item, + filter = Expr.filter[ type ], + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( var i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + var pass = not ^ !!found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw "Syntax error, unrecognized expression: " + msg; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !/\W/.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !/\W/.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !/\W/.test(part) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !/\W/.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace(/\\/g, "") + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace(/\\/g, ""); + }, + + TAG: function( match, curLoop ) { + return match[1].toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace(/\\/g, ""); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace(/\\/g, ""); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + elem.parentNode.selectedIndex; + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + return "text" === elem.type; + }, + radio: function( elem ) { + return "radio" === elem.type; + }, + + checkbox: function( elem ) { + return "checkbox" === elem.type; + }, + + file: function( elem ) { + return "file" === elem.type; + }, + password: function( elem ) { + return "password" === elem.type; + }, + + submit: function( elem ) { + return "submit" === elem.type; + }, + + image: function( elem ) { + return "image" === elem.type; + }, + + reset: function( elem ) { + return "reset" === elem.type; + }, + + button: function( elem ) { + return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + var first = match[2], + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + var doneName = match[0], + parent = elem.parentNode; + + if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { + var count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent.sizcache = doneName; + } + + var diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // If the nodes are siblings (or identical) we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Utility function for retreiving the text value of an array of DOM nodes +Sizzle.getText = function( elems ) { + var ret = "", elem; + + for ( var i = 0; elems[i]; i++ ) { + elem = elems[i]; + + // Get the text from text nodes and CDATA nodes + if ( elem.nodeType === 3 || elem.nodeType === 4 ) { + ret += elem.nodeValue; + + // Traverse everything else, except comment nodes + } else if ( elem.nodeType !== 8 ) { + ret += Sizzle.getText( elem.childNodes ); + } + } + + return ret; +}; + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + context.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector, + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + if ( matches ) { + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + return matches.call( node, expr ); + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
"; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.POS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var ret = this.pushStack( "", "find", selector ), + length = 0; + + for ( var i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( var n = length; n < ret.length; n++ ) { + for ( var r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && jQuery.filter( selector, this ).length > 0; + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + if ( jQuery.isArray( selectors ) ) { + var match, selector, + matches = {}, + level = 1; + + if ( cur && selectors.length ) { + for ( i = 0, l = selectors.length; i < l; i++ ) { + selector = selectors[i]; + + if ( !matches[selector] ) { + matches[selector] = jQuery.expr.match.POS.test( selector ) ? + jQuery( selector, context || this.context ) : + selector; + } + } + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( selector in matches ) { + match = matches[selector]; + + if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { + ret.push({ selector: selector, elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + } + + return ret; + } + + var pos = POS.test( selectors ) ? + jQuery( selectors, context || this.context ) : null; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique(ret) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + if ( !elem || typeof elem === "string" ) { + return jQuery.inArray( this[0], + // If it receives a string, the selector is used + // If it receives nothing, the siblings are used + elem ? jQuery( elem ) : this.parent().children() ); + } + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( elem.parentNode.firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ), + // The variable 'args' was introduced in + // https://github.com/jquery/jquery/commit/52a0238 + // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. + // http://code.google.com/p/v8/issues/detail?id=1050 + args = slice.call(arguments); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, args.join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return (elem === qualifier) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return (jQuery.inArray( elem, qualifier ) >= 0) === keep; + }); +} + + + + +var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /", "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }; + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + + + + + + +
+
+
+
+ + +

Index

+ +
+ A | B | C | E | G | I | L | M | N | P | R | S | T | V +
+

A

+ + + +
+
Ability (mapped class)
+
AbilityChangelog (mapped class)
+
+
AbilityFlavorText (mapped class)
+
+ +

B

+ + + +
+
Berry (mapped class)
+
BerryFirmness (mapped class)
+
+
BerryFlavor (mapped class)
+
+ +

C

+ + + +
+
ContestCombo (mapped class)
+
ContestEffect (mapped class)
+
+
ContestType (mapped class)
+
+ +

E

+ + + +
+
EggGroup (mapped class)
+
Encounter (mapped class)
+
EncounterCondition (mapped class)
+
EncounterConditionValue (mapped class)
+
EncounterConditionValueMap (mapped class)
+
+
EncounterMethod (mapped class)
+
EncounterSlot (mapped class)
+
EvolutionChain (mapped class)
+
EvolutionTrigger (mapped class)
+
Experience (mapped class)
+
+ +

G

+ + + +
+
Generation (mapped class)
+
+
GrowthRate (mapped class)
+
+ +

I

+ + + +
+
Item (mapped class)
+
ItemCategory (mapped class)
+
ItemFlag (mapped class)
+
ItemFlagMap (mapped class)
+
+
ItemFlavorText (mapped class)
+
ItemFlingEffect (mapped class)
+
ItemGameIndex (mapped class)
+
ItemPocket (mapped class)
+
+ +

L

+ + + +
+
Language (mapped class)
+
Location (mapped class)
+
LocationArea (mapped class)
+
+
LocationAreaEncounterRate (mapped class)
+
LocationGameIndex (mapped class)
+
+ +

M

+ + + +
+
Machine (mapped class)
+
mapped_classes (in module pokedex.db.tables)
+
metadata (in module pokedex.db.tables)
+
Move (mapped class)
+
MoveBattleStyle (mapped class)
+
MoveDamageClass (mapped class)
+
MoveEffect (mapped class)
+
MoveEffectChangelog (mapped class)
+
MoveFlag (mapped class)
+
+
MoveFlagMap (mapped class)
+
MoveFlavorText (mapped class)
+
MoveMeta (mapped class)
+
MoveMetaAilment (mapped class)
+
MoveMetaCategory (mapped class)
+
MoveMetaStatChange (mapped class)
+
MoveTarget (mapped class)
+
MoveVersion (mapped class)
+
+ +

N

+ + + +
+
Nature (mapped class)
+
NatureBattleStylePreference (mapped class)
+
+
NaturePokeathlonStat (mapped class)
+
+ +

P

+ + + +
+
PokeathlonStat (mapped class)
+
Pokedex (mapped class)
+
pokedex.db.tables (module)
+
Pokemon (mapped class)
+
PokemonAbility (mapped class)
+
PokemonColor (mapped class)
+
PokemonDexNumber (mapped class)
+
PokemonEggGroup (mapped class)
+
PokemonEvolution (mapped class)
+
PokemonForm (mapped class)
+
PokemonFormPokeathlonStat (mapped class)
+
+
PokemonGameIndex (mapped class)
+
PokemonHabitat (mapped class)
+
PokemonItem (mapped class)
+
PokemonMove (mapped class)
+
PokemonMoveMethod (mapped class)
+
PokemonShape (mapped class)
+
PokemonSpecies (mapped class)
+
PokemonSpeciesFlavorText (mapped class)
+
PokemonStat (mapped class)
+
PokemonType (mapped class)
+
+ +

R

+ + +
+
Region (mapped class)
+
+ +

S

+ + + +
+
Stat (mapped class)
+
StatHint (mapped class)
+
+
SuperContestCombo (mapped class)
+
SuperContestEffect (mapped class)
+
+ +

T

+ + + +
+
Type (mapped class)
+
+
TypeEfficacy (mapped class)
+
+ +

V

+ + + +
+
Version (mapped class)
+
VersionGroup (mapped class)
+
+
VersionGroupRegion (mapped class)
+
+ + + +
+
+
+
+
+ + + + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..dabf236 --- /dev/null +++ b/index.html @@ -0,0 +1,141 @@ + + + + + + + + + The pokedex documentation — pokedex v0.1 documentation + + + + + + + + + + + + +
+ +
+
+

Table Of Contents

+ + +

Next topic

+

Installing the pokedex library

+

This Page

+ + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/installing.html b/installing.html new file mode 100644 index 0000000..e877dee --- /dev/null +++ b/installing.html @@ -0,0 +1,254 @@ + + + + + + + + + Installing the pokedex library — pokedex v0.1 documentation + + + + + + + + + + + + + +
+
+
+
+ +
+

Installing the pokedex library

+
+

Quick startup with Ubuntu/Debian-like systems

+

Run the following from an empty directory:

+
$ sudo apt-get install git python python-pip python-sqlalchemy
+$ git clone git://git.veekun.com/pokedex.git
+$ pip install -E env -e pokedex
+$ source env/bin/activate
+(env)$ pokedex setup -v
+(env)$ pokedex lookup eevee
+
+

If it all goes smoothly, you can now use env/bin/pokedex, the command-line +tool, and env/bin/python, a Python interpreter configured to use the +pokedex library.

+

That is all you need. Feel free to skip the rest of this chapter if you’re not +interested in the details.

+
+
+

Prerequisites

+
+

Linux

+

Ubuntu/Debian users should run the following:

+
$ sudo apt-get install git python python-pip
+
+

With other Linuxes, install the packages for git, python (2.6 or 2.7, +not 3.x), and python-pip.

+

If you succeeded, skip the Detailed instructions.

+
+
+

Detailed instructions

+

You should know what a command line is and how to work with it. +The here we assume you’re using Linux [1], if that’s not the case, make +sure you have enough computer knowledge to translate the instructions to your +operating system.

+

Pokedex is distributed via Git. So, get Git.

+

You will also need Python 2; the language pokedex is written in. Be sure to get +version 2.6 or 2.7. Pokedex does not work with Python 3.x yet, and it +most likely won’t work with 2.5 or earlier.

+

Next, get pip, a tool to install Python packages. Experts can use another +tool, of course.

+

Make sure git and pip are on your path.

+

Optionally you can install SQLAlchemy, Python markdown, Whoosh, +or construct. If you don’t, pip will atuomatically download and install a copy +for you, but some are pretty big so you might want to install it system-wide. +(Unfortunately, many distros have outdated versions of these libraries, so pip +will install pokedex’s own copy anyway.)

+
+
+
+

Getting and installing pokedex

+

Run the following from an empty directory:

+
$ git clone git://git.veekun.com/pokedex.git
+$ pip install -E env -e pokedex
+
+

This will give you two directories: pokedex (containing the source code and +data), and env (a virtualenv).

+

In env/bin, there are three interesting files:

+
    +
  • pokedex: The pokedex program
  • +
  • python: A copy of Python that knows about pokedex and its prerequisites. +Using the system python won’t work.
  • +
  • activate: Typing source env/bin/activate in a shell will put +pokedex and our bin/python on the $PATH, and generally set things up to work +with them. Your prompt will change to let you know of this. You can end such +a session by typing deactivate.
  • +
+

This documentation will assume that you’ve activated the virtualenv, so +pokedex means env/bin/pokedex.

+
+

Advanced

+

You can of course install into an existing virtualenv, by either using its pip +and leaving out the -E env, or running the setup script directly:

+
(anotherenv)$ cd pokedex
+(anotherenv)pokedex$ python setup.py develop
+
+

It is also possible to install pokedex system-wide. There are problems with +that. Don’t do it. The only time you need sudo is for getting the +prerequisites.

+
+
+
+

Loading the database

+

Before you can do anything useful with pokedex, you need to load the database:

+
$ pokedex setup -v
+
+

This will load the data into a default SQLite database and create a default +Whoosh index.

+
+

Advanced

+

If you want to use another database, make sure you have the corresponding +SQLAlchemy engine for it and either use the -e switch, (e.g. +-e postgresql://@/pokedex), or set the POKEDEX_DB_ENGINE environment +variable.

+

To use another lookup index directory, specify it with -i or the +POKEDEX_INDEX_DIR variable.

+

Make sure you always use the same options whenever you use pokedex.

+

If you’re confused about what pokedex thinks its settings are, check +pokedex status.

+

See pokedex help for even more options.

+
+
+
+

All done

+

To verify that all went smoothly, check that the pokedex tool finds your +favorite pokémon:

+
$ pokedex lookup eevee
+
+

Yes, that was a bit anti-climatic. The command-line tool doesn’t do much, +currently.

+

Footnotes

+ + + + + +
[1]If you write instructions for another OS, well be happy to include them +here. The reason your OS is not listed here is because the author doesn’t +use it, so naturally he can’t write instructions for it.
+
+
+ + +
+
+
+
+
+

Table Of Contents

+ + +

Previous topic

+

The pokedex documentation

+

Next topic

+

Using pokedex

+

This Page

+ + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/main-tables.html b/main-tables.html new file mode 100644 index 0000000..a0f8171 --- /dev/null +++ b/main-tables.html @@ -0,0 +1,2094 @@ + + + + + + + + + The pokédex tables — pokedex v0.1 documentation + + + + + + + + + + + + + +
+
+
+
+ +
+

The pokédex tables

+

All the tables listed here are classes defined with SQLAlchemy’s +sqlalchemy.ext.declarative extension.

+
+
+pokedex.db.tables.metadata
+

The SQLAlchemy sqlalchemy.schema.MetaData containing all the +tables.

+
+ +
+
+pokedex.db.tables.mapped_classes
+

A list of all the classes you see below.

+
+ +

Each of these classes has a translation_classes attribute: a potentially +empty list of translation classes. See pokedex.db.multilang for how +these work.

+

Many tables have these columns:

+
    +
  • +
    id: An integer primary key. Sometimes it’s semantically meaningful, most
    +

    often it isn’t.

    +
    +
    +
  • +
  • +
    identifier: A string identifier of the class, and the preferred way to
    +

    access individual items.

    +
    +
    +
  • +
  • name: A name (uses the multilang functionality)

    +
  • +
+
+

Pokémon

+
+

PokemonSpecies

+
+
+pokedex.db.tables.PokemonSpecies
+

A Pokémon species: the standard 1–151. Or 649. Whatever.

+

Table name: pokemon_species +(single: pokemon_species)

+

Has +id, identifier, and name via pokemon_species_names.

+

PokemonSpecies.generation_id (→ Generation.id):

+
+ID of the generation this species first appeared in
+

PokemonSpecies.evolves_from_species_id (→ PokemonSpecies.id):

+
+The species from which this one evolves
+

PokemonSpecies.evolution_chain_id (→ EvolutionChain.id):

+
+ID of the species’ evolution chain (a.k.a. family)
+

PokemonSpecies.color_id (→ PokemonColor.id):

+
+ID of this Pokémon’s Pokédex color, as used for a gimmick search function in the games.
+

PokemonSpecies.shape_id (→ PokemonShape.id):

+
+ID of this Pokémon’s body shape, as used for a gimmick search function in the games.
+

PokemonSpecies.habitat_id (→ PokemonHabitat.id):

+
+ID of this Pokémon’s habitat, as used for a gimmick search function in the games.
+

PokemonSpecies.gender_rate (int):

+
+The chance of this Pokémon being female, in eighths; or -1 for genderless
+

PokemonSpecies.capture_rate (int):

+
+The base capture rate; up to 255
+

PokemonSpecies.base_happiness (int):

+
+The tameness when caught by a normal ball
+

PokemonSpecies.is_baby (bool):

+
+True iff the Pokémon is a baby, i.e. a lowest-stage Pokémon that cannot breed but whose evolved form can.
+

PokemonSpecies.hatch_counter (int):

+
+Initial hatch counter: one must walk 255 × (hatch_counter + 1) steps before this Pokémon’s egg hatches, unless utilizing bonuses like Flame Body’s
+

PokemonSpecies.has_gender_differences (bool):

+
+Set iff the species exhibits enough sexual dimorphism to have separate sets of sprites in Gen IV and beyond.
+

PokemonSpecies.growth_rate_id (→ GrowthRate.id):

+
+ID of the growth rate for this family
+

PokemonSpecies.forms_switchable (bool):

+
+True iff a particular individual of this species can switch beween its different forms.
+

PokemonSpecies.genus (unicode – plaintext) via pokemon_species_names:

+
+The short flavor text, such as “Seed” or “Lizard”; usually affixed with the word “Pokémon”
+

PokemonSpecies.flavor_summary (unicode – plaintext) via pokemon_species_flavor_summaries:

+
+Text containing facts from all flavor texts, for languages without official game translations
+

PokemonSpecies.form_description (unicode – markdown) via pokemon_species_prose:

+
+Description of how the forms work
+
+ +
+
+

Pokemon

+
+
+pokedex.db.tables.Pokemon
+

A Pokémon. The core to this whole mess. + + This table defines “Pokémon” the same way the games do: a form with + different types, moves, or other game-changing properties counts as a + different Pokémon. For example, this table contains four rows for Deoxys, + but only one for Unown.

+

Table name: pokemon +(single: pokemon)

+

Has +id.

+

Pokemon.species_id (→ PokemonSpecies.id):

+
+ID of the species this Pokémon belongs to
+

Pokemon.height (int):

+
+The height of the Pokémon, in decimeters (tenths of a meter)
+

Pokemon.weight (int):

+
+The weight of the Pokémon, in tenths of a kilogram (decigrams)
+

Pokemon.base_experience (int):

+
+The base EXP gained when defeating this Pokémon
+

Pokemon.order (int):

+
+Order for sorting. Almost national order, except families are grouped together.
+

Pokemon.is_default (bool):

+
+Set for exactly one pokemon used as the default for each species.
+
+ +
+
+

PokemonForm

+
+
+pokedex.db.tables.PokemonForm
+

An individual form of a Pokémon. This includes every variant (except + color differences) of every Pokémon, regardless of how the games treat + them. Even Pokémon with no alternate forms have one row in this table, to + represent their lone “normal” form.

+

Table name: pokemon_forms +(single: pokemon_form)

+

Has +id.

+

PokemonForm.form_identifier (unicode – identifier):

+
+An identifier of the form, uniue among a species. May be None for the default form of the species.
+

PokemonForm.pokemon_id (→ Pokemon.id):

+
+The ID of the base Pokémon for this form.
+

PokemonForm.introduced_in_version_group_id (→ VersionGroup.id):

+
+The ID of the version group in which this form first appeared.
+

PokemonForm.is_default (bool):

+
+Set for exactly one form used as the default for each pokemon (not necessarily species).
+

PokemonForm.is_battle_only (bool):

+
+Set iff the form can only appear in battle.
+

PokemonForm.order (int):

+
+The order in which forms should be sorted. Multiple forms may have equal order, in which case they should fall back on sorting by name.
+

PokemonForm.form_name (unicode – plaintext) via pokemon_form_names:

+
+The full form name, e.g. ‘Sky Forme’, for pokémon with different forms
+

PokemonForm.pokemon_name (unicode – plaintext) via pokemon_form_names:

+
+The full pokémon name, e.g. ‘Sky Shaymin’, for pokémon with different forms
+
+ +
+
+

EvolutionChain

+
+
+pokedex.db.tables.EvolutionChain
+

A family of Pokémon that are linked by evolution

+

Table name: evolution_chains

+

Has +id.

+

EvolutionChain.baby_trigger_item_id (→ Item.id):

+
+Item that a parent must hold while breeding to produce a baby
+
+ +
+
+

PokemonEvolution

+
+
+pokedex.db.tables.PokemonEvolution
+

A required action (“trigger”) and the conditions under which the trigger + must occur to cause a Pokémon to evolve. + + Any condition may be null if it does not apply for a particular Pokémon.

+

Table name: pokemon_evolution

+

Has +id.

+

PokemonEvolution.evolved_species_id (→ PokemonSpecies.id):

+
+The ID of the post-evolution species.
+

PokemonEvolution.evolution_trigger_id (→ EvolutionTrigger.id):

+
+The ID of the evolution trigger.
+

PokemonEvolution.trigger_item_id (→ Item.id):

+
+The ID of the item that must be used on the Pokémon.
+

PokemonEvolution.minimum_level (int):

+
+The minimum level for the Pokémon.
+

PokemonEvolution.gender (enum: [male, female]):

+
+The Pokémon’s required gender, or None if gender doesn’t matter
+

PokemonEvolution.location_id (→ Location.id):

+
+The ID of the location the evolution must be triggered at.
+

PokemonEvolution.held_item_id (→ Item.id):

+
+The ID of the item the Pokémon must hold.
+

PokemonEvolution.time_of_day (enum: [day, night]):

+
+The required time of day.
+

PokemonEvolution.known_move_id (→ Move.id):

+
+The ID of the move the Pokémon must know.
+

PokemonEvolution.minimum_happiness (int):

+
+The minimum happiness value the Pokémon must have.
+

PokemonEvolution.minimum_beauty (int):

+
+The minimum Beauty value the Pokémon must have.
+

PokemonEvolution.relative_physical_stats (int):

+
+The required relation between the Pokémon’s Attack and Defense stats, as sgn(atk-def).
+

PokemonEvolution.party_species_id (→ PokemonSpecies.id):

+
+The ID of the species that must be present in the party.
+

PokemonEvolution.trade_species_id (→ PokemonSpecies.id):

+
+The ID of the species for which this one must be traded.
+
+ +
+
+
+

Moves

+
+

Move

+
+
+pokedex.db.tables.Move
+

A Move: technique or attack a Pokémon can learn to use

+

Table name: moves +(single: move)

+

Has +id, identifier, and name via move_names.

+

Move.generation_id (→ Generation.id):

+
+ID of the generation this move first appeared in
+

Move.priority (int):

+
+The move’s priority bracket
+

Move.target_id (→ MoveTarget.id):

+
+ID of the target (range) of the move
+

Move.damage_class_id (→ MoveDamageClass.id):

+
+ID of the damage class (physical/special) of the move
+

Move.contest_type_id (→ ContestType.id):

+
+ID of the move’s Contest type (e.g. cool or smart)
+

Move.contest_effect_id (→ ContestEffect.id):

+
+ID of the move’s Contest effect
+

Move.super_contest_effect_id (→ SuperContestEffect.id):

+
+ID of the move’s Super Contest effect
+

Move.flavor_summary (unicode – plaintext) via move_flavor_summaries:

+
+Text containing facts from all flavor texts, for languages without official game translations
+
+ +
+
+

MoveEffect

+
+
+pokedex.db.tables.MoveEffect
+

An effect of a move

+

Table name: move_effects +(single: move_effect)

+

Has +id.

+

MoveEffect.short_effect (unicode – markdown) via move_effect_prose:

+
+A short summary of the effect
+

MoveEffect.effect (unicode – markdown) via move_effect_prose:

+
+A detailed description of the effect
+
+ +
+
+

MoveMeta

+
+
+pokedex.db.tables.MoveMeta
+

Metadata for move effects, sorta-kinda ripped straight from the game

+

Table name: move_meta

+

MoveMeta.move_id (→ Move.id):

+
+A numeric ID
+

MoveMeta.meta_category_id (→ MoveMetaCategory.id):

+
+ID of the move category
+

MoveMeta.meta_ailment_id (→ MoveMetaAilment.id):

+
+ID of the caused ailment
+

MoveMeta.min_hits (int):

+
+Minimum number of hits per use
+

MoveMeta.max_hits (int):

+
+Maximum number of hits per use
+

MoveMeta.min_turns (int):

+
+Minimum number of turns the user is forced to use the move
+

MoveMeta.max_turns (int):

+
+Maximum number of turns the user is forced to use the move
+

MoveMeta.recoil (int):

+
+Recoil damage, in percent of damage done
+

MoveMeta.healing (int):

+
+Healing, in percent of user’s max HP
+

MoveMeta.crit_rate (int):

+
+Critical hit rate bonus
+

MoveMeta.ailment_chance (int):

+
+Chance to cause an ailment, in percent
+

MoveMeta.flinch_chance (int):

+
+Chance to cause flinching, in percent
+

MoveMeta.stat_chance (int):

+
+Chance to cause a stat change, in percent
+
+ +
+
+

MoveVersion

+
+
+pokedex.db.tables.MoveVersion
+

History of changes to moves across main game versions.

+

Table name: move_versions

+

MoveVersion.move_id (→ Move.id):

+
+ID of the move this data is for
+

MoveVersion.version_group_id (→ VersionGroup.id):

+
+ID of the version group this data is for
+

MoveVersion.type_id (→ Type.id):

+
+Type of the move
+

MoveVersion.power (int):

+
+Base power of the move
+

MoveVersion.pp (int):

+
+PP of the move
+

MoveVersion.accuracy (int):

+
+Accuracy of the move
+

MoveVersion.effect_id (→ MoveEffect.id):

+
+ID of the move effect
+

MoveVersion.effect_chance (int):

+
+Effect chance
+
+ +
+
+
+

Items

+
+

Item

+
+
+pokedex.db.tables.Item
+

An Item from the games, like “Poké Ball” or “Bicycle”.

+

Table name: items +(single: item)

+

Has +id, identifier, and name via item_names.

+

Item.category_id (→ ItemCategory.id):

+
+ID of a category this item belongs to
+

Item.cost (int):

+
+Cost of the item when bought. Items sell for half this price.
+

Item.fling_power (int):

+
+Power of the move Fling when used with this item.
+

Item.fling_effect_id (→ ItemFlingEffect.id):

+
+ID of the fling-effect of the move Fling when used with this item. Note that these are different from move effects.
+

Item.short_effect (unicode – markdown) via item_prose:

+
+A short summary of the effect
+

Item.effect (unicode – markdown) via item_prose:

+
+Detailed description of the item’s effect.
+

Item.flavor_summary (unicode – plaintext) via item_flavor_summaries:

+
+Text containing facts from all flavor texts, for languages without official game translations
+
+ +
+
+

Berry

+
+
+pokedex.db.tables.Berry
+

A Berry, consumable item that grows on trees + + For data common to all items, such as the name, see the corresponding item entry.

+

Table name: berries

+

Has +id.

+

Berry.item_id (→ Item.id):

+
+The ID of the item that represents this Berry
+

Berry.firmness_id (→ BerryFirmness.id):

+
+The ID of this Berry’s firmness category
+

Berry.natural_gift_power (int):

+
+Natural Gift’s power when used with this Berry
+

Berry.natural_gift_type_id (→ Type.id):

+
+The ID of the Type that Natural Gift has when used with this Berry
+

Berry.size (int):

+
+The size of this Berry, in millimeters
+

Berry.max_harvest (int):

+
+The maximum number of these berries that can grow on one tree in Generation IV
+

Berry.growth_time (int):

+
+Time it takes the tree to grow one stage, in hours. Berry trees go through four of these growth stages before they can be picked.
+

Berry.soil_dryness (int):

+
+The speed at which this Berry dries out the soil as it grows. A higher rate means the soil dries more quickly.
+

Berry.smoothness (int):

+
+The smoothness of this Berry, used in making Pokéblocks or Poffins
+
+ +
+
+
+

Types

+
+

Type

+
+
+pokedex.db.tables.Type
+

Any of the elemental types Pokémon and moves can have.

+

Table name: types +(single: type)

+

Has +id, identifier, and name via type_names.

+

Type.generation_id (→ Generation.id):

+
+The ID of the generation this type first appeared in.
+

Type.damage_class_id (→ MoveDamageClass.id):

+
+The ID of the damage class this type’s moves had before Generation IV, null if not applicable (e.g. ???).
+
+ +
+
+
+

Abilities

+
+

Ability

+
+
+pokedex.db.tables.Ability
+

An ability a Pokémon can have, such as Static or Pressure.

+

Table name: abilities +(single: ability)

+

Has +id, identifier, and name via ability_names.

+

Ability.generation_id (→ Generation.id):

+
+The ID of the generation this ability was introduced in
+

Ability.effect (unicode – markdown) via ability_prose:

+
+A detailed description of this ability’s effect
+

Ability.short_effect (unicode – markdown) via ability_prose:

+
+A short summary of this ability’s effect
+
+ +
+
+
+

Language

+
+

Language

+
+
+pokedex.db.tables.Language
+

A language the Pokémon games have been translated into

+

Table name: languages +(single: language)

+

Has +id, identifier, and name via language_names.

+

Language.iso639 (unicode – identifier):

+
+The two-letter code of the country where this language is spoken. Note that it is not unique.
+

Language.iso3166 (unicode – identifier):

+
+The two-letter code of the language. Note that it is not unique.
+

Language.official (bool):

+
+True iff games are produced in the language.
+

Language.order (int):

+
+Order for sorting in foreign name lists.
+
+ +
+
+
+

Version stuff

+
+

Generation

+
+
+pokedex.db.tables.Generation
+

A Generation of the Pokémon franchise

+

Table name: generations +(single: generation)

+

Has +id, identifier, and name via generation_names.

+

Generation.main_region_id (→ Region.id):

+
+ID of the region this generation’s main games take place in
+

Generation.canonical_pokedex_id (→ Pokedex.id):

+
+ID of the Pokédex this generation’s main games use by default
+
+ +
+
+

VersionGroup

+
+
+pokedex.db.tables.VersionGroup
+

A group of versions, containing either two paired versions (such as Red + and Blue) or a single game (such as Yellow.)

+

Table name: version_groups

+

Has +id.

+

VersionGroup.generation_id (→ Generation.id):

+
+The ID of the generation the games in this group belong to.
+

VersionGroup.pokedex_id (→ Pokedex.id):

+
+The ID of the regional Pokédex used in this version group.
+

VersionGroup.order (int):

+
+Order for sorting changes between versions.
+
+ +
+
+

Version

+
+
+pokedex.db.tables.Version
+

An individual main-series Pokémon game.

+

Table name: versions +(single: version)

+

Has +id, identifier, and name via version_names.

+

Version.version_group_id (→ VersionGroup.id):

+
+The ID of the version group this game belongs to.
+
+ +
+
+

Pokedex

+
+
+pokedex.db.tables.Pokedex
+

A collection of Pokémon species ordered in a particular way

+

Table name: pokedexes +(single: pokedex)

+

Has +id, identifier, and name via pokedex_prose.

+

Pokedex.region_id (→ Region.id):

+
+ID of the region this Pokédex is used in, or None if it’s global
+

Pokedex.description (unicode – plaintext) via pokedex_prose:

+
+A longer description of the Pokédex
+
+ +
+
+

Region

+
+
+pokedex.db.tables.Region
+

Major areas of the world: Kanto, Johto, etc.

+

Table name: regions +(single: region)

+

Has +id, identifier, and name via region_names.

+
+ +
+
+
+

Encounters

+
+

Location

+
+
+pokedex.db.tables.Location
+

A place in the Pokémon world

+

Table name: locations +(single: location)

+

Has +id, identifier, and name via location_names.

+

Location.region_id (→ Region.id):

+
+ID of the region this location is in
+
+ +
+
+

LocationArea

+
+
+pokedex.db.tables.LocationArea
+

A sub-area of a location

+

Table name: location_areas +(single: location_area)

+

Has +id, identifier, and name via location_area_prose.

+

LocationArea.location_id (→ Location.id):

+
+ID of the location this area is part of
+

LocationArea.game_index (int):

+
+ID the games ude for this area
+
+ +
+
+

LocationAreaEncounterRate

+
+
+pokedex.db.tables.LocationAreaEncounterRate
+

None

+

Table name: location_area_encounter_rates

+

LocationAreaEncounterRate.location_area_id (→ LocationArea.id):

+
+ID of the area
+

LocationAreaEncounterRate.encounter_method_id (→ EncounterMethod.id):

+
+ID of the method
+

LocationAreaEncounterRate.version_id (→ Version.id):

+
+ID of the version
+

LocationAreaEncounterRate.rate (int):

+
+The encounter rate
+
+ +
+
+

Encounter

+
+
+pokedex.db.tables.Encounter
+

Encounters with wild Pokémon. + + Bear with me, here. + + Within a given area in a given game, encounters are differentiated by the + “slot” they are in and the state of the game world. + + What the player is doing to get an encounter, such as surfing or walking + through tall grass, is called a method. Each method has its own set of + encounter slots. + + Within a method, slots are defined primarily by rarity. Each slot can + also be affected by world conditions; for example, the 20% slot for walking + in tall grass is affected by whether a swarm is in effect in that area. + “Is there a swarm?” is a condition; “there is a swarm” and “there is not a + swarm” are the possible values of this condition. + + A slot (20% walking in grass) and any appropriate world conditions (no + swarm) are thus enough to define a specific encounter. + + Well, okay, almost: each slot actually appears twice.

+

Table name: encounters

+

Has +id.

+

Encounter.version_id (→ Version.id):

+
+The ID of the version this applies to
+

Encounter.location_area_id (→ LocationArea.id):

+
+The ID of the location of this encounter
+

Encounter.encounter_slot_id (→ EncounterSlot.id):

+
+The ID of the encounter slot, which determines method and rarity
+

Encounter.pokemon_id (→ Pokemon.id):

+
+The ID of the encountered Pokémon
+

Encounter.min_level (int):

+
+The minimum level of the encountered Pokémon
+

Encounter.max_level (int):

+
+The maxmum level of the encountered Pokémon
+
+ +
+
+

EncounterCondition

+
+
+pokedex.db.tables.EncounterCondition
+

A conditions in the game world that affects Pokémon encounters, such as time of day.

+

Table name: encounter_conditions +(single: encounter_condition)

+

Has +id, identifier, and name via encounter_condition_prose.

+
+ +
+
+

EncounterConditionValue

+
+
+pokedex.db.tables.EncounterConditionValue
+

A possible state for a condition; for example, the state of ‘swarm’ could be ‘swarm’ or ‘no swarm’.

+

Table name: encounter_condition_values +(single: encounter_condition_value)

+

Has +id, identifier, and name via encounter_condition_value_prose.

+

EncounterConditionValue.encounter_condition_id (→ EncounterCondition.id):

+
+The ID of the encounter condition this is a value of
+

EncounterConditionValue.is_default (bool):

+
+Set if this value is the default state for the condition
+
+ +
+
+

EncounterMethod

+
+
+pokedex.db.tables.EncounterMethod
+

A way the player can enter a wild encounter, e.g., surfing, fishing, or walking through tall grass.

+

Table name: encounter_methods +(single: encounter_method)

+

Has +id, identifier, and name via encounter_method_prose.

+
+ +
+
+

EncounterSlot

+
+
+pokedex.db.tables.EncounterSlot
+

An abstract “slot” within a method, associated with both some set of conditions and a rarity. + + Note that there are two encounters per slot, so the rarities will only add + up to 50.

+

Table name: encounter_slots

+

Has +id.

+

EncounterSlot.version_group_id (→ VersionGroup.id):

+
+The ID of the version group this slot is in
+

EncounterSlot.encounter_method_id (→ EncounterMethod.id):

+
+The ID of the method
+

EncounterSlot.slot (int):

+
+This slot’s order for the location and method
+

EncounterSlot.rarity (int):

+
+The chance of the encounter as a percentage
+
+ +
+
+
+

Contests

+
+

ContestCombo

+
+
+pokedex.db.tables.ContestCombo
+

Combo of two moves in a Contest.

+

Table name: contest_combos

+

ContestCombo.first_move_id (→ Move.id):

+
+The ID of the first move in the combo
+

ContestCombo.second_move_id (→ Move.id):

+
+The ID of the second and final move in the combo
+
+ +
+
+

ContestEffect

+
+
+pokedex.db.tables.ContestEffect
+

Effect of a move when used in a Contest.

+

Table name: contest_effects +(single: contest_effect)

+

Has +id.

+

ContestEffect.appeal (int):

+
+The base number of hearts the user of this move gets
+

ContestEffect.jam (int):

+
+The base number of hearts the user’s opponent loses
+

ContestEffect.flavor_text (unicode – gametext) via contest_effect_prose:

+
+The in-game description of this effect
+

ContestEffect.effect (unicode – plaintext) via contest_effect_prose:

+
+A detailed description of the effect
+
+ +
+
+

SuperContestCombo

+
+
+pokedex.db.tables.SuperContestCombo
+

Combo of two moves in a Super Contest.

+

Table name: super_contest_combos

+

SuperContestCombo.first_move_id (→ Move.id):

+
+The ID of the first move in the combo.
+

SuperContestCombo.second_move_id (→ Move.id):

+
+The ID of the second and last move.
+
+ +
+
+

SuperContestEffect

+
+
+pokedex.db.tables.SuperContestEffect
+

An effect a move can have when used in the Super Contest

+

Table name: super_contest_effects +(single: super_contest_effect)

+

Has +id.

+

SuperContestEffect.appeal (int):

+
+The number of hearts the user gains.
+

SuperContestEffect.flavor_text (unicode – plaintext) via super_contest_effect_prose:

+
+A description of the effect.
+
+ +
+
+
+

Enum tables

+
+

BerryFirmness

+
+
+pokedex.db.tables.BerryFirmness
+

A Berry firmness, such as “hard” or “very soft”.

+

Table name: berry_firmness +(single: berry_firmness)

+

Has +id, identifier, and name via berry_firmness_names.

+
+ +
+
+

ContestType

+
+
+pokedex.db.tables.ContestType
+

A Contest type, such as “cool” or “smart”, and their associated Berry flavors and Pokéblock colors.

+

Table name: contest_types +(single: contest_type)

+

Has +id, identifier, and name via contest_type_names.

+

ContestType.flavor (unicode – plaintext) via contest_type_names:

+
+The name of the corresponding Berry flavor
+

ContestType.color (unicode – plaintext) via contest_type_names:

+
+The name of the corresponding Pokéblock color
+
+ +
+
+

EggGroup

+
+
+pokedex.db.tables.EggGroup
+

An Egg group. Usually, two Pokémon can breed if they share an Egg Group. + + (exceptions are the Ditto and No Eggs groups)

+

Table name: egg_groups +(single: egg_group)

+

Has +id, identifier, and name via egg_group_prose.

+
+ +
+
+

EvolutionTrigger

+
+
+pokedex.db.tables.EvolutionTrigger
+

An evolution type, such as “level” or “trade”.

+

Table name: evolution_triggers +(single: evolution_trigger)

+

Has +id, identifier, and name via evolution_trigger_prose.

+
+ +
+
+

GrowthRate

+
+
+pokedex.db.tables.GrowthRate
+

Growth rate of a Pokémon, i.e. the EXP → level function.

+

Table name: growth_rates +(single: growth_rate)

+

Has +id, identifier, and name via growth_rate_prose.

+

GrowthRate.formula (unicode – latex):

+
+The formula
+
+ +
+
+

ItemCategory

+
+
+pokedex.db.tables.ItemCategory
+

An item category

+

Table name: item_categories +(single: item_category)

+

Has +id, identifier, and name via item_category_prose.

+

ItemCategory.pocket_id (→ ItemPocket.id):

+
+ID of the pocket these items go to
+
+ +
+
+

ItemFlag

+
+
+pokedex.db.tables.ItemFlag
+

An item attribute such as “consumable” or “holdable”.

+

Table name: item_flags +(single: item_flag)

+

Has +id, identifier, and name via item_flag_prose.

+

ItemFlag.description (unicode – plaintext) via item_flag_prose:

+
+Short description of the flag
+
+ +
+
+

ItemFlingEffect

+
+
+pokedex.db.tables.ItemFlingEffect
+

An effect of the move Fling when used with a specific item

+

Table name: item_fling_effects +(single: item_fling_effect)

+

Has +id.

+

ItemFlingEffect.effect (unicode – plaintext) via item_fling_effect_prose:

+
+Description of the effect
+
+ +
+
+

ItemPocket

+
+
+pokedex.db.tables.ItemPocket
+

A pocket that categorizes items

+

Table name: item_pockets +(single: item_pocket)

+

Has +id, identifier, and name via item_pocket_names.

+
+ +
+
+

MoveBattleStyle

+
+
+pokedex.db.tables.MoveBattleStyle
+

A battle style of a move

+

Table name: move_battle_styles +(single: move_battle_style)

+

Has +id, identifier, and name via move_battle_style_prose.

+
+ +
+
+

MoveDamageClass

+
+
+pokedex.db.tables.MoveDamageClass
+

Any of the damage classes moves can have, i.e. physical, special, or non-damaging.

+

Table name: move_damage_classes +(single: move_damage_class)

+

Has +id, identifier, and name via move_damage_class_prose.

+

MoveDamageClass.description (unicode – plaintext) via move_damage_class_prose:

+
+A description of the class
+
+ +
+
+

MoveMetaAilment

+
+
+pokedex.db.tables.MoveMetaAilment
+

Common status ailments moves can inflict on a single Pokémon, including + major ailments like paralysis and minor ailments like trapping.

+

Table name: move_meta_ailments +(single: move_meta_ailment)

+

Has +id, identifier, and name via move_meta_ailment_names.

+
+ +
+
+

MoveMetaCategory

+
+
+pokedex.db.tables.MoveMetaCategory
+

Very general categories that loosely group move effects.

+

Table name: move_meta_categories +(single: move_meta_category)

+

Has +id and identifier.

+

MoveMetaCategory.description (unicode – plaintext) via move_meta_category_prose:

+
+A description of the category
+
+ +
+
+

MoveTarget

+
+
+pokedex.db.tables.MoveTarget
+

Targetting or “range” of a move, e.g. “Affects all opponents” or “Affects user”.

+

Table name: move_targets +(single: move_target)

+

Has +id, identifier, and name via move_target_prose.

+

MoveTarget.description (unicode – plaintext) via move_target_prose:

+
+A description
+
+ +
+
+

Nature

+
+
+pokedex.db.tables.Nature
+

A nature a Pokémon can have, such as Calm or Brave

+

Table name: natures +(single: nature)

+

Has +id, identifier, and name via nature_names.

+

Nature.decreased_stat_id (→ Stat.id):

+
+ID of the stat that this nature decreases by 10% (if decreased_stat_id is the same, the effects cancel out)
+

Nature.increased_stat_id (→ Stat.id):

+
+ID of the stat that this nature increases by 10% (if decreased_stat_id is the same, the effects cancel out)
+

Nature.hates_flavor_id (→ ContestType.id):

+
+ID of the Berry flavor the Pokémon hates (if likes_flavor_id is the same, the effects cancel out)
+

Nature.likes_flavor_id (→ ContestType.id):

+
+ID of the Berry flavor the Pokémon likes (if hates_flavor_id is the same, the effects cancel out)
+
+ +
+
+

PokemonColor

+
+
+pokedex.db.tables.PokemonColor
+

The “Pokédex color” of a Pokémon species. Usually based on the Pokémon’s color.

+

Table name: pokemon_colors +(single: pokemon_color)

+

Has +id, identifier, and name via pokemon_color_names.

+
+ +
+
+

PokemonMoveMethod

+
+
+pokedex.db.tables.PokemonMoveMethod
+

A method a move can be learned by, such as “Level up” or “Tutor”.

+

Table name: pokemon_move_methods +(single: pokemon_move_method)

+

Has +id, identifier, and name via pokemon_move_method_prose.

+

PokemonMoveMethod.description (unicode – plaintext) via pokemon_move_method_prose:

+
+A detailed description of how the method works
+
+ +
+
+

PokemonShape

+
+
+pokedex.db.tables.PokemonShape
+

The shape of a Pokémon’s body. Used for flavor in generation IV and V + Pokédexes.

+

Table name: pokemon_shapes +(single: pokemon_shape)

+

Has +id, identifier, and name via pokemon_shape_prose.

+

PokemonShape.awesome_name (unicode – plaintext) via pokemon_shape_prose:

+
+A splendiferous name of the body shape
+
+ +
+
+

Stat

+
+
+pokedex.db.tables.Stat
+

A Stat, such as Attack or Speed

+

Table name: stats +(single: stat)

+

Has +id, identifier, and name via stat_names.

+

Stat.damage_class_id (→ MoveDamageClass.id):

+
+For offensive and defensive stats, the damage this stat relates to; otherwise None (the NULL value)
+

Stat.is_battle_only (bool):

+
+Whether this stat only exists within a battle
+
+ +
+
+
+

Changelogs

+
+

AbilityChangelog

+
+
+pokedex.db.tables.AbilityChangelog
+

History of changes to abilities across main game versions.

+

Table name: ability_changelog +(single: ability_changelog)

+

Has +id.

+

AbilityChangelog.ability_id (→ Ability.id):

+
+The ID of the ability that changed
+

AbilityChangelog.changed_in_version_group_id (→ VersionGroup.id):

+
+The ID of the version group in which the ability changed
+

AbilityChangelog.effect (unicode – markdown) via ability_changelog_prose:

+
+A description of the old behavior
+
+ +
+
+

MoveEffectChangelog

+
+
+pokedex.db.tables.MoveEffectChangelog
+

History of changes to move effects across main game versions.

+

Table name: move_effect_changelog +(single: move_effect_changelog)

+

Has +id.

+

MoveEffectChangelog.effect_id (→ MoveEffect.id):

+
+The ID of the effect that changed
+

MoveEffectChangelog.changed_in_version_group_id (→ VersionGroup.id):

+
+The ID of the version group in which the effect changed
+

MoveEffectChangelog.effect (unicode – markdown) via move_effect_changelog_prose:

+
+A description of the old behavior
+
+ +
+
+
+

Flavor text

+
+

ItemFlavorText

+
+
+pokedex.db.tables.ItemFlavorText
+

An in-game description of an item

+

Table name: item_flavor_text +(single: item_flavor_text)

+

ItemFlavorText.item_id (→ Item.id):

+
+The ID of the item
+

ItemFlavorText.version_group_id (→ VersionGroup.id):

+
+ID of the version group that sports this text
+

ItemFlavorText.language_id (→ Language.id):

+
+The language
+

ItemFlavorText.flavor_text (unicode – gametext):

+
+The flavor text itself
+
+ +
+
+

AbilityFlavorText

+
+
+pokedex.db.tables.AbilityFlavorText
+

In-game flavor text of an ability

+

Table name: ability_flavor_text

+

AbilityFlavorText.ability_id (→ Ability.id):

+
+The ID of the ability
+

AbilityFlavorText.version_group_id (→ VersionGroup.id):

+
+The ID of the version group this flavor text is taken from
+

AbilityFlavorText.language_id (→ Language.id):

+
+The language
+

AbilityFlavorText.flavor_text (unicode – gametext):

+
+The actual flavor text
+
+ +
+
+

MoveFlavorText

+
+
+pokedex.db.tables.MoveFlavorText
+

In-game description of a move

+

Table name: move_flavor_text

+

MoveFlavorText.move_id (→ Move.id):

+
+ID of the move
+

MoveFlavorText.version_group_id (→ VersionGroup.id):

+
+ID of the version group this text appears in
+

MoveFlavorText.language_id (→ Language.id):

+
+The language
+

MoveFlavorText.flavor_text (unicode – gametext):

+
+The flavor text
+
+ +
+
+

PokemonSpeciesFlavorText

+
+
+pokedex.db.tables.PokemonSpeciesFlavorText
+

In-game Pokédex descrption of a Pokémon.

+

Table name: pokemon_species_flavor_text

+

PokemonSpeciesFlavorText.species_id (→ PokemonSpecies.id):

+
+ID of the Pokémon
+

PokemonSpeciesFlavorText.version_id (→ Version.id):

+
+ID of the version that has this flavor text
+

PokemonSpeciesFlavorText.language_id (→ Language.id):

+
+The language
+

PokemonSpeciesFlavorText.flavor_text (unicode – gametext):

+
+The flavor text
+
+ +
+
+
+

Association tables

+
+

BerryFlavor

+
+
+pokedex.db.tables.BerryFlavor
+

A Berry flavor level.

+

Table name: berry_flavors

+

BerryFlavor.berry_id (→ Berry.id):

+
+The ID of the berry
+

BerryFlavor.contest_type_id (→ ContestType.id):

+
+The ID of the flavor
+

BerryFlavor.flavor (int):

+
+The level of the flavor in the berry
+
+ +
+
+

EncounterConditionValueMap

+
+
+pokedex.db.tables.EncounterConditionValueMap
+

Maps encounters to the specific conditions under which they occur.

+

Table name: encounter_condition_value_map

+

EncounterConditionValueMap.encounter_id (→ Encounter.id):

+
+The ID of the encounter
+

EncounterConditionValueMap.encounter_condition_value_id (→ EncounterConditionValue.id):

+
+The ID of the encounter condition value
+
+ +
+
+

ItemFlagMap

+
+
+pokedex.db.tables.ItemFlagMap
+

Maps an item flag to its item.

+

Table name: item_flag_map

+

ItemFlagMap.item_id (→ Item.id):

+
+The ID of the item
+

ItemFlagMap.item_flag_id (→ ItemFlag.id):

+
+The ID of the item flag
+
+ +
+
+

Machine

+
+
+pokedex.db.tables.Machine
+

A TM or HM; numbered item that can teach a move to a Pokémon

+

Table name: machines

+

Machine.machine_number (int):

+
+Number of the machine for TMs, or 100 + the munber for HMs
+

Machine.version_group_id (→ VersionGroup.id):

+
+Versions this entry applies to
+

Machine.item_id (→ Item.id):

+
+ID of the corresponding Item
+

Machine.move_id (→ Move.id):

+
+ID of the taught move
+
+ +
+
+

MoveFlag

+
+
+pokedex.db.tables.MoveFlag
+

A Move attribute such as “snatchable” or “contact”.

+

Table name: move_flags +(single: move_flag)

+

Has +id, identifier, and name via move_flag_prose.

+

MoveFlag.description (unicode – markdown) via move_flag_prose:

+
+A short description of the flag
+
+ +
+
+

MoveFlagMap

+
+
+pokedex.db.tables.MoveFlagMap
+

Maps a move flag to a move

+

Table name: move_flag_map

+

MoveFlagMap.move_id (→ Move.id):

+
+ID of the move
+

MoveFlagMap.move_flag_id (→ MoveFlag.id):

+
+ID of the flag
+
+ +
+
+

MoveMetaStatChange

+
+
+pokedex.db.tables.MoveMetaStatChange
+

Stat changes moves (may) make.

+

Table name: move_meta_stat_changes

+

MoveMetaStatChange.move_id (→ Move.id):

+
+ID of the move
+

MoveMetaStatChange.stat_id (→ Stat.id):

+
+ID of the stat
+

MoveMetaStatChange.change (int):

+
+Amount of increase/decrease, in stages
+
+ +
+
+

NatureBattleStylePreference

+
+
+pokedex.db.tables.NatureBattleStylePreference
+

Battle Palace move preference + + Specifies how likely a Pokémon with a specific Nature is to use a move of + a particular battl style in Battle Palace or Battle Tent

+

Table name: nature_battle_style_preferences

+

NatureBattleStylePreference.nature_id (→ Nature.id):

+
+ID of the Pokémon’s nature
+

NatureBattleStylePreference.move_battle_style_id (→ MoveBattleStyle.id):

+
+ID of the battle style
+

NatureBattleStylePreference.low_hp_preference (int):

+
+Chance of using the move, in percent, if HP is under ½
+

NatureBattleStylePreference.high_hp_preference (int):

+
+Chance of using the move, in percent, if HP is over ½
+
+ +
+
+

NaturePokeathlonStat

+
+
+pokedex.db.tables.NaturePokeathlonStat
+

Specifies how a Nature affects a Pokéathlon stat

+

Table name: nature_pokeathlon_stats

+

NaturePokeathlonStat.nature_id (→ Nature.id):

+
+ID of the nature
+

NaturePokeathlonStat.pokeathlon_stat_id (→ PokeathlonStat.id):

+
+ID of the stat
+

NaturePokeathlonStat.max_change (int):

+
+Maximum change
+
+ +
+
+

PokeathlonStat

+
+
+pokedex.db.tables.PokeathlonStat
+

A Pokéathlon stat, such as “Stamina” or “Jump”.

+

Table name: pokeathlon_stats +(single: pokeathlon_stat)

+

Has +id, identifier, and name via pokeathlon_stat_names.

+
+ +
+
+

PokemonAbility

+
+
+pokedex.db.tables.PokemonAbility
+

Maps an ability to a Pokémon that can have it

+

Table name: pokemon_abilities

+

PokemonAbility.pokemon_id (→ Pokemon.id):

+
+ID of the Pokémon
+

PokemonAbility.ability_id (→ Ability.id):

+
+ID of the ability
+

PokemonAbility.is_dream (bool):

+
+Whether this is a Dream World ability
+

PokemonAbility.slot (int):

+
+The ability slot, i.e. 1 or 2 for gen. IV
+
+ +
+
+

PokemonEggGroup

+
+
+pokedex.db.tables.PokemonEggGroup
+

Maps an Egg group to a species; each species belongs to one or two egg groups

+

Table name: pokemon_egg_groups

+

PokemonEggGroup.species_id (→ PokemonSpecies.id):

+
+ID of the species
+

PokemonEggGroup.egg_group_id (→ EggGroup.id):

+
+ID of the egg group
+
+ +
+
+

PokemonFormPokeathlonStat

+
+
+pokedex.db.tables.PokemonFormPokeathlonStat
+

A Pokémon form’s performance in one Pokéathlon stat.

+

Table name: pokemon_form_pokeathlon_stats

+

PokemonFormPokeathlonStat.pokemon_form_id (→ PokemonForm.id):

+
+The ID of the Pokémon form.
+

PokemonFormPokeathlonStat.pokeathlon_stat_id (→ PokeathlonStat.id):

+
+The ID of the Pokéathlon stat.
+

PokemonFormPokeathlonStat.minimum_stat (int):

+
+The minimum value for this stat for this Pokémon form.
+

PokemonFormPokeathlonStat.base_stat (int):

+
+The default value for this stat for this Pokémon form.
+

PokemonFormPokeathlonStat.maximum_stat (int):

+
+The maximum value for this stat for this Pokémon form.
+
+ +
+
+

PokemonHabitat

+
+
+pokedex.db.tables.PokemonHabitat
+

The habitat of a Pokémon, as given in the FireRed/LeafGreen version Pokédex

+

Table name: pokemon_habitats +(single: pokemon_habitat)

+

Has +id, identifier, and name via pokemon_habitat_names.

+
+ +
+
+

PokemonMove

+
+
+pokedex.db.tables.PokemonMove
+

Record of a move a Pokémon can learn

+

Table name: pokemon_moves

+

PokemonMove.pokemon_id (→ Pokemon.id):

+
+ID of the Pokémon
+

PokemonMove.version_group_id (→ VersionGroup.id):

+
+ID of the version group this applies to
+

PokemonMove.move_id (→ Move.id):

+
+ID of the move
+

PokemonMove.pokemon_move_method_id (→ PokemonMoveMethod.id):

+
+ID of the method this move is learned by
+

PokemonMove.level (int):

+
+Level the move is learned at, if applicable
+

PokemonMove.order (int):

+
+A sort key to produce the correct ordering when all else is equal
+
+ +
+
+

PokemonStat

+
+
+pokedex.db.tables.PokemonStat
+

A stat value of a Pokémon

+

Table name: pokemon_stats

+

PokemonStat.pokemon_id (→ Pokemon.id):

+
+ID of the Pokémon
+

PokemonStat.stat_id (→ Stat.id):

+
+ID of the stat
+

PokemonStat.base_stat (int):

+
+The base stat
+

PokemonStat.effort (int):

+
+The effort increase in this stat gained when this Pokémon is defeated
+
+ +
+
+

PokemonItem

+
+
+pokedex.db.tables.PokemonItem
+

Record of an item a Pokémon can hold in the wild

+

Table name: pokemon_items

+

PokemonItem.pokemon_id (→ Pokemon.id):

+
+ID of the Pokémon
+

PokemonItem.version_id (→ Version.id):

+
+ID of the version this applies to
+

PokemonItem.item_id (→ Item.id):

+
+ID of the item
+

PokemonItem.rarity (int):

+
+Chance of the Pokémon holding the item, in percent
+
+ +
+
+

PokemonType

+
+
+pokedex.db.tables.PokemonType
+

Maps a type to a Pokémon. Each Pokémon has 1 or 2 types.

+

Table name: pokemon_types

+

PokemonType.pokemon_id (→ Pokemon.id):

+
+ID of the Pokémon
+

PokemonType.type_id (→ Type.id):

+
+ID of the type
+

PokemonType.slot (int):

+
+The type’s slot, 1 or 2, used to sort types if there are two of them
+
+ +
+
+

TypeEfficacy

+
+
+pokedex.db.tables.TypeEfficacy
+

The damage multiplier used when a move of a particular type damages a + Pokémon of a particular other type.

+

Table name: type_efficacy

+

TypeEfficacy.damage_type_id (→ Type.id):

+
+The ID of the damaging type.
+

TypeEfficacy.target_type_id (→ Type.id):

+
+The ID of the defending Pokémon’s type.
+

TypeEfficacy.damage_factor (int):

+
+The multiplier, as a percentage of damage inflicted.
+
+ +
+
+

VersionGroupRegion

+
+
+pokedex.db.tables.VersionGroupRegion
+

Maps a version group to a region that appears in it.

+

Table name: version_group_regions

+

VersionGroupRegion.version_group_id (→ VersionGroup.id):

+
+The ID of the version group.
+

VersionGroupRegion.region_id (→ Region.id):

+
+The ID of the region.
+
+ +
+
+
+

Index maps

+
+

ItemGameIndex

+
+
+pokedex.db.tables.ItemGameIndex
+

The internal ID number a game uses for an item

+

Table name: item_game_indices

+

ItemGameIndex.item_id (→ Item.id):

+
+The database ID of the item
+

ItemGameIndex.generation_id (→ Generation.id):

+
+ID of the generation of games
+

ItemGameIndex.game_index (int):

+
+Internal ID of the item in the generation
+
+ +
+
+

LocationGameIndex

+
+
+pokedex.db.tables.LocationGameIndex
+

IDs the games use internally for locations

+

Table name: location_game_indices

+

LocationGameIndex.location_id (→ Location.id):

+
+Database ID of the locaion
+

LocationGameIndex.generation_id (→ Generation.id):

+
+ID of the generation this entry to
+

LocationGameIndex.game_index (int):

+
+Internal game ID of the location
+
+ +
+
+

PokemonDexNumber

+
+
+pokedex.db.tables.PokemonDexNumber
+

The number of a species in a particular Pokédex (e.g. Jigglypuff is #138 in Hoenn’s ‘dex)

+

Table name: pokemon_dex_numbers

+

PokemonDexNumber.species_id (→ PokemonSpecies.id):

+
+ID of the species
+

PokemonDexNumber.pokedex_id (→ Pokedex.id):

+
+ID of the Pokédex
+

PokemonDexNumber.pokedex_number (int):

+
+Number of the Pokémon in that the Pokédex
+
+ +
+
+

PokemonGameIndex

+
+
+pokedex.db.tables.PokemonGameIndex
+

The number of a Pokémon a game uses internally

+

Table name: pokemon_game_indices

+

PokemonGameIndex.pokemon_id (→ Pokemon.id):

+
+Database ID of the Pokémon
+

PokemonGameIndex.generation_id (→ Generation.id):

+
+Database ID of the generation
+

PokemonGameIndex.game_index (int):

+
+Internal ID the generation’s games use for the Pokémon
+
+ +
+
+
+

Mics tables

+
+

Experience

+
+
+pokedex.db.tables.Experience
+

EXP needed for a certain level with a certain growth rate

+

Table name: experience

+

Experience.growth_rate_id (→ GrowthRate.id):

+
+ID of the growth rate
+

Experience.level (int):

+
+The level
+

Experience.experience (int):

+
+The number of EXP points needed to get to that level
+
+ +
+
+

StatHint

+
+
+pokedex.db.tables.StatHint
+

Flavor text for genes that appears in a Pokémon’s summary. Sometimes + called “characteristics”.

+

Table name: stat_hints +(single: stat_hint)

+

Has +id.

+

StatHint.stat_id (→ Stat.id):

+
+ID of the highest stat
+

StatHint.gene_mod_5 (int):

+
+Value of the highest stat modulo 5
+

StatHint.message (unicode – plaintext) via stat_hint_names:

+
+The text displayed
+
+ +
+
+
+ + +
+
+
+
+
+

Table Of Contents

+ + +

Previous topic

+

The database schema

+

This Page

+ + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/objects.inv b/objects.inv new file mode 100644 index 0000000..e1476e4 Binary files /dev/null and b/objects.inv differ diff --git a/py-modindex.html b/py-modindex.html new file mode 100644 index 0000000..f4a1061 --- /dev/null +++ b/py-modindex.html @@ -0,0 +1,112 @@ + + + + + + + + + Python Module Index — pokedex v0.1 documentation + + + + + + + + + + + + + + +
+
+
+
+ + +

Python Module Index

+ +
+ p +
+ + + + + + + + + + +
 
+ p
+ pokedex +
    + pokedex.db.tables +
+ + +
+
+
+
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/schema.html b/schema.html new file mode 100644 index 0000000..7a2a06b --- /dev/null +++ b/schema.html @@ -0,0 +1,248 @@ + + + + + + + + + The database schema — pokedex v0.1 documentation + + + + + + + + + + + + + +
+
+
+
+ +
+

The database schema

+ +
+ + +
+
+
+
+
+

Previous topic

+

Using pokedex

+

Next topic

+

The pokédex tables

+

This Page

+ + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/search.html b/search.html new file mode 100644 index 0000000..f7199d2 --- /dev/null +++ b/search.html @@ -0,0 +1,101 @@ + + + + + + + + + Search — pokedex v0.1 documentation + + + + + + + + + + + + + + + +
+
+
+
+ +

Search

+
+ +

+ Please activate JavaScript to enable the search + functionality. +

+
+

+ From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. +

+
+ + + +
+ +
+ +
+ +
+
+
+
+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 0000000..8effc59 --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({objects:{"pokedex.db.tables":{NaturePokeathlonStat:[2,1,1],SuperContestEffect:[2,1,1],PokemonHabitat:[2,1,1],PokemonDexNumber:[2,1,1],ItemCategory:[2,1,1],PokemonEggGroup:[2,1,1],ContestCombo:[2,1,1],PokeathlonStat:[2,1,1],PokemonSpeciesFlavorText:[2,1,1],metadata:[2,2,1],Machine:[2,1,1],PokemonSpecies:[2,1,1],Version:[2,1,1],EggGroup:[2,1,1],ItemFlingEffect:[2,1,1],mapped_classes:[2,2,1],PokemonAbility:[2,1,1],NatureBattleStylePreference:[2,1,1],PokemonMove:[2,1,1],Type:[2,1,1],GrowthRate:[2,1,1],MoveVersion:[2,1,1],MoveBattleStyle:[2,1,1],BerryFirmness:[2,1,1],LocationGameIndex:[2,1,1],Stat:[2,1,1],MoveMeta:[2,1,1],PokemonType:[2,1,1],PokemonFormPokeathlonStat:[2,1,1],ContestEffect:[2,1,1],Nature:[2,1,1],EncounterConditionValue:[2,1,1],EvolutionTrigger:[2,1,1],MoveEffect:[2,1,1],MoveMetaAilment:[2,1,1],MoveFlavorText:[2,1,1],LocationArea:[2,1,1],ItemFlag:[2,1,1],PokemonItem:[2,1,1],EncounterSlot:[2,1,1],EncounterCondition:[2,1,1],MoveEffectChangelog:[2,1,1],AbilityFlavorText:[2,1,1],VersionGroupRegion:[2,1,1],MoveFlag:[2,1,1],Encounter:[2,1,1],MoveDamageClass:[2,1,1],ItemGameIndex:[2,1,1],Language:[2,1,1],BerryFlavor:[2,1,1],MoveMetaCategory:[2,1,1],Region:[2,1,1],PokemonGameIndex:[2,1,1],StatHint:[2,1,1],Experience:[2,1,1],PokemonColor:[2,1,1],AbilityChangelog:[2,1,1],Berry:[2,1,1],SuperContestCombo:[2,1,1],PokemonMoveMethod:[2,1,1],MoveTarget:[2,1,1],Ability:[2,1,1],PokemonForm:[2,1,1],ItemPocket:[2,1,1],PokemonEvolution:[2,1,1],Item:[2,1,1],Generation:[2,1,1],VersionGroup:[2,1,1],TypeEfficacy:[2,1,1],Move:[2,1,1],ItemFlagMap:[2,1,1],Pokedex:[2,1,1],EncounterMethod:[2,1,1],MoveMetaStatChange:[2,1,1],ItemFlavorText:[2,1,1],ContestType:[2,1,1],MoveFlagMap:[2,1,1],LocationAreaEncounterRate:[2,1,1],EvolutionChain:[2,1,1],PokemonStat:[2,1,1],EncounterConditionValueMap:[2,1,1],Pokemon:[2,1,1],PokemonShape:[2,1,1],Location:[2,1,1]},"pokedex.db":{tables:[2,0,0]}},terms:{all:[0,1,2,3],code:[2,3],chain:2,type_id:2,queri:0,consum:2,pokemon_move_method_pros:2,yellow:2,four:2,moveflagtyp:[],abil:[2,4],eeve:[0,3],follow:[0,3],hate:2,row:2,whose:2,system:[1,3],aria:0,shaymin:2,"pok\u00e9":2,program:3,location_game_indic:2,skip:3,locaion:2,introduc:2,awesome_nam:2,deactiv:3,sourc:3,everi:[0,2],string:[0,2],tame:2,itemcategori:[2,4],util:[0,2],minimum_level:2,fall:2,veri:2,affect:2,pokemonflavortext:[],min_hit:2,cool:2,itempocket:[2,4],level:2,gender:2,effect_ch:2,max_harvest:2,list:[0,2,3],defens:2,item:[0,2,4],minimum_happi:2,sane:0,form:[0,2],print_item:0,quick:[0,1,3],movetarget:[2,4],pleas:0,height:2,work:[0,2,3],move_flag_pros:2,speci:[0,2],natur:[2,3,4],attribut:[0,2],jump:[1,2],rate:2,cost:[0,2],decigram:2,habitat_id:2,download:3,short_effect:2,even:[2,3],index:[1,2,3,4],what:[0,2,3],appear:2,mainlin:[],section:0,lizard:2,find:3,current:3,version:[0,2,3,4],directori:3,appeal:2,method:[0,2],metadata:2,move_effect:2,evolved_pokemon_id:[],pressur:2,join:0,gener:[2,3,4],never:[],here:[0,2,3],bodi:2,mapped_class:2,abomasnow:0,let:3,contest_effect_id:2,ubuntu:[1,3],path:3,sinc:0,interpret:3,pokemon_species_pros:2,search:[1,2],version_group:2,versiongroup:[2,4],genu:[0,2],reason:3,print_pokemon:0,pokedex:[0,1,2,3,4],dri:2,prior:[],amount:2,base:[0,2],defeat:2,action:2,chang:[0,2,3],gene:2,chanc:2,encounter_slot:2,semant:2,via:[2,3],regardless:2,extra:[],move_flag_type_id:[],appli:2,prefer:2,apt:3,item_flag_map:2,put:3,itemflavortext:[2,4],api:0,encounter_condition_value_map:2,famili:2,sgn:2,instal:[1,3],gimmick:2,item_pocket:2,select:0,uniu:2,is_pokemon:[],from:[0,2,3],would:0,ext:2,two:[2,3],next:3,few:0,jam:2,call:[0,2],calm:2,supercontestcombo:[2,4],criteria:[],taken:2,type:[0,2,3,4],minor:2,more:[0,2,3],sort:[0,2],frenzi:0,babi:2,relat:[0,2],line:3,about:[0,3],pokemonspeciesflavortext:[2,4],warn:[],sore:[],flag:2,form_base_pokemon_id:[],rip:2,particular:[0,2],pokemon_form:2,egg_group_id:2,hold:2,effort:2,descrption:2,must:2,dex:2,none:2,gametext:2,word:2,hour:2,base_experi:2,setup:3,pokedex_db_engin:3,battl:2,uniqu:2,moveeffect:[2,4],histori:2,other:[0,2,3],unique_pokemon_id:[],can:[0,2,3],learn:[0,2],under:2,male:2,firmness_id:2,def:[0,2],versiongroupregion:[2,4],heart:2,sqlite:3,omit:[],prompt:3,climat:3,give:[0,3],nature_nam:2,sudo:3,share:2,indic:1,locationgameindex:[2,4],critic:2,minimum:2,want:[0,3],explos:0,color_id:2,occur:2,paleozo:0,alwai:[0,3],differenti:2,cours:3,end:3,nature_pokeathlon_stat:2,thing:[0,3],anoth:[0,3],contest_type_id:2,write:[0,3],how:[0,2,3],env:3,verifi:3,bit:3,move_meta_ail:2,simpl:0,distro:3,splendifer:2,map:[2,4],plant:0,locationareaencounterr:[2,4],evolution_trigg:2,trigger_item_id:2,mess:2,max:2,clone:3,earlier:3,variant:2,pokemon_habitat_nam:2,befor:[2,3],okai:2,beauti:2,language_nam:2,mai:2,multipl:2,pokemon_evolut:2,stat_hint:2,data:[0,2,3],eighth:2,physic:2,naturepokeathlonstat:[2,4],time_of_dai:2,"short":2,is_babi:2,read:0,seriou:0,counter:2,favorit:3,correspond:[2,3],element:2,caus:2,inform:0,"switch":[2,3],environ:3,enter:2,tall:2,fallback:[],egg:2,order:[0,2],move_battle_style_pros:2,help:3,offici:2,move:[0,2,4],gender_r:2,becaus:3,meter:2,trade:2,trade_pokemon_id:[],"_python":0,through:2,venusaur:0,abilityflavortext:[2,4],still:[],form_:[],testcod:0,multilang:2,oppon:2,style:2,group:2,primarili:2,pokemon_form_id:2,encounter_id:2,is_battle_onli:2,feel:3,jigglypuff:2,crit_rat:2,encountercondit:[2,4],main:2,might:[0,3],them:[0,2,3],good:[],"return":0,hates_flavor_id:2,thei:[0,2],fling:2,python:[0,3],movemetaail:[2,4],pokeathlonstat:[2,4],dai:2,initi:2,nation:2,solarbeam:0,half:2,item_nam:2,now:3,ability_flavor_text:2,term:[],growth_rat:2,name:[0,2],anyth:3,move_flag_id:2,bonu:2,separ:2,iff:2,form_descript:2,trap:2,move_flag_map:2,each:2,found:[],went:3,is_dream:2,mean:[0,2,3],beween:2,ailment:2,weight:2,individu:2,hard:2,idea:[],contest_type_nam:2,locationarea:[2,4],firer:2,"static":2,connect:[0,1],inflict:2,encounter_slot_id:2,leafgreen:2,our:3,meth:0,beyond:2,tenth:2,special:2,out:[0,2,3],variabl:3,"pok\u00e9dex":[0,1,2,4],type_nam:2,virtualenv:3,goe:3,miss:[],defend:2,berryflavor:[2,4],whoosh:3,categori:2,bonus:2,palac:2,extra_languag:[],print:0,formula:2,item_flag:2,item_pocket_nam:2,correct:2,red:2,atuomat:3,pokemonevolut:[2,4],advanc:3,given:2,free:3,standard:2,wormadam:[],evolution_chain:2,orm:0,ability_changelog:2,item_id:2,org:0,teach:2,flare:0,could:2,traceback:0,atk:2,struggl:[],filter:0,turn:2,region_nam:2,place:2,isn:2,pokemonstat:[2,4],summari:2,confus:3,think:3,first:[0,2],oper:[0,3],minimum_beauti:2,rang:2,move_effect_changelog_pros:2,genesect:0,directli:3,spoken:2,engine_prefix:[],pokemon_item:2,number:2,trade_species_id:2,yourself:[],instruct:3,relative_physical_stat:2,done:[1,2,3],construct:3,party_pokemon_id:[],item_fling_effect:2,known_move_id:2,primari:2,size:2,prioriti:2,move_battle_style_id:2,script:[0,3],associ:[2,4],caught:2,breed:2,sometim:[0,2],messag:2,grow:2,kanto:2,swarm:2,attack:2,soil_dry:2,order_bi:0,evolves_from_pokemon_id:[],storm:0,pokemonmovemethod:[2,4],conveni:0,"final":[0,2],schema:[1,2,4],shell:3,option:3,move_target:2,movebattlestyl:[2,4],tool:3,copi:3,ability_pros:2,specifi:[2,3],main_region_id:2,part:2,egggroup:[2,4],consult:0,move_battle_styl:2,exactli:[0,2],than:0,pokemon_move_method_id:2,wide:3,nature_battle_style_prefer:2,pokemon_shap:2,evolution_chain_id:2,whenev:3,tree:2,second:2,growthrat:[2,4],move_meta:2,matter:2,meta_category_id:2,paralysi:2,flame:2,bind:[],pokeathlon_stat:2,danc:0,decimet:2,seri:2,exhibit:2,lowest:2,comput:3,region_id:2,plaintext:2,encounter_method_pros:2,ani:[0,2],decreased_stat_id:2,generation_id:2,generation_nam:2,packag:3,item_flag_id:2,seed:[0,2],have:[0,2,3],tabl:[0,1,2,4],need:[0,2,3],location_area_encounter_r:2,ambigu:[],location_id:2,moveflagmap:[2,4],sell:2,engin:3,techniqu:2,zero:[],movevers:[2,4],item_fling_effect_pros:2,maximum:2,accuraci:2,note:[0,2],also:[2,3],without:[0,2],super_contest_combo:2,take:2,which:2,hatch:2,pokemontyp:[2,4],min_turn:2,singl:2,contesttyp:[2,4],surf:2,blue:2,sure:3,unless:[0,2],distribut:3,normal:[0,2],multipli:2,price:2,berry_flavor:2,ability_nam:2,canonical_pokedex_id:2,most:[0,2,3],pokemon_typ:2,pokemon_mov:2,diglett:0,letter:2,millimet:2,pair:2,stat_hint_nam:2,pokemon_species_nam:2,sub:2,pokemon_nam:2,don:[0,3],pokemon_shape_id:[],dream:2,lose:2,cover:0,uri:0,doe:[2,3],increased_stat_id:2,declar:2,exp:2,movemeta:[2,4],link:2,effect:2,usual:[0,2],moveflag:[2,4],fact:2,translat:[0,2,3],deoxi:2,charmeleon:0,super_contest_effect_id:2,show:0,text:[0,2,4],melodi:0,meloetta:0,type_efficaci:2,area:2,session:[0,3],moveeffectchangelog:[2,4],pokemonshap:[2,4],anywai:3,slot:2,pokemon_form_nam:2,onli:[0,2,3],explicitli:0,locat:[2,4],pretti:3,pokemonspeci:[0,2,4],much:3,explain:0,configur:3,activ:3,cloak:[],should:[0,2,3],wood:0,order_by_nam:0,combo:2,footnot:3,flinch:2,over:2,pokemonitem:[2,4],count:2,hit:2,machine_numb:2,pokemonformgroup:[],get:[0,1,2,3],location_nam:2,form_identifi:2,express:0,target_id:2,stathint:[2,4],bear:2,secondari:[],pocket:2,session_arg:[],cannot:2,foremost:0,ability_changelog_pros:2,increas:2,gen:2,requir:2,target:2,berry_id:2,item_pros:2,evolution_trigger_id:2,fling_pow:2,organ:0,encounter_condition_value_pros:2,maxmum:2,encounter_method_id:2,twice:2,stuff:[2,4],common:[0,2],encounterconditionvalu:[2,4],contain:[2,3],abilitychangelog:[2,4],pokemon_speci:2,bought:2,where:2,natural_gift_type_id:2,encounterconditionvaluemap:[2,4],pokemon_color:2,set:[2,3],modulo:2,pick:2,knowledg:3,startup:[1,3],pokemonmov:[2,4],see:[0,2,3],full:[0,2],fling_effect_id:2,version_group_id:2,sport:2,hammer:0,onc:[],target_type_id:2,statu:[2,3],brave:2,kei:2,expert:3,pokemon_id:2,sorta:2,databas:[0,1,2,3,4],someth:0,yet:3,enough:[2,3],won:[0,3],game_index:2,move_changelog:[],between:2,"import":0,experi:[0,2,4],across:2,contest_combo:2,tent:2,altern:[0,2],naturebattlestyleprefer:[2,4],johto:2,parent:2,numer:2,attempt:[],condit:2,pokemoncolor:[2,4],extens:2,pokedex_index_dir:3,succeed:3,pocket_id:2,pokemon_form_group_pros:[],meta_ailment_id:2,water:0,last:[0,2],berri:[2,4],region:[2,4],"pok\u00e9block":2,equal:2,foreign:2,etc:2,tutori:0,pokemon_species_flavor_summari:2,itemflingeffect:[2,4],pokemon:[0,2,4],nullabl:[],mani:[2,3],dimorph:2,rariti:2,com:3,load:[0,1,3],among:2,pokeathlon_stat_nam:2,markdown:[2,3],pokemon_game_indic:2,point:2,color:2,sky:2,contest_effect_pros:2,item_game_indic:2,written:3,differ:[0,2],linux:3,cancel:2,assum:3,duplic:0,quit:0,baby_trigger_item_id:2,itemflagmap:[2,4],movechangelog:[],encounter_condition_pros:2,three:3,been:2,tutor:2,keldeo:0,trigger:2,contestcombo:[2,4],interest:3,certain:2,pokemon_flavor_summari:[],evolut:[0,2],movemetastatchang:[2,4],quickli:2,firm:2,hoenn:2,ivysaur:0,sprite:2,move_nam:2,xxx:0,great:0,argument:0,item_flag_pros:2,togeth:2,func:0,els:2,berry_firm:2,high_hp_prefer:2,present:2,movedamageclass:[2,4],"case":[2,3],party_species_id:2,max_level:2,look:0,move_meta_ailment_nam:2,pokemon_habitat:2,straight:2,properti:2,encountermethod:[2,4],pokemon_move_method:2,defin:[0,2],"while":2,smart:2,behavior:2,pokemon_shape_pros:2,wild:2,exist:[0,2,3],iso3166:2,loos:2,pokemon_form_group:[],move_flavor_summari:2,move_flag_typ:[],encounter_condition_valu:2,translation_class:2,almost:2,soil:2,max_hit:2,non:2,worri:0,player:2,itself:2,meaning:2,descript:2,pokemon_dex_numb:2,filter_bi:0,result:0,move_effect_changelog:2,pokemonhabitat:[2,4],"null":2,develop:3,berry_firmness_nam:2,author:3,perform:2,parti:2,make:[0,2,3],belong:2,same:[0,2,3],check:3,handl:[],html:0,postgresql:3,document:[0,1,3],higher:2,species_id:2,ball:[0,2],raichu:0,pokedex_pros:2,ability_id:2,pikachu:0,stat_nam:2,engine_arg:[],second_move_id:2,move_vers:2,move_flavor_text:2,rais:[],user:[2,3],has_gender_differ:2,countri:2,changed_in_version_group_id:2,move_meta_stat_chang:2,berryfirm:[2,4],move_id:2,recent:0,appropri:[0,2],super_contest_effect:2,contesteffect:[2,4],natural_gift_pow:2,"pok\u00e9mon":[0,2,3,4],whole:2,thu:2,well:[2,3],except:[0,2],effect_id:2,flinch_chanc:2,moveflavortext:[2,4],location_area_id:2,exampl:[0,2],command:3,item_categori:2,thi:[0,2,3],english:0,forms_switch:2,gift:2,category_id:2,mic:[2,4],unchang:[],identifi:[0,2],munber:2,"true":2,entri:2,move_flag_type_pros:[],rest:[0,3],shape:2,move_effect_pros:2,pokemondexnumb:[2,4],flavor:[2,4],speed:2,contest_typ:2,languag:[0,2,3,4],characterist:2,testoutput:0,percent:2,had:2,encounter_condition_value_id:2,add:2,held_item_id:2,move_damage_class:2,itemflag:[2,4],"pok\u00e9athlon":2,pokemon_flavor_text:[],match:[],build:[],bin:3,applic:2,bicycl:2,pokemon_:2,format:0,preserv:[],big:3,version_nam:2,supercontesteffect:[2,4],veekun:3,form_nam:2,is_default:2,movemetacategori:[2,4],game:2,minimum_stat:2,world:2,shadow:0,walk:2,you:[0,2,3],mod:0,move_target_pros:2,likes_flavor_id:2,like:[0,1,2,3],specif:[0,2],changelog:[2,4],integ:2,collect:2,either:[0,2,3],night:2,evolutionchain:[2,4],anti:3,maximum_stat:2,soft:2,page:1,encount:[2,4],www:0,right:1,old:2,often:2,habitat:2,snatchabl:2,whatev:2,some:[0,2,3],back:2,percentag:2,global:2,damage_type_id:2,intern:2,growth:2,smoothli:3,location_area:2,small:0,guess:0,ailment_ch:2,librari:[0,1,3],gene_mod_5:2,autofunct:0,base_happi:2,charmand:0,both:2,pokemonegggroup:[2,4],"_sqlalchemi":0,language_id:2,per:2,move_flag:2,when:2,evolv:2,leav:3,contact:2,encounterslot:[2,4],damage_class_id:2,egg_group:2,damag:2,machin:[2,4],core:2,object:0,run:[0,3],power:[0,2],contest_effect:2,post:2,"enum":[2,4],version_id:2,evolutiontrigg:[2,4],argumenterror:0,step:2,relationship:0,prerequisit:[1,3],evolves_from_species_id:2,major:[0,2],"super":2,unicod:2,stage:2,chapter:3,min_level:2,actual:[0,2],column:2,holdabl:2,http:0,zweilou:0,unfortun:3,stat_chanc:2,encounter_condit:2,move_damage_class_pros:2,produc:2,encounter_method:2,own:[2,3],pokemon_species_flavor_text:2,item_flavor_text:2,burmi:[],within:2,ditto:2,empti:[2,3],shape_id:2,bool:2,your:[0,3],base_stat:2,move_meta_category_pros:2,unown:2,git:3,fill:0,pokemonformpokeathlonstat:[2,4],wai:[0,2],pokemon_color_nam:2,aren:[],captur:2,lone:2,growth_rate_pros:2,happi:[2,3],stamina:2,start:0,reli:0,version_group_region:2,franchis:2,includ:[0,2,3],pokemon_egg_group:2,max_turn:2,fish:2,treat:2,"function":[0,2],evolution_trigger_pros:2,evolved_species_id:2,necessarili:2,item_flavor_summari:2,latex:2,forc:2,stat_id:2,heal:2,basic:0,femal:2,low_hp_prefer:2,content:1,state:2,recoil:2,gain:2,offens:2,nature_id:2,highest:2,categor:2,flavor_text:2,info:0,iso639:2,max_chang:2,itemgameindex:[2,4],attr:0,possibl:[2,3],whether:2,access:2,smooth:2,displai:2,pokedex_numb:2,growth_rate_id:2,record:2,below:[0,2],taught:2,doc:0,anotherenv:3,otherwis:2,problem:3,grass:[0,2],similar:0,expect:0,pokedex_id:2,egg_group_pros:2,pokeathlon_stat_id:2,creat:[0,3],"int":2,request:[],"abstract":2,futur:0,doesn:[2,3],repres:2,pokemongameindex:[2,4],incomplet:[],decreas:2,file:3,valu:2,pip:3,genderless:2,flavor_summari:2,mole:0,probabl:0,rainbow:0,know:[0,2,3],contest:[2,4],unalias:[],sexual:2,growth_tim:2,detail:[2,3],"default":[0,2,3],bulbasaur:0,bracket:2,lookup:3,whip:0,pokemon_form_pokeathlon_stat:2,typeefficaci:[2,4],first_move_id:2,capture_r:2,petal:0,pichu:0,stat:[2,4],potion:0,intend:0,determin:2,"class":[0,2],time:[2,3],sqlalchemi:[0,2,3],encounter_condition_id:2,affix:2,poffin:2,introduced_in_version_group_id:2,hatch_count:2,kinda:2,sql:0,leaf:0,debian:[1,3],location_area_pros:2,outdat:3,pokemonform:[2,4],longer:2,move_meta_categori:2,super_contest_effect_pros:2,pokemon_stat:2,damage_factor:2,kilogram:2,tricki:0,pirouett:0,potenti:2,item_category_pros:2,fresh:0},objtypes:{"0":"py:module","1":"py:dex-table","2":"py:data"},titles:["Using pokedex","The pokedex documentation","The pok\u00e9dex tables","Installing the pokedex library","The database schema"],objnames:{"0":"Python module","1":"dex-table","2":"Python data"},filenames:["usage","index","main-tables","installing","schema"]}) \ No newline at end of file diff --git a/usage.html b/usage.html new file mode 100644 index 0000000..888557e --- /dev/null +++ b/usage.html @@ -0,0 +1,386 @@ + + + + + + + + + Using pokedex — pokedex v0.1 documentation + + + + + + + + + + + + + +
+
+
+
+ +
+

Using pokedex

+

The pokédex is, first and foremost, a Python library. To get the most of it, +you’ll need to learn `Python`_ and `SQLAlchemy`_.

+

Here is a small example of using pokedex:

+
from pokedex.db import connect, tables, util
+session = connect()
+pokemon = util.get(session, tables.PokemonSpecies, 'bulbasaur')
+print u'{0.name}, the {0.genus} Pokemon'.format(pokemon)
+
+
+

Running this will give you some Bulbasaur info:

+
Bulbasaur, the Seed Pokemon
+
+
+
+

Connecting

+

To get information out of the Pokédex, you will need to create a +Session. To do that, use +pokedex.db.connect(). For simple uses, you don’t need to give it any +arguments: it the database that pokedex load fills up by default. If you +need to select another database, give its URI as the first argument.

+

The object connect() gives you is actually a +sqlalchemy.orm.session.Session, giving you the +full power of SQLAlchemy for working with the data. We’ll cover some basics +here, but if you intend to do some serious work, do read SQLAlchemy’s docs.

+

XXX: write the rest of this

+

..:

+
Pokédex tables
+--------------
+
+Data in the pokédex is organized in tables, defined in
+:mod:`pokedex.db.tables`.
+There is quite a few or them. To get you started, here are a few common ones:
+
+* :class:`~pokedex.db.tables.Pokemon` (includes some alternate forms)
+* :class:`~pokedex.db.tables.Move`
+* :class:`~pokedex.db.tables.Item`
+* :class:`~pokedex.db.tables.Type`
+
+Getting things
+--------------
+
+If you know what you want from the pokédex, you can use the
+:func:`pokedex.db.util.get` function. It looks up a thing in a table, based on
+its identifier, name, or ID, and returns it.
+
+.. testcode::
+
+    def print_pokemon(pokemon):
+        print u'{0.name}, the {0.genus} Pokemon'.format(pokemon)
+
+    print_pokemon(util.get(session, tables.PokemonSpecies, identifier='eevee'))
+    print_pokemon(util.get(session, tables.PokemonSpecies, name=u'Ho-Oh'))
+    print_pokemon(util.get(session, tables.PokemonSpecies, id=50))
+
+    def print_item(item):
+        print u'{0.name}: ${0.cost}'.format(item)
+
+    print_item(util.get(session, tables.Item, identifier='great-ball'))
+    print_item(util.get(session, tables.Item, name='Potion'))
+    print_item(util.get(session, tables.Item, id=30))
+
+.. testoutput::
+
+    Eevee, the Evolution Pokemon
+    Ho-Oh, the Rainbow Pokemon
+    Diglett, the Mole Pokemon
+    Great Ball: $600
+    Potion: $300
+    Fresh Water: $200
+
+.. :
+    Simple lists
+    ------------
+
+    .. note::
+
+        These functions are only included for convenience in experiments and simple
+        scripts.
+        If you want to do something specific, please query the pokédex as explained
+        in the following sections.
+
+    If you want to get a simple list of pokémon without needing to worry about
+    things like the different forms and sorting the list, you can use the
+    :func:`pokedex.util.simple.pokemon` function.
+
+    .. testcode::
+
+        from pokedex.util import simple
+        for pokemon in simple.pokemon(session):
+            print u'{0.name}, the {0.species} Pokemon'.format(pokemon)
+
+    .. testoutput::
+
+        Bulbasaur, the Seed Pokemon
+        Ivysaur, the Seed Pokemon
+        ...
+        Meloetta, the Melody Pokemon
+        Genesect, the Paleozoic Pokemon
+
+    Similar functions exist for :func:`~pokedex.util.simple.moves`,
+    :func:`~pokedex.util.simple.items` and :func:`~pokedex.util.simple.types`.
+
+    All of these give you quick simple lists, basically something a pokédex would
+    show you. They filter out things you probably won't need (such as Shadow moves
+    or duplicate Pokémon moves), and sort the results in some sane way, but they
+    can't guess your needs exactly, and their guesses might change in future
+    versions.
+    If you want to do some serious work with the pokédex, read on.
+
+    Querying
+    --------
+
+    So, how do you get data from the session? You use the session's
+    :meth:`~sqlalchemy.orm.session.Session.query` method, and give it a pokédex
+    Table as an argument. This will give you a :class:`SQLAlchemy query
+    <sqlalchemy.orm.query.Query>`.
+
+    To get you started, we'll cover some common query operations below. If you
+    need to do more, consult the `SQLAlchemy documentation`_.
+
+    Ordering
+    ^^^^^^^^
+
+    As always with SQL, you should not rely on query results being in some
+    particular order – unless you have ordered the query first. This means that
+    you'll likely want to sort every query you will make.
+
+    For example, you can get a list of all pokémon, sorted by their
+    :attr:`~pokedex.db.tables.Pokemon.order`, like so:
+
+    .. testcode::
+
+        for pokemon in session.query(tables.Pokemon).order_by(tables.Pokemon.order):
+            print pokemon.name
+
+    .. testoutput::
+
+        Bulbasaur
+        Ivysaur
+        Venusaur
+        Charmander
+        Charmeleon
+        ...
+        Pichu
+        Pikachu
+        Raichu
+        ...
+        Keldeo
+        Aria Meloetta
+        Pirouette Meloetta
+        Genesect
+
+    Ordering by name
+    ****************
+
+    Since the pokédex can be used in other languages than English, working with
+    texts such as names is sometimes tricky.
+
+    The “name” attribute is actually a relation that uses the connection's
+    default language to select an appropriate translation. It usually works the
+    same way as a normal attribute, but ordering is an exception to this:
+
+    .. testcode::
+
+        for pokemon in session.query(tables.Pokemon).order_by(tables.Pokemon.name):
+            print pokemon.name
+
+    .. testoutput::
+
+        Traceback (most recent call last):
+            ...
+        ArgumentError: SQL expression object or string expected.
+
+    This means that to order by name, you either have to explicitly join the
+    translation table and sort by that, or use
+    :func:`pokedex.db.util.order_by_name`:
+
+
+    .. testcode::
+
+        from pokedex.db import util
+        for pokemon in util.order_by_name(session.query(tables.Pokemon), tables.Pokemon):
+            print pokemon.name
+
+    .. testoutput::
+
+        Abomasnow
+        ...
+        Zweilous
+
+    Filtering
+    ^^^^^^^^^
+
+    Another major operation on queries is filtering, using the query's
+    :meth:`~sqlalchemy.orm.query.Query.filter` or
+    :meth:`~sqlalchemy.orm.query.Query.filter_by` methods:
+
+    .. testcode::
+
+        for move in session.query(tables.Move).filter(tables.Move.power > 200):
+            print move.name
+
+    .. testoutput::
+
+        Explosion
+
+    Joining
+    ^^^^^^^
+
+    The final operation we'll cover here is joining other tables to the query,
+    using the query's :meth:`~sqlalchemy.orm.query.Query.join`.
+    You will usually want to join on a relationship, such as in the following
+    example:
+
+    .. testcode::
+
+        query = session.query(tables.Move)
+        query = query.join(tables.Move.type)
+        query = query.filter(tables.Type.identifier == 'grass')
+        query = query.filter(tables.Move.power >= 100)
+        query = query.order_by(tables.Move.power)
+        query = util.order_by_name(query, tables.Move)
+
+        print 'The most powerful Grass moves:'
+        for move in query:
+            print u'{0.name} ({0.power})'.format(move)
+
+    .. testoutput::
+
+        The most powerful Grass moves:
+        Petal Dance (120)
+        Power Whip (120)
+        Seed Flare (120)
+        SolarBeam (120)
+        Wood Hammer (120)
+        Leaf Storm (140)
+        Frenzy Plant (150)
+
+
+    API documentation
+    -----------------
+
+    .. autofunction:: pokedex.db.connect
+
+        See :class:`sqlalchemy.orm.session.Session` for more documentation on the
+        returned object.
+
+    .. autofunction:: pokedex.db.util.get
+    .. autofunction:: pokedex.db.util.order_by_name
+
+    Simple lists
+    ^^^^^^^^^^^^
+
+    .. autofunction:: pokedex.util.simple.pokemon
+    .. autofunction:: pokedex.util.simple.moves
+    .. autofunction:: pokedex.util.simple.items
+    .. autofunction:: pokedex.util.simple.types
+
+
+    .. _Python: http://www.python.org
+    .. _SQLAlchemy: http://www.sqlalchemy.org
+    .. _`SQLAlchemy documentation`: http://www.sqlalchemy.org/docs/orm/tutorial.html
+
+
+
+ + +
+
+
+
+
+

Table Of Contents

+ + +

Previous topic

+

Installing the pokedex library

+

Next topic

+

The database schema

+

This Page

+ + + +
+
+
+
+ + + + \ No newline at end of file