├── requirements.in ├── tests ├── inputs │ ├── snake.gif │ ├── subdir │ │ └── means.js │ ├── rainbow.png │ ├── fibonacci.js │ ├── basic.html │ ├── scripts_external.html │ ├── styles_inline.html │ ├── styles_uris.html │ └── scripts_inline.html ├── expected │ ├── basic.html │ ├── styles_inline.html │ ├── scripts_external.html │ ├── scripts_inline.html │ └── styles_uris.html ├── test_special_cases.py ├── test_archiver.py ├── conftest.py └── fixtures │ └── cassettes │ └── special_cases.json ├── requirements.txt ├── tox.ini ├── .travis.yml ├── LICENSE ├── setup.py ├── .gitignore ├── README.rst └── html_archiver.py /requirements.in: -------------------------------------------------------------------------------- 1 | beautifulsoup4 2 | requests 3 | requests_toolbelt 4 | -------------------------------------------------------------------------------- /tests/inputs/snake.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexwlchan/html-archiver/master/tests/inputs/snake.gif -------------------------------------------------------------------------------- /tests/inputs/subdir/means.js: -------------------------------------------------------------------------------- 1 | function arithmetic_mean(x, y, z) { 2 | return (x + y + z) / 3; 3 | } 4 | -------------------------------------------------------------------------------- /tests/inputs/rainbow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexwlchan/html-archiver/master/tests/inputs/rainbow.png -------------------------------------------------------------------------------- /tests/inputs/fibonacci.js: -------------------------------------------------------------------------------- 1 | function fibonacci(n) { 2 | if ((n == 1) || (n == 2)) { 3 | return 1; 4 | } else { 5 | return fibonacci(n - 1) + fibonacci(n - 2); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is autogenerated by pip-compile 3 | # To update, run: 4 | # 5 | # pip-compile --output-file requirements.txt requirements.in 6 | # 7 | beautifulsoup4==4.5.3 8 | requests-toolbelt==0.7.1 9 | requests==2.13.0 10 | -------------------------------------------------------------------------------- /tests/expected/basic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a basic page 6 | 7 | 8 | 9 |

This is a page which should be unmodified by html-archiver.

10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/inputs/basic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a basic page 6 | 7 | 8 | 9 |

This is a page which should be unmodified by html-archiver.

10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py27, py33, py34, py35, py36, lint 3 | 4 | [testenv] 5 | deps = 6 | betamax>=0.8.0,<1 7 | pytest>=3.0.7,<4 8 | commands = py.test {toxinidir}/tests/ 9 | 10 | [testenv:lint] 11 | basepython = python3.6 12 | deps = flake8 13 | commands = flake8 --max-complexity 10 archiver.py tests 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | sudo: false 3 | 4 | cache: 5 | directories: 6 | - $HOME/.cache/pip 7 | 8 | matrix: 9 | include: 10 | - python: "3.6" 11 | env: TOXENV=lint 12 | - python: "2.7" 13 | env: TOXENV=py27 14 | - python: "3.3" 15 | env: TOXENV=py33 16 | - python: "3.4" 17 | env: TOXENV=py34 18 | - python: "3.5" 19 | env: TOXENV=py35 20 | - python: "3.6" 21 | env: TOXENV=py36 22 | 23 | script: 24 | - tox -e $TOXENV 25 | 26 | install: 27 | - "pip install -U pip setuptools" 28 | - "pip install -U tox" 29 | -------------------------------------------------------------------------------- /tests/inputs/scripts_external.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a page with external scripts 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |

This is a page to test how html-archiver handles external scripts.

19 | 20 |

External scripts should always be inlined if possible.

21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/test_special_cases.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 2 | """ 3 | This test makes requests to real web pages (or rather, betamax copies 4 | of them) and tests the archiver behaviour. 5 | """ 6 | 7 | 8 | def test_marco_org_encoding_is_correct(betamax_archiver): 9 | """ 10 | Test that the encoding is inferred correctly on marco.org. 11 | 12 | There was a bug (#15) where the page was read as Latin-1, even though 13 | the page had a tag specifying a UTF-8 charset. This meant the 14 | permalink wouldn't render as an infinity-symbol, but as special chars. 15 | Check we do it correctly. 16 | """ 17 | html = betamax_archiver.archive_url('https://marco.org/2017/04/15/mac-pro-audacity-of-yes') # noqa 18 | assert u'∞' in html 19 | -------------------------------------------------------------------------------- /tests/expected/styles_inline.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a page with inline styles 6 | 7 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |

This is a page to test how html-archiver handles inline styles.

23 | 24 |

These inline styles do not refer to external resources, so they should be left unmodified.

25 | 26 |

This text is orange.

27 | 28 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/inputs/styles_inline.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a page with inline styles 6 | 7 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |

This is a page to test how html-archiver handles inline styles.

23 | 24 |

These inline styles do not refer to external resources, so they should be left unmodified.

25 | 26 |

This text is orange.

27 | 28 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/expected/scripts_external.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a page with external scripts 6 | 7 | 8 | 17 | 18 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |

This is a page to test how html-archiver handles external scripts.

31 | 32 |

External scripts should always be inlined if possible.

33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /tests/inputs/styles_uris.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a page with styles that call out to uri resources 6 | 7 | 8 | 11 | 12 | 13 | 16 | 17 | 18 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 |

This is a page to test how html-archiver handles styles that use external resources.

31 | 32 |

Anything with a url() that can be accessed should be inlined and base64-encoded.

33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017 Alex Chan 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /tests/inputs/scripts_inline.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a page with inline scripts 6 | 7 | 8 | 9 | 12 | 13 | 16 | 17 | 20 | 21 | 22 | 23 | 24 |

This is a page to test how html-archiver handles inline scripts.

25 | 26 |

Because inline scripts do not refer to external resources, they should always be left unmodified.

27 | 28 | 29 | 30 | 33 | 34 | 37 | 38 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /tests/expected/scripts_inline.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a page with inline scripts 6 | 7 | 8 | 9 | 12 | 13 | 16 | 17 | 20 | 21 | 22 | 23 | 24 |

This is a page to test how html-archiver handles inline scripts.

25 | 26 |

Because inline scripts do not refer to external resources, they should always be left unmodified.

27 | 28 | 29 | 30 | 33 | 34 | 37 | 38 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /tests/test_archiver.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- encoding: utf-8 3 | 4 | import glob 5 | import os 6 | 7 | import pytest 8 | 9 | 10 | TEST_DIR = os.path.dirname(os.path.abspath(__file__)) 11 | INPUT_DIR = os.path.join(TEST_DIR, 'inputs') 12 | EXPECTED_DIR = os.path.join(TEST_DIR, 'expected') 13 | 14 | 15 | def test_cases(): 16 | return [ 17 | p[len('%s/' % INPUT_DIR):] 18 | for p in (glob.glob('%s/*.html' % INPUT_DIR) + 19 | glob.glob('%s/**/*.html' % INPUT_DIR)) 20 | ] 21 | 22 | 23 | @pytest.mark.parametrize('input_path', test_cases()) 24 | def test_archiver_is_correct(archiver, input_path): 25 | url = 'file:///%s' % input_path 26 | out = '%s/%s.html' % (EXPECTED_DIR, os.path.splitext(input_path)[0]) 27 | 28 | assert archiver.archive_url(url) == open(out).read() 29 | 30 | 31 | @pytest.mark.parametrize('status_code', [400, 401, 404, 500]) 32 | def test_archive_throws_runtimeerror_for_unknown_url(archiver, status_code): 33 | """ 34 | Trying to look up a page that returns a non-200 status code is an error. 35 | """ 36 | with pytest.raises(RuntimeError): 37 | archiver.archive_url('http://httpstat.us/%d' % status_code) 38 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import sys 6 | import codecs 7 | 8 | from setuptools import setup 9 | 10 | here = os.path.dirname(os.path.abspath(__file__)) 11 | 12 | with codecs.open('README.rst', encoding='utf-8') as f: 13 | long_description = f.read() 14 | 15 | if sys.argv[-1] == "publish": 16 | os.system("python setup.py sdist bdist_wheel upload") 17 | sys.exit() 18 | 19 | setup( 20 | name='html-archiver', 21 | version='0.1.0', 22 | description='Creating self-contained HTML archives of webpages', 23 | long_description=long_description, 24 | author='Alex Chan', 25 | author_email='alex@alexwlchan.net', 26 | url='https://github.com/alexwlchan/html-archiver', 27 | py_modules=['html_archiver'], 28 | install_requires=[ 29 | 'beautifulsoup4>=4.5.3,<5', 30 | 'requests>=2.13.0,<3', 31 | 'requests-toolbelt>=0.7.1,<1', 32 | ], 33 | license='MIT', 34 | classifiers=( 35 | 'Development Status :: 4 - Beta', 36 | 'Programming Language :: Python :: 2.7', 37 | 'Programming Language :: Python :: 3.3', 38 | 'Programming Language :: Python :: 3.4', 39 | 'Programming Language :: Python :: 3.5', 40 | 'Programming Language :: Python :: 3.6', 41 | 'Topic :: Internet :: WWW/HTTP :: Indexing/Search', 42 | 'Topic :: System :: Archiving :: Backup', 43 | 'Topic :: System :: Archiving', 44 | ), 45 | ) 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/osx,python 3 | 4 | ### OSX ### 5 | *.DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | 9 | # Icon must end with two \r 10 | Icon 11 | 12 | 13 | # Thumbnails 14 | ._* 15 | 16 | # Files that might appear in the root of a volume 17 | .DocumentRevisions-V100 18 | .fseventsd 19 | .Spotlight-V100 20 | .TemporaryItems 21 | .Trashes 22 | .VolumeIcon.icns 23 | .com.apple.timemachine.donotpresent 24 | 25 | # Directories potentially created on remote AFP share 26 | .AppleDB 27 | .AppleDesktop 28 | Network Trash Folder 29 | Temporary Items 30 | .apdisk 31 | 32 | ### Python ### 33 | # Byte-compiled / optimized / DLL files 34 | __pycache__/ 35 | *.py[cod] 36 | *$py.class 37 | 38 | # C extensions 39 | *.so 40 | 41 | # Distribution / packaging 42 | .Python 43 | env/ 44 | build/ 45 | develop-eggs/ 46 | dist/ 47 | downloads/ 48 | eggs/ 49 | .eggs/ 50 | lib/ 51 | lib64/ 52 | parts/ 53 | sdist/ 54 | var/ 55 | wheels/ 56 | *.egg-info/ 57 | .installed.cfg 58 | *.egg 59 | 60 | # PyInstaller 61 | # Usually these files are written by a python script from a template 62 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 63 | *.manifest 64 | *.spec 65 | 66 | # Installer logs 67 | pip-log.txt 68 | pip-delete-this-directory.txt 69 | 70 | # Unit test / coverage reports 71 | htmlcov/ 72 | .tox/ 73 | .coverage 74 | .coverage.* 75 | .cache 76 | nosetests.xml 77 | coverage.xml 78 | *,cover 79 | .hypothesis/ 80 | 81 | # Translations 82 | *.mo 83 | *.pot 84 | 85 | # Django stuff: 86 | *.log 87 | local_settings.py 88 | 89 | # Flask stuff: 90 | instance/ 91 | .webassets-cache 92 | 93 | # Scrapy stuff: 94 | .scrapy 95 | 96 | # Sphinx documentation 97 | docs/_build/ 98 | 99 | # PyBuilder 100 | target/ 101 | 102 | # Jupyter Notebook 103 | .ipynb_checkpoints 104 | 105 | # pyenv 106 | .python-version 107 | 108 | # celery beat schedule file 109 | celerybeat-schedule 110 | 111 | # SageMath parsed files 112 | *.sage.py 113 | 114 | # dotenv 115 | .env 116 | 117 | # virtualenv 118 | .venv 119 | venv/ 120 | ENV/ 121 | 122 | # Spyder project settings 123 | .spyderproject 124 | 125 | # Rope project settings 126 | .ropeproject 127 | 128 | # End of https://www.gitignore.io/api/osx,python 129 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 2 | 3 | import os 4 | 5 | try: 6 | from urllib.request import url2pathname 7 | except ImportError: 8 | from urllib import url2pathname 9 | 10 | from betamax import Betamax 11 | import requests 12 | import pytest 13 | 14 | from html_archiver import HTMLArchiver 15 | 16 | 17 | @pytest.fixture 18 | def archiver(): 19 | sess = requests.session() 20 | sess.mount('file://', LocalFileAdapter()) 21 | return HTMLArchiver(sess=sess) 22 | 23 | 24 | with Betamax.configure() as config: 25 | config.cassette_library_dir = 'tests/fixtures/cassettes' 26 | 27 | 28 | @pytest.fixture 29 | def betamax_archiver(): 30 | sess = requests.Session() 31 | with Betamax(sess).use_cassette('special_cases'): 32 | yield HTMLArchiver(sess=sess) 33 | 34 | 35 | class LocalFileAdapter(requests.adapters.BaseAdapter): 36 | """Protocol Adapter to allow Requests to GET file:// URLs 37 | 38 | @todo: Properly handle non-empty hostname portions. 39 | """ 40 | # http://stackoverflow.com/a/27786580/1558022 41 | 42 | @staticmethod 43 | def _chkpath(method, path): 44 | """Return an HTTP status for the given filesystem path.""" 45 | if method.lower() in ('put', 'delete'): 46 | return 501, "Not Implemented" # TODO 47 | elif method.lower() not in ('get', 'head'): 48 | return 405, "Method Not Allowed" 49 | elif os.path.isdir(path): 50 | return 400, "Path Not A File" 51 | elif not os.path.isfile(path): 52 | return 404, "File Not Found" 53 | elif not os.access(path, os.R_OK): 54 | return 403, "Access Denied" 55 | else: 56 | return 200, "OK" 57 | 58 | def send(self, req, **kwargs): # pylint: disable=unused-argument 59 | """Return the file specified by the given request 60 | 61 | @type req: C{PreparedRequest} 62 | @todo: Should I bother filling `response.headers` and processing 63 | If-Modified-Since and friends using `os.stat`? 64 | """ 65 | path = os.path.normcase(os.path.normpath(url2pathname(req.path_url))) 66 | path = os.path.join( 67 | os.path.dirname(os.path.abspath(__file__)), 'inputs', 68 | path.lstrip('/')) 69 | response = requests.Response() 70 | 71 | response.status_code, response.reason = self._chkpath(req.method, path) 72 | if response.status_code == 200 and req.method.lower() != 'head': 73 | try: 74 | response.raw = open(path, 'rb') 75 | except (OSError, IOError) as err: 76 | response.status_code = 500 77 | response.reason = str(err) 78 | 79 | if isinstance(req.url, bytes): 80 | response.url = req.url.decode('utf-8') 81 | else: 82 | response.url = req.url 83 | 84 | response.request = req 85 | response.connection = self 86 | 87 | return response 88 | 89 | def close(self): 90 | pass 91 | -------------------------------------------------------------------------------- /tests/expected/styles_uris.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a page with styles that call out to uri resources 6 | 7 | 8 | 11 | 12 | 13 | 16 | 17 | 18 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 |

This is a page to test how html-archiver handles styles that use external resources.

31 | 32 |

Anything with a url() that can be accessed should be inlined and base64-encoded.

33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | html-archiver 2 | ============= 3 | 4 | html-archiver is a Python module for creating a self-contained HTML archive 5 | of a web page. It inlines everything on the page – CSS, JavaScript, images – 6 | so you have an entire copy of the page in a single file. 7 | 8 | For a while I've used the `page archiving tool`_ on Pinboard, which takes a 9 | similar approach: inline CSS and JavaScript, grab a local copy of images, 10 | base64-encode certain elements. I wrote this because I wanted a couple of 11 | extra features: 12 | 13 | * A tool that didn't rely on a third-party service 14 | * Support for saving resources in ``url()`` values in CSS (e.g. webfonts) 15 | * A single-page output -- Pinboard saves images as separate files, and serves 16 | them alongside the HTML 17 | 18 | It isn't perfect -- if you want a true archival copy, you'd be better off 19 | saving all the resources individually, and mimicing the web server layout -- 20 | but this is really aimed at making quick and cheap copies. 21 | 22 | .. _page archiving tool: https://pinboard.in/tour/#archive 23 | 24 | Usage 25 | ***** 26 | 27 | It can be invoked from the command line: 28 | 29 | .. code-block:: console 30 | 31 | $ python3 html_archiver.py "http://example.org/foo/bar" 32 | 33 | or from Python: 34 | 35 | .. code-block:: python 36 | 37 | from html_archiver import HTMLArchiver 38 | 39 | a = HTMLArchiver() 40 | a.archive_url("http://example.org/foo/bar") 41 | 42 | Features 43 | ******** 44 | 45 | html-archiver attempts to produce a self-contained HTML archive. As well 46 | as downloading the HTML from a page, it: 47 | 48 | * Downloads any CSS and JavaScript dependencies. For example, the following: 49 | 50 | .. code-block:: html 51 | 52 | 53 | 54 | 55 | 56 | would be replaced with: 57 | 58 | .. code-block:: html 59 | 60 | 63 | 64 | 67 | 68 | * Replaces any images with base64-encoded `data URIs`_. For example, the 69 | following: 70 | 71 | .. code-block:: html 72 | 73 | 74 | 75 | would be replaced with: 76 | 77 | .. code-block:: html 78 | 79 | 80 | 81 | **Note:** This only works for images supplied in the ``src`` attribute; 82 | the ``srcset`` attribute is not supported. See `issue #1`_ 83 | 84 | * Any CSS rules that have a ``url()`` value are also replaced with 85 | base64-encoded data URIs. 86 | 87 | * For pages that require login, you can pass a custom ``Session`` object 88 | with appropriate cookies to ``HTMLArchiver``, and it will use that session 89 | to download the page. For example: 90 | 91 | .. code-block:: python 92 | 93 | from archiver import HTMLArchiver 94 | from requests import Session 95 | 96 | sess = Session() 97 | sess.post('https://example.org/login', auth=('username', 'password')) 98 | 99 | archiver = HTMLArchiver(sess=sess) 100 | archiver.archive('https://example.org/logged_in_page') 101 | 102 | .. _data URIs: https://en.wikipedia.org/wiki/Data_URI_scheme 103 | .. _issue #1: https://github.com/alexwlchan/html-archiver/issues/1 104 | 105 | Installation 106 | ************ 107 | 108 | Clone this repository and install dependencies with pip: 109 | 110 | .. code-block:: console 111 | 112 | $ git clone https://github.com/alexwlchan/html-archiver.git 113 | $ cd html-archiver 114 | $ virtualenv env 115 | $ source env/bin/activate 116 | $ pip install -r requirements.txt 117 | 118 | I develop and test against Python 2.7 and Python 3.3+. 119 | 120 | Issues 121 | ****** 122 | 123 | If you find a bug, or a page that html-archiver misinterprets, please file an 124 | issue `on the GitHub repo`_. 125 | 126 | .. _on the GitHub repo: https://github.com/alexwlchan/html-archiver/issues/new 127 | 128 | 129 | License 130 | ******* 131 | 132 | MIT. 133 | -------------------------------------------------------------------------------- /html_archiver.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- encoding: utf-8 3 | 4 | import base64 5 | import cgi 6 | import os 7 | import re 8 | import sys 9 | import warnings 10 | 11 | try: 12 | from urllib.parse import urljoin, urlparse, unquote_plus 13 | except ImportError: 14 | from urllib import unquote_plus 15 | from urlparse import urljoin, urlparse 16 | 17 | from bs4 import BeautifulSoup 18 | import requests 19 | from requests_toolbelt.utils.deprecated import ( 20 | get_encodings_from_content as _get_encodings_from_content 21 | ) 22 | 23 | 24 | DATA_MEDIA_TYPES = { 25 | 'png': 'image/png', 26 | 'gif': 'image/gif', 27 | 'jpg': 'image/jpeg', 28 | 'jpeg': 'image/jpeg', 29 | 'svg': 'image/svg-xml', 30 | 'woff': 'application/font-woff', 31 | 'woff2': 'font/woff2', 32 | 'eot': 'font/eot', 33 | 'ttf': 'font/ttf', 34 | } 35 | 36 | 37 | def _get_encoding_from_headers(headers): 38 | """Returns encodings from given HTTP Header Dict. 39 | 40 | This is similar to a function in ``requests.utils``, but unlike that 41 | function, it returns ``None`` if it is unable to positively determine 42 | the encoding -- whereas requests defaults to ISO-8859-1. 43 | 44 | :param headers: dictionary to extract encoding from. 45 | """ 46 | content_type = headers.get('content-type') 47 | 48 | if content_type: 49 | _, params = cgi.parse_header(content_type) 50 | 51 | if 'charset' in params: 52 | return params['charset'].strip("'\"") 53 | 54 | 55 | class HTMLArchiver: 56 | 57 | def __init__(self, sess=None): 58 | if sess is None: 59 | self.sess = requests.Session() 60 | else: 61 | self.sess = sess 62 | 63 | #: URLs for resources we've tried to cache but failed 64 | self.bad_urls = set() 65 | 66 | #: Cached resources 67 | self.cached_resources = {} 68 | self.cached_raw_resources = {} 69 | 70 | def archive_url(self, url): 71 | """ 72 | Given a URL, return a single-page HTML archive. 73 | """ 74 | resp = self.sess.get(url) 75 | 76 | if resp.status_code != 200: 77 | raise RuntimeError( 78 | "Unable to fetch %r [%d]" % (url, resp.status_code) 79 | ) 80 | 81 | # We assume that this is an HTML page -- try to work out the 82 | # encoding. By default, requests will use data from the HTTP headers 83 | # or default to ISO-8859-1 if none is available. We should look in 84 | # the tags if we can't work out one from the headers. 85 | # 86 | # http://docs.python-requests.org/en/master/user/advanced/#encodings 87 | # TODO: Test this code. 88 | encoding = _get_encoding_from_headers(resp.headers) 89 | if encoding is None: 90 | encodings = _get_encodings_from_content(resp.text) 91 | if len(set(encodings)) > 1: 92 | raise RuntimeError( 93 | 'Conflicting encodings detected in %r' % url 94 | ) 95 | if encodings: 96 | encoding = encodings.pop() 97 | 98 | if encoding is not None: 99 | resp.encoding = encoding 100 | 101 | return self.archive_html(resp.text, base_url=url) 102 | 103 | def archive_html(self, html_string, base_url): 104 | """ 105 | Given a block of HTML, return a single-page HTML archive. 106 | """ 107 | soup = BeautifulSoup(html_string, 'html.parser') 108 | 109 | html_string = self._archive_js_scripts( 110 | html_string=html_string, 111 | soup=soup, 112 | base_url=base_url) 113 | html_string = self._archive_style_tags( 114 | html_string=html_string, 115 | soup=soup, 116 | base_url=base_url) 117 | html_string = self._archive_link_tags( 118 | html_string=html_string, 119 | soup=soup, 120 | base_url=base_url) 121 | html_string = self._archive_img_tags( 122 | html_string=html_string, 123 | soup=soup, 124 | base_url=base_url) 125 | 126 | return html_string 127 | 128 | def _get_resource(self, url): 129 | if url in self.bad_urls: 130 | return None 131 | try: 132 | return self.cached_resources[url] 133 | except KeyError: 134 | resp = self.sess.get(url, stream=True) 135 | if resp.status_code == 200: 136 | self.cached_resources[url] = resp 137 | return self.cached_resources[url] 138 | else: 139 | warnings.warn( 140 | 'Unable to fetch %r [%d]' % (url, resp.status_code) 141 | ) 142 | self.bad_urls.add(url) 143 | return None 144 | 145 | def _get_raw_resource(self, url): 146 | try: 147 | return self.cached_raw_resources[url] 148 | except KeyError: 149 | resp = self._get_resource(url) 150 | if resp is None: 151 | return None 152 | else: 153 | raw_resp = resp.raw.read() 154 | self.cached_raw_resources[url] = raw_resp 155 | return raw_resp 156 | 157 | def _get_base64_encode(self, url): 158 | extension = os.path.splitext(urlparse(url).path)[1] 159 | extension = extension[1:] # Lose the leading . 160 | try: 161 | media_type = DATA_MEDIA_TYPES[extension] 162 | except KeyError: 163 | warnings.warn('Unable to determine media_type for %r' % url) 164 | return None 165 | 166 | raw_resp = self._get_raw_resource(url) 167 | if raw_resp is None: 168 | return None 169 | encoded_string = base64.b64encode(raw_resp) 170 | return 'data:%s;base64,%s' % (media_type, encoded_string.decode()) 171 | 172 | def _archive_js_scripts(self, html_string, soup, base_url): 173 | """ 174 | Archive all the ' % ( 191 | re.escape(js_tag['src'])), html_string 192 | ) 193 | assert match is not None, js_tag['src'] 194 | 195 | new_tag = soup.new_tag(name='script') 196 | new_tag.string = '\n' + resp.text.strip() + '\n' 197 | new_tag.attrs['type'] = 'text/javascript' 198 | html_string = html_string.replace(match.group(0), str(new_tag)) 199 | assert match.group(0) not in html_string 200 | return html_string 201 | 202 | def _archive_style_tags(self, html_string, soup, base_url): 203 | """ 204 | Archive all the ' % ( 221 | re.escape(orig_css_string)), 222 | html_string, 223 | ) 224 | assert match is not None, orig_css_string 225 | html_string = html_string.replace( 226 | match.group(0), 227 | '\n' % match.group('attrs') + css_string.strip() + '\n' 228 | ) 229 | assert match.group(0) not in html_string 230 | 231 | for desc in soup.descendants: 232 | try: 233 | if desc.attrs.get('style') is None: 234 | continue 235 | except AttributeError: 236 | continue 237 | orig_css_string = desc.attrs['style'] 238 | css_string = self.archive_css(orig_css_string, base_url=base_url) 239 | if orig_css_string != css_string: 240 | match = re.search( 241 | r'style=(?P[\'"]?)%s(?P=quot)' % ( 242 | re.escape(orig_css_string)), html_string 243 | ) 244 | assert match is not None, orig_css_string 245 | html_string = html_string.replace( 246 | match.group(0), 'style=%s%s%s' % ( 247 | match.group('quot'), css_string, match.group('quot'))) 248 | assert match.group(0) not in html_string 249 | 250 | return html_string 251 | 252 | def _archive_link_tags(self, html_string, soup, base_url): 253 | """ 254 | Archive all the tags in a soup. 255 | """ 256 | desired_attrs = { 257 | 'rel': 'stylesheet', 258 | 'type': 'text/css', 259 | } 260 | for link_tag in soup.find_all('link', attrs=desired_attrs): 261 | if link_tag.get('href') is None: 262 | continue 263 | 264 | style_tag = soup.new_tag(name='style') 265 | resource_url = urljoin(base_url, link_tag['href']) 266 | 267 | resp = self._get_resource(resource_url) 268 | if resp is None: 269 | continue 270 | 271 | css_string = resp.text.strip() 272 | css_string = self.archive_css(css_string, 273 | base_url=resource_url) 274 | 275 | match = re.search( 276 | r'[\'"]?)%s(?P=quot)[^>]*>' % ( 277 | re.escape(link_tag['href'])), html_string 278 | ) 279 | assert match is not None, link_tag['href'] 280 | style_tag.string = '\n' + css_string + '\n' 281 | html_string = html_string.replace(match.group(0), str(style_tag)) 282 | assert match.group(0) not in html_string 283 | 284 | return html_string 285 | 286 | def _archive_img_tags(self, html_string, soup, base_url): 287 | """ 288 | Archive all the tags in a soup. 289 | """ 290 | for img_tag in soup.find_all('img'): 291 | if img_tag.get('src') is None: 292 | continue 293 | 294 | resource_url = urljoin(base_url, img_tag['src']) 295 | data = self._get_base64_encode(resource_url) 296 | 297 | match = re.search( 298 | r'[\'"]?)%s(?P=quot)[^>]*>' % ( 299 | re.escape(img_tag['src'])), html_string 300 | ) 301 | assert match is not None, img_tag['src'] 302 | img_tag['src'] = data 303 | html_string = html_string.replace(match.group(0), str(img_tag)) 304 | assert match.group(0) not in html_string 305 | return html_string 306 | 307 | def archive_css(self, css_string, base_url): 308 | """ 309 | Given a block of CSS, find any instances of the `url()` data type 310 | that refer to remote resources and replace them with 311 | a base64-encoded data URI. 312 | """ 313 | # It would be nice to do this with a proper CSS parser, but all the 314 | # ones I've tried are missing modern CSS features, e.g. ignore URIs in 315 | # a @font-face rule. 316 | for match in re.finditer(r'url\((?P[^\)]+)\)', css_string): 317 | resource_url = match.group('url') 318 | resource_url = resource_url.strip('"').strip("'") 319 | 320 | # Something to do with SVG resources that are identified elsewhere 321 | # in the stylesheet 322 | resource_url = unquote_plus(resource_url) 323 | if resource_url.startswith('#'): 324 | continue 325 | 326 | # Any existing data: URIs are already self-contained and don't 327 | # need changing. 328 | if resource_url.startswith('data:'): 329 | continue 330 | 331 | # Determine the media type for the data: URI 332 | resource_url = urljoin(base_url, resource_url) 333 | data = self._get_base64_encode(resource_url) 334 | if data is not None: 335 | css_string = css_string.replace(match.group('url'), data) 336 | 337 | return css_string 338 | 339 | 340 | if __name__ == '__main__': 341 | if len(sys.argv) != 2: 342 | sys.exit('Usage: %s ' % os.path.basename(__file__)) 343 | archiver = HTMLArchiver() 344 | print(archiver.archive_url(sys.argv[1])) 345 | -------------------------------------------------------------------------------- /tests/fixtures/cassettes/special_cases.json: -------------------------------------------------------------------------------- 1 | {"http_interactions": [{"request": {"method": "GET", "body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": ["gzip, deflate"], "Accept": ["*/*"], "User-Agent": ["python-requests/2.13.0"], "Connection": ["keep-alive"]}, "uri": "https://marco.org/2017/04/15/mac-pro-audacity-of-yes"}, "response": {"status": {"message": "OK", "code": 200}, "body": {"base64_string": "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", "encoding": "ISO-8859-1"}, "headers": {"Content-Encoding": ["gzip"], "Connection": ["close"], "Content-Length": ["5780"], "Vary": ["Accept-Encoding"], "Date": ["Mon, 17 Apr 2017 08:17:28 GMT"], "Content-Type": ["text/html"], "Last-Modified": ["Sun, 16 Apr 2017 09:24:22 GMT"], "ETag": ["\"3a03-54d453d6b6bde-gzip\""], "Server": ["Apache"], "Accept-Ranges": ["bytes"]}, "url": "https://marco.org/2017/04/15/mac-pro-audacity-of-yes"}, "recorded_at": "2017-04-17T08:17:28"}, {"request": {"method": "GET", "body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": ["gzip, deflate"], "Accept": ["*/*"], "User-Agent": ["python-requests/2.13.0"], "Connection": ["keep-alive"]}, "uri": "https://marco.org/jquery-and-bigfoot.js"}, "response": {"status": {"message": "OK", "code": 200}, "body": {"string": "(function(e,undefined){var t,n,r=typeof undefined,i=e.location,o=e.document,s=o.documentElement,a=e.jQuery,u=e.$,l={},c=[],p=\"2.0.3\",f=c.concat,h=c.push,d=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,x=function(e,n){return new x.fn.init(e,n,t)},b=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,w=/\\S+/g,T=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,C=/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,k=/^-ms-/,N=/-([\\da-z])/gi,E=function(e,t){return t.toUpperCase()},S=function(){o.removeEventListener(\"DOMContentLoaded\",S,!1),e.removeEventListener(\"load\",S,!1),x.ready()};x.fn=x.prototype={jquery:p,constructor:x,init:function(e,t,n){var r,i;if(!e)return this;if(\"string\"==typeof e){if(r=\"<\"===e.charAt(0)&&\">\"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:T.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof x?t[0]:t,x.merge(this,x.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:o,!0)),C.test(r[1])&&x.isPlainObject(t))for(r in t)x.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return i=o.getElementById(r[2]),i&&i.parentNode&&(this.length=1,this[0]=i),this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?n.ready(e):(e.selector!==undefined&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:\"\",length:0,toArray:function(){return d.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,t,n,r,i,o,s=arguments[0]||{},a=1,u=arguments.length,l=!1;for(\"boolean\"==typeof s&&(l=s,s=arguments[1]||{},a=2),\"object\"==typeof s||x.isFunction(s)||(s={}),u===a&&(s=this,--a);u>a;a++)if(null!=(e=arguments[a]))for(t in e)n=s[t],r=e[t],s!==r&&(l&&r&&(x.isPlainObject(r)||(i=x.isArray(r)))?(i?(i=!1,o=n&&x.isArray(n)?n:[]):o=n&&x.isPlainObject(n)?n:{},s[t]=x.extend(l,o,r)):r!==undefined&&(s[t]=r));return s},x.extend({expando:\"jQuery\"+(p+Math.random()).replace(/\\D/g,\"\"),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=a),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){(e===!0?--x.readyWait:x.isReady)||(x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(o,[x]),x.fn.trigger&&x(o).trigger(\"ready\").off(\"ready\")))},isFunction:function(e){return\"function\"===x.type(e)},isArray:Array.isArray,isWindow:function(e){return null!=e&&e===e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?l[m.call(e)]||\"object\":typeof e},isPlainObject:function(e){if(\"object\"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!y.call(e.constructor.prototype,\"isPrototypeOf\"))return!1}catch(t){return!1}return!0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||\"string\"!=typeof e)return null;\"boolean\"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:JSON.parse,parseXML:function(e){var t,n;if(!e||\"string\"!=typeof e)return null;try{n=new DOMParser,t=n.parseFromString(e,\"text/xml\")}catch(r){t=undefined}return(!t||t.getElementsByTagName(\"parsererror\").length)&&x.error(\"Invalid XML: \"+e),t},noop:function(){},globalEval:function(e){var t,n=eval;e=x.trim(e),e&&(1===e.indexOf(\"use strict\")?(t=o.createElement(\"script\"),t.text=e,o.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(k,\"ms-\").replace(N,E)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,s=j(e);if(n){if(s){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(s){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:function(e){return null==e?\"\":v.call(e)},makeArray:function(e,t){var n=t||[];return null!=e&&(j(Object(e))?x.merge(n,\"string\"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:g.call(t,e,n)},merge:function(e,t){var n=t.length,r=e.length,i=0;if(\"number\"==typeof n)for(;n>i;i++)e[r++]=t[i];else while(t[i]!==undefined)e[r++]=t[i++];return e.length=r,e},grep:function(e,t,n){var r,i=[],o=0,s=e.length;for(n=!!n;s>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,s=j(e),a=[];if(s)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(a[a.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(a[a.length]=r);return f.apply([],a)},guid:1,proxy:function(e,t){var n,r,i;return\"string\"==typeof t&&(n=e[t],t=e,e=n),x.isFunction(e)?(r=d.call(arguments,2),i=function(){return e.apply(t||this,r.concat(d.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):undefined},access:function(e,t,n,r,i,o,s){var a=0,u=e.length,l=null==n;if(\"object\"===x.type(n)){i=!0;for(a in n)x.access(e,t,a,n[a],!0,o,s)}else if(r!==undefined&&(i=!0,x.isFunction(r)||(s=!0),l&&(s?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(x(e),n)})),t))for(;u>a;a++)t(e[a],n,s?r:r.call(e[a],a,t(e[a],n)));return i?e:l?t.call(e):u?t(e[0],n):o},now:Date.now,swap:function(e,t,n,r){var i,o,s={};for(o in t)s[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=s[o];return i}}),x.ready.promise=function(t){return n||(n=x.Deferred(),\"complete\"===o.readyState?setTimeout(x.ready):(o.addEventListener(\"DOMContentLoaded\",S,!1),e.addEventListener(\"load\",S,!1))),n.promise(t)},x.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"),function(e,t){l[\"[object \"+t+\"]\"]=t.toLowerCase()});function j(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:\"array\"===n||\"function\"!==n&&(0===t||\"number\"==typeof t&&t>0&&t-1 in e)}t=x(o),function(e,undefined){var t,n,r,i,o,s,a,u,l,c,p,f,h,d,g,m,y,v=\"sizzle\"+-new Date,b=e.document,w=0,T=0,C=st(),k=st(),N=st(),E=!1,S=function(e,t){return e===t?(E=!0,0):0},j=typeof undefined,D=1<<31,A={}.hasOwnProperty,L=[],q=L.pop,H=L.push,O=L.push,F=L.slice,P=L.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},R=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",M=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",W=\"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",$=W.replace(\"w\",\"w#\"),B=\"\\\\[\"+M+\"*(\"+W+\")\"+M+\"*(?:([*^$|!~]?=)\"+M+\"*(?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|(\"+$+\")|)|)\"+M+\"*\\\\]\",I=\":(\"+W+\")(?:\\\\(((['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+B.replace(3,8)+\")*)|.*)\\\\)|)\",z=RegExp(\"^\"+M+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+M+\"+$\",\"g\"),_=RegExp(\"^\"+M+\"*,\"+M+\"*\"),X=RegExp(\"^\"+M+\"*([>+~]|\"+M+\")\"+M+\"*\"),U=RegExp(M+\"*[+~]\"),Y=RegExp(\"=\"+M+\"*([^\\\\]'\\\"]*)\"+M+\"*\\\\]\",\"g\"),V=RegExp(I),G=RegExp(\"^\"+$+\"$\"),J={ID:RegExp(\"^#(\"+W+\")\"),CLASS:RegExp(\"^\\\\.(\"+W+\")\"),TAG:RegExp(\"^(\"+W.replace(\"w\",\"w*\")+\")\"),ATTR:RegExp(\"^\"+B),PSEUDO:RegExp(\"^\"+I),CHILD:RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+M+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+M+\"*(?:([+-]|)\"+M+\"*(\\\\d+)|))\"+M+\"*\\\\)|)\",\"i\"),bool:RegExp(\"^(?:\"+R+\")$\",\"i\"),needsContext:RegExp(\"^\"+M+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+M+\"*((?:-\\\\d)?\\\\d*)\"+M+\"*\\\\)|)(?=[^-]|$)\",\"i\")},Q=/^[^{]+\\{\\s*\\[native \\w/,K=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,Z=/^(?:input|select|textarea|button)$/i,et=/^h\\d$/i,tt=/'|\\\\/g,nt=RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+M+\"?|(\"+M+\")|.)\",\"ig\"),rt=function(e,t,n){var r=\"0x\"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{O.apply(L=F.call(b.childNodes),b.childNodes),L[b.childNodes.length].nodeType}catch(it){O={apply:L.length?function(e,t){H.apply(e,F.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function ot(e,t,r,i){var o,s,a,u,l,f,g,m,x,w;if((t?t.ownerDocument||t:b)!==p&&c(t),t=t||p,r=r||[],!e||\"string\"!=typeof e)return r;if(1!==(u=t.nodeType)&&9!==u)return[];if(h&&!i){if(o=K.exec(e))if(a=o[1]){if(9===u){if(s=t.getElementById(a),!s||!s.parentNode)return r;if(s.id===a)return r.push(s),r}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(a))&&y(t,s)&&s.id===a)return r.push(s),r}else{if(o[2])return O.apply(r,t.getElementsByTagName(e)),r;if((a=o[3])&&n.getElementsByClassName&&t.getElementsByClassName)return O.apply(r,t.getElementsByClassName(a)),r}if(n.qsa&&(!d||!d.test(e))){if(m=g=v,x=t,w=9===u&&e,1===u&&\"object\"!==t.nodeName.toLowerCase()){f=gt(e),(g=t.getAttribute(\"id\"))?m=g.replace(tt,\"\\\\$&\"):t.setAttribute(\"id\",m),m=\"[id='\"+m+\"'] \",l=f.length;while(l--)f[l]=m+mt(f[l]);x=U.test(e)&&t.parentNode||t,w=f.join(\",\")}if(w)try{return O.apply(r,x.querySelectorAll(w)),r}catch(T){}finally{g||t.removeAttribute(\"id\")}}}return kt(e.replace(z,\"$1\"),t,r,i)}function st(){var e=[];function t(n,r){return e.push(n+=\" \")>i.cacheLength&&delete t[e.shift()],t[n]=r}return t}function at(e){return e[v]=!0,e}function ut(e){var t=p.createElement(\"div\");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function lt(e,t){var n=e.split(\"|\"),r=e.length;while(r--)i.attrHandle[n[r]]=t}function ct(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pt(e){return function(t){var n=t.nodeName.toLowerCase();return\"input\"===n&&t.type===e}}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return(\"input\"===n||\"button\"===n)&&t.type===e}}function ht(e){return at(function(t){return t=+t,at(function(n,r){var i,o=e([],n.length,t),s=o.length;while(s--)n[i=o[s]]&&(n[i]=!(r[i]=n[i]))})})}s=ot.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?\"HTML\"!==t.nodeName:!1},n=ot.support={},c=ot.setDocument=function(e){var t=e?e.ownerDocument||e:b,r=t.defaultView;return t!==p&&9===t.nodeType&&t.documentElement?(p=t,f=t.documentElement,h=!s(t),r&&r.attachEvent&&r!==r.top&&r.attachEvent(\"onbeforeunload\",function(){c()}),n.attributes=ut(function(e){return e.className=\"i\",!e.getAttribute(\"className\")}),n.getElementsByTagName=ut(function(e){return e.appendChild(t.createComment(\"\")),!e.getElementsByTagName(\"*\").length}),n.getElementsByClassName=ut(function(e){return e.innerHTML=\"
\",e.firstChild.className=\"i\",2===e.getElementsByClassName(\"i\").length}),n.getById=ut(function(e){return f.appendChild(e).id=v,!t.getElementsByName||!t.getElementsByName(v).length}),n.getById?(i.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){return e.getAttribute(\"id\")===t}}):(delete i.find.ID,i.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode(\"id\");return n&&n.value===t}}),i.find.TAG=n.getElementsByTagName?function(e,t){return typeof t.getElementsByTagName!==j?t.getElementsByTagName(e):undefined}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if(\"*\"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.CLASS=n.getElementsByClassName&&function(e,t){return typeof t.getElementsByClassName!==j&&h?t.getElementsByClassName(e):undefined},g=[],d=[],(n.qsa=Q.test(t.querySelectorAll))&&(ut(function(e){e.innerHTML=\"\",e.querySelectorAll(\"[selected]\").length||d.push(\"\\\\[\"+M+\"*(?:value|\"+R+\")\"),e.querySelectorAll(\":checked\").length||d.push(\":checked\")}),ut(function(e){var n=t.createElement(\"input\");n.setAttribute(\"type\",\"hidden\"),e.appendChild(n).setAttribute(\"t\",\"\"),e.querySelectorAll(\"[t^='']\").length&&d.push(\"[*^$]=\"+M+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\":enabled\").length||d.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),d.push(\",.*:\")})),(n.matchesSelector=Q.test(m=f.webkitMatchesSelector||f.mozMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&ut(function(e){n.disconnectedMatch=m.call(e,\"div\"),m.call(e,\"[s!='']:x\"),g.push(\"!=\",I)}),d=d.length&&RegExp(d.join(\"|\")),g=g.length&&RegExp(g.join(\"|\")),y=Q.test(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},S=f.compareDocumentPosition?function(e,r){if(e===r)return E=!0,0;var i=r.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(r);return i?1&i||!n.sortDetached&&r.compareDocumentPosition(e)===i?e===t||y(b,e)?-1:r===t||y(b,r)?1:l?P.call(l,e)-P.call(l,r):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,n){var r,i=0,o=e.parentNode,s=n.parentNode,a=[e],u=[n];if(e===n)return E=!0,0;if(!o||!s)return e===t?-1:n===t?1:o?-1:s?1:l?P.call(l,e)-P.call(l,n):0;if(o===s)return ct(e,n);r=e;while(r=r.parentNode)a.unshift(r);r=n;while(r=r.parentNode)u.unshift(r);while(a[i]===u[i])i++;return i?ct(a[i],u[i]):a[i]===b?-1:u[i]===b?1:0},t):p},ot.matches=function(e,t){return ot(e,null,null,t)},ot.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Y,\"='$1']\"),!(!n.matchesSelector||!h||g&&g.test(t)||d&&d.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return ot(t,p,null,[e]).length>0},ot.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},ot.attr=function(e,t){(e.ownerDocument||e)!==p&&c(e);var r=i.attrHandle[t.toLowerCase()],o=r&&A.call(i.attrHandle,t.toLowerCase())?r(e,t,!h):undefined;return o===undefined?n.attributes||!h?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null:o},ot.error=function(e){throw Error(\"Syntax error, unrecognized expression: \"+e)},ot.uniqueSort=function(e){var t,r=[],i=0,o=0;if(E=!n.detectDuplicates,l=!n.sortStable&&e.slice(0),e.sort(S),E){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return e},o=ot.getText=function(e){var t,n=\"\",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if(\"string\"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=ot.selectors={cacheLength:50,createPseudo:at,match:J,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(nt,rt),e[3]=(e[4]||e[5]||\"\").replace(nt,rt),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||ot.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&ot.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return J.CHILD.test(e[0])?null:(e[3]&&e[4]!==undefined?e[2]=e[4]:n&&V.test(n)&&(t=gt(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(nt,rt).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=C[e+\" \"];return t||(t=RegExp(\"(^|\"+M+\")\"+e+\"(\"+M+\"|$)\"))&&C(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute(\"class\")||\"\")})},ATTR:function(e,t,n){return function(r){var i=ot.attr(r,e);return null==i?\"!=\"===t:t?(i+=\"\",\"=\"===t?i===n:\"!=\"===t?i!==n:\"^=\"===t?n&&0===i.indexOf(n):\"*=\"===t?n&&i.indexOf(n)>-1:\"$=\"===t?n&&i.slice(-n.length)===n:\"~=\"===t?(\" \"+i+\" \").indexOf(n)>-1:\"|=\"===t?i===n||i.slice(0,n.length+1)===n+\"-\":!1):!0}},CHILD:function(e,t,n,r,i){var o=\"nth\"!==e.slice(0,3),s=\"last\"!==e.slice(-4),a=\"of-type\"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,h,d,g=o!==s?\"nextSibling\":\"previousSibling\",m=t.parentNode,y=a&&t.nodeName.toLowerCase(),x=!u&&!a;if(m){if(o){while(g){p=t;while(p=p[g])if(a?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;d=g=\"only\"===e&&!d&&\"nextSibling\"}return!0}if(d=[s?m.firstChild:m.lastChild],s&&x){c=m[v]||(m[v]={}),l=c[e]||[],h=l[0]===w&&l[1],f=l[0]===w&&l[2],p=h&&m.childNodes[h];while(p=++h&&p&&p[g]||(f=h=0)||d.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[w,h,f];break}}else if(x&&(l=(t[v]||(t[v]={}))[e])&&l[0]===w)f=l[1];else while(p=++h&&p&&p[g]||(f=h=0)||d.pop())if((a?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(x&&((p[v]||(p[v]={}))[e]=[w,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||ot.error(\"unsupported pseudo: \"+e);return r[v]?r(t):r.length>1?(n=[e,e,\"\",t],i.setFilters.hasOwnProperty(e.toLowerCase())?at(function(e,n){var i,o=r(e,t),s=o.length;while(s--)i=P.call(e,o[s]),e[i]=!(n[i]=o[s])}):function(e){return r(e,0,n)}):r}},pseudos:{not:at(function(e){var t=[],n=[],r=a(e.replace(z,\"$1\"));return r[v]?at(function(e,t,n,i){var o,s=r(e,null,i,[]),a=e.length;while(a--)(o=s[a])&&(e[a]=!(t[a]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:at(function(e){return function(t){return ot(e,t).length>0}}),contains:at(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:at(function(e){return G.test(e||\"\")||ot.error(\"unsupported lang: \"+e),e=e.replace(nt,rt).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute(\"xml:lang\")||t.getAttribute(\"lang\"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+\"-\");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&!!e.checked||\"option\"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>\"@\"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return et.test(e.nodeName)},input:function(e){return Z.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&\"button\"===e.type||\"button\"===t},text:function(e){var t;return\"input\"===e.nodeName.toLowerCase()&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},i.pseudos.nth=i.pseudos.eq;for(t in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[t]=pt(t);for(t in{submit:!0,reset:!0})i.pseudos[t]=ft(t);function dt(){}dt.prototype=i.filters=i.pseudos,i.setFilters=new dt;function gt(e,t){var n,r,o,s,a,u,l,c=k[e+\" \"];if(c)return t?0:c.slice(0);a=e,u=[],l=i.preFilter;while(a){(!n||(r=_.exec(a)))&&(r&&(a=a.slice(r[0].length)||a),u.push(o=[])),n=!1,(r=X.exec(a))&&(n=r.shift(),o.push({value:n,type:r[0].replace(z,\" \")}),a=a.slice(n.length));for(s in i.filter)!(r=J[s].exec(a))||l[s]&&!(r=l[s](r))||(n=r.shift(),o.push({value:n,type:s,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?ot.error(e):k(e,u).slice(0)}function mt(e){var t=0,n=e.length,r=\"\";for(;n>t;t++)r+=e[t].value;return r}function yt(e,t,n){var i=t.dir,o=n&&\"parentNode\"===i,s=T++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,a){var u,l,c,p=w+\" \"+s;if(a){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,a))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[v]||(t[v]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,a)||r,l[1]===!0)return!0}}function vt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,s=[],a=0,u=e.length,l=null!=t;for(;u>a;a++)(o=e[a])&&(!n||n(o,r,i))&&(s.push(o),l&&t.push(a));return s}function bt(e,t,n,r,i,o){return r&&!r[v]&&(r=bt(r)),i&&!i[v]&&(i=bt(i,o)),at(function(o,s,a,u){var l,c,p,f=[],h=[],d=s.length,g=o||Ct(t||\"*\",a.nodeType?[a]:a,[]),m=!e||!o&&t?g:xt(g,f,e,a,u),y=n?i||(o?e:d||r)?[]:s:m;if(n&&n(m,y,a,u),r){l=xt(y,h),r(l,[],a,u),c=l.length;while(c--)(p=l[c])&&(y[h[c]]=!(m[h[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?P.call(o,p):f[c])>-1&&(o[l]=!(s[l]=p))}}else y=xt(y===s?y.splice(d,y.length):y),i?i(null,s,y,u):O.apply(s,y)})}function wt(e){var t,n,r,o=e.length,s=i.relative[e[0].type],a=s||i.relative[\" \"],l=s?1:0,c=yt(function(e){return e===t},a,!0),p=yt(function(e){return P.call(t,e)>-1},a,!0),f=[function(e,n,r){return!s&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>l;l++)if(n=i.relative[e[l].type])f=[yt(vt(f),n)];else{if(n=i.filter[e[l].type].apply(null,e[l].matches),n[v]){for(r=++l;o>r;r++)if(i.relative[e[r].type])break;return bt(l>1&&vt(f),l>1&&mt(e.slice(0,l-1).concat({value:\" \"===e[l-2].type?\"*\":\"\"})).replace(z,\"$1\"),n,r>l&&wt(e.slice(l,r)),o>r&&wt(e=e.slice(r)),o>r&&mt(e))}f.push(n)}return vt(f)}function Tt(e,t){var n=0,o=t.length>0,s=e.length>0,a=function(a,l,c,f,h){var d,g,m,y=[],v=0,x=\"0\",b=a&&[],T=null!=h,C=u,k=a||s&&i.find.TAG(\"*\",h&&l.parentNode||l),N=w+=null==C?1:Math.random()||.1;for(T&&(u=l!==p&&l,r=n);null!=(d=k[x]);x++){if(s&&d){g=0;while(m=e[g++])if(m(d,l,c)){f.push(d);break}T&&(w=N,r=++n)}o&&((d=!m&&d)&&v--,a&&b.push(d))}if(v+=x,o&&x!==v){g=0;while(m=t[g++])m(b,y,l,c);if(a){if(v>0)while(x--)b[x]||y[x]||(y[x]=q.call(f));y=xt(y)}O.apply(f,y),T&&!a&&y.length>0&&v+t.length>1&&ot.uniqueSort(f)}return T&&(w=N,u=C),b};return o?at(a):a}a=ot.compile=function(e,t){var n,r=[],i=[],o=N[e+\" \"];if(!o){t||(t=gt(e)),n=t.length;while(n--)o=wt(t[n]),o[v]?r.push(o):i.push(o);o=N(e,Tt(i,r))}return o};function Ct(e,t,n){var r=0,i=t.length;for(;i>r;r++)ot(e,t[r],n);return n}function kt(e,t,r,o){var s,u,l,c,p,f=gt(e);if(!o&&1===f.length){if(u=f[0]=f[0].slice(0),u.length>2&&\"ID\"===(l=u[0]).type&&n.getById&&9===t.nodeType&&h&&i.relative[u[1].type]){if(t=(i.find.ID(l.matches[0].replace(nt,rt),t)||[])[0],!t)return r;e=e.slice(u.shift().value.length)}s=J.needsContext.test(e)?0:u.length;while(s--){if(l=u[s],i.relative[c=l.type])break;if((p=i.find[c])&&(o=p(l.matches[0].replace(nt,rt),U.test(u[0].type)&&t.parentNode||t))){if(u.splice(s,1),e=o.length&&mt(u),!e)return O.apply(r,o),r;break}}}return a(e,f)(o,t,!h,r,U.test(e)),r}n.sortStable=v.split(\"\").sort(S).join(\"\")===v,n.detectDuplicates=E,c(),n.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(p.createElement(\"div\"))}),ut(function(e){return e.innerHTML=\"\",\"#\"===e.firstChild.getAttribute(\"href\")})||lt(\"type|href|height|width\",function(e,t,n){return n?undefined:e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)}),n.attributes&&ut(function(e){return e.innerHTML=\"\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")})||lt(\"value\",function(e,t,n){return n||\"input\"!==e.nodeName.toLowerCase()?undefined:e.defaultValue}),ut(function(e){return null==e.getAttribute(\"disabled\")})||lt(R,function(e,t,n){var r;return n?undefined:(r=e.getAttributeNode(t))&&r.specified?r.value:e[t]===!0?t.toLowerCase():null}),x.find=ot,x.expr=ot.selectors,x.expr[\":\"]=x.expr.pseudos,x.unique=ot.uniqueSort,x.text=ot.getText,x.isXMLDoc=ot.isXML,x.contains=ot.contains}(e);var D={};function A(e){var t=D[e]={};return x.each(e.match(w)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e=\"string\"==typeof e?D[e]||A(e):x.extend({},e);var t,n,r,i,o,s,a=[],u=!e.once&&[],l=function(p){for(t=e.memory&&p,n=!0,s=i||0,i=0,o=a.length,r=!0;a&&o>s;s++)if(a[s].apply(p[0],p[1])===!1&&e.stopOnFalse){t=!1;break}r=!1,a&&(u?u.length&&l(u.shift()):t?a=[]:c.disable())},c={add:function(){if(a){var n=a.length;(function s(t){x.each(t,function(t,n){var r=x.type(n);\"function\"===r?e.unique&&c.has(n)||a.push(n):n&&n.length&&\"string\"!==r&&s(n)})})(arguments),r?o=a.length:t&&(i=n,l(t))}return this},remove:function(){return a&&x.each(arguments,function(e,t){var n;while((n=x.inArray(t,a,n))>-1)a.splice(n,1),r&&(o>=n&&o--,s>=n&&s--)}),this},has:function(e){return e?x.inArray(e,a)>-1:!(!a||!a.length)},empty:function(){return a=[],o=0,this},disable:function(){return a=u=t=undefined,this},disabled:function(){return!a},lock:function(){return u=undefined,t||c.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!a||n&&!u||(t=t||[],t=[e,t.slice?t.slice():t],r?u.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!n}};return c},x.extend({Deferred:function(e){var t=[[\"resolve\",\"done\",x.Callbacks(\"once memory\"),\"resolved\"],[\"reject\",\"fail\",x.Callbacks(\"once memory\"),\"rejected\"],[\"notify\",\"progress\",x.Callbacks(\"memory\")]],n=\"pending\",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var s=o[0],a=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+\"With\"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var s=o[2],a=o[3];r[o[1]]=s.add,a&&s.add(function(){n=a},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+\"With\"](this===i?r:this,arguments),this},i[o[0]+\"With\"]=s.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=d.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),s=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?d.call(arguments):r,n===a?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},a,u,l;if(r>1)for(a=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(s(t,l,n)).fail(o.reject).progress(s(t,u,a)):--i;return i||o.resolveWith(l,n),o.promise()}}),x.support=function(t){var n=o.createElement(\"input\"),r=o.createDocumentFragment(),i=o.createElement(\"div\"),s=o.createElement(\"select\"),a=s.appendChild(o.createElement(\"option\"));return n.type?(n.type=\"checkbox\",t.checkOn=\"\"!==n.value,t.optSelected=a.selected,t.reliableMarginRight=!0,t.boxSizingReliable=!0,t.pixelPosition=!1,n.checked=!0,t.noCloneChecked=n.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!a.disabled,n=o.createElement(\"input\"),n.value=\"t\",n.type=\"radio\",t.radioValue=\"t\"===n.value,n.setAttribute(\"checked\",\"t\"),n.setAttribute(\"name\",\"t\"),r.appendChild(n),t.checkClone=r.cloneNode(!0).cloneNode(!0).lastChild.checked,t.focusinBubbles=\"onfocusin\"in e,i.style.backgroundClip=\"content-box\",i.cloneNode(!0).style.backgroundClip=\"\",t.clearCloneStyle=\"content-box\"===i.style.backgroundClip,x(function(){var n,r,s=\"padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box\",a=o.getElementsByTagName(\"body\")[0];a&&(n=o.createElement(\"div\"),n.style.cssText=\"border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px\",a.appendChild(n).appendChild(i),i.innerHTML=\"\",i.style.cssText=\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%\",x.swap(a,null!=a.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===i.offsetWidth}),e.getComputedStyle&&(t.pixelPosition=\"1%\"!==(e.getComputedStyle(i,null)||{}).top,t.boxSizingReliable=\"4px\"===(e.getComputedStyle(i,null)||{width:\"4px\"}).width,r=i.appendChild(o.createElement(\"div\")),r.style.cssText=i.style.cssText=s,r.style.marginRight=r.style.width=\"0\",i.style.width=\"1px\",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),a.removeChild(n))}),t):t}({});var L,q,H=/(?:\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])$/,O=/([A-Z])/g;function F(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=x.expando+Math.random()}F.uid=1,F.accepts=function(e){return e.nodeType?1===e.nodeType||9===e.nodeType:!0},F.prototype={key:function(e){if(!F.accepts(e))return 0;var t={},n=e[this.expando];if(!n){n=F.uid++;try{t[this.expando]={value:n},Object.defineProperties(e,t)}catch(r){t[this.expando]=n,x.extend(e,t)}}return this.cache[n]||(this.cache[n]={}),n},set:function(e,t,n){var r,i=this.key(e),o=this.cache[i];if(\"string\"==typeof t)o[t]=n;else if(x.isEmptyObject(o))x.extend(this.cache[i],t);else for(r in t)o[r]=t[r];return o},get:function(e,t){var n=this.cache[this.key(e)];return t===undefined?n:n[t]},access:function(e,t,n){var r;return t===undefined||t&&\"string\"==typeof t&&n===undefined?(r=this.get(e,t),r!==undefined?r:this.get(e,x.camelCase(t))):(this.set(e,t,n),n!==undefined?n:t)},remove:function(e,t){var n,r,i,o=this.key(e),s=this.cache[o];if(t===undefined)this.cache[o]={};else{x.isArray(t)?r=t.concat(t.map(x.camelCase)):(i=x.camelCase(t),t in s?r=[t,i]:(r=i,r=r in s?[r]:r.match(w)||[])),n=r.length;while(n--)delete s[r[n]]}},hasData:function(e){return!x.isEmptyObject(this.cache[e[this.expando]]||{})},discard:function(e){e[this.expando]&&delete this.cache[e[this.expando]]}},L=new F,q=new F,x.extend({acceptData:F.accepts,hasData:function(e){return L.hasData(e)||q.hasData(e)},data:function(e,t,n){return L.access(e,t,n)},removeData:function(e,t){L.remove(e,t)},_data:function(e,t,n){return q.access(e,t,n)},_removeData:function(e,t){q.remove(e,t)}}),x.fn.extend({data:function(e,t){var n,r,i=this[0],o=0,s=null;if(e===undefined){if(this.length&&(s=L.get(i),1===i.nodeType&&!q.get(i,\"hasDataAttrs\"))){for(n=i.attributes;n.length>o;o++)r=n[o].name,0===r.indexOf(\"data-\")&&(r=x.camelCase(r.slice(5)),P(i,r,s[r]));q.set(i,\"hasDataAttrs\",!0)}return s}return\"object\"==typeof e?this.each(function(){L.set(this,e)}):x.access(this,function(t){var n,r=x.camelCase(e);if(i&&t===undefined){if(n=L.get(i,e),n!==undefined)return n;if(n=L.get(i,r),n!==undefined)return n;if(n=P(i,r,undefined),n!==undefined)return n}else this.each(function(){var n=L.get(this,r);L.set(this,r,t),-1!==e.indexOf(\"-\")&&n!==undefined&&L.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){L.remove(this,e)})}});function P(e,t,n){var r;if(n===undefined&&1===e.nodeType)if(r=\"data-\"+t.replace(O,\"-$1\").toLowerCase(),n=e.getAttribute(r),\"string\"==typeof n){try{n=\"true\"===n?!0:\"false\"===n?!1:\"null\"===n?null:+n+\"\"===n?+n:H.test(n)?JSON.parse(n):n}catch(i){}L.set(e,t,n)}else n=undefined;return n}x.extend({queue:function(e,t,n){var r;return e?(t=(t||\"fx\")+\"queue\",r=q.get(e,t),n&&(!r||x.isArray(n)?r=q.access(e,t,x.makeArray(n)):r.push(n)),r||[]):undefined},dequeue:function(e,t){t=t||\"fx\";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),s=function(){x.dequeue(e,t)\n};\"inprogress\"===i&&(i=n.shift(),r--),i&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete o.stop,i.call(e,s,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return q.get(e,n)||q.access(e,n,{empty:x.Callbacks(\"once memory\").add(function(){q.remove(e,[t+\"queue\",n])})})}}),x.fn.extend({queue:function(e,t){var n=2;return\"string\"!=typeof e&&(t=e,e=\"fx\",n--),n>arguments.length?x.queue(this[0],e):t===undefined?this:this.each(function(){var n=x.queue(this,e,t);x._queueHooks(this,e),\"fx\"===e&&\"inprogress\"!==n[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||\"fx\",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||\"fx\",[])},promise:function(e,t){var n,r=1,i=x.Deferred(),o=this,s=this.length,a=function(){--r||i.resolveWith(o,[o])};\"string\"!=typeof e&&(t=e,e=undefined),e=e||\"fx\";while(s--)n=q.get(o[s],e+\"queueHooks\"),n&&n.empty&&(r++,n.empty.add(a));return a(),i.promise(t)}});var R,M,W=/[\\t\\r\\n\\f]/g,$=/\\r/g,B=/^(?:input|select|textarea|button)$/i;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[x.propFix[e]||e]})},addClass:function(e){var t,n,r,i,o,s=0,a=this.length,u=\"string\"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||\"\").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(\" \"+n.className+\" \").replace(W,\" \"):\" \")){o=0;while(i=t[o++])0>r.indexOf(\" \"+i+\" \")&&(r+=i+\" \");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,s=0,a=this.length,u=0===arguments.length||\"string\"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||\"\").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(\" \"+n.className+\" \").replace(W,\" \"):\"\")){o=0;while(i=t[o++])while(r.indexOf(\" \"+i+\" \")>=0)r=r.replace(\" \"+i+\" \",\" \");n.className=e?x.trim(r):\"\"}return this},toggleClass:function(e,t){var n=typeof e;return\"boolean\"==typeof t&&\"string\"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(\"string\"===n){var t,i=0,o=x(this),s=e.match(w)||[];while(t=s[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===r||\"boolean\"===n)&&(this.className&&q.set(this,\"__className__\",this.className),this.className=this.className||e===!1?\"\":q.get(this,\"__className__\")||\"\")})},hasClass:function(e){var t=\" \"+e+\" \",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(\" \"+this[n].className+\" \").replace(W,\" \").indexOf(t)>=0)return!0;return!1},val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=x.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,x(this).val()):e,null==i?i=\"\":\"number\"==typeof i?i+=\"\":x.isArray(i)&&(i=x.map(i,function(e){return null==e?\"\":e+\"\"})),t=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],t&&\"set\"in t&&t.set(this,i,\"value\")!==undefined||(this.value=i))});if(i)return t=x.valHooks[i.type]||x.valHooks[i.nodeName.toLowerCase()],t&&\"get\"in t&&(n=t.get(i,\"value\"))!==undefined?n:(n=i.value,\"string\"==typeof n?n.replace($,\"\"):null==n?\"\":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o=\"select-one\"===e.type||0>i,s=o?null:[],a=o?i+1:r.length,u=0>i?a:o?i:0;for(;a>u;u++)if(n=r[u],!(!n.selected&&u!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute(\"disabled\"))||n.parentNode.disabled&&x.nodeName(n.parentNode,\"optgroup\"))){if(t=x(n).val(),o)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),s=i.length;while(s--)r=i[s],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,t,n){var i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===r?x.prop(e,t,n):(1===s&&x.isXMLDoc(e)||(t=t.toLowerCase(),i=x.attrHooks[t]||(x.expr.match.bool.test(t)?M:R)),n===undefined?i&&\"get\"in i&&null!==(o=i.get(e,t))?o:(o=x.find.attr(e,t),null==o?undefined:o):null!==n?i&&\"set\"in i&&(o=i.set(e,n,t))!==undefined?o:(e.setAttribute(t,n+\"\"),n):(x.removeAttr(e,t),undefined))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)&&(e[r]=!1),e.removeAttribute(n)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&\"radio\"===t&&x.nodeName(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"},prop:function(e,t,n){var r,i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return o=1!==s||!x.isXMLDoc(e),o&&(t=x.propFix[t]||t,i=x.propHooks[t]),n!==undefined?i&&\"set\"in i&&(r=i.set(e,n,t))!==undefined?r:e[t]=n:i&&\"get\"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){return e.hasAttribute(\"tabindex\")||B.test(e.nodeName)||e.href?e.tabIndex:-1}}}}),M={set:function(e,t,n){return t===!1?x.removeAttr(e,n):e.setAttribute(n,n),n}},x.each(x.expr.match.bool.source.match(/\\w+/g),function(e,t){var n=x.expr.attrHandle[t]||x.find.attr;x.expr.attrHandle[t]=function(e,t,r){var i=x.expr.attrHandle[t],o=r?undefined:(x.expr.attrHandle[t]=undefined)!=n(e,t,r)?t.toLowerCase():null;return x.expr.attrHandle[t]=i,o}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),x.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){x.propFix[this.toLowerCase()]=this}),x.each([\"radio\",\"checkbox\"],function(){x.valHooks[this]={set:function(e,t){return x.isArray(t)?e.checked=x.inArray(x(e).val(),t)>=0:undefined}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})});var I=/^key/,z=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,X=/^([^.]*)(?:\\.(.+)|)$/;function U(){return!0}function Y(){return!1}function V(){try{return o.activeElement}catch(e){}}x.event={global:{},add:function(e,t,n,i,o){var s,a,u,l,c,p,f,h,d,g,m,y=q.get(e);if(y){n.handler&&(s=n,n=s.handler,o=s.selector),n.guid||(n.guid=x.guid++),(l=y.events)||(l=y.events={}),(a=y.handle)||(a=y.handle=function(e){return typeof x===r||e&&x.event.triggered===e.type?undefined:x.event.dispatch.apply(a.elem,arguments)},a.elem=e),t=(t||\"\").match(w)||[\"\"],c=t.length;while(c--)u=X.exec(t[c])||[],d=m=u[1],g=(u[2]||\"\").split(\".\").sort(),d&&(f=x.event.special[d]||{},d=(o?f.delegateType:f.bindType)||d,f=x.event.special[d]||{},p=x.extend({type:d,origType:m,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&x.expr.match.needsContext.test(o),namespace:g.join(\".\")},s),(h=l[d])||(h=l[d]=[],h.delegateCount=0,f.setup&&f.setup.call(e,i,g,a)!==!1||e.addEventListener&&e.addEventListener(d,a,!1)),f.add&&(f.add.call(e,p),p.handler.guid||(p.handler.guid=n.guid)),o?h.splice(h.delegateCount++,0,p):h.push(p),x.event.global[d]=!0);e=null}},remove:function(e,t,n,r,i){var o,s,a,u,l,c,p,f,h,d,g,m=q.hasData(e)&&q.get(e);if(m&&(u=m.events)){t=(t||\"\").match(w)||[\"\"],l=t.length;while(l--)if(a=X.exec(t[l])||[],h=g=a[1],d=(a[2]||\"\").split(\".\").sort(),h){p=x.event.special[h]||{},h=(r?p.delegateType:p.bindType)||h,f=u[h]||[],a=a[2]&&RegExp(\"(^|\\\\.)\"+d.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),s=o=f.length;while(o--)c=f[o],!i&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||r&&r!==c.selector&&(\"**\"!==r||!c.selector)||(f.splice(o,1),c.selector&&f.delegateCount--,p.remove&&p.remove.call(e,c));s&&!f.length&&(p.teardown&&p.teardown.call(e,d,m.handle)!==!1||x.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)x.event.remove(e,h+t[l],n,r,!0);x.isEmptyObject(u)&&(delete m.handle,q.remove(e,\"events\"))}},trigger:function(t,n,r,i){var s,a,u,l,c,p,f,h=[r||o],d=y.call(t,\"type\")?t.type:t,g=y.call(t,\"namespace\")?t.namespace.split(\".\"):[];if(a=u=r=r||o,3!==r.nodeType&&8!==r.nodeType&&!_.test(d+x.event.triggered)&&(d.indexOf(\".\")>=0&&(g=d.split(\".\"),d=g.shift(),g.sort()),c=0>d.indexOf(\":\")&&\"on\"+d,t=t[x.expando]?t:new x.Event(d,\"object\"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=g.join(\".\"),t.namespace_re=t.namespace?RegExp(\"(^|\\\\.)\"+g.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,t.result=undefined,t.target||(t.target=r),n=null==n?[t]:x.makeArray(n,[t]),f=x.event.special[d]||{},i||!f.trigger||f.trigger.apply(r,n)!==!1)){if(!i&&!f.noBubble&&!x.isWindow(r)){for(l=f.delegateType||d,_.test(l+d)||(a=a.parentNode);a;a=a.parentNode)h.push(a),u=a;u===(r.ownerDocument||o)&&h.push(u.defaultView||u.parentWindow||e)}s=0;while((a=h[s++])&&!t.isPropagationStopped())t.type=s>1?l:f.bindType||d,p=(q.get(a,\"events\")||{})[t.type]&&q.get(a,\"handle\"),p&&p.apply(a,n),p=c&&a[c],p&&x.acceptData(a)&&p.apply&&p.apply(a,n)===!1&&t.preventDefault();return t.type=d,i||t.isDefaultPrevented()||f._default&&f._default.apply(h.pop(),n)!==!1||!x.acceptData(r)||c&&x.isFunction(r[d])&&!x.isWindow(r)&&(u=r[c],u&&(r[c]=null),x.event.triggered=d,r[d](),x.event.triggered=undefined,u&&(r[c]=u)),t.result}},dispatch:function(e){e=x.event.fix(e);var t,n,r,i,o,s=[],a=d.call(arguments),u=(q.get(this,\"events\")||{})[e.type]||[],l=x.event.special[e.type]||{};if(a[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),t=0;while((i=s[t++])&&!e.isPropagationStopped()){e.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(o.namespace))&&(e.handleObj=o,e.data=o.data,r=((x.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,a),r!==undefined&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,s=[],a=t.delegateCount,u=e.target;if(a&&u.nodeType&&(!e.button||\"click\"!==e.type))for(;u!==this;u=u.parentNode||this)if(u.disabled!==!0||\"click\"!==e.type){for(r=[],n=0;a>n;n++)o=t[n],i=o.selector+\" \",r[i]===undefined&&(r[i]=o.needsContext?x(i,this).index(u)>=0:x.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&s.push({elem:u,handlers:r})}return t.length>a&&s.push({elem:this,handlers:t.slice(a)}),s},props:\"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),fixHooks:{},keyHooks:{props:\"char charCode key keyCode\".split(\" \"),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:\"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),filter:function(e,t){var n,r,i,s=t.button;return null==e.pageX&&null!=t.clientX&&(n=e.target.ownerDocument||o,r=n.documentElement,i=n.body,e.pageX=t.clientX+(r&&r.scrollLeft||i&&i.scrollLeft||0)-(r&&r.clientLeft||i&&i.clientLeft||0),e.pageY=t.clientY+(r&&r.scrollTop||i&&i.scrollTop||0)-(r&&r.clientTop||i&&i.clientTop||0)),e.which||s===undefined||(e.which=1&s?1:2&s?3:4&s?2:0),e}},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,s=e,a=this.fixHooks[i];a||(this.fixHooks[i]=a=z.test(i)?this.mouseHooks:I.test(i)?this.keyHooks:{}),r=a.props?this.props.concat(a.props):this.props,e=new x.Event(s),t=r.length;while(t--)n=r[t],e[n]=s[n];return e.target||(e.target=o),3===e.target.nodeType&&(e.target=e.target.parentNode),a.filter?a.filter(e,s):e},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==V()&&this.focus?(this.focus(),!1):undefined},delegateType:\"focusin\"},blur:{trigger:function(){return this===V()&&this.blur?(this.blur(),!1):undefined},delegateType:\"focusout\"},click:{trigger:function(){return\"checkbox\"===this.type&&this.click&&x.nodeName(this,\"input\")?(this.click(),!1):undefined},_default:function(e){return x.nodeName(e.target,\"a\")}},beforeunload:{postDispatch:function(e){e.result!==undefined&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)},x.Event=function(e,t){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.getPreventDefault&&e.getPreventDefault()?U:Y):this.type=e,t&&x.extend(this,t),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,undefined):new x.Event(e,t)},x.Event.prototype={isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=U,e&&e.preventDefault&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=U,e&&e.stopPropagation&&e.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=U,this.stopPropagation()}},x.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.focusinBubbles||x.each({focus:\"focusin\",blur:\"focusout\"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,t,n,r,i){var o,s;if(\"object\"==typeof e){\"string\"!=typeof t&&(n=n||t,t=undefined);for(s in e)this.on(s,t,n,e[s],i);return this}if(null==n&&null==r?(r=t,n=t=undefined):null==r&&(\"string\"==typeof t?(r=n,n=undefined):(r=n,n=t,t=undefined)),r===!1)r=Y;else if(!r)return this;return 1===i&&(o=r,r=function(e){return x().off(e),o.apply(this,arguments)},r.guid=o.guid||(o.guid=x.guid++)),this.each(function(){x.event.add(this,e,r,n,t)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,x(e.delegateTarget).off(r.namespace?r.origType+\".\"+r.namespace:r.origType,r.selector,r.handler),this;if(\"object\"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return(t===!1||\"function\"==typeof t)&&(n=t,t=undefined),n===!1&&(n=Y),this.each(function(){x.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];return n?x.event.trigger(e,t,n,!0):undefined}});var G=/^.[^:#\\[\\.,]*$/,J=/^(?:parents|prev(?:Until|All))/,Q=x.expr.match.needsContext,K={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if(\"string\"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+\" \"+e:e,n},has:function(e){var t=x(e,this),n=t.length;return this.filter(function(){var e=0;for(;n>e;e++)if(x.contains(this,t[e]))return!0})},not:function(e){return this.pushStack(et(this,e||[],!0))},filter:function(e){return this.pushStack(et(this,e||[],!1))},is:function(e){return!!et(this,\"string\"==typeof e&&Q.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],s=Q.test(e)||\"string\"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(s?s.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?\"string\"==typeof e?g.call(x(e),this[0]):g.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n=\"string\"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function Z(e,t){while((e=e[t])&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,\"parentNode\")},parentsUntil:function(e,t,n){return x.dir(e,\"parentNode\",n)},next:function(e){return Z(e,\"nextSibling\")},prev:function(e){return Z(e,\"previousSibling\")},nextAll:function(e){return x.dir(e,\"nextSibling\")},prevAll:function(e){return x.dir(e,\"previousSibling\")},nextUntil:function(e,t,n){return x.dir(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return x.dir(e,\"previousSibling\",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return e.contentDocument||x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return\"Until\"!==e.slice(-5)&&(r=n),r&&\"string\"==typeof r&&(i=x.filter(r,i)),this.length>1&&(K[e]||x.unique(i),J.test(e)&&i.reverse()),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,t,n){var r=[],i=n!==undefined;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&x(e).is(n))break;r.push(e)}return r},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function et(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if(\"string\"==typeof t){if(G.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return g.call(t,e)>=0!==n})}var tt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,nt=/<([\\w:]+)/,rt=/<|&#?\\w+;/,it=/<(?:script|style|link)/i,ot=/^(?:checkbox|radio)$/i,st=/checked\\s*(?:[^=]|=\\s*.checked.)/i,at=/^$|\\/(?:java|ecma)script/i,ut=/^true\\/(.*)/,lt=/^\\s*\\s*$/g,ct={option:[1,\"\"],thead:[1,\"\",\"
\"],col:[2,\"\",\"
\"],tr:[2,\"\",\"
\"],td:[3,\"\",\"
\"],_default:[0,\"\",\"\"]};ct.optgroup=ct.option,ct.tbody=ct.tfoot=ct.colgroup=ct.caption=ct.thead,ct.th=ct.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===undefined?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=pt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=pt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(mt(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&dt(mt(n,\"script\")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++)1===e.nodeType&&(x.cleanData(mt(e,!1)),e.textContent=\"\");return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var t=this[0]||{},n=0,r=this.length;if(e===undefined&&1===t.nodeType)return t.innerHTML;if(\"string\"==typeof e&&!it.test(e)&&!ct[(nt.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=e.replace(tt,\"<$1>\");try{for(;r>n;n++)t=this[n]||{},1===t.nodeType&&(x.cleanData(mt(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=f.apply([],e);var r,i,o,s,a,u,l=0,c=this.length,p=this,h=c-1,d=e[0],g=x.isFunction(d);if(g||!(1>=c||\"string\"!=typeof d||x.support.checkClone)&&st.test(d))return this.each(function(r){var i=p.eq(r);g&&(e[0]=d.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(r=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),i=r.firstChild,1===r.childNodes.length&&(r=i),i)){for(o=x.map(mt(r,\"script\"),ft),s=o.length;c>l;l++)a=r,l!==h&&(a=x.clone(a,!0,!0),s&&x.merge(o,mt(a,\"script\"))),t.call(this[l],a,l);if(s)for(u=o[o.length-1].ownerDocument,x.map(o,ht),l=0;s>l;l++)a=o[l],at.test(a.type||\"\")&&!q.access(a,\"globalEval\")&&x.contains(u,a)&&(a.src?x._evalUrl(a.src):x.globalEval(a.textContent.replace(lt,\"\")))}return this}}),x.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(e,t){x.fn[e]=function(e){var n,r=[],i=x(e),o=i.length-1,s=0;for(;o>=s;s++)n=s===o?this:this.clone(!0),x(i[s])[t](n),h.apply(r,n.get());return this.pushStack(r)}}),x.extend({clone:function(e,t,n){var r,i,o,s,a=e.cloneNode(!0),u=x.contains(e.ownerDocument,e);if(!(x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(s=mt(a),o=mt(e),r=0,i=o.length;i>r;r++)yt(o[r],s[r]);if(t)if(n)for(o=o||mt(e),s=s||mt(a),r=0,i=o.length;i>r;r++)gt(o[r],s[r]);else gt(e,a);return s=mt(a,\"script\"),s.length>0&&dt(s,!u&&mt(e,\"script\")),a},buildFragment:function(e,t,n,r){var i,o,s,a,u,l,c=0,p=e.length,f=t.createDocumentFragment(),h=[];for(;p>c;c++)if(i=e[c],i||0===i)if(\"object\"===x.type(i))x.merge(h,i.nodeType?[i]:i);else if(rt.test(i)){o=o||f.appendChild(t.createElement(\"div\")),s=(nt.exec(i)||[\"\",\"\"])[1].toLowerCase(),a=ct[s]||ct._default,o.innerHTML=a[1]+i.replace(tt,\"<$1>\")+a[2],l=a[0];while(l--)o=o.lastChild;x.merge(h,o.childNodes),o=f.firstChild,o.textContent=\"\"}else h.push(t.createTextNode(i));f.textContent=\"\",c=0;while(i=h[c++])if((!r||-1===x.inArray(i,r))&&(u=x.contains(i.ownerDocument,i),o=mt(f.appendChild(i),\"script\"),u&&dt(o),n)){l=0;while(i=o[l++])at.test(i.type||\"\")&&n.push(i)}return f},cleanData:function(e){var t,n,r,i,o,s,a=x.event.special,u=0;for(;(n=e[u])!==undefined;u++){if(F.accepts(n)&&(o=n[q.expando],o&&(t=q.cache[o]))){if(r=Object.keys(t.events||{}),r.length)for(s=0;(i=r[s])!==undefined;s++)a[i]?x.event.remove(n,i):x.removeEvent(n,i,t.handle);q.cache[o]&&delete q.cache[o]}delete L.cache[n[L.expando]]}},_evalUrl:function(e){return x.ajax({url:e,type:\"GET\",dataType:\"script\",async:!1,global:!1,\"throws\":!0})}});function pt(e,t){return x.nodeName(e,\"table\")&&x.nodeName(1===t.nodeType?t:t.firstChild,\"tr\")?e.getElementsByTagName(\"tbody\")[0]||e.appendChild(e.ownerDocument.createElement(\"tbody\")):e}function ft(e){return e.type=(null!==e.getAttribute(\"type\"))+\"/\"+e.type,e}function ht(e){var t=ut.exec(e.type);return t?e.type=t[1]:e.removeAttribute(\"type\"),e}function dt(e,t){var n=e.length,r=0;for(;n>r;r++)q.set(e[r],\"globalEval\",!t||q.get(t[r],\"globalEval\"))}function gt(e,t){var n,r,i,o,s,a,u,l;if(1===t.nodeType){if(q.hasData(e)&&(o=q.access(e),s=q.set(t,o),l=o.events)){delete s.handle,s.events={};for(i in l)for(n=0,r=l[i].length;r>n;n++)x.event.add(t,i,l[i][n])}L.hasData(e)&&(a=L.access(e),u=x.extend({},a),L.set(t,u))}}function mt(e,t){var n=e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):e.querySelectorAll?e.querySelectorAll(t||\"*\"):[];return t===undefined||t&&x.nodeName(e,t)?x.merge([e],n):n}function yt(e,t){var n=t.nodeName.toLowerCase();\"input\"===n&&ot.test(e.type)?t.checked=e.checked:(\"input\"===n||\"textarea\"===n)&&(t.defaultValue=e.defaultValue)}x.fn.extend({wrapAll:function(e){var t;return x.isFunction(e)?this.each(function(t){x(this).wrapAll(e.call(this,t))}):(this[0]&&(t=x(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,\"body\")||x(this).replaceWith(this.childNodes)}).end()}});var vt,xt,bt=/^(none|table(?!-c[ea]).+)/,wt=/^margin/,Tt=RegExp(\"^(\"+b+\")(.*)$\",\"i\"),Ct=RegExp(\"^(\"+b+\")(?!px)[a-z%]+$\",\"i\"),kt=RegExp(\"^([+-])=(\"+b+\")\",\"i\"),Nt={BODY:\"block\"},Et={position:\"absolute\",visibility:\"hidden\",display:\"block\"},St={letterSpacing:0,fontWeight:400},jt=[\"Top\",\"Right\",\"Bottom\",\"Left\"],Dt=[\"Webkit\",\"O\",\"Moz\",\"ms\"];function At(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Dt.length;while(i--)if(t=Dt[i]+n,t in e)return t;return r}function Lt(e,t){return e=t||e,\"none\"===x.css(e,\"display\")||!x.contains(e.ownerDocument,e)}function qt(t){return e.getComputedStyle(t,null)}function Ht(e,t){var n,r,i,o=[],s=0,a=e.length;for(;a>s;s++)r=e[s],r.style&&(o[s]=q.get(r,\"olddisplay\"),n=r.style.display,t?(o[s]||\"none\"!==n||(r.style.display=\"\"),\"\"===r.style.display&&Lt(r)&&(o[s]=q.access(r,\"olddisplay\",Rt(r.nodeName)))):o[s]||(i=Lt(r),(n&&\"none\"!==n||!i)&&q.set(r,\"olddisplay\",i?n:x.css(r,\"display\"))));for(s=0;a>s;s++)r=e[s],r.style&&(t&&\"none\"!==r.style.display&&\"\"!==r.style.display||(r.style.display=t?o[s]||\"\":\"none\"));return e}x.fn.extend({css:function(e,t){return x.access(this,function(e,t,n){var r,i,o={},s=0;if(x.isArray(t)){for(r=qt(e),i=t.length;i>s;s++)o[t[s]]=x.css(e,t[s],!1,r);return o}return n!==undefined?x.style(e,t,n):x.css(e,t)},e,t,arguments.length>1)},show:function(){return Ht(this,!0)},hide:function(){return Ht(this)},toggle:function(e){return\"boolean\"==typeof e?e?this.show():this.hide():this.each(function(){Lt(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=vt(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{\"float\":\"cssFloat\"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,s,a=x.camelCase(t),u=e.style;return t=x.cssProps[a]||(x.cssProps[a]=At(u,a)),s=x.cssHooks[t]||x.cssHooks[a],n===undefined?s&&\"get\"in s&&(i=s.get(e,!1,r))!==undefined?i:u[t]:(o=typeof n,\"string\"===o&&(i=kt.exec(n))&&(n=(i[1]+1)*i[2]+parseFloat(x.css(e,t)),o=\"number\"),null==n||\"number\"===o&&isNaN(n)||(\"number\"!==o||x.cssNumber[a]||(n+=\"px\"),x.support.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(u[t]=\"inherit\"),s&&\"set\"in s&&(n=s.set(e,n,r))===undefined||(u[t]=n)),undefined)}},css:function(e,t,n,r){var i,o,s,a=x.camelCase(t);return t=x.cssProps[a]||(x.cssProps[a]=At(e.style,a)),s=x.cssHooks[t]||x.cssHooks[a],s&&\"get\"in s&&(i=s.get(e,!0,n)),i===undefined&&(i=vt(e,t,r)),\"normal\"===i&&t in St&&(i=St[t]),\"\"===n||n?(o=parseFloat(i),n===!0||x.isNumeric(o)?o||0:i):i}}),vt=function(e,t,n){var r,i,o,s=n||qt(e),a=s?s.getPropertyValue(t)||s[t]:undefined,u=e.style;return s&&(\"\"!==a||x.contains(e.ownerDocument,e)||(a=x.style(e,t)),Ct.test(a)&&wt.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=s.width,u.width=r,u.minWidth=i,u.maxWidth=o)),a};function Ot(e,t,n){var r=Tt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||\"px\"):t}function Ft(e,t,n,r,i){var o=n===(r?\"border\":\"content\")?4:\"width\"===t?1:0,s=0;for(;4>o;o+=2)\"margin\"===n&&(s+=x.css(e,n+jt[o],!0,i)),r?(\"content\"===n&&(s-=x.css(e,\"padding\"+jt[o],!0,i)),\"margin\"!==n&&(s-=x.css(e,\"border\"+jt[o]+\"Width\",!0,i))):(s+=x.css(e,\"padding\"+jt[o],!0,i),\"padding\"!==n&&(s+=x.css(e,\"border\"+jt[o]+\"Width\",!0,i)));return s}function Pt(e,t,n){var r=!0,i=\"width\"===t?e.offsetWidth:e.offsetHeight,o=qt(e),s=x.support.boxSizing&&\"border-box\"===x.css(e,\"boxSizing\",!1,o);if(0>=i||null==i){if(i=vt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Ct.test(i))return i;r=s&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+Ft(e,t,n||(s?\"border\":\"content\"),r,o)+\"px\"}function Rt(e){var t=o,n=Nt[e];return n||(n=Mt(e,t),\"none\"!==n&&n||(xt=(xt||x(\"