Merge ~ahasenack/ubuntu/+source/python-maxminddb:focal-python-maxminddb-1.5.2-update into ubuntu/+source/python-maxminddb:ubuntu/devel
- Git
- lp:~ahasenack/ubuntu/+source/python-maxminddb
- focal-python-maxminddb-1.5.2-update
- Merge into ubuntu/devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Andreas Hasenack | ||||
Approved revision: | 21f19875d091eecd13074ff3e7fbed52e3000507 | ||||
Merge reported by: | Andreas Hasenack | ||||
Merged at revision: | 21f19875d091eecd13074ff3e7fbed52e3000507 | ||||
Proposed branch: | ~ahasenack/ubuntu/+source/python-maxminddb:focal-python-maxminddb-1.5.2-update | ||||
Merge into: | ubuntu/+source/python-maxminddb:ubuntu/devel | ||||
Diff against target: |
69325 lines (+16657/-798) 42 files modified
HISTORY.rst (+29/-4) PKG-INFO (+140/-0) README.rst (+14/-5) debian/changelog (+16/-0) debian/control (+3/-1) debian/copyright (+1/-1) debian/patches/rebuild-sphinx-docs.patch (+283/-0) debian/patches/series (+1/-0) debian/rules (+5/-4) dev/null (+0/-528) docs/html/.buildinfo (+4/-0) docs/html/_sources/index.rst.txt (+1/-1) docs/html/_static/basic.css (+768/-0) docs/html/_static/doctools.js (+314/-0) docs/html/_static/documentation_options.js (+11/-0) docs/html/_static/jquery-3.4.1.js (+10598/-0) docs/html/_static/jquery.js (+2/-0) docs/html/_static/language_data.js (+297/-0) docs/html/_static/pygments.css (+69/-0) docs/html/_static/searchtools.js (+506/-0) docs/html/_static/sphinxdoc.css (+345/-0) docs/html/_static/underscore-1.3.1.js (+999/-0) docs/html/_static/underscore.js (+31/-0) docs/html/genindex.html (+218/-0) docs/html/index.html (+439/-0) docs/html/py-modindex.html (+105/-0) docs/html/search.html (+91/-0) docs/html/searchindex.js (+1/-0) extension/maxminddb.c (+759/-0) maxminddb.egg-info/PKG-INFO (+140/-0) maxminddb.egg-info/SOURCES.txt (+74/-0) maxminddb.egg-info/dependency_links.txt (+1/-0) maxminddb.egg-info/top_level.txt (+1/-0) maxminddb/__init__.py (+3/-3) maxminddb/compat.py (+0/-3) maxminddb/decoder.py (+64/-51) maxminddb/file.py (+3/-5) maxminddb/reader.py (+45/-28) setup.cfg (+5/-1) setup.py (+51/-61) tests/decoder_test.py (+3/-6) tests/reader_test.py (+217/-96) |
||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Christian Ehrhardt (community) | Approve | ||
Canonical Server | Pending | ||
Review via email: mp+380854@code.launchpad.net |
Commit message
Description of the change
Update to version 1.5.2, going ahead of debian.
Long description because this is for a MIR. FFe bug linked.
PPA: https:/
Long explanation for the single patch I added.
TL;DR we don't want to ship duplicates of javascript files in the doc package, like jquery, which has its own deb package already.
There are two places for upstream releases:
- https:/
- https:/
The github tarballs lack the test files, so tests fail to run. But they have the doc source directory, which means sphinx can be used to rebuild the docs.
The pypi tarball has the sphinx docs already built, and has the test files. Looks like a winner!
The problem with sphinx docs being already built, despite making lintian unhappy, is that it means some javascript files will be shipped with the doc package, files for which we have packages in ubuntu already. Duplication. Security (potential) nightmare.
dh_sphinxdoc can be used to detect this, and replace those files with symlinks to /usr/share/
To do that, dh_sphinxdoc checks the md5 hash of the files in /usr/share/
dh_sphinxdoc is also not happy with the built documentation, and complains about unknown javascript files, and has a bug[1] which was fixed in debian already, but not Ubuntu.
I thought it would be easier to rebuild the sphinx doc in this package than to copy over from some other git repo the binary database files used for the tests. After all, the "source" of the documentation is a simple index.rst file that is shipped in the tarball, despite the docs being pre-built.
For the other changes:
- didn't cherry-pick https:/
- lintian fix for R³
- clean up the clean (hah) d/rules override
Let's talk about lintian:
$ lintian -I --pedantic
E: python-maxminddb source: source-is-missing docs/html/
E: python-maxminddb source: source-is-missing docs/html/
I: python-maxminddb source: out-of-
P: python-maxminddb source: source-
P: python-maxminddb source: source-
P: python-maxminddb source: source-
P: python-maxminddb source: very-long-
P: python-maxminddb source: very-long-
Lintian is definitely upset with the built sphinx docs. Since we are rebuilding the docs, there isn't really much to do about the above. Perhaps the "E:" tags could be fixed by this, as suggested by lintian:
N: Please repack your package to include the source or add it to
N: "debian/
I mean the debian/
Andreas Hasenack (ahasenack) wrote : | # |
> I also know that mdeslaur asked for the tests to work, and I found at least those to run properly > at build:
> Ran 231 tests in 3.925s
That was for libcbor, of the openssh fido mir
Andreas Hasenack (ahasenack) wrote : | # |
Thanks for the review. I'll upload this, so we can close the MIR, and then check with debian.
Andreas Hasenack (ahasenack) wrote : | # |
Taggina and uploading 21f19875d091eec
$ git push pkg upload/
Enumerating objects: 153, done.
Counting objects: 100% (153/153), done.
Delta compression using up to 4 threads
Compressing objects: 100% (102/102), done.
Writing objects: 100% (109/109), 273.36 KiB | 283.00 KiB/s, done.
Total 109 (delta 33), reused 1 (delta 0)
remote: Resolving deltas: 100% (33/33), completed with 15 local objects.
To ssh://git.
* [new tag] upload/
$ dput ubuntu ../python-
Checking signature on .changes
gpg: ../python-
Checking signature on .dsc
gpg: ../python-
Uploading to ubuntu (via ftp to upload.ubuntu.com):
Uploading python-
Uploading python-
Uploading python-
Uploading python-
Uploading python-
Successfully uploaded packages.
Andreas Hasenack (ahasenack) wrote : | # |
This migrated into focal release.
Preview Diff
1 | diff --git a/.gitignore b/.gitignore |
2 | deleted file mode 100644 |
3 | index 7c72610..0000000 |
4 | --- a/.gitignore |
5 | +++ /dev/null |
6 | @@ -1,20 +0,0 @@ |
7 | -*.egg |
8 | -*.iml |
9 | -*.pyc |
10 | -*.so |
11 | -*.sw? |
12 | -*~ |
13 | -.coverage |
14 | -.eggs |
15 | -.idea |
16 | -build |
17 | -core |
18 | -dist |
19 | -docs/_build |
20 | -docs/html |
21 | -env/ |
22 | -MANIFEST |
23 | -maxminddb.egg-info/ |
24 | -pylint.txt |
25 | -valgrind-python.supp |
26 | -violations.pyflakes.txt |
27 | diff --git a/.gitmodules b/.gitmodules |
28 | deleted file mode 100644 |
29 | index 9cf24ec..0000000 |
30 | --- a/.gitmodules |
31 | +++ /dev/null |
32 | @@ -1,3 +0,0 @@ |
33 | -[submodule "tests/data"] |
34 | - path = tests/data |
35 | - url = git://github.com/maxmind/MaxMind-DB.git |
36 | diff --git a/.pylintrc b/.pylintrc |
37 | deleted file mode 100644 |
38 | index 19353df..0000000 |
39 | --- a/.pylintrc |
40 | +++ /dev/null |
41 | @@ -1,6 +0,0 @@ |
42 | -[MESSAGES CONTROL] |
43 | -disable=R0201,W0105 |
44 | - |
45 | -[BASIC] |
46 | - |
47 | -no-docstring-rgx=_.* |
48 | diff --git a/.travis-yapf.sh b/.travis-yapf.sh |
49 | deleted file mode 100755 |
50 | index eb9f613..0000000 |
51 | --- a/.travis-yapf.sh |
52 | +++ /dev/null |
53 | @@ -1,14 +0,0 @@ |
54 | -#!/bin/bash |
55 | - |
56 | -diff=$(yapf -rd maxminddb tests) |
57 | - |
58 | -if [[ $? != 0 ]]; then |
59 | - echo "yapf failed to run." |
60 | - echo "$diff" |
61 | - exit $? |
62 | -elif [[ $diff ]]; then |
63 | - echo "$diff" |
64 | - exit 1 |
65 | -else |
66 | - exit 0 |
67 | -fi |
68 | diff --git a/.travis.yml b/.travis.yml |
69 | deleted file mode 100644 |
70 | index 3e8e174..0000000 |
71 | --- a/.travis.yml |
72 | +++ /dev/null |
73 | @@ -1,55 +0,0 @@ |
74 | -language: python |
75 | - |
76 | -python: |
77 | - - 2.6 |
78 | - - 2.7 |
79 | - - 3.3 |
80 | - - 3.4 |
81 | - - 3.5 |
82 | - - 3.6 |
83 | - - 3.7-dev |
84 | - - pypy |
85 | - |
86 | -before_install: |
87 | - - git submodule update --init --recursive |
88 | - - git clone --recursive git://github.com/maxmind/libmaxminddb |
89 | - - cd libmaxminddb |
90 | - - ./bootstrap |
91 | - - ./configure |
92 | - - make |
93 | - - sudo make install |
94 | - - sudo ldconfig |
95 | - - cd .. |
96 | - - pip install coverage coveralls |
97 | - - if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then pip install pylint yapf; fi |
98 | - - if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install unittest2; fi |
99 | - |
100 | -script: |
101 | - - if [[ $TRAVIS_PYTHON_VERSION != 'pypy' ]]; then export MM_FORCE_EXT_TESTS=1; fi |
102 | - - CFLAGS="-Werror -Wall -Wextra" coverage run --source maxminddb setup.py test |
103 | - - if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then pylint --rcfile .pylintrc maxminddb/*.py; fi |
104 | - - if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then ./.travis-yapf.sh; fi |
105 | - |
106 | -after_success: |
107 | - - coveralls |
108 | - |
109 | -notifications: |
110 | - email: |
111 | - recipients: |
112 | - - dev-ci@maxmind.com |
113 | - on_success: change |
114 | - on_failure: always |
115 | - |
116 | -env: |
117 | - global: |
118 | - - secure: "pVcpV/al5Q607TbRzl/sbkdsx5hUjxehaJm6t5tgWrFn45icwdZrPw3JWcpt0R57NhPvXHxcJdm4WBtcGElWoDtR52QOW3yYh+gRw23y1MJg+5qHIbh5R1sOC/fLJ9TzQzvvRH5QQ5bKIe1hRQW9Cpqm7nX5Zhq6SqnAzcG1emE=" |
119 | - |
120 | -addons: |
121 | - coverity_scan: |
122 | - project: |
123 | - name: "maxmind/MaxMind-DB-Reader-python" |
124 | - description: "Build submitted via Travis CI" |
125 | - notification_email: dev-ci@maxmind.com |
126 | - build_command_prepend: "python setup.py clean" |
127 | - build_command: "python setup.py build" |
128 | - branch_pattern: .*coverity.* |
129 | diff --git a/.uncrustify.cfg b/.uncrustify.cfg |
130 | deleted file mode 100644 |
131 | index 46b4428..0000000 |
132 | --- a/.uncrustify.cfg |
133 | +++ /dev/null |
134 | @@ -1,78 +0,0 @@ |
135 | -# |
136 | -# based on uncrustify config file for the linux kernel |
137 | -# |
138 | - |
139 | -code_width = 80 |
140 | -indent_case_brace = 4 |
141 | -indent_columns = 4 |
142 | -indent_label = 2 # pos: absolute col, neg: relative column |
143 | -indent_with_tabs = 0 |
144 | - |
145 | -# |
146 | -# inter-symbol newlines |
147 | -# |
148 | -nl_brace_else = remove # "} else" vs "} \n else" - cuddle else |
149 | -nl_brace_while = remove # "} while" vs "} \n while" - cuddle while |
150 | -nl_do_brace = remove # "do {" vs "do \n {" |
151 | -nl_else_brace = remove # "else {" vs "else \n {" |
152 | -nl_enum_brace = remove # "enum {" vs "enum \n {" |
153 | -nl_fcall_brace = remove # "list_for_each() {" vs "list_for_each()\n{" |
154 | -nl_fdef_brace = force # "int foo() {" vs "int foo()\n{" |
155 | -nl_for_brace = remove # "for () {" vs "for () \n {" |
156 | -nl_func_var_def_blk = 0 # don't add newlines after a block of var declarations |
157 | -nl_if_brace = remove # "if () {" vs "if () \n {" |
158 | -nl_multi_line_define = true |
159 | -nl_struct_brace = remove # "struct {" vs "struct \n {" |
160 | -nl_switch_brace = remove # "switch () {" vs "switch () \n {" |
161 | -nl_union_brace = remove # "union {" vs "union \n {" |
162 | -nl_while_brace = remove # "while () {" vs "while () \n {" |
163 | - |
164 | - |
165 | -# |
166 | -# Source code modifications |
167 | -# |
168 | -mod_full_brace_do = force # "do a--; while ();" vs "do { a--; } while ();" |
169 | -mod_full_brace_for = force # "for () a--;" vs "for () { a--; }" |
170 | -mod_full_brace_if = force # "if (a) a--;" vs "if (a) { a--; }" |
171 | -mod_full_brace_nl = 3 # don't remove if more than 3 newlines |
172 | -mod_full_brace_while = force # "while (a) a--;" vs "while (a) { a--; }" |
173 | -mod_paren_on_return = remove # "return 1;" vs "return (1);" |
174 | - |
175 | - |
176 | -# |
177 | -# inter-character spacing options |
178 | -# |
179 | -sp_after_cast = remove # "(int) a" vs "(int)a" |
180 | -sp_after_comma = force |
181 | -sp_after_sparen = force # "if () {" vs "if (){" |
182 | -sp_arith = force |
183 | -sp_assign = force |
184 | -sp_assign = force |
185 | -sp_before_comma = remove |
186 | -sp_before_ptr_star = force # "char *foo" vs "char* foo |
187 | -sp_before_sparen = force # "if (" vs "if(" |
188 | -sp_between_ptr_star = remove # "char * *foo" vs "char **foo" |
189 | -sp_bool = force |
190 | -sp_compare = force |
191 | -sp_func_call_paren = remove # "foo (" vs "foo(" |
192 | -sp_func_def_paren = remove # "int foo (){" vs "int foo(){" |
193 | -sp_func_proto_paren = remove # "int foo ();" vs "int foo();" |
194 | -sp_inside_braces = force # "{ 1 }" vs "{1}" |
195 | -sp_inside_braces_enum = force # "{ 1 }" vs "{1}" |
196 | -sp_inside_braces_struct = force # "{ 1 }" vs "{1}" |
197 | -sp_inside_sparen = remove |
198 | -sp_paren_brace = force |
199 | -sp_sizeof_paren = remove # "sizeof (int)" vs "sizeof(int)" |
200 | - |
201 | -# |
202 | -# Aligning stuff |
203 | -# |
204 | -align_enum_equ_span = 4 # '=' in enum definition |
205 | -align_nl_cont = true |
206 | -align_on_tabstop = FALSE # align on tabstops |
207 | -align_right_cmt_span = 3 |
208 | -align_struct_init_span = 1 |
209 | -align_struct_init_span = 3 # align stuff in a structure init '= { }' |
210 | -align_var_def_star_style = 2 # void *foo; |
211 | -align_var_struct_span = 0 |
212 | -align_with_tabs = FALSE # use tabs to align |
213 | diff --git a/HISTORY.rst b/HISTORY.rst |
214 | index 390f5f0..5784604 100644 |
215 | --- a/HISTORY.rst |
216 | +++ b/HISTORY.rst |
217 | @@ -3,6 +3,31 @@ |
218 | History |
219 | ------- |
220 | |
221 | +1.5.2 (2019-12-20) |
222 | +++++++++++++++++++ |
223 | + |
224 | +* Minor performance improvements in the pure Python reader. |
225 | + |
226 | +1.5.1 (2019-09-27) |
227 | +++++++++++++++++++ |
228 | + |
229 | +* Fix a possible segfault due to not correctly incrementing the reference |
230 | + on a returned object. |
231 | + |
232 | +1.5.0 (2019-09-27) |
233 | +++++++++++++++++++ |
234 | + |
235 | +* Python 3.3 and 3.4 are no longer supported. |
236 | +* The extension source directory was moved to prevent an ``ImportWarning`` |
237 | + when importing the module on Python 2 with ``-Wdefault`` set. Reported by |
238 | + David Szotten and Craig de Stigter. GitHub #31. |
239 | +* The ``get`` method now accepts ``ipaddress.IPv4Address`` and |
240 | + ``ipaddress.IPv6Address`` objects in addition to strings. This works with |
241 | + both the pure Python implementation as well as the extension. Based on a |
242 | + pull request #48 by Eric Pruitt. GitHub #50. |
243 | +* A new method, ``get_with_prefix_len``, was added. This method returns a |
244 | + tuple containing the record and the prefix length. |
245 | + |
246 | 1.4.1 (2018-06-22) |
247 | ++++++++++++++++++ |
248 | |
249 | @@ -12,13 +37,13 @@ History |
250 | ++++++++++++++++++ |
251 | |
252 | * IMPORTANT: Previously, the pure Python reader would allow |
253 | - `ipaddress.IPv4Address` and `ipaddress.IPv6Address` objects when calling |
254 | - `.get()`. This would fail with the C extension. The fact that these objects |
255 | + ``ipaddress.IPv4Address`` and ``ipaddress.IPv6Address`` objects when calling |
256 | + ``.get()``. This would fail with the C extension. The fact that these objects |
257 | worked at all was an implementation detail and has varied with different |
258 | releases. This release makes the pure Python implementation consistent |
259 | - with the extension. A `TypeError` will now be thrown if you attempt to |
260 | + with the extension. A ``TypeError`` will now be thrown if you attempt to |
261 | use these types with either the pure Python implementation or the |
262 | - extension. The IP address passed to `.get()` should be a string type. |
263 | + extension. The IP address passed to ``.get()`` should be a string type. |
264 | * Fix issue where incorrect size was used when unpacking some types with the |
265 | pure Python reader. Reported by Lee Symes. GitHub #30. |
266 | * You may now pass in the database via a file descriptor rather than a file |
267 | diff --git a/PKG-INFO b/PKG-INFO |
268 | new file mode 100644 |
269 | index 0000000..1a961e9 |
270 | --- /dev/null |
271 | +++ b/PKG-INFO |
272 | @@ -0,0 +1,140 @@ |
273 | +Metadata-Version: 1.2 |
274 | +Name: maxminddb |
275 | +Version: 1.5.2 |
276 | +Summary: Reader for the MaxMind DB format |
277 | +Home-page: http://www.maxmind.com/ |
278 | +Author: Gregory Oschwald |
279 | +Author-email: goschwald@maxmind.com |
280 | +License: Apache License, Version 2.0 |
281 | +Description: ======================== |
282 | + MaxMind DB Python Module |
283 | + ======================== |
284 | + |
285 | + Description |
286 | + ----------- |
287 | + |
288 | + This is a Python module for reading MaxMind DB files. The module includes both |
289 | + a pure Python reader and an optional C extension. |
290 | + |
291 | + MaxMind DB is a binary file format that stores data indexed by IP address |
292 | + subnets (IPv4 or IPv6). |
293 | + |
294 | + Installation |
295 | + ------------ |
296 | + |
297 | + If you want to use the C extension, you must first install `libmaxminddb |
298 | + <https://github.com/maxmind/libmaxminddb>`_ C library installed before |
299 | + installing this extension. If the library is not available, the module will |
300 | + fall-back to a pure Python implementation. |
301 | + |
302 | + To install maxminddb, type: |
303 | + |
304 | + .. code-block:: bash |
305 | + |
306 | + $ pip install maxminddb |
307 | + |
308 | + If you are not able to use pip, you may also use easy_install from the |
309 | + source directory: |
310 | + |
311 | + .. code-block:: bash |
312 | + |
313 | + $ easy_install . |
314 | + |
315 | + Usage |
316 | + ----- |
317 | + |
318 | + To use this module, you must first download or create a MaxMind DB file. We |
319 | + provide `free GeoLite2 databases |
320 | + <https://dev.maxmind.com/geoip/geoip2/geolite2>`_. These files must be |
321 | + decompressed with ``gunzip``. |
322 | + |
323 | + After you have obtained a database and imported the module, call |
324 | + ``open_database`` with a path, or file descriptor (in the case of MODE_FD), |
325 | + to the database as the first argument. Optionally, you may pass a mode as the |
326 | + second argument. The modes are exported from ``maxminddb``. Valid modes are: |
327 | + |
328 | + * MODE_MMAP_EXT - use the C extension with memory map. |
329 | + * MODE_MMAP - read from memory map. Pure Python. |
330 | + * MODE_FILE - read database as standard file. Pure Python. |
331 | + * MODE_MEMORY - load database into memory. Pure Python. |
332 | + * MODE_FD - load database into memory from a file descriptor. Pure Python. |
333 | + * MODE_AUTO - try MODE_MMAP_EXT, MODE_MMAP, MODE_FILE in that order. Default. |
334 | + |
335 | + **NOTE**: When using ``MODE_FD``, it is the *caller's* responsibility to be |
336 | + sure that the file descriptor gets closed properly. The caller may close the |
337 | + file descriptor immediately after the ``Reader`` object is created. |
338 | + |
339 | + The ``open_database`` function returns a ``Reader`` object. To look up an IP |
340 | + address, use the ``get`` method on this object. The method will return the |
341 | + corresponding values for the IP address from the database (e.g., a dictionary |
342 | + for GeoIP2/GeoLite2 databases). If the database does not contain a record for |
343 | + that IP address, the method will return ``None``. |
344 | + |
345 | + If you wish to also retrieve the prefix length for the record, use the |
346 | + ``get_with_prefix_len`` method. This returns a tuple containing the record |
347 | + followed by the network prefix length associated with the record. |
348 | + |
349 | + Example |
350 | + ------- |
351 | + |
352 | + .. code-block:: pycon |
353 | + |
354 | + >>> import maxminddb |
355 | + >>> |
356 | + >>> reader = maxminddb.open_database('GeoLite2-City.mmdb') |
357 | + >>> |
358 | + >>> reader.get('1.1.1.1') |
359 | + {'country': ... } |
360 | + >>> |
361 | + >>> reader.get_with_prefix_len('1.1.1.1') |
362 | + ({'country': ... }, 24) |
363 | + >>> |
364 | + >>> reader.close() |
365 | + |
366 | + Exceptions |
367 | + ---------- |
368 | + |
369 | + The module will return an ``InvalidDatabaseError`` if the database is corrupt |
370 | + or otherwise invalid. A ``ValueError`` will be thrown if you look up an |
371 | + invalid IP address or an IPv6 address in an IPv4 database. |
372 | + |
373 | + Requirements |
374 | + ------------ |
375 | + |
376 | + This code requires Python 2.7+ or 3.5+. Older versions are not supported. The C |
377 | + extension requires CPython. The pure Python implementation has been tested with |
378 | + PyPy. |
379 | + |
380 | + On Python 2, the `ipaddress module <https://pypi.python.org/pypi/ipaddress>`_ is |
381 | + required. |
382 | + |
383 | + Versioning |
384 | + ---------- |
385 | + |
386 | + The MaxMind DB Python module uses `Semantic Versioning <https://semver.org/>`_. |
387 | + |
388 | + Support |
389 | + ------- |
390 | + |
391 | + Please report all issues with this code using the `GitHub issue tracker |
392 | + <https://github.com/maxmind/MaxMind-DB-Reader-python/issues>`_ |
393 | + |
394 | + If you are having an issue with a MaxMind service that is not specific to this |
395 | + API, please contact `MaxMind support <https://www.maxmind.com/en/support>`_ for |
396 | + assistance. |
397 | + |
398 | +Platform: UNKNOWN |
399 | +Classifier: Development Status :: 5 - Production/Stable |
400 | +Classifier: Environment :: Web Environment |
401 | +Classifier: Intended Audience :: Developers |
402 | +Classifier: Intended Audience :: System Administrators |
403 | +Classifier: License :: OSI Approved :: Apache Software License |
404 | +Classifier: Programming Language :: Python :: 2.7 |
405 | +Classifier: Programming Language :: Python :: 3 |
406 | +Classifier: Programming Language :: Python :: 3.5 |
407 | +Classifier: Programming Language :: Python :: 3.6 |
408 | +Classifier: Programming Language :: Python :: 3.7 |
409 | +Classifier: Programming Language :: Python |
410 | +Classifier: Topic :: Internet :: Proxy Servers |
411 | +Classifier: Topic :: Internet |
412 | +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* |
413 | diff --git a/README.rst b/README.rst |
414 | index aa2eaab..e905493 100644 |
415 | --- a/README.rst |
416 | +++ b/README.rst |
417 | @@ -37,7 +37,7 @@ Usage |
418 | |
419 | To use this module, you must first download or create a MaxMind DB file. We |
420 | provide `free GeoLite2 databases |
421 | -<http://dev.maxmind.com/geoip/geoip2/geolite2>`_. These files must be |
422 | +<https://dev.maxmind.com/geoip/geoip2/geolite2>`_. These files must be |
423 | decompressed with ``gunzip``. |
424 | |
425 | After you have obtained a database and imported the module, call |
426 | @@ -62,6 +62,10 @@ corresponding values for the IP address from the database (e.g., a dictionary |
427 | for GeoIP2/GeoLite2 databases). If the database does not contain a record for |
428 | that IP address, the method will return ``None``. |
429 | |
430 | +If you wish to also retrieve the prefix length for the record, use the |
431 | +``get_with_prefix_len`` method. This returns a tuple containing the record |
432 | +followed by the network prefix length associated with the record. |
433 | + |
434 | Example |
435 | ------- |
436 | |
437 | @@ -70,9 +74,13 @@ Example |
438 | >>> import maxminddb |
439 | >>> |
440 | >>> reader = maxminddb.open_database('GeoLite2-City.mmdb') |
441 | + >>> |
442 | >>> reader.get('1.1.1.1') |
443 | {'country': ... } |
444 | >>> |
445 | + >>> reader.get_with_prefix_len('1.1.1.1') |
446 | + ({'country': ... }, 24) |
447 | + >>> |
448 | >>> reader.close() |
449 | |
450 | Exceptions |
451 | @@ -85,8 +93,9 @@ invalid IP address or an IPv6 address in an IPv4 database. |
452 | Requirements |
453 | ------------ |
454 | |
455 | -This code requires Python 2.6+ or 3.3+. The C extension requires CPython. The |
456 | -pure Python implementation has been tested with PyPy. |
457 | +This code requires Python 2.7+ or 3.5+. Older versions are not supported. The C |
458 | +extension requires CPython. The pure Python implementation has been tested with |
459 | +PyPy. |
460 | |
461 | On Python 2, the `ipaddress module <https://pypi.python.org/pypi/ipaddress>`_ is |
462 | required. |
463 | @@ -94,7 +103,7 @@ required. |
464 | Versioning |
465 | ---------- |
466 | |
467 | -The MaxMind DB Python module uses `Semantic Versioning <http://semver.org/>`_. |
468 | +The MaxMind DB Python module uses `Semantic Versioning <https://semver.org/>`_. |
469 | |
470 | Support |
471 | ------- |
472 | @@ -103,5 +112,5 @@ Please report all issues with this code using the `GitHub issue tracker |
473 | <https://github.com/maxmind/MaxMind-DB-Reader-python/issues>`_ |
474 | |
475 | If you are having an issue with a MaxMind service that is not specific to this |
476 | -API, please contact `MaxMind support <http://www.maxmind.com/en/support>`_ for |
477 | +API, please contact `MaxMind support <https://www.maxmind.com/en/support>`_ for |
478 | assistance. |
479 | diff --git a/debian/changelog b/debian/changelog |
480 | index ff5ce3d..d333eda 100644 |
481 | --- a/debian/changelog |
482 | +++ b/debian/changelog |
483 | @@ -1,3 +1,19 @@ |
484 | +python-maxminddb (1.5.2-0ubuntu1) focal; urgency=medium |
485 | + |
486 | + * New upstream release: 1.5.2 (LP: #1867919) |
487 | + * Rebuild sphinx docs to avoid shipping other copies of several |
488 | + javascript files, like jquery.js, in the doc package: |
489 | + - d/p/rebuild-sphinx-docs.patch: pull in upstream's sphinx-build conf.py |
490 | + - d/rules: use docs-source for building docs |
491 | + - d/rules: remove the index.rst file from docs-source during clean |
492 | + * d/control: add Rules-Requires-Root: no |
493 | + * d/rules: update dh_auto_clean override |
494 | + |
495 | + [ Faidon Liambotis] |
496 | + * d/copyright: Switch the copyright format URI to https |
497 | + |
498 | + -- Andreas Hasenack <andreas@canonical.com> Wed, 18 Mar 2020 17:57:58 -0300 |
499 | + |
500 | python-maxminddb (1.4.1-2build2) focal; urgency=medium |
501 | |
502 | * No-change rebuild to drop python3.7. |
503 | diff --git a/debian/control b/debian/control |
504 | index 390ce71..1c9fa11 100644 |
505 | --- a/debian/control |
506 | +++ b/debian/control |
507 | @@ -1,5 +1,6 @@ |
508 | Source: python-maxminddb |
509 | -Maintainer: Faidon Liambotis <paravoid@debian.org> |
510 | +Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> |
511 | +XSBC-Original-Maintainer: Faidon Liambotis <paravoid@debian.org> |
512 | Section: python |
513 | Priority: optional |
514 | Build-Depends: |
515 | @@ -17,6 +18,7 @@ Homepage: https://github.com/maxmind/MaxMind-DB-Reader-python |
516 | Vcs-Browser: https://salsa.debian.org/debian/python-maxminddb |
517 | Vcs-Git: https://salsa.debian.org/debian/python-maxminddb.git |
518 | Testsuite: autopkgtest-pkg-python |
519 | +Rules-Requires-Root: no |
520 | |
521 | Package: python3-maxminddb |
522 | Architecture: any |
523 | diff --git a/debian/copyright b/debian/copyright |
524 | index 7d6c0ba..365443a 100644 |
525 | --- a/debian/copyright |
526 | +++ b/debian/copyright |
527 | @@ -1,4 +1,4 @@ |
528 | -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ |
529 | +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ |
530 | Upstream-Name: MaxMind-DB-Reader-python |
531 | Source: https://github.com/maxmind/MaxMind-DB-Reader-python |
532 | |
533 | diff --git a/debian/patches/rebuild-sphinx-docs.patch b/debian/patches/rebuild-sphinx-docs.patch |
534 | new file mode 100644 |
535 | index 0000000..bbce8e6 |
536 | --- /dev/null |
537 | +++ b/debian/patches/rebuild-sphinx-docs.patch |
538 | @@ -0,0 +1,283 @@ |
539 | +Description: Allow rebuilding the docs with sphinx |
540 | + The upstream tarball at https://pypi.org/project/maxminddb/ has the sphinx |
541 | + docs already built, but using jquery 3.4.1. Since Ubuntu has 3.3.1 at this |
542 | + time, dh_sphinxdoc won't symlink the jquery.js file to the sphinx copy in |
543 | + /usr/share/javascript/sphinxdoc/1.0/jquery.js, which will result in us |
544 | + shipping another jquery.js file in a debian package. |
545 | + . |
546 | + The easiest solution is to rebuild the docs at package build time, but that |
547 | + upstream tarball does not have the conf.py file needed by sphinx-build. That |
548 | + is available in the upstream git repo at |
549 | + https://github.com/maxmind/MaxMind-DB-Reader-python/blob/master/docs/conf.py |
550 | + or in the github tarball releases at |
551 | + https://github.com/maxmind/MaxMind-DB-Reader-python/releases |
552 | + . |
553 | + The github tarball release, on the other hand, do not have the datafiles used |
554 | + for the tests: they come from another remote (see the "data" directory in |
555 | + https://github.com/maxmind/MaxMind-DB-Reader-python/tree/master/tests). If we |
556 | + use the github tarball releases, we don't get to run the tests. |
557 | + . |
558 | + I believe the simplest solution is to copy over the docs/conf.py file from the |
559 | + github 1.5.2 release tarball, and this is what this patch does: |
560 | + . |
561 | + https://github.com/maxmind/MaxMind-DB-Reader-python/archive/v1.5.2.tar.gz |
562 | + SHA256: d60742040d99cbe75ca049dc901b57867b4ff07df7058af640768d51d92a82a3 |
563 | +Author: Andreas Hasenack <andreas@canonical.com) |
564 | +Forwarded: not-needed |
565 | +Last-Update: 2020-03-18 |
566 | +--- |
567 | +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
568 | +diff --git a/docs-source/conf.py b/docs-source/conf.py |
569 | +new file mode 100644 |
570 | +index 0000000..f0ae2c9 |
571 | +--- /dev/null |
572 | ++++ b/docs-source/conf.py |
573 | +@@ -0,0 +1,248 @@ |
574 | ++#!/usr/bin/env python3 |
575 | ++# -*- coding: utf-8 -*- |
576 | ++# |
577 | ++# maxminddb documentation build configuration file, created by |
578 | ++# sphinx-quickstart on Tue Apr 9 13:34:57 2013. |
579 | ++# |
580 | ++# This file is execfile()d with the current directory set to its containing dir. |
581 | ++# |
582 | ++# Note that not all possible configuration values are present in this |
583 | ++# autogenerated file. |
584 | ++# |
585 | ++# All configuration values have a default; values that are commented out |
586 | ++# serve to show the default. |
587 | ++ |
588 | ++import sys |
589 | ++import os |
590 | ++ |
591 | ++sys.path.insert(0, os.path.abspath('..')) |
592 | ++import maxminddb |
593 | ++ |
594 | ++__version__ = maxminddb.__version__ |
595 | ++ |
596 | ++# If extensions (or modules to document with autodoc) are in another directory, |
597 | ++# add these directories to sys.path here. If the directory is relative to the |
598 | ++# documentation root, use os.path.abspath to make it absolute, like shown here. |
599 | ++sys.path.insert(0, os.path.abspath('..')) |
600 | ++ |
601 | ++# -- General configuration ----------------------------------------------- |
602 | ++ |
603 | ++# If your documentation needs a minimal Sphinx version, state it here. |
604 | ++#needs_sphinx = '1.0' |
605 | ++ |
606 | ++# Add any Sphinx extension module names here, as strings. They can be extensions |
607 | ++# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. |
608 | ++extensions = [ |
609 | ++ 'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', |
610 | ++ 'sphinx.ext.coverage' |
611 | ++] |
612 | ++ |
613 | ++# Add any paths that contain templates here, relative to this directory. |
614 | ++templates_path = ['_templates'] |
615 | ++ |
616 | ++# The suffix of source filenames. |
617 | ++source_suffix = '.rst' |
618 | ++ |
619 | ++# The encoding of source files. |
620 | ++#source_encoding = 'utf-8-sig' |
621 | ++ |
622 | ++# The master toctree document. |
623 | ++master_doc = 'index' |
624 | ++ |
625 | ++# General information about the project. |
626 | ++project = 'maxminddb' |
627 | ++copyright = '2013-2019, MaxMind, Inc.' |
628 | ++ |
629 | ++# The version info for the project you're documenting, acts as replacement for |
630 | ++# |version| and |release|, also used in various other places throughout the |
631 | ++# built documents. |
632 | ++# |
633 | ++# The short X.Y version. |
634 | ++version = __version__ |
635 | ++# The full version, including alpha/beta/rc tags. |
636 | ++release = __version__ |
637 | ++ |
638 | ++# The language for content autogenerated by Sphinx. Refer to documentation |
639 | ++# for a list of supported languages. |
640 | ++#language = None |
641 | ++ |
642 | ++# There are two options for replacing |today|: either, you set today to some |
643 | ++# non-false value, then it is used: |
644 | ++#today = '' |
645 | ++# Else, today_fmt is used as the format for a strftime call. |
646 | ++#today_fmt = '%B %d, %Y' |
647 | ++ |
648 | ++# List of patterns, relative to source directory, that match files and |
649 | ++# directories to ignore when looking for source files. |
650 | ++exclude_patterns = ['_build'] |
651 | ++ |
652 | ++# The reST default role (used for this markup: `text`) to use for all documents. |
653 | ++#default_role = None |
654 | ++ |
655 | ++# If true, '()' will be appended to :func: etc. cross-reference text. |
656 | ++#add_function_parentheses = True |
657 | ++ |
658 | ++# If true, the current module name will be prepended to all description |
659 | ++# unit titles (such as .. function::). |
660 | ++#add_module_names = True |
661 | ++ |
662 | ++# If true, sectionauthor and moduleauthor directives will be shown in the |
663 | ++# output. They are ignored by default. |
664 | ++#show_authors = False |
665 | ++ |
666 | ++# The name of the Pygments (syntax highlighting) style to use. |
667 | ++pygments_style = 'sphinx' |
668 | ++ |
669 | ++# A list of ignored prefixes for module index sorting. |
670 | ++#modindex_common_prefix = [] |
671 | ++ |
672 | ++# -- Options for HTML output --------------------------------------------- |
673 | ++ |
674 | ++# The theme to use for HTML and HTML Help pages. See the documentation for |
675 | ++# a list of builtin themes. |
676 | ++html_theme = 'sphinxdoc' |
677 | ++ |
678 | ++# Theme options are theme-specific and customize the look and feel of a theme |
679 | ++# further. For a list of options available for each theme, see the |
680 | ++# documentation. |
681 | ++#html_theme_options = {} |
682 | ++ |
683 | ++# Add any paths that contain custom themes here, relative to this directory. |
684 | ++#html_theme_path = [] |
685 | ++ |
686 | ++# The name for this set of Sphinx documents. If None, it defaults to |
687 | ++# "<project> v<release> documentation". |
688 | ++#html_title = None |
689 | ++ |
690 | ++# A shorter title for the navigation bar. Default is the same as html_title. |
691 | ++#html_short_title = None |
692 | ++ |
693 | ++# The name of an image file (relative to this directory) to place at the top |
694 | ++# of the sidebar. |
695 | ++#html_logo = None |
696 | ++ |
697 | ++# The name of an image file (within the static path) to use as favicon of the |
698 | ++# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 |
699 | ++# pixels large. |
700 | ++#html_favicon = None |
701 | ++ |
702 | ++# Add any paths that contain custom static files (such as style sheets) here, |
703 | ++# relative to this directory. They are copied after the builtin static files, |
704 | ++# so a file named "default.css" will overwrite the builtin "default.css". |
705 | ++html_static_path = ['_static'] |
706 | ++ |
707 | ++# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, |
708 | ++# using the given strftime format. |
709 | ++#html_last_updated_fmt = '%b %d, %Y' |
710 | ++ |
711 | ++# If true, SmartyPants will be used to convert quotes and dashes to |
712 | ++# typographically correct entities. |
713 | ++#html_use_smartypants = True |
714 | ++ |
715 | ++# Custom sidebar templates, maps document names to template names. |
716 | ++#html_sidebars = {} |
717 | ++ |
718 | ++# Additional templates that should be rendered to pages, maps page names to |
719 | ++# template names. |
720 | ++#html_additional_pages = {} |
721 | ++ |
722 | ++# If false, no module index is generated. |
723 | ++#html_domain_indices = True |
724 | ++ |
725 | ++# If false, no index is generated. |
726 | ++#html_use_index = True |
727 | ++ |
728 | ++# If true, the index is split into individual pages for each letter. |
729 | ++#html_split_index = False |
730 | ++ |
731 | ++# If true, links to the reST sources are added to the pages. |
732 | ++#html_show_sourcelink = True |
733 | ++ |
734 | ++# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. |
735 | ++#html_show_sphinx = True |
736 | ++ |
737 | ++# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. |
738 | ++#html_show_copyright = True |
739 | ++ |
740 | ++# If true, an OpenSearch description file will be output, and all pages will |
741 | ++# contain a <link> tag referring to it. The value of this option must be the |
742 | ++# base URL from which the finished HTML is served. |
743 | ++#html_use_opensearch = '' |
744 | ++ |
745 | ++# This is the file name suffix for HTML files (e.g. ".xhtml"). |
746 | ++#html_file_suffix = None |
747 | ++ |
748 | ++# Output file base name for HTML help builder. |
749 | ++htmlhelp_basename = 'maxminddbdoc' |
750 | ++ |
751 | ++# -- Options for LaTeX output -------------------------------------------- |
752 | ++ |
753 | ++latex_elements = { |
754 | ++ # The paper size ('letterpaper' or 'a4paper'). |
755 | ++ #'papersize': 'letterpaper', |
756 | ++ |
757 | ++ # The font size ('10pt', '11pt' or '12pt'). |
758 | ++ #'pointsize': '10pt', |
759 | ++ |
760 | ++ # Additional stuff for the LaTeX preamble. |
761 | ++ #'preamble': '', |
762 | ++} |
763 | ++ |
764 | ++# Grouping the document tree into LaTeX files. List of tuples |
765 | ++# (source start file, target name, title, author, documentclass [howto/manual]). |
766 | ++latex_documents = [ |
767 | ++ ('index', 'maxminddb.tex', 'maxminddb Documentation', 'Gregory Oschwald', |
768 | ++ 'manual'), |
769 | ++] |
770 | ++ |
771 | ++# The name of an image file (relative to this directory) to place at the top of |
772 | ++# the title page. |
773 | ++#latex_logo = None |
774 | ++ |
775 | ++# For "manual" documents, if this is true, then toplevel headings are parts, |
776 | ++# not chapters. |
777 | ++#latex_use_parts = False |
778 | ++ |
779 | ++# If true, show page references after internal links. |
780 | ++#latex_show_pagerefs = False |
781 | ++ |
782 | ++# If true, show URL addresses after external links. |
783 | ++#latex_show_urls = False |
784 | ++ |
785 | ++# Documents to append as an appendix to all manuals. |
786 | ++#latex_appendices = [] |
787 | ++ |
788 | ++# If false, no module index is generated. |
789 | ++#latex_domain_indices = True |
790 | ++ |
791 | ++# -- Options for manual page output -------------------------------------- |
792 | ++ |
793 | ++# One entry per manual page. List of tuples |
794 | ++# (source start file, name, description, authors, manual section). |
795 | ++man_pages = [('index', 'maxminddb', 'maxminddb Documentation', |
796 | ++ ['Gregory Oschwald'], 1)] |
797 | ++ |
798 | ++# If true, show URL addresses after external links. |
799 | ++#man_show_urls = False |
800 | ++ |
801 | ++# -- Options for Texinfo output ------------------------------------------ |
802 | ++ |
803 | ++# Grouping the document tree into Texinfo files. List of tuples |
804 | ++# (source start file, target name, title, author, |
805 | ++# dir menu entry, description, category) |
806 | ++texinfo_documents = [ |
807 | ++ ('index', 'maxminddb', 'maxminddb Documentation', 'Gregory Oschwald', |
808 | ++ 'maxminddb', 'MaxMind DB Reader', 'Miscellaneous'), |
809 | ++] |
810 | ++ |
811 | ++# Documents to append as an appendix to all manuals. |
812 | ++#texinfo_appendices = [] |
813 | ++ |
814 | ++# If false, no module index is generated. |
815 | ++#texinfo_domain_indices = True |
816 | ++ |
817 | ++# How to display URL addresses: 'footnote', 'no', or 'inline'. |
818 | ++#texinfo_show_urls = 'footnote' |
819 | ++ |
820 | ++# Example configuration for intersphinx: refer to the Python standard library. |
821 | ++intersphinx_mapping = {'http://docs.python.org/': None} |
822 | diff --git a/debian/patches/series b/debian/patches/series |
823 | new file mode 100644 |
824 | index 0000000..f8a9263 |
825 | --- /dev/null |
826 | +++ b/debian/patches/series |
827 | @@ -0,0 +1 @@ |
828 | +rebuild-sphinx-docs.patch |
829 | diff --git a/debian/rules b/debian/rules |
830 | index 3774142..ac48e30 100755 |
831 | --- a/debian/rules |
832 | +++ b/debian/rules |
833 | @@ -7,13 +7,14 @@ export PYBUILD_NAME=maxminddb |
834 | dh $@ --with python3,sphinxdoc --buildsystem=pybuild |
835 | |
836 | override_dh_auto_build: |
837 | - PYTHONPATH=.:$$PYTHONPATH sphinx-build -b html -d .build/.doctrees -N docs .build/html |
838 | + cp docs/html/_sources/index.rst.txt docs-source/index.rst |
839 | + PYTHONPATH=.:$$PYTHONPATH sphinx-build -b html -d .build/.doctrees -N docs-source .build/html |
840 | dh_auto_build |
841 | |
842 | override_dh_auto_clean: |
843 | - dh_auto_clean |
844 | - rm -f maxminddb/extension.so maxminddb/extension.*.so |
845 | - rm -rf .build/ maxminddb.egg-info/ |
846 | + dh_auto_clean --buildsystem=pybuild |
847 | + rm -rf .build/ |
848 | + rm -f docs-source/index.rst |
849 | |
850 | override_dh_auto_test: |
851 | dh_auto_test -- --before-test "ln -sf {dir}/README.rst {build_dir}/" \ |
852 | diff --git a/dev-bin/release.sh b/dev-bin/release.sh |
853 | deleted file mode 100755 |
854 | index bd0060a..0000000 |
855 | --- a/dev-bin/release.sh |
856 | +++ /dev/null |
857 | @@ -1,66 +0,0 @@ |
858 | -#!/bin/bash |
859 | - |
860 | -set -eu -o pipefail |
861 | - |
862 | -changelog=$(cat HISTORY.rst) |
863 | - |
864 | -regex=' |
865 | -([0-9]+\.[0-9]+\.[0-9]+) \(([0-9]{4}-[0-9]{2}-[0-9]{2})\) |
866 | -\+* |
867 | - |
868 | -((.| |
869 | -)*) |
870 | -' |
871 | - |
872 | -if [[ ! $changelog =~ $regex ]]; then |
873 | - echo "Could not find date line in change log!" |
874 | - exit 1 |
875 | -fi |
876 | - |
877 | -version="${BASH_REMATCH[1]}" |
878 | -date="${BASH_REMATCH[2]}" |
879 | -notes="$(echo "${BASH_REMATCH[3]}" | sed -n -e '/^[0-9]\+\.[0-9]\+\.[0-9]\+/,$!p')" |
880 | - |
881 | -if [[ "$date" -ne $(date +"%Y-%m-%d") ]]; then |
882 | - echo "$date is not today!" |
883 | - exit 1 |
884 | -fi |
885 | - |
886 | -tag="v$version" |
887 | - |
888 | -if [ -n "$(git status --porcelain)" ]; then |
889 | - echo ". is not clean." >&2 |
890 | - exit 1 |
891 | -fi |
892 | - |
893 | -perl -pi -e "s/(?<=__version__ = ').+?(?=')/$version/gsm" maxminddb/__init__.py |
894 | - |
895 | -echo $"Test results:" |
896 | -python setup.py test |
897 | - |
898 | -echo $'\nDiff:' |
899 | -git diff |
900 | - |
901 | -echo $'\nRelease notes:' |
902 | -echo "$notes" |
903 | - |
904 | -read -e -p "Commit changes and push to origin? " should_push |
905 | - |
906 | -if [ "$should_push" != "y" ]; then |
907 | - echo "Aborting" |
908 | - exit 1 |
909 | -fi |
910 | - |
911 | -git commit -m "Update for $tag" -a |
912 | - |
913 | -git push |
914 | - |
915 | -message="$version |
916 | - |
917 | -$notes" |
918 | - |
919 | -hub release create -m "$message" "$tag" |
920 | - |
921 | -git push --tags |
922 | - |
923 | -python setup.py release |
924 | diff --git a/docs/Makefile b/docs/Makefile |
925 | deleted file mode 100644 |
926 | index 316a75a..0000000 |
927 | --- a/docs/Makefile |
928 | +++ /dev/null |
929 | @@ -1,153 +0,0 @@ |
930 | -# Makefile for Sphinx documentation |
931 | -# |
932 | - |
933 | -# You can set these variables from the command line. |
934 | -SPHINXOPTS = |
935 | -SPHINXBUILD = sphinx-build |
936 | -PAPER = |
937 | -BUILDDIR = _build |
938 | - |
939 | -# Internal variables. |
940 | -PAPEROPT_a4 = -D latex_paper_size=a4 |
941 | -PAPEROPT_letter = -D latex_paper_size=letter |
942 | -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . |
943 | -# the i18n builder cannot share the environment and doctrees with the others |
944 | -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . |
945 | - |
946 | -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext |
947 | - |
948 | -help: |
949 | - @echo "Please use \`make <target>' where <target> is one of" |
950 | - @echo " html to make standalone HTML files" |
951 | - @echo " dirhtml to make HTML files named index.html in directories" |
952 | - @echo " singlehtml to make a single large HTML file" |
953 | - @echo " pickle to make pickle files" |
954 | - @echo " json to make JSON files" |
955 | - @echo " htmlhelp to make HTML files and a HTML help project" |
956 | - @echo " qthelp to make HTML files and a qthelp project" |
957 | - @echo " devhelp to make HTML files and a Devhelp project" |
958 | - @echo " epub to make an epub" |
959 | - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" |
960 | - @echo " latexpdf to make LaTeX files and run them through pdflatex" |
961 | - @echo " text to make text files" |
962 | - @echo " man to make manual pages" |
963 | - @echo " texinfo to make Texinfo files" |
964 | - @echo " info to make Texinfo files and run them through makeinfo" |
965 | - @echo " gettext to make PO message catalogs" |
966 | - @echo " changes to make an overview of all changed/added/deprecated items" |
967 | - @echo " linkcheck to check all external links for integrity" |
968 | - @echo " doctest to run all doctests embedded in the documentation (if enabled)" |
969 | - |
970 | -clean: |
971 | - -rm -rf $(BUILDDIR)/* |
972 | - |
973 | -html: |
974 | - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html |
975 | - @echo |
976 | - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." |
977 | - |
978 | -dirhtml: |
979 | - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml |
980 | - @echo |
981 | - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." |
982 | - |
983 | -singlehtml: |
984 | - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml |
985 | - @echo |
986 | - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." |
987 | - |
988 | -pickle: |
989 | - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle |
990 | - @echo |
991 | - @echo "Build finished; now you can process the pickle files." |
992 | - |
993 | -json: |
994 | - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json |
995 | - @echo |
996 | - @echo "Build finished; now you can process the JSON files." |
997 | - |
998 | -htmlhelp: |
999 | - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp |
1000 | - @echo |
1001 | - @echo "Build finished; now you can run HTML Help Workshop with the" \ |
1002 | - ".hhp project file in $(BUILDDIR)/htmlhelp." |
1003 | - |
1004 | -qthelp: |
1005 | - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp |
1006 | - @echo |
1007 | - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ |
1008 | - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" |
1009 | - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/maxminddb.qhcp" |
1010 | - @echo "To view the help file:" |
1011 | - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/maxminddb.qhc" |
1012 | - |
1013 | -devhelp: |
1014 | - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp |
1015 | - @echo |
1016 | - @echo "Build finished." |
1017 | - @echo "To view the help file:" |
1018 | - @echo "# mkdir -p $$HOME/.local/share/devhelp/maxminddb" |
1019 | - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/maxminddb" |
1020 | - @echo "# devhelp" |
1021 | - |
1022 | -epub: |
1023 | - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub |
1024 | - @echo |
1025 | - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." |
1026 | - |
1027 | -latex: |
1028 | - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex |
1029 | - @echo |
1030 | - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." |
1031 | - @echo "Run \`make' in that directory to run these through (pdf)latex" \ |
1032 | - "(use \`make latexpdf' here to do that automatically)." |
1033 | - |
1034 | -latexpdf: |
1035 | - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex |
1036 | - @echo "Running LaTeX files through pdflatex..." |
1037 | - $(MAKE) -C $(BUILDDIR)/latex all-pdf |
1038 | - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." |
1039 | - |
1040 | -text: |
1041 | - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text |
1042 | - @echo |
1043 | - @echo "Build finished. The text files are in $(BUILDDIR)/text." |
1044 | - |
1045 | -man: |
1046 | - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man |
1047 | - @echo |
1048 | - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." |
1049 | - |
1050 | -texinfo: |
1051 | - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo |
1052 | - @echo |
1053 | - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." |
1054 | - @echo "Run \`make' in that directory to run these through makeinfo" \ |
1055 | - "(use \`make info' here to do that automatically)." |
1056 | - |
1057 | -info: |
1058 | - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo |
1059 | - @echo "Running Texinfo files through makeinfo..." |
1060 | - make -C $(BUILDDIR)/texinfo info |
1061 | - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." |
1062 | - |
1063 | -gettext: |
1064 | - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale |
1065 | - @echo |
1066 | - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." |
1067 | - |
1068 | -changes: |
1069 | - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes |
1070 | - @echo |
1071 | - @echo "The overview file is in $(BUILDDIR)/changes." |
1072 | - |
1073 | -linkcheck: |
1074 | - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck |
1075 | - @echo |
1076 | - @echo "Link check complete; look for any errors in the above output " \ |
1077 | - "or in $(BUILDDIR)/linkcheck/output.txt." |
1078 | - |
1079 | -doctest: |
1080 | - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest |
1081 | - @echo "Testing of doctests in the sources finished, look at the " \ |
1082 | - "results in $(BUILDDIR)/doctest/output.txt." |
1083 | diff --git a/docs/conf.py b/docs/conf.py |
1084 | deleted file mode 100644 |
1085 | index 9b107b4..0000000 |
1086 | --- a/docs/conf.py |
1087 | +++ /dev/null |
1088 | @@ -1,248 +0,0 @@ |
1089 | -#!/usr/bin/env python3 |
1090 | -# -*- coding: utf-8 -*- |
1091 | -# |
1092 | -# maxminddb documentation build configuration file, created by |
1093 | -# sphinx-quickstart on Tue Apr 9 13:34:57 2013. |
1094 | -# |
1095 | -# This file is execfile()d with the current directory set to its containing dir. |
1096 | -# |
1097 | -# Note that not all possible configuration values are present in this |
1098 | -# autogenerated file. |
1099 | -# |
1100 | -# All configuration values have a default; values that are commented out |
1101 | -# serve to show the default. |
1102 | - |
1103 | -import sys |
1104 | -import os |
1105 | - |
1106 | -sys.path.insert(0, os.path.abspath('..')) |
1107 | -import maxminddb |
1108 | - |
1109 | -__version__ = maxminddb.__version__ |
1110 | - |
1111 | -# If extensions (or modules to document with autodoc) are in another directory, |
1112 | -# add these directories to sys.path here. If the directory is relative to the |
1113 | -# documentation root, use os.path.abspath to make it absolute, like shown here. |
1114 | -sys.path.insert(0, os.path.abspath('..')) |
1115 | - |
1116 | -# -- General configuration ----------------------------------------------- |
1117 | - |
1118 | -# If your documentation needs a minimal Sphinx version, state it here. |
1119 | -#needs_sphinx = '1.0' |
1120 | - |
1121 | -# Add any Sphinx extension module names here, as strings. They can be extensions |
1122 | -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. |
1123 | -extensions = [ |
1124 | - 'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', |
1125 | - 'sphinx.ext.coverage' |
1126 | -] |
1127 | - |
1128 | -# Add any paths that contain templates here, relative to this directory. |
1129 | -templates_path = ['_templates'] |
1130 | - |
1131 | -# The suffix of source filenames. |
1132 | -source_suffix = '.rst' |
1133 | - |
1134 | -# The encoding of source files. |
1135 | -#source_encoding = 'utf-8-sig' |
1136 | - |
1137 | -# The master toctree document. |
1138 | -master_doc = 'index' |
1139 | - |
1140 | -# General information about the project. |
1141 | -project = 'maxminddb' |
1142 | -copyright = '2013-2018, MaxMind, Inc.' |
1143 | - |
1144 | -# The version info for the project you're documenting, acts as replacement for |
1145 | -# |version| and |release|, also used in various other places throughout the |
1146 | -# built documents. |
1147 | -# |
1148 | -# The short X.Y version. |
1149 | -version = __version__ |
1150 | -# The full version, including alpha/beta/rc tags. |
1151 | -release = __version__ |
1152 | - |
1153 | -# The language for content autogenerated by Sphinx. Refer to documentation |
1154 | -# for a list of supported languages. |
1155 | -#language = None |
1156 | - |
1157 | -# There are two options for replacing |today|: either, you set today to some |
1158 | -# non-false value, then it is used: |
1159 | -#today = '' |
1160 | -# Else, today_fmt is used as the format for a strftime call. |
1161 | -#today_fmt = '%B %d, %Y' |
1162 | - |
1163 | -# List of patterns, relative to source directory, that match files and |
1164 | -# directories to ignore when looking for source files. |
1165 | -exclude_patterns = ['_build'] |
1166 | - |
1167 | -# The reST default role (used for this markup: `text`) to use for all documents. |
1168 | -#default_role = None |
1169 | - |
1170 | -# If true, '()' will be appended to :func: etc. cross-reference text. |
1171 | -#add_function_parentheses = True |
1172 | - |
1173 | -# If true, the current module name will be prepended to all description |
1174 | -# unit titles (such as .. function::). |
1175 | -#add_module_names = True |
1176 | - |
1177 | -# If true, sectionauthor and moduleauthor directives will be shown in the |
1178 | -# output. They are ignored by default. |
1179 | -#show_authors = False |
1180 | - |
1181 | -# The name of the Pygments (syntax highlighting) style to use. |
1182 | -pygments_style = 'sphinx' |
1183 | - |
1184 | -# A list of ignored prefixes for module index sorting. |
1185 | -#modindex_common_prefix = [] |
1186 | - |
1187 | -# -- Options for HTML output --------------------------------------------- |
1188 | - |
1189 | -# The theme to use for HTML and HTML Help pages. See the documentation for |
1190 | -# a list of builtin themes. |
1191 | -html_theme = 'sphinxdoc' |
1192 | - |
1193 | -# Theme options are theme-specific and customize the look and feel of a theme |
1194 | -# further. For a list of options available for each theme, see the |
1195 | -# documentation. |
1196 | -#html_theme_options = {} |
1197 | - |
1198 | -# Add any paths that contain custom themes here, relative to this directory. |
1199 | -#html_theme_path = [] |
1200 | - |
1201 | -# The name for this set of Sphinx documents. If None, it defaults to |
1202 | -# "<project> v<release> documentation". |
1203 | -#html_title = None |
1204 | - |
1205 | -# A shorter title for the navigation bar. Default is the same as html_title. |
1206 | -#html_short_title = None |
1207 | - |
1208 | -# The name of an image file (relative to this directory) to place at the top |
1209 | -# of the sidebar. |
1210 | -#html_logo = None |
1211 | - |
1212 | -# The name of an image file (within the static path) to use as favicon of the |
1213 | -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 |
1214 | -# pixels large. |
1215 | -#html_favicon = None |
1216 | - |
1217 | -# Add any paths that contain custom static files (such as style sheets) here, |
1218 | -# relative to this directory. They are copied after the builtin static files, |
1219 | -# so a file named "default.css" will overwrite the builtin "default.css". |
1220 | -html_static_path = ['_static'] |
1221 | - |
1222 | -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, |
1223 | -# using the given strftime format. |
1224 | -#html_last_updated_fmt = '%b %d, %Y' |
1225 | - |
1226 | -# If true, SmartyPants will be used to convert quotes and dashes to |
1227 | -# typographically correct entities. |
1228 | -#html_use_smartypants = True |
1229 | - |
1230 | -# Custom sidebar templates, maps document names to template names. |
1231 | -#html_sidebars = {} |
1232 | - |
1233 | -# Additional templates that should be rendered to pages, maps page names to |
1234 | -# template names. |
1235 | -#html_additional_pages = {} |
1236 | - |
1237 | -# If false, no module index is generated. |
1238 | -#html_domain_indices = True |
1239 | - |
1240 | -# If false, no index is generated. |
1241 | -#html_use_index = True |
1242 | - |
1243 | -# If true, the index is split into individual pages for each letter. |
1244 | -#html_split_index = False |
1245 | - |
1246 | -# If true, links to the reST sources are added to the pages. |
1247 | -#html_show_sourcelink = True |
1248 | - |
1249 | -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. |
1250 | -#html_show_sphinx = True |
1251 | - |
1252 | -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. |
1253 | -#html_show_copyright = True |
1254 | - |
1255 | -# If true, an OpenSearch description file will be output, and all pages will |
1256 | -# contain a <link> tag referring to it. The value of this option must be the |
1257 | -# base URL from which the finished HTML is served. |
1258 | -#html_use_opensearch = '' |
1259 | - |
1260 | -# This is the file name suffix for HTML files (e.g. ".xhtml"). |
1261 | -#html_file_suffix = None |
1262 | - |
1263 | -# Output file base name for HTML help builder. |
1264 | -htmlhelp_basename = 'maxminddbdoc' |
1265 | - |
1266 | -# -- Options for LaTeX output -------------------------------------------- |
1267 | - |
1268 | -latex_elements = { |
1269 | - # The paper size ('letterpaper' or 'a4paper'). |
1270 | - #'papersize': 'letterpaper', |
1271 | - |
1272 | - # The font size ('10pt', '11pt' or '12pt'). |
1273 | - #'pointsize': '10pt', |
1274 | - |
1275 | - # Additional stuff for the LaTeX preamble. |
1276 | - #'preamble': '', |
1277 | -} |
1278 | - |
1279 | -# Grouping the document tree into LaTeX files. List of tuples |
1280 | -# (source start file, target name, title, author, documentclass [howto/manual]). |
1281 | -latex_documents = [ |
1282 | - ('index', 'maxminddb.tex', 'maxminddb Documentation', 'Gregory Oschwald', |
1283 | - 'manual'), |
1284 | -] |
1285 | - |
1286 | -# The name of an image file (relative to this directory) to place at the top of |
1287 | -# the title page. |
1288 | -#latex_logo = None |
1289 | - |
1290 | -# For "manual" documents, if this is true, then toplevel headings are parts, |
1291 | -# not chapters. |
1292 | -#latex_use_parts = False |
1293 | - |
1294 | -# If true, show page references after internal links. |
1295 | -#latex_show_pagerefs = False |
1296 | - |
1297 | -# If true, show URL addresses after external links. |
1298 | -#latex_show_urls = False |
1299 | - |
1300 | -# Documents to append as an appendix to all manuals. |
1301 | -#latex_appendices = [] |
1302 | - |
1303 | -# If false, no module index is generated. |
1304 | -#latex_domain_indices = True |
1305 | - |
1306 | -# -- Options for manual page output -------------------------------------- |
1307 | - |
1308 | -# One entry per manual page. List of tuples |
1309 | -# (source start file, name, description, authors, manual section). |
1310 | -man_pages = [('index', 'maxminddb', 'maxminddb Documentation', |
1311 | - ['Gregory Oschwald'], 1)] |
1312 | - |
1313 | -# If true, show URL addresses after external links. |
1314 | -#man_show_urls = False |
1315 | - |
1316 | -# -- Options for Texinfo output ------------------------------------------ |
1317 | - |
1318 | -# Grouping the document tree into Texinfo files. List of tuples |
1319 | -# (source start file, target name, title, author, |
1320 | -# dir menu entry, description, category) |
1321 | -texinfo_documents = [ |
1322 | - ('index', 'maxminddb', 'maxminddb Documentation', 'Gregory Oschwald', |
1323 | - 'maxminddb', 'MaxMind DB Reader', 'Miscellaneous'), |
1324 | -] |
1325 | - |
1326 | -# Documents to append as an appendix to all manuals. |
1327 | -#texinfo_appendices = [] |
1328 | - |
1329 | -# If false, no module index is generated. |
1330 | -#texinfo_domain_indices = True |
1331 | - |
1332 | -# How to display URL addresses: 'footnote', 'no', or 'inline'. |
1333 | -#texinfo_show_urls = 'footnote' |
1334 | - |
1335 | -# Example configuration for intersphinx: refer to the Python standard library. |
1336 | -intersphinx_mapping = {'http://docs.python.org/': None} |
1337 | diff --git a/docs/html/.buildinfo b/docs/html/.buildinfo |
1338 | new file mode 100644 |
1339 | index 0000000..5e0172d |
1340 | --- /dev/null |
1341 | +++ b/docs/html/.buildinfo |
1342 | @@ -0,0 +1,4 @@ |
1343 | +# Sphinx build info version 1 |
1344 | +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. |
1345 | +config: f4b35ba4b456e07a1fe93fc0f298d57b |
1346 | +tags: 645f666f9bcd5a90fca523b33c5a78b7 |
1347 | diff --git a/docs/index.rst b/docs/html/_sources/index.rst.txt |
1348 | similarity index 96% |
1349 | rename from docs/index.rst |
1350 | rename to docs/html/_sources/index.rst.txt |
1351 | index a003c74..20fdb5a 100644 |
1352 | --- a/docs/index.rst |
1353 | +++ b/docs/html/_sources/index.rst.txt |
1354 | @@ -35,6 +35,6 @@ Indices and tables |
1355 | * :ref:`modindex` |
1356 | * :ref:`search` |
1357 | |
1358 | -:copyright: (c) 2013-2018 by MaxMind, Inc. |
1359 | +:copyright: (c) 2013-2019 by MaxMind, Inc. |
1360 | :license: Apache License, Version 2.0 |
1361 | |
1362 | diff --git a/docs/html/_static/basic.css b/docs/html/_static/basic.css |
1363 | new file mode 100644 |
1364 | index 0000000..b04360d |
1365 | --- /dev/null |
1366 | +++ b/docs/html/_static/basic.css |
1367 | @@ -0,0 +1,768 @@ |
1368 | +/* |
1369 | + * basic.css |
1370 | + * ~~~~~~~~~ |
1371 | + * |
1372 | + * Sphinx stylesheet -- basic theme. |
1373 | + * |
1374 | + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. |
1375 | + * :license: BSD, see LICENSE for details. |
1376 | + * |
1377 | + */ |
1378 | + |
1379 | +/* -- main layout ----------------------------------------------------------- */ |
1380 | + |
1381 | +div.clearer { |
1382 | + clear: both; |
1383 | +} |
1384 | + |
1385 | +/* -- relbar ---------------------------------------------------------------- */ |
1386 | + |
1387 | +div.related { |
1388 | + width: 100%; |
1389 | + font-size: 90%; |
1390 | +} |
1391 | + |
1392 | +div.related h3 { |
1393 | + display: none; |
1394 | +} |
1395 | + |
1396 | +div.related ul { |
1397 | + margin: 0; |
1398 | + padding: 0 0 0 10px; |
1399 | + list-style: none; |
1400 | +} |
1401 | + |
1402 | +div.related li { |
1403 | + display: inline; |
1404 | +} |
1405 | + |
1406 | +div.related li.right { |
1407 | + float: right; |
1408 | + margin-right: 5px; |
1409 | +} |
1410 | + |
1411 | +/* -- sidebar --------------------------------------------------------------- */ |
1412 | + |
1413 | +div.sphinxsidebarwrapper { |
1414 | + padding: 10px 5px 0 10px; |
1415 | +} |
1416 | + |
1417 | +div.sphinxsidebar { |
1418 | + float: left; |
1419 | + width: 230px; |
1420 | + margin-left: -100%; |
1421 | + font-size: 90%; |
1422 | + word-wrap: break-word; |
1423 | + overflow-wrap : break-word; |
1424 | +} |
1425 | + |
1426 | +div.sphinxsidebar ul { |
1427 | + list-style: none; |
1428 | +} |
1429 | + |
1430 | +div.sphinxsidebar ul ul, |
1431 | +div.sphinxsidebar ul.want-points { |
1432 | + margin-left: 20px; |
1433 | + list-style: square; |
1434 | +} |
1435 | + |
1436 | +div.sphinxsidebar ul ul { |
1437 | + margin-top: 0; |
1438 | + margin-bottom: 0; |
1439 | +} |
1440 | + |
1441 | +div.sphinxsidebar form { |
1442 | + margin-top: 10px; |
1443 | +} |
1444 | + |
1445 | +div.sphinxsidebar input { |
1446 | + border: 1px solid #98dbcc; |
1447 | + font-family: sans-serif; |
1448 | + font-size: 1em; |
1449 | +} |
1450 | + |
1451 | +div.sphinxsidebar #searchbox form.search { |
1452 | + overflow: hidden; |
1453 | +} |
1454 | + |
1455 | +div.sphinxsidebar #searchbox input[type="text"] { |
1456 | + float: left; |
1457 | + width: 80%; |
1458 | + padding: 0.25em; |
1459 | + box-sizing: border-box; |
1460 | +} |
1461 | + |
1462 | +div.sphinxsidebar #searchbox input[type="submit"] { |
1463 | + float: left; |
1464 | + width: 20%; |
1465 | + border-left: none; |
1466 | + padding: 0.25em; |
1467 | + box-sizing: border-box; |
1468 | +} |
1469 | + |
1470 | + |
1471 | +img { |
1472 | + border: 0; |
1473 | + max-width: 100%; |
1474 | +} |
1475 | + |
1476 | +/* -- search page ----------------------------------------------------------- */ |
1477 | + |
1478 | +ul.search { |
1479 | + margin: 10px 0 0 20px; |
1480 | + padding: 0; |
1481 | +} |
1482 | + |
1483 | +ul.search li { |
1484 | + padding: 5px 0 5px 20px; |
1485 | + background-image: url(file.png); |
1486 | + background-repeat: no-repeat; |
1487 | + background-position: 0 7px; |
1488 | +} |
1489 | + |
1490 | +ul.search li a { |
1491 | + font-weight: bold; |
1492 | +} |
1493 | + |
1494 | +ul.search li div.context { |
1495 | + color: #888; |
1496 | + margin: 2px 0 0 30px; |
1497 | + text-align: left; |
1498 | +} |
1499 | + |
1500 | +ul.keywordmatches li.goodmatch a { |
1501 | + font-weight: bold; |
1502 | +} |
1503 | + |
1504 | +/* -- index page ------------------------------------------------------------ */ |
1505 | + |
1506 | +table.contentstable { |
1507 | + width: 90%; |
1508 | + margin-left: auto; |
1509 | + margin-right: auto; |
1510 | +} |
1511 | + |
1512 | +table.contentstable p.biglink { |
1513 | + line-height: 150%; |
1514 | +} |
1515 | + |
1516 | +a.biglink { |
1517 | + font-size: 1.3em; |
1518 | +} |
1519 | + |
1520 | +span.linkdescr { |
1521 | + font-style: italic; |
1522 | + padding-top: 5px; |
1523 | + font-size: 90%; |
1524 | +} |
1525 | + |
1526 | +/* -- general index --------------------------------------------------------- */ |
1527 | + |
1528 | +table.indextable { |
1529 | + width: 100%; |
1530 | +} |
1531 | + |
1532 | +table.indextable td { |
1533 | + text-align: left; |
1534 | + vertical-align: top; |
1535 | +} |
1536 | + |
1537 | +table.indextable ul { |
1538 | + margin-top: 0; |
1539 | + margin-bottom: 0; |
1540 | + list-style-type: none; |
1541 | +} |
1542 | + |
1543 | +table.indextable > tbody > tr > td > ul { |
1544 | + padding-left: 0em; |
1545 | +} |
1546 | + |
1547 | +table.indextable tr.pcap { |
1548 | + height: 10px; |
1549 | +} |
1550 | + |
1551 | +table.indextable tr.cap { |
1552 | + margin-top: 10px; |
1553 | + background-color: #f2f2f2; |
1554 | +} |
1555 | + |
1556 | +img.toggler { |
1557 | + margin-right: 3px; |
1558 | + margin-top: 3px; |
1559 | + cursor: pointer; |
1560 | +} |
1561 | + |
1562 | +div.modindex-jumpbox { |
1563 | + border-top: 1px solid #ddd; |
1564 | + border-bottom: 1px solid #ddd; |
1565 | + margin: 1em 0 1em 0; |
1566 | + padding: 0.4em; |
1567 | +} |
1568 | + |
1569 | +div.genindex-jumpbox { |
1570 | + border-top: 1px solid #ddd; |
1571 | + border-bottom: 1px solid #ddd; |
1572 | + margin: 1em 0 1em 0; |
1573 | + padding: 0.4em; |
1574 | +} |
1575 | + |
1576 | +/* -- domain module index --------------------------------------------------- */ |
1577 | + |
1578 | +table.modindextable td { |
1579 | + padding: 2px; |
1580 | + border-collapse: collapse; |
1581 | +} |
1582 | + |
1583 | +/* -- general body styles --------------------------------------------------- */ |
1584 | + |
1585 | +div.body { |
1586 | + min-width: 450px; |
1587 | + max-width: 800px; |
1588 | +} |
1589 | + |
1590 | +div.body p, div.body dd, div.body li, div.body blockquote { |
1591 | + -moz-hyphens: auto; |
1592 | + -ms-hyphens: auto; |
1593 | + -webkit-hyphens: auto; |
1594 | + hyphens: auto; |
1595 | +} |
1596 | + |
1597 | +a.headerlink { |
1598 | + visibility: hidden; |
1599 | +} |
1600 | + |
1601 | +a.brackets:before, |
1602 | +span.brackets > a:before{ |
1603 | + content: "["; |
1604 | +} |
1605 | + |
1606 | +a.brackets:after, |
1607 | +span.brackets > a:after { |
1608 | + content: "]"; |
1609 | +} |
1610 | + |
1611 | +h1:hover > a.headerlink, |
1612 | +h2:hover > a.headerlink, |
1613 | +h3:hover > a.headerlink, |
1614 | +h4:hover > a.headerlink, |
1615 | +h5:hover > a.headerlink, |
1616 | +h6:hover > a.headerlink, |
1617 | +dt:hover > a.headerlink, |
1618 | +caption:hover > a.headerlink, |
1619 | +p.caption:hover > a.headerlink, |
1620 | +div.code-block-caption:hover > a.headerlink { |
1621 | + visibility: visible; |
1622 | +} |
1623 | + |
1624 | +div.body p.caption { |
1625 | + text-align: inherit; |
1626 | +} |
1627 | + |
1628 | +div.body td { |
1629 | + text-align: left; |
1630 | +} |
1631 | + |
1632 | +.first { |
1633 | + margin-top: 0 !important; |
1634 | +} |
1635 | + |
1636 | +p.rubric { |
1637 | + margin-top: 30px; |
1638 | + font-weight: bold; |
1639 | +} |
1640 | + |
1641 | +img.align-left, .figure.align-left, object.align-left { |
1642 | + clear: left; |
1643 | + float: left; |
1644 | + margin-right: 1em; |
1645 | +} |
1646 | + |
1647 | +img.align-right, .figure.align-right, object.align-right { |
1648 | + clear: right; |
1649 | + float: right; |
1650 | + margin-left: 1em; |
1651 | +} |
1652 | + |
1653 | +img.align-center, .figure.align-center, object.align-center { |
1654 | + display: block; |
1655 | + margin-left: auto; |
1656 | + margin-right: auto; |
1657 | +} |
1658 | + |
1659 | +img.align-default, .figure.align-default { |
1660 | + display: block; |
1661 | + margin-left: auto; |
1662 | + margin-right: auto; |
1663 | +} |
1664 | + |
1665 | +.align-left { |
1666 | + text-align: left; |
1667 | +} |
1668 | + |
1669 | +.align-center { |
1670 | + text-align: center; |
1671 | +} |
1672 | + |
1673 | +.align-default { |
1674 | + text-align: center; |
1675 | +} |
1676 | + |
1677 | +.align-right { |
1678 | + text-align: right; |
1679 | +} |
1680 | + |
1681 | +/* -- sidebars -------------------------------------------------------------- */ |
1682 | + |
1683 | +div.sidebar { |
1684 | + margin: 0 0 0.5em 1em; |
1685 | + border: 1px solid #ddb; |
1686 | + padding: 7px 7px 0 7px; |
1687 | + background-color: #ffe; |
1688 | + width: 40%; |
1689 | + float: right; |
1690 | +} |
1691 | + |
1692 | +p.sidebar-title { |
1693 | + font-weight: bold; |
1694 | +} |
1695 | + |
1696 | +/* -- topics ---------------------------------------------------------------- */ |
1697 | + |
1698 | +div.topic { |
1699 | + border: 1px solid #ccc; |
1700 | + padding: 7px 7px 0 7px; |
1701 | + margin: 10px 0 10px 0; |
1702 | +} |
1703 | + |
1704 | +p.topic-title { |
1705 | + font-size: 1.1em; |
1706 | + font-weight: bold; |
1707 | + margin-top: 10px; |
1708 | +} |
1709 | + |
1710 | +/* -- admonitions ----------------------------------------------------------- */ |
1711 | + |
1712 | +div.admonition { |
1713 | + margin-top: 10px; |
1714 | + margin-bottom: 10px; |
1715 | + padding: 7px; |
1716 | +} |
1717 | + |
1718 | +div.admonition dt { |
1719 | + font-weight: bold; |
1720 | +} |
1721 | + |
1722 | +div.admonition dl { |
1723 | + margin-bottom: 0; |
1724 | +} |
1725 | + |
1726 | +p.admonition-title { |
1727 | + margin: 0px 10px 5px 0px; |
1728 | + font-weight: bold; |
1729 | +} |
1730 | + |
1731 | +div.body p.centered { |
1732 | + text-align: center; |
1733 | + margin-top: 25px; |
1734 | +} |
1735 | + |
1736 | +/* -- tables ---------------------------------------------------------------- */ |
1737 | + |
1738 | +table.docutils { |
1739 | + border: 0; |
1740 | + border-collapse: collapse; |
1741 | +} |
1742 | + |
1743 | +table.align-center { |
1744 | + margin-left: auto; |
1745 | + margin-right: auto; |
1746 | +} |
1747 | + |
1748 | +table.align-default { |
1749 | + margin-left: auto; |
1750 | + margin-right: auto; |
1751 | +} |
1752 | + |
1753 | +table caption span.caption-number { |
1754 | + font-style: italic; |
1755 | +} |
1756 | + |
1757 | +table caption span.caption-text { |
1758 | +} |
1759 | + |
1760 | +table.docutils td, table.docutils th { |
1761 | + padding: 1px 8px 1px 5px; |
1762 | + border-top: 0; |
1763 | + border-left: 0; |
1764 | + border-right: 0; |
1765 | + border-bottom: 1px solid #aaa; |
1766 | +} |
1767 | + |
1768 | +table.footnote td, table.footnote th { |
1769 | + border: 0 !important; |
1770 | +} |
1771 | + |
1772 | +th { |
1773 | + text-align: left; |
1774 | + padding-right: 5px; |
1775 | +} |
1776 | + |
1777 | +table.citation { |
1778 | + border-left: solid 1px gray; |
1779 | + margin-left: 1px; |
1780 | +} |
1781 | + |
1782 | +table.citation td { |
1783 | + border-bottom: none; |
1784 | +} |
1785 | + |
1786 | +th > p:first-child, |
1787 | +td > p:first-child { |
1788 | + margin-top: 0px; |
1789 | +} |
1790 | + |
1791 | +th > p:last-child, |
1792 | +td > p:last-child { |
1793 | + margin-bottom: 0px; |
1794 | +} |
1795 | + |
1796 | +/* -- figures --------------------------------------------------------------- */ |
1797 | + |
1798 | +div.figure { |
1799 | + margin: 0.5em; |
1800 | + padding: 0.5em; |
1801 | +} |
1802 | + |
1803 | +div.figure p.caption { |
1804 | + padding: 0.3em; |
1805 | +} |
1806 | + |
1807 | +div.figure p.caption span.caption-number { |
1808 | + font-style: italic; |
1809 | +} |
1810 | + |
1811 | +div.figure p.caption span.caption-text { |
1812 | +} |
1813 | + |
1814 | +/* -- field list styles ----------------------------------------------------- */ |
1815 | + |
1816 | +table.field-list td, table.field-list th { |
1817 | + border: 0 !important; |
1818 | +} |
1819 | + |
1820 | +.field-list ul { |
1821 | + margin: 0; |
1822 | + padding-left: 1em; |
1823 | +} |
1824 | + |
1825 | +.field-list p { |
1826 | + margin: 0; |
1827 | +} |
1828 | + |
1829 | +.field-name { |
1830 | + -moz-hyphens: manual; |
1831 | + -ms-hyphens: manual; |
1832 | + -webkit-hyphens: manual; |
1833 | + hyphens: manual; |
1834 | +} |
1835 | + |
1836 | +/* -- hlist styles ---------------------------------------------------------- */ |
1837 | + |
1838 | +table.hlist td { |
1839 | + vertical-align: top; |
1840 | +} |
1841 | + |
1842 | + |
1843 | +/* -- other body styles ----------------------------------------------------- */ |
1844 | + |
1845 | +ol.arabic { |
1846 | + list-style: decimal; |
1847 | +} |
1848 | + |
1849 | +ol.loweralpha { |
1850 | + list-style: lower-alpha; |
1851 | +} |
1852 | + |
1853 | +ol.upperalpha { |
1854 | + list-style: upper-alpha; |
1855 | +} |
1856 | + |
1857 | +ol.lowerroman { |
1858 | + list-style: lower-roman; |
1859 | +} |
1860 | + |
1861 | +ol.upperroman { |
1862 | + list-style: upper-roman; |
1863 | +} |
1864 | + |
1865 | +li > p:first-child { |
1866 | + margin-top: 0px; |
1867 | +} |
1868 | + |
1869 | +li > p:last-child { |
1870 | + margin-bottom: 0px; |
1871 | +} |
1872 | + |
1873 | +dl.footnote > dt, |
1874 | +dl.citation > dt { |
1875 | + float: left; |
1876 | +} |
1877 | + |
1878 | +dl.footnote > dd, |
1879 | +dl.citation > dd { |
1880 | + margin-bottom: 0em; |
1881 | +} |
1882 | + |
1883 | +dl.footnote > dd:after, |
1884 | +dl.citation > dd:after { |
1885 | + content: ""; |
1886 | + clear: both; |
1887 | +} |
1888 | + |
1889 | +dl.field-list { |
1890 | + display: grid; |
1891 | + grid-template-columns: fit-content(30%) auto; |
1892 | +} |
1893 | + |
1894 | +dl.field-list > dt { |
1895 | + font-weight: bold; |
1896 | + word-break: break-word; |
1897 | + padding-left: 0.5em; |
1898 | + padding-right: 5px; |
1899 | +} |
1900 | + |
1901 | +dl.field-list > dt:after { |
1902 | + content: ":"; |
1903 | +} |
1904 | + |
1905 | +dl.field-list > dd { |
1906 | + padding-left: 0.5em; |
1907 | + margin-top: 0em; |
1908 | + margin-left: 0em; |
1909 | + margin-bottom: 0em; |
1910 | +} |
1911 | + |
1912 | +dl { |
1913 | + margin-bottom: 15px; |
1914 | +} |
1915 | + |
1916 | +dd > p:first-child { |
1917 | + margin-top: 0px; |
1918 | +} |
1919 | + |
1920 | +dd ul, dd table { |
1921 | + margin-bottom: 10px; |
1922 | +} |
1923 | + |
1924 | +dd { |
1925 | + margin-top: 3px; |
1926 | + margin-bottom: 10px; |
1927 | + margin-left: 30px; |
1928 | +} |
1929 | + |
1930 | +dt:target, span.highlighted { |
1931 | + background-color: #fbe54e; |
1932 | +} |
1933 | + |
1934 | +rect.highlighted { |
1935 | + fill: #fbe54e; |
1936 | +} |
1937 | + |
1938 | +dl.glossary dt { |
1939 | + font-weight: bold; |
1940 | + font-size: 1.1em; |
1941 | +} |
1942 | + |
1943 | +.optional { |
1944 | + font-size: 1.3em; |
1945 | +} |
1946 | + |
1947 | +.sig-paren { |
1948 | + font-size: larger; |
1949 | +} |
1950 | + |
1951 | +.versionmodified { |
1952 | + font-style: italic; |
1953 | +} |
1954 | + |
1955 | +.system-message { |
1956 | + background-color: #fda; |
1957 | + padding: 5px; |
1958 | + border: 3px solid red; |
1959 | +} |
1960 | + |
1961 | +.footnote:target { |
1962 | + background-color: #ffa; |
1963 | +} |
1964 | + |
1965 | +.line-block { |
1966 | + display: block; |
1967 | + margin-top: 1em; |
1968 | + margin-bottom: 1em; |
1969 | +} |
1970 | + |
1971 | +.line-block .line-block { |
1972 | + margin-top: 0; |
1973 | + margin-bottom: 0; |
1974 | + margin-left: 1.5em; |
1975 | +} |
1976 | + |
1977 | +.guilabel, .menuselection { |
1978 | + font-family: sans-serif; |
1979 | +} |
1980 | + |
1981 | +.accelerator { |
1982 | + text-decoration: underline; |
1983 | +} |
1984 | + |
1985 | +.classifier { |
1986 | + font-style: oblique; |
1987 | +} |
1988 | + |
1989 | +.classifier:before { |
1990 | + font-style: normal; |
1991 | + margin: 0.5em; |
1992 | + content: ":"; |
1993 | +} |
1994 | + |
1995 | +abbr, acronym { |
1996 | + border-bottom: dotted 1px; |
1997 | + cursor: help; |
1998 | +} |
1999 | + |
2000 | +/* -- code displays --------------------------------------------------------- */ |
2001 | + |
2002 | +pre { |
2003 | + overflow: auto; |
2004 | + overflow-y: hidden; /* fixes display issues on Chrome browsers */ |
2005 | +} |
2006 | + |
2007 | +span.pre { |
2008 | + -moz-hyphens: none; |
2009 | + -ms-hyphens: none; |
2010 | + -webkit-hyphens: none; |
2011 | + hyphens: none; |
2012 | +} |
2013 | + |
2014 | +td.linenos pre { |
2015 | + padding: 5px 0px; |
2016 | + border: 0; |
2017 | + background-color: transparent; |
2018 | + color: #aaa; |
2019 | +} |
2020 | + |
2021 | +table.highlighttable { |
2022 | + margin-left: 0.5em; |
2023 | +} |
2024 | + |
2025 | +table.highlighttable td { |
2026 | + padding: 0 0.5em 0 0.5em; |
2027 | +} |
2028 | + |
2029 | +div.code-block-caption { |
2030 | + padding: 2px 5px; |
2031 | + font-size: small; |
2032 | +} |
2033 | + |
2034 | +div.code-block-caption code { |
2035 | + background-color: transparent; |
2036 | +} |
2037 | + |
2038 | +div.code-block-caption + div > div.highlight > pre { |
2039 | + margin-top: 0; |
2040 | +} |
2041 | + |
2042 | +div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ |
2043 | + user-select: none; |
2044 | +} |
2045 | + |
2046 | +div.code-block-caption span.caption-number { |
2047 | + padding: 0.1em 0.3em; |
2048 | + font-style: italic; |
2049 | +} |
2050 | + |
2051 | +div.code-block-caption span.caption-text { |
2052 | +} |
2053 | + |
2054 | +div.literal-block-wrapper { |
2055 | + padding: 1em 1em 0; |
2056 | +} |
2057 | + |
2058 | +div.literal-block-wrapper div.highlight { |
2059 | + margin: 0; |
2060 | +} |
2061 | + |
2062 | +code.descname { |
2063 | + background-color: transparent; |
2064 | + font-weight: bold; |
2065 | + font-size: 1.2em; |
2066 | +} |
2067 | + |
2068 | +code.descclassname { |
2069 | + background-color: transparent; |
2070 | +} |
2071 | + |
2072 | +code.xref, a code { |
2073 | + background-color: transparent; |
2074 | + font-weight: bold; |
2075 | +} |
2076 | + |
2077 | +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { |
2078 | + background-color: transparent; |
2079 | +} |
2080 | + |
2081 | +.viewcode-link { |
2082 | + float: right; |
2083 | +} |
2084 | + |
2085 | +.viewcode-back { |
2086 | + float: right; |
2087 | + font-family: sans-serif; |
2088 | +} |
2089 | + |
2090 | +div.viewcode-block:target { |
2091 | + margin: -1px -10px; |
2092 | + padding: 0 10px; |
2093 | +} |
2094 | + |
2095 | +/* -- math display ---------------------------------------------------------- */ |
2096 | + |
2097 | +img.math { |
2098 | + vertical-align: middle; |
2099 | +} |
2100 | + |
2101 | +div.body div.math p { |
2102 | + text-align: center; |
2103 | +} |
2104 | + |
2105 | +span.eqno { |
2106 | + float: right; |
2107 | +} |
2108 | + |
2109 | +span.eqno a.headerlink { |
2110 | + position: relative; |
2111 | + left: 0px; |
2112 | + z-index: 1; |
2113 | +} |
2114 | + |
2115 | +div.math:hover a.headerlink { |
2116 | + visibility: visible; |
2117 | +} |
2118 | + |
2119 | +/* -- printout stylesheet --------------------------------------------------- */ |
2120 | + |
2121 | +@media print { |
2122 | + div.document, |
2123 | + div.documentwrapper, |
2124 | + div.bodywrapper { |
2125 | + margin: 0 !important; |
2126 | + width: 100%; |
2127 | + } |
2128 | + |
2129 | + div.sphinxsidebar, |
2130 | + div.related, |
2131 | + div.footer, |
2132 | + #top-link { |
2133 | + display: none; |
2134 | + } |
2135 | +} |
2136 | \ No newline at end of file |
2137 | diff --git a/docs/html/_static/contents.png b/docs/html/_static/contents.png |
2138 | new file mode 100644 |
2139 | index 0000000..6c59aa1 |
2140 | Binary files /dev/null and b/docs/html/_static/contents.png differ |
2141 | diff --git a/docs/html/_static/doctools.js b/docs/html/_static/doctools.js |
2142 | new file mode 100644 |
2143 | index 0000000..b33f87f |
2144 | --- /dev/null |
2145 | +++ b/docs/html/_static/doctools.js |
2146 | @@ -0,0 +1,314 @@ |
2147 | +/* |
2148 | + * doctools.js |
2149 | + * ~~~~~~~~~~~ |
2150 | + * |
2151 | + * Sphinx JavaScript utilities for all documentation. |
2152 | + * |
2153 | + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. |
2154 | + * :license: BSD, see LICENSE for details. |
2155 | + * |
2156 | + */ |
2157 | + |
2158 | +/** |
2159 | + * select a different prefix for underscore |
2160 | + */ |
2161 | +$u = _.noConflict(); |
2162 | + |
2163 | +/** |
2164 | + * make the code below compatible with browsers without |
2165 | + * an installed firebug like debugger |
2166 | +if (!window.console || !console.firebug) { |
2167 | + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", |
2168 | + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", |
2169 | + "profile", "profileEnd"]; |
2170 | + window.console = {}; |
2171 | + for (var i = 0; i < names.length; ++i) |
2172 | + window.console[names[i]] = function() {}; |
2173 | +} |
2174 | + */ |
2175 | + |
2176 | +/** |
2177 | + * small helper function to urldecode strings |
2178 | + */ |
2179 | +jQuery.urldecode = function(x) { |
2180 | + return decodeURIComponent(x).replace(/\+/g, ' '); |
2181 | +}; |
2182 | + |
2183 | +/** |
2184 | + * small helper function to urlencode strings |
2185 | + */ |
2186 | +jQuery.urlencode = encodeURIComponent; |
2187 | + |
2188 | +/** |
2189 | + * This function returns the parsed url parameters of the |
2190 | + * current request. Multiple values per key are supported, |
2191 | + * it will always return arrays of strings for the value parts. |
2192 | + */ |
2193 | +jQuery.getQueryParameters = function(s) { |
2194 | + if (typeof s === 'undefined') |
2195 | + s = document.location.search; |
2196 | + var parts = s.substr(s.indexOf('?') + 1).split('&'); |
2197 | + var result = {}; |
2198 | + for (var i = 0; i < parts.length; i++) { |
2199 | + var tmp = parts[i].split('=', 2); |
2200 | + var key = jQuery.urldecode(tmp[0]); |
2201 | + var value = jQuery.urldecode(tmp[1]); |
2202 | + if (key in result) |
2203 | + result[key].push(value); |
2204 | + else |
2205 | + result[key] = [value]; |
2206 | + } |
2207 | + return result; |
2208 | +}; |
2209 | + |
2210 | +/** |
2211 | + * highlight a given string on a jquery object by wrapping it in |
2212 | + * span elements with the given class name. |
2213 | + */ |
2214 | +jQuery.fn.highlightText = function(text, className) { |
2215 | + function highlight(node, addItems) { |
2216 | + if (node.nodeType === 3) { |
2217 | + var val = node.nodeValue; |
2218 | + var pos = val.toLowerCase().indexOf(text); |
2219 | + if (pos >= 0 && |
2220 | + !jQuery(node.parentNode).hasClass(className) && |
2221 | + !jQuery(node.parentNode).hasClass("nohighlight")) { |
2222 | + var span; |
2223 | + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); |
2224 | + if (isInSVG) { |
2225 | + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); |
2226 | + } else { |
2227 | + span = document.createElement("span"); |
2228 | + span.className = className; |
2229 | + } |
2230 | + span.appendChild(document.createTextNode(val.substr(pos, text.length))); |
2231 | + node.parentNode.insertBefore(span, node.parentNode.insertBefore( |
2232 | + document.createTextNode(val.substr(pos + text.length)), |
2233 | + node.nextSibling)); |
2234 | + node.nodeValue = val.substr(0, pos); |
2235 | + if (isInSVG) { |
2236 | + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); |
2237 | + var bbox = node.parentElement.getBBox(); |
2238 | + rect.x.baseVal.value = bbox.x; |
2239 | + rect.y.baseVal.value = bbox.y; |
2240 | + rect.width.baseVal.value = bbox.width; |
2241 | + rect.height.baseVal.value = bbox.height; |
2242 | + rect.setAttribute('class', className); |
2243 | + addItems.push({ |
2244 | + "parent": node.parentNode, |
2245 | + "target": rect}); |
2246 | + } |
2247 | + } |
2248 | + } |
2249 | + else if (!jQuery(node).is("button, select, textarea")) { |
2250 | + jQuery.each(node.childNodes, function() { |
2251 | + highlight(this, addItems); |
2252 | + }); |
2253 | + } |
2254 | + } |
2255 | + var addItems = []; |
2256 | + var result = this.each(function() { |
2257 | + highlight(this, addItems); |
2258 | + }); |
2259 | + for (var i = 0; i < addItems.length; ++i) { |
2260 | + jQuery(addItems[i].parent).before(addItems[i].target); |
2261 | + } |
2262 | + return result; |
2263 | +}; |
2264 | + |
2265 | +/* |
2266 | + * backward compatibility for jQuery.browser |
2267 | + * This will be supported until firefox bug is fixed. |
2268 | + */ |
2269 | +if (!jQuery.browser) { |
2270 | + jQuery.uaMatch = function(ua) { |
2271 | + ua = ua.toLowerCase(); |
2272 | + |
2273 | + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || |
2274 | + /(webkit)[ \/]([\w.]+)/.exec(ua) || |
2275 | + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || |
2276 | + /(msie) ([\w.]+)/.exec(ua) || |
2277 | + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || |
2278 | + []; |
2279 | + |
2280 | + return { |
2281 | + browser: match[ 1 ] || "", |
2282 | + version: match[ 2 ] || "0" |
2283 | + }; |
2284 | + }; |
2285 | + jQuery.browser = {}; |
2286 | + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; |
2287 | +} |
2288 | + |
2289 | +/** |
2290 | + * Small JavaScript module for the documentation. |
2291 | + */ |
2292 | +var Documentation = { |
2293 | + |
2294 | + init : function() { |
2295 | + this.fixFirefoxAnchorBug(); |
2296 | + this.highlightSearchWords(); |
2297 | + this.initIndexTable(); |
2298 | + if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { |
2299 | + this.initOnKeyListeners(); |
2300 | + } |
2301 | + }, |
2302 | + |
2303 | + /** |
2304 | + * i18n support |
2305 | + */ |
2306 | + TRANSLATIONS : {}, |
2307 | + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, |
2308 | + LOCALE : 'unknown', |
2309 | + |
2310 | + // gettext and ngettext don't access this so that the functions |
2311 | + // can safely bound to a different name (_ = Documentation.gettext) |
2312 | + gettext : function(string) { |
2313 | + var translated = Documentation.TRANSLATIONS[string]; |
2314 | + if (typeof translated === 'undefined') |
2315 | + return string; |
2316 | + return (typeof translated === 'string') ? translated : translated[0]; |
2317 | + }, |
2318 | + |
2319 | + ngettext : function(singular, plural, n) { |
2320 | + var translated = Documentation.TRANSLATIONS[singular]; |
2321 | + if (typeof translated === 'undefined') |
2322 | + return (n == 1) ? singular : plural; |
2323 | + return translated[Documentation.PLURALEXPR(n)]; |
2324 | + }, |
2325 | + |
2326 | + addTranslations : function(catalog) { |
2327 | + for (var key in catalog.messages) |
2328 | + this.TRANSLATIONS[key] = catalog.messages[key]; |
2329 | + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); |
2330 | + this.LOCALE = catalog.locale; |
2331 | + }, |
2332 | + |
2333 | + /** |
2334 | + * add context elements like header anchor links |
2335 | + */ |
2336 | + addContextElements : function() { |
2337 | + $('div[id] > :header:first').each(function() { |
2338 | + $('<a class="headerlink">\u00B6</a>'). |
2339 | + attr('href', '#' + this.id). |
2340 | + attr('title', _('Permalink to this headline')). |
2341 | + appendTo(this); |
2342 | + }); |
2343 | + $('dt[id]').each(function() { |
2344 | + $('<a class="headerlink">\u00B6</a>'). |
2345 | + attr('href', '#' + this.id). |
2346 | + attr('title', _('Permalink to this definition')). |
2347 | + appendTo(this); |
2348 | + }); |
2349 | + }, |
2350 | + |
2351 | + /** |
2352 | + * workaround a firefox stupidity |
2353 | + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 |
2354 | + */ |
2355 | + fixFirefoxAnchorBug : function() { |
2356 | + if (document.location.hash && $.browser.mozilla) |
2357 | + window.setTimeout(function() { |
2358 | + document.location.href += ''; |
2359 | + }, 10); |
2360 | + }, |
2361 | + |
2362 | + /** |
2363 | + * highlight the search words provided in the url in the text |
2364 | + */ |
2365 | + highlightSearchWords : function() { |
2366 | + var params = $.getQueryParameters(); |
2367 | + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; |
2368 | + if (terms.length) { |
2369 | + var body = $('div.body'); |
2370 | + if (!body.length) { |
2371 | + body = $('body'); |
2372 | + } |
2373 | + window.setTimeout(function() { |
2374 | + $.each(terms, function() { |
2375 | + body.highlightText(this.toLowerCase(), 'highlighted'); |
2376 | + }); |
2377 | + }, 10); |
2378 | + $('<p class="highlight-link"><a href="javascript:Documentation.' + |
2379 | + 'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>') |
2380 | + .appendTo($('#searchbox')); |
2381 | + } |
2382 | + }, |
2383 | + |
2384 | + /** |
2385 | + * init the domain index toggle buttons |
2386 | + */ |
2387 | + initIndexTable : function() { |
2388 | + var togglers = $('img.toggler').click(function() { |
2389 | + var src = $(this).attr('src'); |
2390 | + var idnum = $(this).attr('id').substr(7); |
2391 | + $('tr.cg-' + idnum).toggle(); |
2392 | + if (src.substr(-9) === 'minus.png') |
2393 | + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); |
2394 | + else |
2395 | + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); |
2396 | + }).css('display', ''); |
2397 | + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { |
2398 | + togglers.click(); |
2399 | + } |
2400 | + }, |
2401 | + |
2402 | + /** |
2403 | + * helper function to hide the search marks again |
2404 | + */ |
2405 | + hideSearchWords : function() { |
2406 | + $('#searchbox .highlight-link').fadeOut(300); |
2407 | + $('span.highlighted').removeClass('highlighted'); |
2408 | + }, |
2409 | + |
2410 | + /** |
2411 | + * make the url absolute |
2412 | + */ |
2413 | + makeURL : function(relativeURL) { |
2414 | + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; |
2415 | + }, |
2416 | + |
2417 | + /** |
2418 | + * get the current relative url |
2419 | + */ |
2420 | + getCurrentURL : function() { |
2421 | + var path = document.location.pathname; |
2422 | + var parts = path.split(/\//); |
2423 | + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { |
2424 | + if (this === '..') |
2425 | + parts.pop(); |
2426 | + }); |
2427 | + var url = parts.join('/'); |
2428 | + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); |
2429 | + }, |
2430 | + |
2431 | + initOnKeyListeners: function() { |
2432 | + $(document).keyup(function(event) { |
2433 | + var activeElementType = document.activeElement.tagName; |
2434 | + // don't navigate when in search box or textarea |
2435 | + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { |
2436 | + switch (event.keyCode) { |
2437 | + case 37: // left |
2438 | + var prevHref = $('link[rel="prev"]').prop('href'); |
2439 | + if (prevHref) { |
2440 | + window.location.href = prevHref; |
2441 | + return false; |
2442 | + } |
2443 | + case 39: // right |
2444 | + var nextHref = $('link[rel="next"]').prop('href'); |
2445 | + if (nextHref) { |
2446 | + window.location.href = nextHref; |
2447 | + return false; |
2448 | + } |
2449 | + } |
2450 | + } |
2451 | + }); |
2452 | + } |
2453 | +}; |
2454 | + |
2455 | +// quick alias for translations |
2456 | +_ = Documentation.gettext; |
2457 | + |
2458 | +$(document).ready(function() { |
2459 | + Documentation.init(); |
2460 | +}); |
2461 | diff --git a/docs/html/_static/documentation_options.js b/docs/html/_static/documentation_options.js |
2462 | new file mode 100644 |
2463 | index 0000000..375482b |
2464 | --- /dev/null |
2465 | +++ b/docs/html/_static/documentation_options.js |
2466 | @@ -0,0 +1,11 @@ |
2467 | +var DOCUMENTATION_OPTIONS = { |
2468 | + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), |
2469 | + VERSION: '1.5.2', |
2470 | + LANGUAGE: 'None', |
2471 | + COLLAPSE_INDEX: false, |
2472 | + BUILDER: 'html', |
2473 | + FILE_SUFFIX: '.html', |
2474 | + HAS_SOURCE: true, |
2475 | + SOURCELINK_SUFFIX: '.txt', |
2476 | + NAVIGATION_WITH_KEYS: false |
2477 | +}; |
2478 | \ No newline at end of file |
2479 | diff --git a/docs/html/_static/file.png b/docs/html/_static/file.png |
2480 | new file mode 100644 |
2481 | index 0000000..a858a41 |
2482 | Binary files /dev/null and b/docs/html/_static/file.png differ |
2483 | diff --git a/docs/html/_static/jquery-3.4.1.js b/docs/html/_static/jquery-3.4.1.js |
2484 | new file mode 100644 |
2485 | index 0000000..773ad95 |
2486 | --- /dev/null |
2487 | +++ b/docs/html/_static/jquery-3.4.1.js |
2488 | @@ -0,0 +1,10598 @@ |
2489 | +/*! |
2490 | + * jQuery JavaScript Library v3.4.1 |
2491 | + * https://jquery.com/ |
2492 | + * |
2493 | + * Includes Sizzle.js |
2494 | + * https://sizzlejs.com/ |
2495 | + * |
2496 | + * Copyright JS Foundation and other contributors |
2497 | + * Released under the MIT license |
2498 | + * https://jquery.org/license |
2499 | + * |
2500 | + * Date: 2019-05-01T21:04Z |
2501 | + */ |
2502 | +( function( global, factory ) { |
2503 | + |
2504 | + "use strict"; |
2505 | + |
2506 | + if ( typeof module === "object" && typeof module.exports === "object" ) { |
2507 | + |
2508 | + // For CommonJS and CommonJS-like environments where a proper `window` |
2509 | + // is present, execute the factory and get jQuery. |
2510 | + // For environments that do not have a `window` with a `document` |
2511 | + // (such as Node.js), expose a factory as module.exports. |
2512 | + // This accentuates the need for the creation of a real `window`. |
2513 | + // e.g. var jQuery = require("jquery")(window); |
2514 | + // See ticket #14549 for more info. |
2515 | + module.exports = global.document ? |
2516 | + factory( global, true ) : |
2517 | + function( w ) { |
2518 | + if ( !w.document ) { |
2519 | + throw new Error( "jQuery requires a window with a document" ); |
2520 | + } |
2521 | + return factory( w ); |
2522 | + }; |
2523 | + } else { |
2524 | + factory( global ); |
2525 | + } |
2526 | + |
2527 | +// Pass this if window is not defined yet |
2528 | +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { |
2529 | + |
2530 | +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 |
2531 | +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode |
2532 | +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common |
2533 | +// enough that all such attempts are guarded in a try block. |
2534 | +"use strict"; |
2535 | + |
2536 | +var arr = []; |
2537 | + |
2538 | +var document = window.document; |
2539 | + |
2540 | +var getProto = Object.getPrototypeOf; |
2541 | + |
2542 | +var slice = arr.slice; |
2543 | + |
2544 | +var concat = arr.concat; |
2545 | + |
2546 | +var push = arr.push; |
2547 | + |
2548 | +var indexOf = arr.indexOf; |
2549 | + |
2550 | +var class2type = {}; |
2551 | + |
2552 | +var toString = class2type.toString; |
2553 | + |
2554 | +var hasOwn = class2type.hasOwnProperty; |
2555 | + |
2556 | +var fnToString = hasOwn.toString; |
2557 | + |
2558 | +var ObjectFunctionString = fnToString.call( Object ); |
2559 | + |
2560 | +var support = {}; |
2561 | + |
2562 | +var isFunction = function isFunction( obj ) { |
2563 | + |
2564 | + // Support: Chrome <=57, Firefox <=52 |
2565 | + // In some browsers, typeof returns "function" for HTML <object> elements |
2566 | + // (i.e., `typeof document.createElement( "object" ) === "function"`). |
2567 | + // We don't want to classify *any* DOM node as a function. |
2568 | + return typeof obj === "function" && typeof obj.nodeType !== "number"; |
2569 | + }; |
2570 | + |
2571 | + |
2572 | +var isWindow = function isWindow( obj ) { |
2573 | + return obj != null && obj === obj.window; |
2574 | + }; |
2575 | + |
2576 | + |
2577 | + |
2578 | + |
2579 | + var preservedScriptAttributes = { |
2580 | + type: true, |
2581 | + src: true, |
2582 | + nonce: true, |
2583 | + noModule: true |
2584 | + }; |
2585 | + |
2586 | + function DOMEval( code, node, doc ) { |
2587 | + doc = doc || document; |
2588 | + |
2589 | + var i, val, |
2590 | + script = doc.createElement( "script" ); |
2591 | + |
2592 | + script.text = code; |
2593 | + if ( node ) { |
2594 | + for ( i in preservedScriptAttributes ) { |
2595 | + |
2596 | + // Support: Firefox 64+, Edge 18+ |
2597 | + // Some browsers don't support the "nonce" property on scripts. |
2598 | + // On the other hand, just using `getAttribute` is not enough as |
2599 | + // the `nonce` attribute is reset to an empty string whenever it |
2600 | + // becomes browsing-context connected. |
2601 | + // See https://github.com/whatwg/html/issues/2369 |
2602 | + // See https://html.spec.whatwg.org/#nonce-attributes |
2603 | + // The `node.getAttribute` check was added for the sake of |
2604 | + // `jQuery.globalEval` so that it can fake a nonce-containing node |
2605 | + // via an object. |
2606 | + val = node[ i ] || node.getAttribute && node.getAttribute( i ); |
2607 | + if ( val ) { |
2608 | + script.setAttribute( i, val ); |
2609 | + } |
2610 | + } |
2611 | + } |
2612 | + doc.head.appendChild( script ).parentNode.removeChild( script ); |
2613 | + } |
2614 | + |
2615 | + |
2616 | +function toType( obj ) { |
2617 | + if ( obj == null ) { |
2618 | + return obj + ""; |
2619 | + } |
2620 | + |
2621 | + // Support: Android <=2.3 only (functionish RegExp) |
2622 | + return typeof obj === "object" || typeof obj === "function" ? |
2623 | + class2type[ toString.call( obj ) ] || "object" : |
2624 | + typeof obj; |
2625 | +} |
2626 | +/* global Symbol */ |
2627 | +// Defining this global in .eslintrc.json would create a danger of using the global |
2628 | +// unguarded in another place, it seems safer to define global only for this module |
2629 | + |
2630 | + |
2631 | + |
2632 | +var |
2633 | + version = "3.4.1", |
2634 | + |
2635 | + // Define a local copy of jQuery |
2636 | + jQuery = function( selector, context ) { |
2637 | + |
2638 | + // The jQuery object is actually just the init constructor 'enhanced' |
2639 | + // Need init if jQuery is called (just allow error to be thrown if not included) |
2640 | + return new jQuery.fn.init( selector, context ); |
2641 | + }, |
2642 | + |
2643 | + // Support: Android <=4.0 only |
2644 | + // Make sure we trim BOM and NBSP |
2645 | + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; |
2646 | + |
2647 | +jQuery.fn = jQuery.prototype = { |
2648 | + |
2649 | + // The current version of jQuery being used |
2650 | + jquery: version, |
2651 | + |
2652 | + constructor: jQuery, |
2653 | + |
2654 | + // The default length of a jQuery object is 0 |
2655 | + length: 0, |
2656 | + |
2657 | + toArray: function() { |
2658 | + return slice.call( this ); |
2659 | + }, |
2660 | + |
2661 | + // Get the Nth element in the matched element set OR |
2662 | + // Get the whole matched element set as a clean array |
2663 | + get: function( num ) { |
2664 | + |
2665 | + // Return all the elements in a clean array |
2666 | + if ( num == null ) { |
2667 | + return slice.call( this ); |
2668 | + } |
2669 | + |
2670 | + // Return just the one element from the set |
2671 | + return num < 0 ? this[ num + this.length ] : this[ num ]; |
2672 | + }, |
2673 | + |
2674 | + // Take an array of elements and push it onto the stack |
2675 | + // (returning the new matched element set) |
2676 | + pushStack: function( elems ) { |
2677 | + |
2678 | + // Build a new jQuery matched element set |
2679 | + var ret = jQuery.merge( this.constructor(), elems ); |
2680 | + |
2681 | + // Add the old object onto the stack (as a reference) |
2682 | + ret.prevObject = this; |
2683 | + |
2684 | + // Return the newly-formed element set |
2685 | + return ret; |
2686 | + }, |
2687 | + |
2688 | + // Execute a callback for every element in the matched set. |
2689 | + each: function( callback ) { |
2690 | + return jQuery.each( this, callback ); |
2691 | + }, |
2692 | + |
2693 | + map: function( callback ) { |
2694 | + return this.pushStack( jQuery.map( this, function( elem, i ) { |
2695 | + return callback.call( elem, i, elem ); |
2696 | + } ) ); |
2697 | + }, |
2698 | + |
2699 | + slice: function() { |
2700 | + return this.pushStack( slice.apply( this, arguments ) ); |
2701 | + }, |
2702 | + |
2703 | + first: function() { |
2704 | + return this.eq( 0 ); |
2705 | + }, |
2706 | + |
2707 | + last: function() { |
2708 | + return this.eq( -1 ); |
2709 | + }, |
2710 | + |
2711 | + eq: function( i ) { |
2712 | + var len = this.length, |
2713 | + j = +i + ( i < 0 ? len : 0 ); |
2714 | + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); |
2715 | + }, |
2716 | + |
2717 | + end: function() { |
2718 | + return this.prevObject || this.constructor(); |
2719 | + }, |
2720 | + |
2721 | + // For internal use only. |
2722 | + // Behaves like an Array's method, not like a jQuery method. |
2723 | + push: push, |
2724 | + sort: arr.sort, |
2725 | + splice: arr.splice |
2726 | +}; |
2727 | + |
2728 | +jQuery.extend = jQuery.fn.extend = function() { |
2729 | + var options, name, src, copy, copyIsArray, clone, |
2730 | + target = arguments[ 0 ] || {}, |
2731 | + i = 1, |
2732 | + length = arguments.length, |
2733 | + deep = false; |
2734 | + |
2735 | + // Handle a deep copy situation |
2736 | + if ( typeof target === "boolean" ) { |
2737 | + deep = target; |
2738 | + |
2739 | + // Skip the boolean and the target |
2740 | + target = arguments[ i ] || {}; |
2741 | + i++; |
2742 | + } |
2743 | + |
2744 | + // Handle case when target is a string or something (possible in deep copy) |
2745 | + if ( typeof target !== "object" && !isFunction( target ) ) { |
2746 | + target = {}; |
2747 | + } |
2748 | + |
2749 | + // Extend jQuery itself if only one argument is passed |
2750 | + if ( i === length ) { |
2751 | + target = this; |
2752 | + i--; |
2753 | + } |
2754 | + |
2755 | + for ( ; i < length; i++ ) { |
2756 | + |
2757 | + // Only deal with non-null/undefined values |
2758 | + if ( ( options = arguments[ i ] ) != null ) { |
2759 | + |
2760 | + // Extend the base object |
2761 | + for ( name in options ) { |
2762 | + copy = options[ name ]; |
2763 | + |
2764 | + // Prevent Object.prototype pollution |
2765 | + // Prevent never-ending loop |
2766 | + if ( name === "__proto__" || target === copy ) { |
2767 | + continue; |
2768 | + } |
2769 | + |
2770 | + // Recurse if we're merging plain objects or arrays |
2771 | + if ( deep && copy && ( jQuery.isPlainObject( copy ) || |
2772 | + ( copyIsArray = Array.isArray( copy ) ) ) ) { |
2773 | + src = target[ name ]; |
2774 | + |
2775 | + // Ensure proper type for the source value |
2776 | + if ( copyIsArray && !Array.isArray( src ) ) { |
2777 | + clone = []; |
2778 | + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { |
2779 | + clone = {}; |
2780 | + } else { |
2781 | + clone = src; |
2782 | + } |
2783 | + copyIsArray = false; |
2784 | + |
2785 | + // Never move original objects, clone them |
2786 | + target[ name ] = jQuery.extend( deep, clone, copy ); |
2787 | + |
2788 | + // Don't bring in undefined values |
2789 | + } else if ( copy !== undefined ) { |
2790 | + target[ name ] = copy; |
2791 | + } |
2792 | + } |
2793 | + } |
2794 | + } |
2795 | + |
2796 | + // Return the modified object |
2797 | + return target; |
2798 | +}; |
2799 | + |
2800 | +jQuery.extend( { |
2801 | + |
2802 | + // Unique for each copy of jQuery on the page |
2803 | + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), |
2804 | + |
2805 | + // Assume jQuery is ready without the ready module |
2806 | + isReady: true, |
2807 | + |
2808 | + error: function( msg ) { |
2809 | + throw new Error( msg ); |
2810 | + }, |
2811 | + |
2812 | + noop: function() {}, |
2813 | + |
2814 | + isPlainObject: function( obj ) { |
2815 | + var proto, Ctor; |
2816 | + |
2817 | + // Detect obvious negatives |
2818 | + // Use toString instead of jQuery.type to catch host objects |
2819 | + if ( !obj || toString.call( obj ) !== "[object Object]" ) { |
2820 | + return false; |
2821 | + } |
2822 | + |
2823 | + proto = getProto( obj ); |
2824 | + |
2825 | + // Objects with no prototype (e.g., `Object.create( null )`) are plain |
2826 | + if ( !proto ) { |
2827 | + return true; |
2828 | + } |
2829 | + |
2830 | + // Objects with prototype are plain iff they were constructed by a global Object function |
2831 | + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; |
2832 | + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; |
2833 | + }, |
2834 | + |
2835 | + isEmptyObject: function( obj ) { |
2836 | + var name; |
2837 | + |
2838 | + for ( name in obj ) { |
2839 | + return false; |
2840 | + } |
2841 | + return true; |
2842 | + }, |
2843 | + |
2844 | + // Evaluates a script in a global context |
2845 | + globalEval: function( code, options ) { |
2846 | + DOMEval( code, { nonce: options && options.nonce } ); |
2847 | + }, |
2848 | + |
2849 | + each: function( obj, callback ) { |
2850 | + var length, i = 0; |
2851 | + |
2852 | + if ( isArrayLike( obj ) ) { |
2853 | + length = obj.length; |
2854 | + for ( ; i < length; i++ ) { |
2855 | + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { |
2856 | + break; |
2857 | + } |
2858 | + } |
2859 | + } else { |
2860 | + for ( i in obj ) { |
2861 | + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { |
2862 | + break; |
2863 | + } |
2864 | + } |
2865 | + } |
2866 | + |
2867 | + return obj; |
2868 | + }, |
2869 | + |
2870 | + // Support: Android <=4.0 only |
2871 | + trim: function( text ) { |
2872 | + return text == null ? |
2873 | + "" : |
2874 | + ( text + "" ).replace( rtrim, "" ); |
2875 | + }, |
2876 | + |
2877 | + // results is for internal usage only |
2878 | + makeArray: function( arr, results ) { |
2879 | + var ret = results || []; |
2880 | + |
2881 | + if ( arr != null ) { |
2882 | + if ( isArrayLike( Object( arr ) ) ) { |
2883 | + jQuery.merge( ret, |
2884 | + typeof arr === "string" ? |
2885 | + [ arr ] : arr |
2886 | + ); |
2887 | + } else { |
2888 | + push.call( ret, arr ); |
2889 | + } |
2890 | + } |
2891 | + |
2892 | + return ret; |
2893 | + }, |
2894 | + |
2895 | + inArray: function( elem, arr, i ) { |
2896 | + return arr == null ? -1 : indexOf.call( arr, elem, i ); |
2897 | + }, |
2898 | + |
2899 | + // Support: Android <=4.0 only, PhantomJS 1 only |
2900 | + // push.apply(_, arraylike) throws on ancient WebKit |
2901 | + merge: function( first, second ) { |
2902 | + var len = +second.length, |
2903 | + j = 0, |
2904 | + i = first.length; |
2905 | + |
2906 | + for ( ; j < len; j++ ) { |
2907 | + first[ i++ ] = second[ j ]; |
2908 | + } |
2909 | + |
2910 | + first.length = i; |
2911 | + |
2912 | + return first; |
2913 | + }, |
2914 | + |
2915 | + grep: function( elems, callback, invert ) { |
2916 | + var callbackInverse, |
2917 | + matches = [], |
2918 | + i = 0, |
2919 | + length = elems.length, |
2920 | + callbackExpect = !invert; |
2921 | + |
2922 | + // Go through the array, only saving the items |
2923 | + // that pass the validator function |
2924 | + for ( ; i < length; i++ ) { |
2925 | + callbackInverse = !callback( elems[ i ], i ); |
2926 | + if ( callbackInverse !== callbackExpect ) { |
2927 | + matches.push( elems[ i ] ); |
2928 | + } |
2929 | + } |
2930 | + |
2931 | + return matches; |
2932 | + }, |
2933 | + |
2934 | + // arg is for internal usage only |
2935 | + map: function( elems, callback, arg ) { |
2936 | + var length, value, |
2937 | + i = 0, |
2938 | + ret = []; |
2939 | + |
2940 | + // Go through the array, translating each of the items to their new values |
2941 | + if ( isArrayLike( elems ) ) { |
2942 | + length = elems.length; |
2943 | + for ( ; i < length; i++ ) { |
2944 | + value = callback( elems[ i ], i, arg ); |
2945 | + |
2946 | + if ( value != null ) { |
2947 | + ret.push( value ); |
2948 | + } |
2949 | + } |
2950 | + |
2951 | + // Go through every key on the object, |
2952 | + } else { |
2953 | + for ( i in elems ) { |
2954 | + value = callback( elems[ i ], i, arg ); |
2955 | + |
2956 | + if ( value != null ) { |
2957 | + ret.push( value ); |
2958 | + } |
2959 | + } |
2960 | + } |
2961 | + |
2962 | + // Flatten any nested arrays |
2963 | + return concat.apply( [], ret ); |
2964 | + }, |
2965 | + |
2966 | + // A global GUID counter for objects |
2967 | + guid: 1, |
2968 | + |
2969 | + // jQuery.support is not used in Core but other projects attach their |
2970 | + // properties to it so it needs to exist. |
2971 | + support: support |
2972 | +} ); |
2973 | + |
2974 | +if ( typeof Symbol === "function" ) { |
2975 | + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; |
2976 | +} |
2977 | + |
2978 | +// Populate the class2type map |
2979 | +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), |
2980 | +function( i, name ) { |
2981 | + class2type[ "[object " + name + "]" ] = name.toLowerCase(); |
2982 | +} ); |
2983 | + |
2984 | +function isArrayLike( obj ) { |
2985 | + |
2986 | + // Support: real iOS 8.2 only (not reproducible in simulator) |
2987 | + // `in` check used to prevent JIT error (gh-2145) |
2988 | + // hasOwn isn't used here due to false negatives |
2989 | + // regarding Nodelist length in IE |
2990 | + var length = !!obj && "length" in obj && obj.length, |
2991 | + type = toType( obj ); |
2992 | + |
2993 | + if ( isFunction( obj ) || isWindow( obj ) ) { |
2994 | + return false; |
2995 | + } |
2996 | + |
2997 | + return type === "array" || length === 0 || |
2998 | + typeof length === "number" && length > 0 && ( length - 1 ) in obj; |
2999 | +} |
3000 | +var Sizzle = |
3001 | +/*! |
3002 | + * Sizzle CSS Selector Engine v2.3.4 |
3003 | + * https://sizzlejs.com/ |
3004 | + * |
3005 | + * Copyright JS Foundation and other contributors |
3006 | + * Released under the MIT license |
3007 | + * https://js.foundation/ |
3008 | + * |
3009 | + * Date: 2019-04-08 |
3010 | + */ |
3011 | +(function( window ) { |
3012 | + |
3013 | +var i, |
3014 | + support, |
3015 | + Expr, |
3016 | + getText, |
3017 | + isXML, |
3018 | + tokenize, |
3019 | + compile, |
3020 | + select, |
3021 | + outermostContext, |
3022 | + sortInput, |
3023 | + hasDuplicate, |
3024 | + |
3025 | + // Local document vars |
3026 | + setDocument, |
3027 | + document, |
3028 | + docElem, |
3029 | + documentIsHTML, |
3030 | + rbuggyQSA, |
3031 | + rbuggyMatches, |
3032 | + matches, |
3033 | + contains, |
3034 | + |
3035 | + // Instance-specific data |
3036 | + expando = "sizzle" + 1 * new Date(), |
3037 | + preferredDoc = window.document, |
3038 | + dirruns = 0, |
3039 | + done = 0, |
3040 | + classCache = createCache(), |
3041 | + tokenCache = createCache(), |
3042 | + compilerCache = createCache(), |
3043 | + nonnativeSelectorCache = createCache(), |
3044 | + sortOrder = function( a, b ) { |
3045 | + if ( a === b ) { |
3046 | + hasDuplicate = true; |
3047 | + } |
3048 | + return 0; |
3049 | + }, |
3050 | + |
3051 | + // Instance methods |
3052 | + hasOwn = ({}).hasOwnProperty, |
3053 | + arr = [], |
3054 | + pop = arr.pop, |
3055 | + push_native = arr.push, |
3056 | + push = arr.push, |
3057 | + slice = arr.slice, |
3058 | + // Use a stripped-down indexOf as it's faster than native |
3059 | + // https://jsperf.com/thor-indexof-vs-for/5 |
3060 | + indexOf = function( list, elem ) { |
3061 | + var i = 0, |
3062 | + len = list.length; |
3063 | + for ( ; i < len; i++ ) { |
3064 | + if ( list[i] === elem ) { |
3065 | + return i; |
3066 | + } |
3067 | + } |
3068 | + return -1; |
3069 | + }, |
3070 | + |
3071 | + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", |
3072 | + |
3073 | + // Regular expressions |
3074 | + |
3075 | + // http://www.w3.org/TR/css3-selectors/#whitespace |
3076 | + whitespace = "[\\x20\\t\\r\\n\\f]", |
3077 | + |
3078 | + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier |
3079 | + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", |
3080 | + |
3081 | + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors |
3082 | + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + |
3083 | + // Operator (capture 2) |
3084 | + "*([*^$|!~]?=)" + whitespace + |
3085 | + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" |
3086 | + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + |
3087 | + "*\\]", |
3088 | + |
3089 | + pseudos = ":(" + identifier + ")(?:\\((" + |
3090 | + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: |
3091 | + // 1. quoted (capture 3; capture 4 or capture 5) |
3092 | + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + |
3093 | + // 2. simple (capture 6) |
3094 | + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + |
3095 | + // 3. anything else (capture 2) |
3096 | + ".*" + |
3097 | + ")\\)|)", |
3098 | + |
3099 | + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter |
3100 | + rwhitespace = new RegExp( whitespace + "+", "g" ), |
3101 | + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), |
3102 | + |
3103 | + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), |
3104 | + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), |
3105 | + rdescend = new RegExp( whitespace + "|>" ), |
3106 | + |
3107 | + rpseudo = new RegExp( pseudos ), |
3108 | + ridentifier = new RegExp( "^" + identifier + "$" ), |
3109 | + |
3110 | + matchExpr = { |
3111 | + "ID": new RegExp( "^#(" + identifier + ")" ), |
3112 | + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), |
3113 | + "TAG": new RegExp( "^(" + identifier + "|[*])" ), |
3114 | + "ATTR": new RegExp( "^" + attributes ), |
3115 | + "PSEUDO": new RegExp( "^" + pseudos ), |
3116 | + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + |
3117 | + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + |
3118 | + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), |
3119 | + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), |
3120 | + // For use in libraries implementing .is() |
3121 | + // We use this for POS matching in `select` |
3122 | + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + |
3123 | + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) |
3124 | + }, |
3125 | + |
3126 | + rhtml = /HTML$/i, |
3127 | + rinputs = /^(?:input|select|textarea|button)$/i, |
3128 | + rheader = /^h\d$/i, |
3129 | + |
3130 | + rnative = /^[^{]+\{\s*\[native \w/, |
3131 | + |
3132 | + // Easily-parseable/retrievable ID or TAG or CLASS selectors |
3133 | + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, |
3134 | + |
3135 | + rsibling = /[+~]/, |
3136 | + |
3137 | + // CSS escapes |
3138 | + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters |
3139 | + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), |
3140 | + funescape = function( _, escaped, escapedWhitespace ) { |
3141 | + var high = "0x" + escaped - 0x10000; |
3142 | + // NaN means non-codepoint |
3143 | + // Support: Firefox<24 |
3144 | + // Workaround erroneous numeric interpretation of +"0x" |
3145 | + return high !== high || escapedWhitespace ? |
3146 | + escaped : |
3147 | + high < 0 ? |
3148 | + // BMP codepoint |
3149 | + String.fromCharCode( high + 0x10000 ) : |
3150 | + // Supplemental Plane codepoint (surrogate pair) |
3151 | + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); |
3152 | + }, |
3153 | + |
3154 | + // CSS string/identifier serialization |
3155 | + // https://drafts.csswg.org/cssom/#common-serializing-idioms |
3156 | + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, |
3157 | + fcssescape = function( ch, asCodePoint ) { |
3158 | + if ( asCodePoint ) { |
3159 | + |
3160 | + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER |
3161 | + if ( ch === "\0" ) { |
3162 | + return "\uFFFD"; |
3163 | + } |
3164 | + |
3165 | + // Control characters and (dependent upon position) numbers get escaped as code points |
3166 | + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; |
3167 | + } |
3168 | + |
3169 | + // Other potentially-special ASCII characters get backslash-escaped |
3170 | + return "\\" + ch; |
3171 | + }, |
3172 | + |
3173 | + // Used for iframes |
3174 | + // See setDocument() |
3175 | + // Removing the function wrapper causes a "Permission Denied" |
3176 | + // error in IE |
3177 | + unloadHandler = function() { |
3178 | + setDocument(); |
3179 | + }, |
3180 | + |
3181 | + inDisabledFieldset = addCombinator( |
3182 | + function( elem ) { |
3183 | + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; |
3184 | + }, |
3185 | + { dir: "parentNode", next: "legend" } |
3186 | + ); |
3187 | + |
3188 | +// Optimize for push.apply( _, NodeList ) |
3189 | +try { |
3190 | + push.apply( |
3191 | + (arr = slice.call( preferredDoc.childNodes )), |
3192 | + preferredDoc.childNodes |
3193 | + ); |
3194 | + // Support: Android<4.0 |
3195 | + // Detect silently failing push.apply |
3196 | + arr[ preferredDoc.childNodes.length ].nodeType; |
3197 | +} catch ( e ) { |
3198 | + push = { apply: arr.length ? |
3199 | + |
3200 | + // Leverage slice if possible |
3201 | + function( target, els ) { |
3202 | + push_native.apply( target, slice.call(els) ); |
3203 | + } : |
3204 | + |
3205 | + // Support: IE<9 |
3206 | + // Otherwise append directly |
3207 | + function( target, els ) { |
3208 | + var j = target.length, |
3209 | + i = 0; |
3210 | + // Can't trust NodeList.length |
3211 | + while ( (target[j++] = els[i++]) ) {} |
3212 | + target.length = j - 1; |
3213 | + } |
3214 | + }; |
3215 | +} |
3216 | + |
3217 | +function Sizzle( selector, context, results, seed ) { |
3218 | + var m, i, elem, nid, match, groups, newSelector, |
3219 | + newContext = context && context.ownerDocument, |
3220 | + |
3221 | + // nodeType defaults to 9, since context defaults to document |
3222 | + nodeType = context ? context.nodeType : 9; |
3223 | + |
3224 | + results = results || []; |
3225 | + |
3226 | + // Return early from calls with invalid selector or context |
3227 | + if ( typeof selector !== "string" || !selector || |
3228 | + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { |
3229 | + |
3230 | + return results; |
3231 | + } |
3232 | + |
3233 | + // Try to shortcut find operations (as opposed to filters) in HTML documents |
3234 | + if ( !seed ) { |
3235 | + |
3236 | + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { |
3237 | + setDocument( context ); |
3238 | + } |
3239 | + context = context || document; |
3240 | + |
3241 | + if ( documentIsHTML ) { |
3242 | + |
3243 | + // If the selector is sufficiently simple, try using a "get*By*" DOM method |
3244 | + // (excepting DocumentFragment context, where the methods don't exist) |
3245 | + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { |
3246 | + |
3247 | + // ID selector |
3248 | + if ( (m = match[1]) ) { |
3249 | + |
3250 | + // Document context |
3251 | + if ( nodeType === 9 ) { |
3252 | + if ( (elem = context.getElementById( m )) ) { |
3253 | + |
3254 | + // Support: IE, Opera, Webkit |
3255 | + // TODO: identify versions |
3256 | + // getElementById can match elements by name instead of ID |
3257 | + if ( elem.id === m ) { |
3258 | + results.push( elem ); |
3259 | + return results; |
3260 | + } |
3261 | + } else { |
3262 | + return results; |
3263 | + } |
3264 | + |
3265 | + // Element context |
3266 | + } else { |
3267 | + |
3268 | + // Support: IE, Opera, Webkit |
3269 | + // TODO: identify versions |
3270 | + // getElementById can match elements by name instead of ID |
3271 | + if ( newContext && (elem = newContext.getElementById( m )) && |
3272 | + contains( context, elem ) && |
3273 | + elem.id === m ) { |
3274 | + |
3275 | + results.push( elem ); |
3276 | + return results; |
3277 | + } |
3278 | + } |
3279 | + |
3280 | + // Type selector |
3281 | + } else if ( match[2] ) { |
3282 | + push.apply( results, context.getElementsByTagName( selector ) ); |
3283 | + return results; |
3284 | + |
3285 | + // Class selector |
3286 | + } else if ( (m = match[3]) && support.getElementsByClassName && |
3287 | + context.getElementsByClassName ) { |
3288 | + |
3289 | + push.apply( results, context.getElementsByClassName( m ) ); |
3290 | + return results; |
3291 | + } |
3292 | + } |
3293 | + |
3294 | + // Take advantage of querySelectorAll |
3295 | + if ( support.qsa && |
3296 | + !nonnativeSelectorCache[ selector + " " ] && |
3297 | + (!rbuggyQSA || !rbuggyQSA.test( selector )) && |
3298 | + |
3299 | + // Support: IE 8 only |
3300 | + // Exclude object elements |
3301 | + (nodeType !== 1 || context.nodeName.toLowerCase() !== "object") ) { |
3302 | + |
3303 | + newSelector = selector; |
3304 | + newContext = context; |
3305 | + |
3306 | + // qSA considers elements outside a scoping root when evaluating child or |
3307 | + // descendant combinators, which is not what we want. |
3308 | + // In such cases, we work around the behavior by prefixing every selector in the |
3309 | + // list with an ID selector referencing the scope context. |
3310 | + // Thanks to Andrew Dupont for this technique. |
3311 | + if ( nodeType === 1 && rdescend.test( selector ) ) { |
3312 | + |
3313 | + // Capture the context ID, setting it first if necessary |
3314 | + if ( (nid = context.getAttribute( "id" )) ) { |
3315 | + nid = nid.replace( rcssescape, fcssescape ); |
3316 | + } else { |
3317 | + context.setAttribute( "id", (nid = expando) ); |
3318 | + } |
3319 | + |
3320 | + // Prefix every selector in the list |
3321 | + groups = tokenize( selector ); |
3322 | + i = groups.length; |
3323 | + while ( i-- ) { |
3324 | + groups[i] = "#" + nid + " " + toSelector( groups[i] ); |
3325 | + } |
3326 | + newSelector = groups.join( "," ); |
3327 | + |
3328 | + // Expand context for sibling selectors |
3329 | + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || |
3330 | + context; |
3331 | + } |
3332 | + |
3333 | + try { |
3334 | + push.apply( results, |
3335 | + newContext.querySelectorAll( newSelector ) |
3336 | + ); |
3337 | + return results; |
3338 | + } catch ( qsaError ) { |
3339 | + nonnativeSelectorCache( selector, true ); |
3340 | + } finally { |
3341 | + if ( nid === expando ) { |
3342 | + context.removeAttribute( "id" ); |
3343 | + } |
3344 | + } |
3345 | + } |
3346 | + } |
3347 | + } |
3348 | + |
3349 | + // All others |
3350 | + return select( selector.replace( rtrim, "$1" ), context, results, seed ); |
3351 | +} |
3352 | + |
3353 | +/** |
3354 | + * Create key-value caches of limited size |
3355 | + * @returns {function(string, object)} Returns the Object data after storing it on itself with |
3356 | + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) |
3357 | + * deleting the oldest entry |
3358 | + */ |
3359 | +function createCache() { |
3360 | + var keys = []; |
3361 | + |
3362 | + function cache( key, value ) { |
3363 | + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) |
3364 | + if ( keys.push( key + " " ) > Expr.cacheLength ) { |
3365 | + // Only keep the most recent entries |
3366 | + delete cache[ keys.shift() ]; |
3367 | + } |
3368 | + return (cache[ key + " " ] = value); |
3369 | + } |
3370 | + return cache; |
3371 | +} |
3372 | + |
3373 | +/** |
3374 | + * Mark a function for special use by Sizzle |
3375 | + * @param {Function} fn The function to mark |
3376 | + */ |
3377 | +function markFunction( fn ) { |
3378 | + fn[ expando ] = true; |
3379 | + return fn; |
3380 | +} |
3381 | + |
3382 | +/** |
3383 | + * Support testing using an element |
3384 | + * @param {Function} fn Passed the created element and returns a boolean result |
3385 | + */ |
3386 | +function assert( fn ) { |
3387 | + var el = document.createElement("fieldset"); |
3388 | + |
3389 | + try { |
3390 | + return !!fn( el ); |
3391 | + } catch (e) { |
3392 | + return false; |
3393 | + } finally { |
3394 | + // Remove from its parent by default |
3395 | + if ( el.parentNode ) { |
3396 | + el.parentNode.removeChild( el ); |
3397 | + } |
3398 | + // release memory in IE |
3399 | + el = null; |
3400 | + } |
3401 | +} |
3402 | + |
3403 | +/** |
3404 | + * Adds the same handler for all of the specified attrs |
3405 | + * @param {String} attrs Pipe-separated list of attributes |
3406 | + * @param {Function} handler The method that will be applied |
3407 | + */ |
3408 | +function addHandle( attrs, handler ) { |
3409 | + var arr = attrs.split("|"), |
3410 | + i = arr.length; |
3411 | + |
3412 | + while ( i-- ) { |
3413 | + Expr.attrHandle[ arr[i] ] = handler; |
3414 | + } |
3415 | +} |
3416 | + |
3417 | +/** |
3418 | + * Checks document order of two siblings |
3419 | + * @param {Element} a |
3420 | + * @param {Element} b |
3421 | + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b |
3422 | + */ |
3423 | +function siblingCheck( a, b ) { |
3424 | + var cur = b && a, |
3425 | + diff = cur && a.nodeType === 1 && b.nodeType === 1 && |
3426 | + a.sourceIndex - b.sourceIndex; |
3427 | + |
3428 | + // Use IE sourceIndex if available on both nodes |
3429 | + if ( diff ) { |
3430 | + return diff; |
3431 | + } |
3432 | + |
3433 | + // Check if b follows a |
3434 | + if ( cur ) { |
3435 | + while ( (cur = cur.nextSibling) ) { |
3436 | + if ( cur === b ) { |
3437 | + return -1; |
3438 | + } |
3439 | + } |
3440 | + } |
3441 | + |
3442 | + return a ? 1 : -1; |
3443 | +} |
3444 | + |
3445 | +/** |
3446 | + * Returns a function to use in pseudos for input types |
3447 | + * @param {String} type |
3448 | + */ |
3449 | +function createInputPseudo( type ) { |
3450 | + return function( elem ) { |
3451 | + var name = elem.nodeName.toLowerCase(); |
3452 | + return name === "input" && elem.type === type; |
3453 | + }; |
3454 | +} |
3455 | + |
3456 | +/** |
3457 | + * Returns a function to use in pseudos for buttons |
3458 | + * @param {String} type |
3459 | + */ |
3460 | +function createButtonPseudo( type ) { |
3461 | + return function( elem ) { |
3462 | + var name = elem.nodeName.toLowerCase(); |
3463 | + return (name === "input" || name === "button") && elem.type === type; |
3464 | + }; |
3465 | +} |
3466 | + |
3467 | +/** |
3468 | + * Returns a function to use in pseudos for :enabled/:disabled |
3469 | + * @param {Boolean} disabled true for :disabled; false for :enabled |
3470 | + */ |
3471 | +function createDisabledPseudo( disabled ) { |
3472 | + |
3473 | + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable |
3474 | + return function( elem ) { |
3475 | + |
3476 | + // Only certain elements can match :enabled or :disabled |
3477 | + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled |
3478 | + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled |
3479 | + if ( "form" in elem ) { |
3480 | + |
3481 | + // Check for inherited disabledness on relevant non-disabled elements: |
3482 | + // * listed form-associated elements in a disabled fieldset |
3483 | + // https://html.spec.whatwg.org/multipage/forms.html#category-listed |
3484 | + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled |
3485 | + // * option elements in a disabled optgroup |
3486 | + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled |
3487 | + // All such elements have a "form" property. |
3488 | + if ( elem.parentNode && elem.disabled === false ) { |
3489 | + |
3490 | + // Option elements defer to a parent optgroup if present |
3491 | + if ( "label" in elem ) { |
3492 | + if ( "label" in elem.parentNode ) { |
3493 | + return elem.parentNode.disabled === disabled; |
3494 | + } else { |
3495 | + return elem.disabled === disabled; |
3496 | + } |
3497 | + } |
3498 | + |
3499 | + // Support: IE 6 - 11 |
3500 | + // Use the isDisabled shortcut property to check for disabled fieldset ancestors |
3501 | + return elem.isDisabled === disabled || |
3502 | + |
3503 | + // Where there is no isDisabled, check manually |
3504 | + /* jshint -W018 */ |
3505 | + elem.isDisabled !== !disabled && |
3506 | + inDisabledFieldset( elem ) === disabled; |
3507 | + } |
3508 | + |
3509 | + return elem.disabled === disabled; |
3510 | + |
3511 | + // Try to winnow out elements that can't be disabled before trusting the disabled property. |
3512 | + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't |
3513 | + // even exist on them, let alone have a boolean value. |
3514 | + } else if ( "label" in elem ) { |
3515 | + return elem.disabled === disabled; |
3516 | + } |
3517 | + |
3518 | + // Remaining elements are neither :enabled nor :disabled |
3519 | + return false; |
3520 | + }; |
3521 | +} |
3522 | + |
3523 | +/** |
3524 | + * Returns a function to use in pseudos for positionals |
3525 | + * @param {Function} fn |
3526 | + */ |
3527 | +function createPositionalPseudo( fn ) { |
3528 | + return markFunction(function( argument ) { |
3529 | + argument = +argument; |
3530 | + return markFunction(function( seed, matches ) { |
3531 | + var j, |
3532 | + matchIndexes = fn( [], seed.length, argument ), |
3533 | + i = matchIndexes.length; |
3534 | + |
3535 | + // Match elements found at the specified indexes |
3536 | + while ( i-- ) { |
3537 | + if ( seed[ (j = matchIndexes[i]) ] ) { |
3538 | + seed[j] = !(matches[j] = seed[j]); |
3539 | + } |
3540 | + } |
3541 | + }); |
3542 | + }); |
3543 | +} |
3544 | + |
3545 | +/** |
3546 | + * Checks a node for validity as a Sizzle context |
3547 | + * @param {Element|Object=} context |
3548 | + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value |
3549 | + */ |
3550 | +function testContext( context ) { |
3551 | + return context && typeof context.getElementsByTagName !== "undefined" && context; |
3552 | +} |
3553 | + |
3554 | +// Expose support vars for convenience |
3555 | +support = Sizzle.support = {}; |
3556 | + |
3557 | +/** |
3558 | + * Detects XML nodes |
3559 | + * @param {Element|Object} elem An element or a document |
3560 | + * @returns {Boolean} True iff elem is a non-HTML XML node |
3561 | + */ |
3562 | +isXML = Sizzle.isXML = function( elem ) { |
3563 | + var namespace = elem.namespaceURI, |
3564 | + docElem = (elem.ownerDocument || elem).documentElement; |
3565 | + |
3566 | + // Support: IE <=8 |
3567 | + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes |
3568 | + // https://bugs.jquery.com/ticket/4833 |
3569 | + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); |
3570 | +}; |
3571 | + |
3572 | +/** |
3573 | + * Sets document-related variables once based on the current document |
3574 | + * @param {Element|Object} [doc] An element or document object to use to set the document |
3575 | + * @returns {Object} Returns the current document |
3576 | + */ |
3577 | +setDocument = Sizzle.setDocument = function( node ) { |
3578 | + var hasCompare, subWindow, |
3579 | + doc = node ? node.ownerDocument || node : preferredDoc; |
3580 | + |
3581 | + // Return early if doc is invalid or already selected |
3582 | + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { |
3583 | + return document; |
3584 | + } |
3585 | + |
3586 | + // Update global variables |
3587 | + document = doc; |
3588 | + docElem = document.documentElement; |
3589 | + documentIsHTML = !isXML( document ); |
3590 | + |
3591 | + // Support: IE 9-11, Edge |
3592 | + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) |
3593 | + if ( preferredDoc !== document && |
3594 | + (subWindow = document.defaultView) && subWindow.top !== subWindow ) { |
3595 | + |
3596 | + // Support: IE 11, Edge |
3597 | + if ( subWindow.addEventListener ) { |
3598 | + subWindow.addEventListener( "unload", unloadHandler, false ); |
3599 | + |
3600 | + // Support: IE 9 - 10 only |
3601 | + } else if ( subWindow.attachEvent ) { |
3602 | + subWindow.attachEvent( "onunload", unloadHandler ); |
3603 | + } |
3604 | + } |
3605 | + |
3606 | + /* Attributes |
3607 | + ---------------------------------------------------------------------- */ |
3608 | + |
3609 | + // Support: IE<8 |
3610 | + // Verify that getAttribute really returns attributes and not properties |
3611 | + // (excepting IE8 booleans) |
3612 | + support.attributes = assert(function( el ) { |
3613 | + el.className = "i"; |
3614 | + return !el.getAttribute("className"); |
3615 | + }); |
3616 | + |
3617 | + /* getElement(s)By* |
3618 | + ---------------------------------------------------------------------- */ |
3619 | + |
3620 | + // Check if getElementsByTagName("*") returns only elements |
3621 | + support.getElementsByTagName = assert(function( el ) { |
3622 | + el.appendChild( document.createComment("") ); |
3623 | + return !el.getElementsByTagName("*").length; |
3624 | + }); |
3625 | + |
3626 | + // Support: IE<9 |
3627 | + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); |
3628 | + |
3629 | + // Support: IE<10 |
3630 | + // Check if getElementById returns elements by name |
3631 | + // The broken getElementById methods don't pick up programmatically-set names, |
3632 | + // so use a roundabout getElementsByName test |
3633 | + support.getById = assert(function( el ) { |
3634 | + docElem.appendChild( el ).id = expando; |
3635 | + return !document.getElementsByName || !document.getElementsByName( expando ).length; |
3636 | + }); |
3637 | + |
3638 | + // ID filter and find |
3639 | + if ( support.getById ) { |
3640 | + Expr.filter["ID"] = function( id ) { |
3641 | + var attrId = id.replace( runescape, funescape ); |
3642 | + return function( elem ) { |
3643 | + return elem.getAttribute("id") === attrId; |
3644 | + }; |
3645 | + }; |
3646 | + Expr.find["ID"] = function( id, context ) { |
3647 | + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { |
3648 | + var elem = context.getElementById( id ); |
3649 | + return elem ? [ elem ] : []; |
3650 | + } |
3651 | + }; |
3652 | + } else { |
3653 | + Expr.filter["ID"] = function( id ) { |
3654 | + var attrId = id.replace( runescape, funescape ); |
3655 | + return function( elem ) { |
3656 | + var node = typeof elem.getAttributeNode !== "undefined" && |
3657 | + elem.getAttributeNode("id"); |
3658 | + return node && node.value === attrId; |
3659 | + }; |
3660 | + }; |
3661 | + |
3662 | + // Support: IE 6 - 7 only |
3663 | + // getElementById is not reliable as a find shortcut |
3664 | + Expr.find["ID"] = function( id, context ) { |
3665 | + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { |
3666 | + var node, i, elems, |
3667 | + elem = context.getElementById( id ); |
3668 | + |
3669 | + if ( elem ) { |
3670 | + |
3671 | + // Verify the id attribute |
3672 | + node = elem.getAttributeNode("id"); |
3673 | + if ( node && node.value === id ) { |
3674 | + return [ elem ]; |
3675 | + } |
3676 | + |
3677 | + // Fall back on getElementsByName |
3678 | + elems = context.getElementsByName( id ); |
3679 | + i = 0; |
3680 | + while ( (elem = elems[i++]) ) { |
3681 | + node = elem.getAttributeNode("id"); |
3682 | + if ( node && node.value === id ) { |
3683 | + return [ elem ]; |
3684 | + } |
3685 | + } |
3686 | + } |
3687 | + |
3688 | + return []; |
3689 | + } |
3690 | + }; |
3691 | + } |
3692 | + |
3693 | + // Tag |
3694 | + Expr.find["TAG"] = support.getElementsByTagName ? |
3695 | + function( tag, context ) { |
3696 | + if ( typeof context.getElementsByTagName !== "undefined" ) { |
3697 | + return context.getElementsByTagName( tag ); |
3698 | + |
3699 | + // DocumentFragment nodes don't have gEBTN |
3700 | + } else if ( support.qsa ) { |
3701 | + return context.querySelectorAll( tag ); |
3702 | + } |
3703 | + } : |
3704 | + |
3705 | + function( tag, context ) { |
3706 | + var elem, |
3707 | + tmp = [], |
3708 | + i = 0, |
3709 | + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too |
3710 | + results = context.getElementsByTagName( tag ); |
3711 | + |
3712 | + // Filter out possible comments |
3713 | + if ( tag === "*" ) { |
3714 | + while ( (elem = results[i++]) ) { |
3715 | + if ( elem.nodeType === 1 ) { |
3716 | + tmp.push( elem ); |
3717 | + } |
3718 | + } |
3719 | + |
3720 | + return tmp; |
3721 | + } |
3722 | + return results; |
3723 | + }; |
3724 | + |
3725 | + // Class |
3726 | + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { |
3727 | + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { |
3728 | + return context.getElementsByClassName( className ); |
3729 | + } |
3730 | + }; |
3731 | + |
3732 | + /* QSA/matchesSelector |
3733 | + ---------------------------------------------------------------------- */ |
3734 | + |
3735 | + // QSA and matchesSelector support |
3736 | + |
3737 | + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) |
3738 | + rbuggyMatches = []; |
3739 | + |
3740 | + // qSa(:focus) reports false when true (Chrome 21) |
3741 | + // We allow this because of a bug in IE8/9 that throws an error |
3742 | + // whenever `document.activeElement` is accessed on an iframe |
3743 | + // So, we allow :focus to pass through QSA all the time to avoid the IE error |
3744 | + // See https://bugs.jquery.com/ticket/13378 |
3745 | + rbuggyQSA = []; |
3746 | + |
3747 | + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { |
3748 | + // Build QSA regex |
3749 | + // Regex strategy adopted from Diego Perini |
3750 | + assert(function( el ) { |
3751 | + // Select is set to empty string on purpose |
3752 | + // This is to test IE's treatment of not explicitly |
3753 | + // setting a boolean content attribute, |
3754 | + // since its presence should be enough |
3755 | + // https://bugs.jquery.com/ticket/12359 |
3756 | + docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + |
3757 | + "<select id='" + expando + "-\r\\' msallowcapture=''>" + |
3758 | + "<option selected=''></option></select>"; |
3759 | + |
3760 | + // Support: IE8, Opera 11-12.16 |
3761 | + // Nothing should be selected when empty strings follow ^= or $= or *= |
3762 | + // The test attribute must be unknown in Opera but "safe" for WinRT |
3763 | + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section |
3764 | + if ( el.querySelectorAll("[msallowcapture^='']").length ) { |
3765 | + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); |
3766 | + } |
3767 | + |
3768 | + // Support: IE8 |
3769 | + // Boolean attributes and "value" are not treated correctly |
3770 | + if ( !el.querySelectorAll("[selected]").length ) { |
3771 | + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); |
3772 | + } |
3773 | + |
3774 | + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ |
3775 | + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { |
3776 | + rbuggyQSA.push("~="); |
3777 | + } |
3778 | + |
3779 | + // Webkit/Opera - :checked should return selected option elements |
3780 | + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked |
3781 | + // IE8 throws error here and will not see later tests |
3782 | + if ( !el.querySelectorAll(":checked").length ) { |
3783 | + rbuggyQSA.push(":checked"); |
3784 | + } |
3785 | + |
3786 | + // Support: Safari 8+, iOS 8+ |
3787 | + // https://bugs.webkit.org/show_bug.cgi?id=136851 |
3788 | + // In-page `selector#id sibling-combinator selector` fails |
3789 | + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { |
3790 | + rbuggyQSA.push(".#.+[+~]"); |
3791 | + } |
3792 | + }); |
3793 | + |
3794 | + assert(function( el ) { |
3795 | + el.innerHTML = "<a href='' disabled='disabled'></a>" + |
3796 | + "<select disabled='disabled'><option/></select>"; |
3797 | + |
3798 | + // Support: Windows 8 Native Apps |
3799 | + // The type and name attributes are restricted during .innerHTML assignment |
3800 | + var input = document.createElement("input"); |
3801 | + input.setAttribute( "type", "hidden" ); |
3802 | + el.appendChild( input ).setAttribute( "name", "D" ); |
3803 | + |
3804 | + // Support: IE8 |
3805 | + // Enforce case-sensitivity of name attribute |
3806 | + if ( el.querySelectorAll("[name=d]").length ) { |
3807 | + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); |
3808 | + } |
3809 | + |
3810 | + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) |
3811 | + // IE8 throws error here and will not see later tests |
3812 | + if ( el.querySelectorAll(":enabled").length !== 2 ) { |
3813 | + rbuggyQSA.push( ":enabled", ":disabled" ); |
3814 | + } |
3815 | + |
3816 | + // Support: IE9-11+ |
3817 | + // IE's :disabled selector does not pick up the children of disabled fieldsets |
3818 | + docElem.appendChild( el ).disabled = true; |
3819 | + if ( el.querySelectorAll(":disabled").length !== 2 ) { |
3820 | + rbuggyQSA.push( ":enabled", ":disabled" ); |
3821 | + } |
3822 | + |
3823 | + // Opera 10-11 does not throw on post-comma invalid pseudos |
3824 | + el.querySelectorAll("*,:x"); |
3825 | + rbuggyQSA.push(",.*:"); |
3826 | + }); |
3827 | + } |
3828 | + |
3829 | + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || |
3830 | + docElem.webkitMatchesSelector || |
3831 | + docElem.mozMatchesSelector || |
3832 | + docElem.oMatchesSelector || |
3833 | + docElem.msMatchesSelector) )) ) { |
3834 | + |
3835 | + assert(function( el ) { |
3836 | + // Check to see if it's possible to do matchesSelector |
3837 | + // on a disconnected node (IE 9) |
3838 | + support.disconnectedMatch = matches.call( el, "*" ); |
3839 | + |
3840 | + // This should fail with an exception |
3841 | + // Gecko does not error, returns false instead |
3842 | + matches.call( el, "[s!='']:x" ); |
3843 | + rbuggyMatches.push( "!=", pseudos ); |
3844 | + }); |
3845 | + } |
3846 | + |
3847 | + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); |
3848 | + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); |
3849 | + |
3850 | + /* Contains |
3851 | + ---------------------------------------------------------------------- */ |
3852 | + hasCompare = rnative.test( docElem.compareDocumentPosition ); |
3853 | + |
3854 | + // Element contains another |
3855 | + // Purposefully self-exclusive |
3856 | + // As in, an element does not contain itself |
3857 | + contains = hasCompare || rnative.test( docElem.contains ) ? |
3858 | + function( a, b ) { |
3859 | + var adown = a.nodeType === 9 ? a.documentElement : a, |
3860 | + bup = b && b.parentNode; |
3861 | + return a === bup || !!( bup && bup.nodeType === 1 && ( |
3862 | + adown.contains ? |
3863 | + adown.contains( bup ) : |
3864 | + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 |
3865 | + )); |
3866 | + } : |
3867 | + function( a, b ) { |
3868 | + if ( b ) { |
3869 | + while ( (b = b.parentNode) ) { |
3870 | + if ( b === a ) { |
3871 | + return true; |
3872 | + } |
3873 | + } |
3874 | + } |
3875 | + return false; |
3876 | + }; |
3877 | + |
3878 | + /* Sorting |
3879 | + ---------------------------------------------------------------------- */ |
3880 | + |
3881 | + // Document order sorting |
3882 | + sortOrder = hasCompare ? |
3883 | + function( a, b ) { |
3884 | + |
3885 | + // Flag for duplicate removal |
3886 | + if ( a === b ) { |
3887 | + hasDuplicate = true; |
3888 | + return 0; |
3889 | + } |
3890 | + |
3891 | + // Sort on method existence if only one input has compareDocumentPosition |
3892 | + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; |
3893 | + if ( compare ) { |
3894 | + return compare; |
3895 | + } |
3896 | + |
3897 | + // Calculate position if both inputs belong to the same document |
3898 | + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? |
3899 | + a.compareDocumentPosition( b ) : |
3900 | + |
3901 | + // Otherwise we know they are disconnected |
3902 | + 1; |
3903 | + |
3904 | + // Disconnected nodes |
3905 | + if ( compare & 1 || |
3906 | + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { |
3907 | + |
3908 | + // Choose the first element that is related to our preferred document |
3909 | + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { |
3910 | + return -1; |
3911 | + } |
3912 | + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { |
3913 | + return 1; |
3914 | + } |
3915 | + |
3916 | + // Maintain original order |
3917 | + return sortInput ? |
3918 | + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : |
3919 | + 0; |
3920 | + } |
3921 | + |
3922 | + return compare & 4 ? -1 : 1; |
3923 | + } : |
3924 | + function( a, b ) { |
3925 | + // Exit early if the nodes are identical |
3926 | + if ( a === b ) { |
3927 | + hasDuplicate = true; |
3928 | + return 0; |
3929 | + } |
3930 | + |
3931 | + var cur, |
3932 | + i = 0, |
3933 | + aup = a.parentNode, |
3934 | + bup = b.parentNode, |
3935 | + ap = [ a ], |
3936 | + bp = [ b ]; |
3937 | + |
3938 | + // Parentless nodes are either documents or disconnected |
3939 | + if ( !aup || !bup ) { |
3940 | + return a === document ? -1 : |
3941 | + b === document ? 1 : |
3942 | + aup ? -1 : |
3943 | + bup ? 1 : |
3944 | + sortInput ? |
3945 | + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : |
3946 | + 0; |
3947 | + |
3948 | + // If the nodes are siblings, we can do a quick check |
3949 | + } else if ( aup === bup ) { |
3950 | + return siblingCheck( a, b ); |
3951 | + } |
3952 | + |
3953 | + // Otherwise we need full lists of their ancestors for comparison |
3954 | + cur = a; |
3955 | + while ( (cur = cur.parentNode) ) { |
3956 | + ap.unshift( cur ); |
3957 | + } |
3958 | + cur = b; |
3959 | + while ( (cur = cur.parentNode) ) { |
3960 | + bp.unshift( cur ); |
3961 | + } |
3962 | + |
3963 | + // Walk down the tree looking for a discrepancy |
3964 | + while ( ap[i] === bp[i] ) { |
3965 | + i++; |
3966 | + } |
3967 | + |
3968 | + return i ? |
3969 | + // Do a sibling check if the nodes have a common ancestor |
3970 | + siblingCheck( ap[i], bp[i] ) : |
3971 | + |
3972 | + // Otherwise nodes in our document sort first |
3973 | + ap[i] === preferredDoc ? -1 : |
3974 | + bp[i] === preferredDoc ? 1 : |
3975 | + 0; |
3976 | + }; |
3977 | + |
3978 | + return document; |
3979 | +}; |
3980 | + |
3981 | +Sizzle.matches = function( expr, elements ) { |
3982 | + return Sizzle( expr, null, null, elements ); |
3983 | +}; |
3984 | + |
3985 | +Sizzle.matchesSelector = function( elem, expr ) { |
3986 | + // Set document vars if needed |
3987 | + if ( ( elem.ownerDocument || elem ) !== document ) { |
3988 | + setDocument( elem ); |
3989 | + } |
3990 | + |
3991 | + if ( support.matchesSelector && documentIsHTML && |
3992 | + !nonnativeSelectorCache[ expr + " " ] && |
3993 | + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && |
3994 | + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { |
3995 | + |
3996 | + try { |
3997 | + var ret = matches.call( elem, expr ); |
3998 | + |
3999 | + // IE 9's matchesSelector returns false on disconnected nodes |
4000 | + if ( ret || support.disconnectedMatch || |
4001 | + // As well, disconnected nodes are said to be in a document |
4002 | + // fragment in IE 9 |
4003 | + elem.document && elem.document.nodeType !== 11 ) { |
4004 | + return ret; |
4005 | + } |
4006 | + } catch (e) { |
4007 | + nonnativeSelectorCache( expr, true ); |
4008 | + } |
4009 | + } |
4010 | + |
4011 | + return Sizzle( expr, document, null, [ elem ] ).length > 0; |
4012 | +}; |
4013 | + |
4014 | +Sizzle.contains = function( context, elem ) { |
4015 | + // Set document vars if needed |
4016 | + if ( ( context.ownerDocument || context ) !== document ) { |
4017 | + setDocument( context ); |
4018 | + } |
4019 | + return contains( context, elem ); |
4020 | +}; |
4021 | + |
4022 | +Sizzle.attr = function( elem, name ) { |
4023 | + // Set document vars if needed |
4024 | + if ( ( elem.ownerDocument || elem ) !== document ) { |
4025 | + setDocument( elem ); |
4026 | + } |
4027 | + |
4028 | + var fn = Expr.attrHandle[ name.toLowerCase() ], |
4029 | + // Don't get fooled by Object.prototype properties (jQuery #13807) |
4030 | + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? |
4031 | + fn( elem, name, !documentIsHTML ) : |
4032 | + undefined; |
4033 | + |
4034 | + return val !== undefined ? |
4035 | + val : |
4036 | + support.attributes || !documentIsHTML ? |
4037 | + elem.getAttribute( name ) : |
4038 | + (val = elem.getAttributeNode(name)) && val.specified ? |
4039 | + val.value : |
4040 | + null; |
4041 | +}; |
4042 | + |
4043 | +Sizzle.escape = function( sel ) { |
4044 | + return (sel + "").replace( rcssescape, fcssescape ); |
4045 | +}; |
4046 | + |
4047 | +Sizzle.error = function( msg ) { |
4048 | + throw new Error( "Syntax error, unrecognized expression: " + msg ); |
4049 | +}; |
4050 | + |
4051 | +/** |
4052 | + * Document sorting and removing duplicates |
4053 | + * @param {ArrayLike} results |
4054 | + */ |
4055 | +Sizzle.uniqueSort = function( results ) { |
4056 | + var elem, |
4057 | + duplicates = [], |
4058 | + j = 0, |
4059 | + i = 0; |
4060 | + |
4061 | + // Unless we *know* we can detect duplicates, assume their presence |
4062 | + hasDuplicate = !support.detectDuplicates; |
4063 | + sortInput = !support.sortStable && results.slice( 0 ); |
4064 | + results.sort( sortOrder ); |
4065 | + |
4066 | + if ( hasDuplicate ) { |
4067 | + while ( (elem = results[i++]) ) { |
4068 | + if ( elem === results[ i ] ) { |
4069 | + j = duplicates.push( i ); |
4070 | + } |
4071 | + } |
4072 | + while ( j-- ) { |
4073 | + results.splice( duplicates[ j ], 1 ); |
4074 | + } |
4075 | + } |
4076 | + |
4077 | + // Clear input after sorting to release objects |
4078 | + // See https://github.com/jquery/sizzle/pull/225 |
4079 | + sortInput = null; |
4080 | + |
4081 | + return results; |
4082 | +}; |
4083 | + |
4084 | +/** |
4085 | + * Utility function for retrieving the text value of an array of DOM nodes |
4086 | + * @param {Array|Element} elem |
4087 | + */ |
4088 | +getText = Sizzle.getText = function( elem ) { |
4089 | + var node, |
4090 | + ret = "", |
4091 | + i = 0, |
4092 | + nodeType = elem.nodeType; |
4093 | + |
4094 | + if ( !nodeType ) { |
4095 | + // If no nodeType, this is expected to be an array |
4096 | + while ( (node = elem[i++]) ) { |
4097 | + // Do not traverse comment nodes |
4098 | + ret += getText( node ); |
4099 | + } |
4100 | + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { |
4101 | + // Use textContent for elements |
4102 | + // innerText usage removed for consistency of new lines (jQuery #11153) |
4103 | + if ( typeof elem.textContent === "string" ) { |
4104 | + return elem.textContent; |
4105 | + } else { |
4106 | + // Traverse its children |
4107 | + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { |
4108 | + ret += getText( elem ); |
4109 | + } |
4110 | + } |
4111 | + } else if ( nodeType === 3 || nodeType === 4 ) { |
4112 | + return elem.nodeValue; |
4113 | + } |
4114 | + // Do not include comment or processing instruction nodes |
4115 | + |
4116 | + return ret; |
4117 | +}; |
4118 | + |
4119 | +Expr = Sizzle.selectors = { |
4120 | + |
4121 | + // Can be adjusted by the user |
4122 | + cacheLength: 50, |
4123 | + |
4124 | + createPseudo: markFunction, |
4125 | + |
4126 | + match: matchExpr, |
4127 | + |
4128 | + attrHandle: {}, |
4129 | + |
4130 | + find: {}, |
4131 | + |
4132 | + relative: { |
4133 | + ">": { dir: "parentNode", first: true }, |
4134 | + " ": { dir: "parentNode" }, |
4135 | + "+": { dir: "previousSibling", first: true }, |
4136 | + "~": { dir: "previousSibling" } |
4137 | + }, |
4138 | + |
4139 | + preFilter: { |
4140 | + "ATTR": function( match ) { |
4141 | + match[1] = match[1].replace( runescape, funescape ); |
4142 | + |
4143 | + // Move the given value to match[3] whether quoted or unquoted |
4144 | + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); |
4145 | + |
4146 | + if ( match[2] === "~=" ) { |
4147 | + match[3] = " " + match[3] + " "; |
4148 | + } |
4149 | + |
4150 | + return match.slice( 0, 4 ); |
4151 | + }, |
4152 | + |
4153 | + "CHILD": function( match ) { |
4154 | + /* matches from matchExpr["CHILD"] |
4155 | + 1 type (only|nth|...) |
4156 | + 2 what (child|of-type) |
4157 | + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) |
4158 | + 4 xn-component of xn+y argument ([+-]?\d*n|) |
4159 | + 5 sign of xn-component |
4160 | + 6 x of xn-component |
4161 | + 7 sign of y-component |
4162 | + 8 y of y-component |
4163 | + */ |
4164 | + match[1] = match[1].toLowerCase(); |
4165 | + |
4166 | + if ( match[1].slice( 0, 3 ) === "nth" ) { |
4167 | + // nth-* requires argument |
4168 | + if ( !match[3] ) { |
4169 | + Sizzle.error( match[0] ); |
4170 | + } |
4171 | + |
4172 | + // numeric x and y parameters for Expr.filter.CHILD |
4173 | + // remember that false/true cast respectively to 0/1 |
4174 | + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); |
4175 | + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); |
4176 | + |
4177 | + // other types prohibit arguments |
4178 | + } else if ( match[3] ) { |
4179 | + Sizzle.error( match[0] ); |
4180 | + } |
4181 | + |
4182 | + return match; |
4183 | + }, |
4184 | + |
4185 | + "PSEUDO": function( match ) { |
4186 | + var excess, |
4187 | + unquoted = !match[6] && match[2]; |
4188 | + |
4189 | + if ( matchExpr["CHILD"].test( match[0] ) ) { |
4190 | + return null; |
4191 | + } |
4192 | + |
4193 | + // Accept quoted arguments as-is |
4194 | + if ( match[3] ) { |
4195 | + match[2] = match[4] || match[5] || ""; |
4196 | + |
4197 | + // Strip excess characters from unquoted arguments |
4198 | + } else if ( unquoted && rpseudo.test( unquoted ) && |
4199 | + // Get excess from tokenize (recursively) |
4200 | + (excess = tokenize( unquoted, true )) && |
4201 | + // advance to the next closing parenthesis |
4202 | + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { |
4203 | + |
4204 | + // excess is a negative index |
4205 | + match[0] = match[0].slice( 0, excess ); |
4206 | + match[2] = unquoted.slice( 0, excess ); |
4207 | + } |
4208 | + |
4209 | + // Return only captures needed by the pseudo filter method (type and argument) |
4210 | + return match.slice( 0, 3 ); |
4211 | + } |
4212 | + }, |
4213 | + |
4214 | + filter: { |
4215 | + |
4216 | + "TAG": function( nodeNameSelector ) { |
4217 | + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); |
4218 | + return nodeNameSelector === "*" ? |
4219 | + function() { return true; } : |
4220 | + function( elem ) { |
4221 | + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; |
4222 | + }; |
4223 | + }, |
4224 | + |
4225 | + "CLASS": function( className ) { |
4226 | + var pattern = classCache[ className + " " ]; |
4227 | + |
4228 | + return pattern || |
4229 | + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && |
4230 | + classCache( className, function( elem ) { |
4231 | + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); |
4232 | + }); |
4233 | + }, |
4234 | + |
4235 | + "ATTR": function( name, operator, check ) { |
4236 | + return function( elem ) { |
4237 | + var result = Sizzle.attr( elem, name ); |
4238 | + |
4239 | + if ( result == null ) { |
4240 | + return operator === "!="; |
4241 | + } |
4242 | + if ( !operator ) { |
4243 | + return true; |
4244 | + } |
4245 | + |
4246 | + result += ""; |
4247 | + |
4248 | + return operator === "=" ? result === check : |
4249 | + operator === "!=" ? result !== check : |
4250 | + operator === "^=" ? check && result.indexOf( check ) === 0 : |
4251 | + operator === "*=" ? check && result.indexOf( check ) > -1 : |
4252 | + operator === "$=" ? check && result.slice( -check.length ) === check : |
4253 | + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : |
4254 | + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : |
4255 | + false; |
4256 | + }; |
4257 | + }, |
4258 | + |
4259 | + "CHILD": function( type, what, argument, first, last ) { |
4260 | + var simple = type.slice( 0, 3 ) !== "nth", |
4261 | + forward = type.slice( -4 ) !== "last", |
4262 | + ofType = what === "of-type"; |
4263 | + |
4264 | + return first === 1 && last === 0 ? |
4265 | + |
4266 | + // Shortcut for :nth-*(n) |
4267 | + function( elem ) { |
4268 | + return !!elem.parentNode; |
4269 | + } : |
4270 | + |
4271 | + function( elem, context, xml ) { |
4272 | + var cache, uniqueCache, outerCache, node, nodeIndex, start, |
4273 | + dir = simple !== forward ? "nextSibling" : "previousSibling", |
4274 | + parent = elem.parentNode, |
4275 | + name = ofType && elem.nodeName.toLowerCase(), |
4276 | + useCache = !xml && !ofType, |
4277 | + diff = false; |
4278 | + |
4279 | + if ( parent ) { |
4280 | + |
4281 | + // :(first|last|only)-(child|of-type) |
4282 | + if ( simple ) { |
4283 | + while ( dir ) { |
4284 | + node = elem; |
4285 | + while ( (node = node[ dir ]) ) { |
4286 | + if ( ofType ? |
4287 | + node.nodeName.toLowerCase() === name : |
4288 | + node.nodeType === 1 ) { |
4289 | + |
4290 | + return false; |
4291 | + } |
4292 | + } |
4293 | + // Reverse direction for :only-* (if we haven't yet done so) |
4294 | + start = dir = type === "only" && !start && "nextSibling"; |
4295 | + } |
4296 | + return true; |
4297 | + } |
4298 | + |
4299 | + start = [ forward ? parent.firstChild : parent.lastChild ]; |
4300 | + |
4301 | + // non-xml :nth-child(...) stores cache data on `parent` |
4302 | + if ( forward && useCache ) { |
4303 | + |
4304 | + // Seek `elem` from a previously-cached index |
4305 | + |
4306 | + // ...in a gzip-friendly way |
4307 | + node = parent; |
4308 | + outerCache = node[ expando ] || (node[ expando ] = {}); |
4309 | + |
4310 | + // Support: IE <9 only |
4311 | + // Defend against cloned attroperties (jQuery gh-1709) |
4312 | + uniqueCache = outerCache[ node.uniqueID ] || |
4313 | + (outerCache[ node.uniqueID ] = {}); |
4314 | + |
4315 | + cache = uniqueCache[ type ] || []; |
4316 | + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; |
4317 | + diff = nodeIndex && cache[ 2 ]; |
4318 | + node = nodeIndex && parent.childNodes[ nodeIndex ]; |
4319 | + |
4320 | + while ( (node = ++nodeIndex && node && node[ dir ] || |
4321 | + |
4322 | + // Fallback to seeking `elem` from the start |
4323 | + (diff = nodeIndex = 0) || start.pop()) ) { |
4324 | + |
4325 | + // When found, cache indexes on `parent` and break |
4326 | + if ( node.nodeType === 1 && ++diff && node === elem ) { |
4327 | + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; |
4328 | + break; |
4329 | + } |
4330 | + } |
4331 | + |
4332 | + } else { |
4333 | + // Use previously-cached element index if available |
4334 | + if ( useCache ) { |
4335 | + // ...in a gzip-friendly way |
4336 | + node = elem; |
4337 | + outerCache = node[ expando ] || (node[ expando ] = {}); |
4338 | + |
4339 | + // Support: IE <9 only |
4340 | + // Defend against cloned attroperties (jQuery gh-1709) |
4341 | + uniqueCache = outerCache[ node.uniqueID ] || |
4342 | + (outerCache[ node.uniqueID ] = {}); |
4343 | + |
4344 | + cache = uniqueCache[ type ] || []; |
4345 | + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; |
4346 | + diff = nodeIndex; |
4347 | + } |
4348 | + |
4349 | + // xml :nth-child(...) |
4350 | + // or :nth-last-child(...) or :nth(-last)?-of-type(...) |
4351 | + if ( diff === false ) { |
4352 | + // Use the same loop as above to seek `elem` from the start |
4353 | + while ( (node = ++nodeIndex && node && node[ dir ] || |
4354 | + (diff = nodeIndex = 0) || start.pop()) ) { |
4355 | + |
4356 | + if ( ( ofType ? |
4357 | + node.nodeName.toLowerCase() === name : |
4358 | + node.nodeType === 1 ) && |
4359 | + ++diff ) { |
4360 | + |
4361 | + // Cache the index of each encountered element |
4362 | + if ( useCache ) { |
4363 | + outerCache = node[ expando ] || (node[ expando ] = {}); |
4364 | + |
4365 | + // Support: IE <9 only |
4366 | + // Defend against cloned attroperties (jQuery gh-1709) |
4367 | + uniqueCache = outerCache[ node.uniqueID ] || |
4368 | + (outerCache[ node.uniqueID ] = {}); |
4369 | + |
4370 | + uniqueCache[ type ] = [ dirruns, diff ]; |
4371 | + } |
4372 | + |
4373 | + if ( node === elem ) { |
4374 | + break; |
4375 | + } |
4376 | + } |
4377 | + } |
4378 | + } |
4379 | + } |
4380 | + |
4381 | + // Incorporate the offset, then check against cycle size |
4382 | + diff -= last; |
4383 | + return diff === first || ( diff % first === 0 && diff / first >= 0 ); |
4384 | + } |
4385 | + }; |
4386 | + }, |
4387 | + |
4388 | + "PSEUDO": function( pseudo, argument ) { |
4389 | + // pseudo-class names are case-insensitive |
4390 | + // http://www.w3.org/TR/selectors/#pseudo-classes |
4391 | + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters |
4392 | + // Remember that setFilters inherits from pseudos |
4393 | + var args, |
4394 | + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || |
4395 | + Sizzle.error( "unsupported pseudo: " + pseudo ); |
4396 | + |
4397 | + // The user may use createPseudo to indicate that |
4398 | + // arguments are needed to create the filter function |
4399 | + // just as Sizzle does |
4400 | + if ( fn[ expando ] ) { |
4401 | + return fn( argument ); |
4402 | + } |
4403 | + |
4404 | + // But maintain support for old signatures |
4405 | + if ( fn.length > 1 ) { |
4406 | + args = [ pseudo, pseudo, "", argument ]; |
4407 | + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? |
4408 | + markFunction(function( seed, matches ) { |
4409 | + var idx, |
4410 | + matched = fn( seed, argument ), |
4411 | + i = matched.length; |
4412 | + while ( i-- ) { |
4413 | + idx = indexOf( seed, matched[i] ); |
4414 | + seed[ idx ] = !( matches[ idx ] = matched[i] ); |
4415 | + } |
4416 | + }) : |
4417 | + function( elem ) { |
4418 | + return fn( elem, 0, args ); |
4419 | + }; |
4420 | + } |
4421 | + |
4422 | + return fn; |
4423 | + } |
4424 | + }, |
4425 | + |
4426 | + pseudos: { |
4427 | + // Potentially complex pseudos |
4428 | + "not": markFunction(function( selector ) { |
4429 | + // Trim the selector passed to compile |
4430 | + // to avoid treating leading and trailing |
4431 | + // spaces as combinators |
4432 | + var input = [], |
4433 | + results = [], |
4434 | + matcher = compile( selector.replace( rtrim, "$1" ) ); |
4435 | + |
4436 | + return matcher[ expando ] ? |
4437 | + markFunction(function( seed, matches, context, xml ) { |
4438 | + var elem, |
4439 | + unmatched = matcher( seed, null, xml, [] ), |
4440 | + i = seed.length; |
4441 | + |
4442 | + // Match elements unmatched by `matcher` |
4443 | + while ( i-- ) { |
4444 | + if ( (elem = unmatched[i]) ) { |
4445 | + seed[i] = !(matches[i] = elem); |
4446 | + } |
4447 | + } |
4448 | + }) : |
4449 | + function( elem, context, xml ) { |
4450 | + input[0] = elem; |
4451 | + matcher( input, null, xml, results ); |
4452 | + // Don't keep the element (issue #299) |
4453 | + input[0] = null; |
4454 | + return !results.pop(); |
4455 | + }; |
4456 | + }), |
4457 | + |
4458 | + "has": markFunction(function( selector ) { |
4459 | + return function( elem ) { |
4460 | + return Sizzle( selector, elem ).length > 0; |
4461 | + }; |
4462 | + }), |
4463 | + |
4464 | + "contains": markFunction(function( text ) { |
4465 | + text = text.replace( runescape, funescape ); |
4466 | + return function( elem ) { |
4467 | + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; |
4468 | + }; |
4469 | + }), |
4470 | + |
4471 | + // "Whether an element is represented by a :lang() selector |
4472 | + // is based solely on the element's language value |
4473 | + // being equal to the identifier C, |
4474 | + // or beginning with the identifier C immediately followed by "-". |
4475 | + // The matching of C against the element's language value is performed case-insensitively. |
4476 | + // The identifier C does not have to be a valid language name." |
4477 | + // http://www.w3.org/TR/selectors/#lang-pseudo |
4478 | + "lang": markFunction( function( lang ) { |
4479 | + // lang value must be a valid identifier |
4480 | + if ( !ridentifier.test(lang || "") ) { |
4481 | + Sizzle.error( "unsupported lang: " + lang ); |
4482 | + } |
4483 | + lang = lang.replace( runescape, funescape ).toLowerCase(); |
4484 | + return function( elem ) { |
4485 | + var elemLang; |
4486 | + do { |
4487 | + if ( (elemLang = documentIsHTML ? |
4488 | + elem.lang : |
4489 | + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { |
4490 | + |
4491 | + elemLang = elemLang.toLowerCase(); |
4492 | + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; |
4493 | + } |
4494 | + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); |
4495 | + return false; |
4496 | + }; |
4497 | + }), |
4498 | + |
4499 | + // Miscellaneous |
4500 | + "target": function( elem ) { |
4501 | + var hash = window.location && window.location.hash; |
4502 | + return hash && hash.slice( 1 ) === elem.id; |
4503 | + }, |
4504 | + |
4505 | + "root": function( elem ) { |
4506 | + return elem === docElem; |
4507 | + }, |
4508 | + |
4509 | + "focus": function( elem ) { |
4510 | + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); |
4511 | + }, |
4512 | + |
4513 | + // Boolean properties |
4514 | + "enabled": createDisabledPseudo( false ), |
4515 | + "disabled": createDisabledPseudo( true ), |
4516 | + |
4517 | + "checked": function( elem ) { |
4518 | + // In CSS3, :checked should return both checked and selected elements |
4519 | + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked |
4520 | + var nodeName = elem.nodeName.toLowerCase(); |
4521 | + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); |
4522 | + }, |
4523 | + |
4524 | + "selected": function( elem ) { |
4525 | + // Accessing this property makes selected-by-default |
4526 | + // options in Safari work properly |
4527 | + if ( elem.parentNode ) { |
4528 | + elem.parentNode.selectedIndex; |
4529 | + } |
4530 | + |
4531 | + return elem.selected === true; |
4532 | + }, |
4533 | + |
4534 | + // Contents |
4535 | + "empty": function( elem ) { |
4536 | + // http://www.w3.org/TR/selectors/#empty-pseudo |
4537 | + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), |
4538 | + // but not by others (comment: 8; processing instruction: 7; etc.) |
4539 | + // nodeType < 6 works because attributes (2) do not appear as children |
4540 | + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { |
4541 | + if ( elem.nodeType < 6 ) { |
4542 | + return false; |
4543 | + } |
4544 | + } |
4545 | + return true; |
4546 | + }, |
4547 | + |
4548 | + "parent": function( elem ) { |
4549 | + return !Expr.pseudos["empty"]( elem ); |
4550 | + }, |
4551 | + |
4552 | + // Element/input types |
4553 | + "header": function( elem ) { |
4554 | + return rheader.test( elem.nodeName ); |
4555 | + }, |
4556 | + |
4557 | + "input": function( elem ) { |
4558 | + return rinputs.test( elem.nodeName ); |
4559 | + }, |
4560 | + |
4561 | + "button": function( elem ) { |
4562 | + var name = elem.nodeName.toLowerCase(); |
4563 | + return name === "input" && elem.type === "button" || name === "button"; |
4564 | + }, |
4565 | + |
4566 | + "text": function( elem ) { |
4567 | + var attr; |
4568 | + return elem.nodeName.toLowerCase() === "input" && |
4569 | + elem.type === "text" && |
4570 | + |
4571 | + // Support: IE<8 |
4572 | + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" |
4573 | + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); |
4574 | + }, |
4575 | + |
4576 | + // Position-in-collection |
4577 | + "first": createPositionalPseudo(function() { |
4578 | + return [ 0 ]; |
4579 | + }), |
4580 | + |
4581 | + "last": createPositionalPseudo(function( matchIndexes, length ) { |
4582 | + return [ length - 1 ]; |
4583 | + }), |
4584 | + |
4585 | + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { |
4586 | + return [ argument < 0 ? argument + length : argument ]; |
4587 | + }), |
4588 | + |
4589 | + "even": createPositionalPseudo(function( matchIndexes, length ) { |
4590 | + var i = 0; |
4591 | + for ( ; i < length; i += 2 ) { |
4592 | + matchIndexes.push( i ); |
4593 | + } |
4594 | + return matchIndexes; |
4595 | + }), |
4596 | + |
4597 | + "odd": createPositionalPseudo(function( matchIndexes, length ) { |
4598 | + var i = 1; |
4599 | + for ( ; i < length; i += 2 ) { |
4600 | + matchIndexes.push( i ); |
4601 | + } |
4602 | + return matchIndexes; |
4603 | + }), |
4604 | + |
4605 | + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { |
4606 | + var i = argument < 0 ? |
4607 | + argument + length : |
4608 | + argument > length ? |
4609 | + length : |
4610 | + argument; |
4611 | + for ( ; --i >= 0; ) { |
4612 | + matchIndexes.push( i ); |
4613 | + } |
4614 | + return matchIndexes; |
4615 | + }), |
4616 | + |
4617 | + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { |
4618 | + var i = argument < 0 ? argument + length : argument; |
4619 | + for ( ; ++i < length; ) { |
4620 | + matchIndexes.push( i ); |
4621 | + } |
4622 | + return matchIndexes; |
4623 | + }) |
4624 | + } |
4625 | +}; |
4626 | + |
4627 | +Expr.pseudos["nth"] = Expr.pseudos["eq"]; |
4628 | + |
4629 | +// Add button/input type pseudos |
4630 | +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { |
4631 | + Expr.pseudos[ i ] = createInputPseudo( i ); |
4632 | +} |
4633 | +for ( i in { submit: true, reset: true } ) { |
4634 | + Expr.pseudos[ i ] = createButtonPseudo( i ); |
4635 | +} |
4636 | + |
4637 | +// Easy API for creating new setFilters |
4638 | +function setFilters() {} |
4639 | +setFilters.prototype = Expr.filters = Expr.pseudos; |
4640 | +Expr.setFilters = new setFilters(); |
4641 | + |
4642 | +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { |
4643 | + var matched, match, tokens, type, |
4644 | + soFar, groups, preFilters, |
4645 | + cached = tokenCache[ selector + " " ]; |
4646 | + |
4647 | + if ( cached ) { |
4648 | + return parseOnly ? 0 : cached.slice( 0 ); |
4649 | + } |
4650 | + |
4651 | + soFar = selector; |
4652 | + groups = []; |
4653 | + preFilters = Expr.preFilter; |
4654 | + |
4655 | + while ( soFar ) { |
4656 | + |
4657 | + // Comma and first run |
4658 | + if ( !matched || (match = rcomma.exec( soFar )) ) { |
4659 | + if ( match ) { |
4660 | + // Don't consume trailing commas as valid |
4661 | + soFar = soFar.slice( match[0].length ) || soFar; |
4662 | + } |
4663 | + groups.push( (tokens = []) ); |
4664 | + } |
4665 | + |
4666 | + matched = false; |
4667 | + |
4668 | + // Combinators |
4669 | + if ( (match = rcombinators.exec( soFar )) ) { |
4670 | + matched = match.shift(); |
4671 | + tokens.push({ |
4672 | + value: matched, |
4673 | + // Cast descendant combinators to space |
4674 | + type: match[0].replace( rtrim, " " ) |
4675 | + }); |
4676 | + soFar = soFar.slice( matched.length ); |
4677 | + } |
4678 | + |
4679 | + // Filters |
4680 | + for ( type in Expr.filter ) { |
4681 | + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || |
4682 | + (match = preFilters[ type ]( match ))) ) { |
4683 | + matched = match.shift(); |
4684 | + tokens.push({ |
4685 | + value: matched, |
4686 | + type: type, |
4687 | + matches: match |
4688 | + }); |
4689 | + soFar = soFar.slice( matched.length ); |
4690 | + } |
4691 | + } |
4692 | + |
4693 | + if ( !matched ) { |
4694 | + break; |
4695 | + } |
4696 | + } |
4697 | + |
4698 | + // Return the length of the invalid excess |
4699 | + // if we're just parsing |
4700 | + // Otherwise, throw an error or return tokens |
4701 | + return parseOnly ? |
4702 | + soFar.length : |
4703 | + soFar ? |
4704 | + Sizzle.error( selector ) : |
4705 | + // Cache the tokens |
4706 | + tokenCache( selector, groups ).slice( 0 ); |
4707 | +}; |
4708 | + |
4709 | +function toSelector( tokens ) { |
4710 | + var i = 0, |
4711 | + len = tokens.length, |
4712 | + selector = ""; |
4713 | + for ( ; i < len; i++ ) { |
4714 | + selector += tokens[i].value; |
4715 | + } |
4716 | + return selector; |
4717 | +} |
4718 | + |
4719 | +function addCombinator( matcher, combinator, base ) { |
4720 | + var dir = combinator.dir, |
4721 | + skip = combinator.next, |
4722 | + key = skip || dir, |
4723 | + checkNonElements = base && key === "parentNode", |
4724 | + doneName = done++; |
4725 | + |
4726 | + return combinator.first ? |
4727 | + // Check against closest ancestor/preceding element |
4728 | + function( elem, context, xml ) { |
4729 | + while ( (elem = elem[ dir ]) ) { |
4730 | + if ( elem.nodeType === 1 || checkNonElements ) { |
4731 | + return matcher( elem, context, xml ); |
4732 | + } |
4733 | + } |
4734 | + return false; |
4735 | + } : |
4736 | + |
4737 | + // Check against all ancestor/preceding elements |
4738 | + function( elem, context, xml ) { |
4739 | + var oldCache, uniqueCache, outerCache, |
4740 | + newCache = [ dirruns, doneName ]; |
4741 | + |
4742 | + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching |
4743 | + if ( xml ) { |
4744 | + while ( (elem = elem[ dir ]) ) { |
4745 | + if ( elem.nodeType === 1 || checkNonElements ) { |
4746 | + if ( matcher( elem, context, xml ) ) { |
4747 | + return true; |
4748 | + } |
4749 | + } |
4750 | + } |
4751 | + } else { |
4752 | + while ( (elem = elem[ dir ]) ) { |
4753 | + if ( elem.nodeType === 1 || checkNonElements ) { |
4754 | + outerCache = elem[ expando ] || (elem[ expando ] = {}); |
4755 | + |
4756 | + // Support: IE <9 only |
4757 | + // Defend against cloned attroperties (jQuery gh-1709) |
4758 | + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); |
4759 | + |
4760 | + if ( skip && skip === elem.nodeName.toLowerCase() ) { |
4761 | + elem = elem[ dir ] || elem; |
4762 | + } else if ( (oldCache = uniqueCache[ key ]) && |
4763 | + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { |
4764 | + |
4765 | + // Assign to newCache so results back-propagate to previous elements |
4766 | + return (newCache[ 2 ] = oldCache[ 2 ]); |
4767 | + } else { |
4768 | + // Reuse newcache so results back-propagate to previous elements |
4769 | + uniqueCache[ key ] = newCache; |
4770 | + |
4771 | + // A match means we're done; a fail means we have to keep checking |
4772 | + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { |
4773 | + return true; |
4774 | + } |
4775 | + } |
4776 | + } |
4777 | + } |
4778 | + } |
4779 | + return false; |
4780 | + }; |
4781 | +} |
4782 | + |
4783 | +function elementMatcher( matchers ) { |
4784 | + return matchers.length > 1 ? |
4785 | + function( elem, context, xml ) { |
4786 | + var i = matchers.length; |
4787 | + while ( i-- ) { |
4788 | + if ( !matchers[i]( elem, context, xml ) ) { |
4789 | + return false; |
4790 | + } |
4791 | + } |
4792 | + return true; |
4793 | + } : |
4794 | + matchers[0]; |
4795 | +} |
4796 | + |
4797 | +function multipleContexts( selector, contexts, results ) { |
4798 | + var i = 0, |
4799 | + len = contexts.length; |
4800 | + for ( ; i < len; i++ ) { |
4801 | + Sizzle( selector, contexts[i], results ); |
4802 | + } |
4803 | + return results; |
4804 | +} |
4805 | + |
4806 | +function condense( unmatched, map, filter, context, xml ) { |
4807 | + var elem, |
4808 | + newUnmatched = [], |
4809 | + i = 0, |
4810 | + len = unmatched.length, |
4811 | + mapped = map != null; |
4812 | + |
4813 | + for ( ; i < len; i++ ) { |
4814 | + if ( (elem = unmatched[i]) ) { |
4815 | + if ( !filter || filter( elem, context, xml ) ) { |
4816 | + newUnmatched.push( elem ); |
4817 | + if ( mapped ) { |
4818 | + map.push( i ); |
4819 | + } |
4820 | + } |
4821 | + } |
4822 | + } |
4823 | + |
4824 | + return newUnmatched; |
4825 | +} |
4826 | + |
4827 | +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { |
4828 | + if ( postFilter && !postFilter[ expando ] ) { |
4829 | + postFilter = setMatcher( postFilter ); |
4830 | + } |
4831 | + if ( postFinder && !postFinder[ expando ] ) { |
4832 | + postFinder = setMatcher( postFinder, postSelector ); |
4833 | + } |
4834 | + return markFunction(function( seed, results, context, xml ) { |
4835 | + var temp, i, elem, |
4836 | + preMap = [], |
4837 | + postMap = [], |
4838 | + preexisting = results.length, |
4839 | + |
4840 | + // Get initial elements from seed or context |
4841 | + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), |
4842 | + |
4843 | + // Prefilter to get matcher input, preserving a map for seed-results synchronization |
4844 | + matcherIn = preFilter && ( seed || !selector ) ? |
4845 | + condense( elems, preMap, preFilter, context, xml ) : |
4846 | + elems, |
4847 | + |
4848 | + matcherOut = matcher ? |
4849 | + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, |
4850 | + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? |
4851 | + |
4852 | + // ...intermediate processing is necessary |
4853 | + [] : |
4854 | + |
4855 | + // ...otherwise use results directly |
4856 | + results : |
4857 | + matcherIn; |
4858 | + |
4859 | + // Find primary matches |
4860 | + if ( matcher ) { |
4861 | + matcher( matcherIn, matcherOut, context, xml ); |
4862 | + } |
4863 | + |
4864 | + // Apply postFilter |
4865 | + if ( postFilter ) { |
4866 | + temp = condense( matcherOut, postMap ); |
4867 | + postFilter( temp, [], context, xml ); |
4868 | + |
4869 | + // Un-match failing elements by moving them back to matcherIn |
4870 | + i = temp.length; |
4871 | + while ( i-- ) { |
4872 | + if ( (elem = temp[i]) ) { |
4873 | + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); |
4874 | + } |
4875 | + } |
4876 | + } |
4877 | + |
4878 | + if ( seed ) { |
4879 | + if ( postFinder || preFilter ) { |
4880 | + if ( postFinder ) { |
4881 | + // Get the final matcherOut by condensing this intermediate into postFinder contexts |
4882 | + temp = []; |
4883 | + i = matcherOut.length; |
4884 | + while ( i-- ) { |
4885 | + if ( (elem = matcherOut[i]) ) { |
4886 | + // Restore matcherIn since elem is not yet a final match |
4887 | + temp.push( (matcherIn[i] = elem) ); |
4888 | + } |
4889 | + } |
4890 | + postFinder( null, (matcherOut = []), temp, xml ); |
4891 | + } |
4892 | + |
4893 | + // Move matched elements from seed to results to keep them synchronized |
4894 | + i = matcherOut.length; |
4895 | + while ( i-- ) { |
4896 | + if ( (elem = matcherOut[i]) && |
4897 | + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { |
4898 | + |
4899 | + seed[temp] = !(results[temp] = elem); |
4900 | + } |
4901 | + } |
4902 | + } |
4903 | + |
4904 | + // Add elements to results, through postFinder if defined |
4905 | + } else { |
4906 | + matcherOut = condense( |
4907 | + matcherOut === results ? |
4908 | + matcherOut.splice( preexisting, matcherOut.length ) : |
4909 | + matcherOut |
4910 | + ); |
4911 | + if ( postFinder ) { |
4912 | + postFinder( null, results, matcherOut, xml ); |
4913 | + } else { |
4914 | + push.apply( results, matcherOut ); |
4915 | + } |
4916 | + } |
4917 | + }); |
4918 | +} |
4919 | + |
4920 | +function matcherFromTokens( tokens ) { |
4921 | + var checkContext, matcher, j, |
4922 | + len = tokens.length, |
4923 | + leadingRelative = Expr.relative[ tokens[0].type ], |
4924 | + implicitRelative = leadingRelative || Expr.relative[" "], |
4925 | + i = leadingRelative ? 1 : 0, |
4926 | + |
4927 | + // The foundational matcher ensures that elements are reachable from top-level context(s) |
4928 | + matchContext = addCombinator( function( elem ) { |
4929 | + return elem === checkContext; |
4930 | + }, implicitRelative, true ), |
4931 | + matchAnyContext = addCombinator( function( elem ) { |
4932 | + return indexOf( checkContext, elem ) > -1; |
4933 | + }, implicitRelative, true ), |
4934 | + matchers = [ function( elem, context, xml ) { |
4935 | + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( |
4936 | + (checkContext = context).nodeType ? |
4937 | + matchContext( elem, context, xml ) : |
4938 | + matchAnyContext( elem, context, xml ) ); |
4939 | + // Avoid hanging onto element (issue #299) |
4940 | + checkContext = null; |
4941 | + return ret; |
4942 | + } ]; |
4943 | + |
4944 | + for ( ; i < len; i++ ) { |
4945 | + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { |
4946 | + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; |
4947 | + } else { |
4948 | + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); |
4949 | + |
4950 | + // Return special upon seeing a positional matcher |
4951 | + if ( matcher[ expando ] ) { |
4952 | + // Find the next relative operator (if any) for proper handling |
4953 | + j = ++i; |
4954 | + for ( ; j < len; j++ ) { |
4955 | + if ( Expr.relative[ tokens[j].type ] ) { |
4956 | + break; |
4957 | + } |
4958 | + } |
4959 | + return setMatcher( |
4960 | + i > 1 && elementMatcher( matchers ), |
4961 | + i > 1 && toSelector( |
4962 | + // If the preceding token was a descendant combinator, insert an implicit any-element `*` |
4963 | + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) |
4964 | + ).replace( rtrim, "$1" ), |
4965 | + matcher, |
4966 | + i < j && matcherFromTokens( tokens.slice( i, j ) ), |
4967 | + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), |
4968 | + j < len && toSelector( tokens ) |
4969 | + ); |
4970 | + } |
4971 | + matchers.push( matcher ); |
4972 | + } |
4973 | + } |
4974 | + |
4975 | + return elementMatcher( matchers ); |
4976 | +} |
4977 | + |
4978 | +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { |
4979 | + var bySet = setMatchers.length > 0, |
4980 | + byElement = elementMatchers.length > 0, |
4981 | + superMatcher = function( seed, context, xml, results, outermost ) { |
4982 | + var elem, j, matcher, |
4983 | + matchedCount = 0, |
4984 | + i = "0", |
4985 | + unmatched = seed && [], |
4986 | + setMatched = [], |
4987 | + contextBackup = outermostContext, |
4988 | + // We must always have either seed elements or outermost context |
4989 | + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), |
4990 | + // Use integer dirruns iff this is the outermost matcher |
4991 | + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), |
4992 | + len = elems.length; |
4993 | + |
4994 | + if ( outermost ) { |
4995 | + outermostContext = context === document || context || outermost; |
4996 | + } |
4997 | + |
4998 | + // Add elements passing elementMatchers directly to results |
4999 | + // Support: IE<9, Safari |
5000 | + // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id |
I came up with a bunch of questions on review, but re-reading the statement above answered all of them. Thanks for explaining the background and decisions taking while working on this!
Rebuilding the docs was the right choice, that way if ever someone patches the doc-src it will actually have an impact to the results - otherwise people might wonder when entertaining this.
So it is the right choice not only to silence lintian :-)
The doc build tries to access "http:// docs.python. org/objects. inv" - it gladly fails and goes on. Just saying this is a dynamic we might not want to have in the build, but not a blocker for now.
I also know that mdeslaur asked for the tests to work, and I found at least those to run properly at build:
Ran 231 tests in 3.925s
You could open a salsa MP as well (or chime in on 953567) to complete this. Just to help Debian as well as increasing the chance to later on be able to make this a sync again.
+1 overall, thanks!