From e4a8833d3dcff34955797a5540b45aaf59ec93da Mon Sep 17 00:00:00 2001 From: Valerio Mariani <valerio.mariani@desy.de> Date: Tue, 13 Aug 2019 11:55:38 +0200 Subject: [PATCH] Refactored and cleaned up code --- cfelpyutils/__init__.py | 33 +- cfelpyutils/crystfel_utils.py | 123 +- cfelpyutils/geometry_utils.py | 175 +- cfelpyutils/named_tuples.py | 41 + docs/.buildinfo | 4 + docs/_modules/cfelpyutils/crystfel_utils.html | 754 ++ docs/_modules/cfelpyutils/geometry_utils.html | 321 + docs/_modules/cfelpyutils/named_tuples.html | 145 + docs/_modules/index.html | 105 + .../cfelpyutils.crystfel_utils.rst.txt | 7 + .../cfelpyutils.geometry_utils.rst.txt | 7 + .../_sources/cfelpyutils.named_tuples.rst.txt | 7 + docs/_sources/cfelpyutils.rst.txt | 13 + docs/_sources/index.rst.txt | 53 + docs/_sources/modules.rst.txt | 7 + docs/_static/ajax-loader.gif | Bin 0 -> 673 bytes docs/_static/alabaster.css | 701 ++ docs/_static/basic.css | 676 + docs/_static/comment-bright.png | Bin 0 -> 756 bytes docs/_static/comment-close.png | Bin 0 -> 829 bytes docs/_static/comment.png | Bin 0 -> 641 bytes docs/_static/custom.css | 1 + docs/_static/doctools.js | 315 + docs/_static/documentation_options.js | 10 + docs/_static/down-pressed.png | Bin 0 -> 222 bytes docs/_static/down.png | Bin 0 -> 202 bytes docs/_static/file.png | Bin 0 -> 286 bytes docs/_static/jquery-3.2.1.js | 10253 ++++++++++++++++ docs/_static/jquery.js | 4 + docs/_static/language_data.js | 297 + docs/_static/minus.png | Bin 0 -> 90 bytes docs/_static/plus.png | Bin 0 -> 90 bytes docs/_static/pygments.css | 77 + docs/_static/searchtools.js | 481 + docs/_static/underscore-1.3.1.js | 999 ++ docs/_static/underscore.js | 31 + docs/_static/up-pressed.png | Bin 0 -> 214 bytes docs/_static/up.png | Bin 0 -> 203 bytes docs/_static/websupport.js | 808 ++ docs/cfelpyutils.crystfel_utils.html | 148 + docs/cfelpyutils.geometry_utils.html | 214 + docs/cfelpyutils.html | 121 + docs/cfelpyutils.named_tuples.html | 170 + docs/cfelpyutils.rst | 16 - docs/conf.py | 84 - docs/genindex.html | 196 + docs/index.html | 117 + docs/index.rst | 26 - docs/modules.html | 114 + docs/objects.inv | 8 + docs/py-modindex.html | 137 + docs/search.html | 120 + docs/searchindex.js | 1 + {docs => docs_src}/Makefile | 8 +- .../cfelpyutils.crystfel_utils.doctree | Bin 0 -> 11347 bytes docs_src/_build/doctrees/cfelpyutils.doctree | Bin 0 -> 3420 bytes .../cfelpyutils.geometry_utils.doctree | Bin 0 -> 30154 bytes .../doctrees/cfelpyutils.named_tuples.doctree | Bin 0 -> 14526 bytes docs_src/_build/doctrees/environment.pickle | Bin 0 -> 51599 bytes docs_src/_build/doctrees/index.doctree | Bin 0 -> 6796 bytes docs_src/_build/doctrees/modules.doctree | Bin 0 -> 2565 bytes docs_src/_build/html/.buildinfo | 4 + .../_modules/cfelpyutils/crystfel_utils.html | 754 ++ .../_modules/cfelpyutils/geometry_utils.html | 321 + .../_modules/cfelpyutils/named_tuples.html | 145 + docs_src/_build/html/_modules/index.html | 105 + .../cfelpyutils.crystfel_utils.rst.txt | 7 + .../cfelpyutils.geometry_utils.rst.txt | 7 + .../_sources/cfelpyutils.named_tuples.rst.txt | 7 + .../_build/html/_sources/cfelpyutils.rst.txt | 13 + docs_src/_build/html/_sources/index.rst.txt | 53 + docs_src/_build/html/_sources/modules.rst.txt | 7 + docs_src/_build/html/_static/ajax-loader.gif | Bin 0 -> 673 bytes docs_src/_build/html/_static/alabaster.css | 701 ++ docs_src/_build/html/_static/basic.css | 676 + .../_build/html/_static/comment-bright.png | Bin 0 -> 756 bytes .../_build/html/_static/comment-close.png | Bin 0 -> 829 bytes docs_src/_build/html/_static/comment.png | Bin 0 -> 641 bytes docs_src/_build/html/_static/custom.css | 1 + docs_src/_build/html/_static/doctools.js | 315 + .../html/_static/documentation_options.js | 10 + docs_src/_build/html/_static/down-pressed.png | Bin 0 -> 222 bytes docs_src/_build/html/_static/down.png | Bin 0 -> 202 bytes docs_src/_build/html/_static/file.png | Bin 0 -> 286 bytes docs_src/_build/html/_static/jquery-3.2.1.js | 10253 ++++++++++++++++ docs_src/_build/html/_static/jquery.js | 4 + docs_src/_build/html/_static/language_data.js | 297 + docs_src/_build/html/_static/minus.png | Bin 0 -> 90 bytes docs_src/_build/html/_static/plus.png | Bin 0 -> 90 bytes docs_src/_build/html/_static/pygments.css | 77 + docs_src/_build/html/_static/searchtools.js | 481 + .../_build/html/_static/underscore-1.3.1.js | 999 ++ docs_src/_build/html/_static/underscore.js | 31 + docs_src/_build/html/_static/up-pressed.png | Bin 0 -> 214 bytes docs_src/_build/html/_static/up.png | Bin 0 -> 203 bytes docs_src/_build/html/_static/websupport.js | 808 ++ .../html/cfelpyutils.crystfel_utils.html | 148 + .../html/cfelpyutils.geometry_utils.html | 214 + docs_src/_build/html/cfelpyutils.html | 121 + .../_build/html/cfelpyutils.named_tuples.html | 170 + docs_src/_build/html/genindex.html | 196 + docs_src/_build/html/index.html | 117 + docs_src/_build/html/modules.html | 114 + docs_src/_build/html/objects.inv | 8 + docs_src/_build/html/py-modindex.html | 137 + docs_src/_build/html/search.html | 120 + docs_src/_build/html/searchindex.js | 1 + .../cfelpyutils.crystfel_utils.rst | 4 +- .../cfelpyutils.geometry_utils.rst | 4 +- docs_src/cfelpyutils.named_tuples.rst | 7 + docs_src/cfelpyutils.rst | 13 + docs_src/conf.py | 190 + docs_src/index.rst | 53 + {docs => docs_src}/make.bat | 1 - setup.py | 7 +- 115 files changed, 35307 insertions(+), 322 deletions(-) create mode 100644 cfelpyutils/named_tuples.py create mode 100644 docs/.buildinfo create mode 100644 docs/_modules/cfelpyutils/crystfel_utils.html create mode 100644 docs/_modules/cfelpyutils/geometry_utils.html create mode 100644 docs/_modules/cfelpyutils/named_tuples.html create mode 100644 docs/_modules/index.html create mode 100644 docs/_sources/cfelpyutils.crystfel_utils.rst.txt create mode 100644 docs/_sources/cfelpyutils.geometry_utils.rst.txt create mode 100644 docs/_sources/cfelpyutils.named_tuples.rst.txt create mode 100644 docs/_sources/cfelpyutils.rst.txt create mode 100644 docs/_sources/index.rst.txt create mode 100644 docs/_sources/modules.rst.txt create mode 100644 docs/_static/ajax-loader.gif create mode 100644 docs/_static/alabaster.css create mode 100644 docs/_static/basic.css create mode 100644 docs/_static/comment-bright.png create mode 100644 docs/_static/comment-close.png create mode 100644 docs/_static/comment.png create mode 100644 docs/_static/custom.css create mode 100644 docs/_static/doctools.js create mode 100644 docs/_static/documentation_options.js create mode 100644 docs/_static/down-pressed.png create mode 100644 docs/_static/down.png create mode 100644 docs/_static/file.png create mode 100644 docs/_static/jquery-3.2.1.js create mode 100644 docs/_static/jquery.js create mode 100644 docs/_static/language_data.js create mode 100644 docs/_static/minus.png create mode 100644 docs/_static/plus.png create mode 100644 docs/_static/pygments.css create mode 100644 docs/_static/searchtools.js create mode 100644 docs/_static/underscore-1.3.1.js create mode 100644 docs/_static/underscore.js create mode 100644 docs/_static/up-pressed.png create mode 100644 docs/_static/up.png create mode 100644 docs/_static/websupport.js create mode 100644 docs/cfelpyutils.crystfel_utils.html create mode 100644 docs/cfelpyutils.geometry_utils.html create mode 100644 docs/cfelpyutils.html create mode 100644 docs/cfelpyutils.named_tuples.html delete mode 100644 docs/cfelpyutils.rst delete mode 100644 docs/conf.py create mode 100644 docs/genindex.html create mode 100644 docs/index.html delete mode 100644 docs/index.rst create mode 100644 docs/modules.html create mode 100644 docs/objects.inv create mode 100644 docs/py-modindex.html create mode 100644 docs/search.html create mode 100644 docs/searchindex.js rename {docs => docs_src}/Makefile (88%) create mode 100644 docs_src/_build/doctrees/cfelpyutils.crystfel_utils.doctree create mode 100644 docs_src/_build/doctrees/cfelpyutils.doctree create mode 100644 docs_src/_build/doctrees/cfelpyutils.geometry_utils.doctree create mode 100644 docs_src/_build/doctrees/cfelpyutils.named_tuples.doctree create mode 100644 docs_src/_build/doctrees/environment.pickle create mode 100644 docs_src/_build/doctrees/index.doctree create mode 100644 docs_src/_build/doctrees/modules.doctree create mode 100644 docs_src/_build/html/.buildinfo create mode 100644 docs_src/_build/html/_modules/cfelpyutils/crystfel_utils.html create mode 100644 docs_src/_build/html/_modules/cfelpyutils/geometry_utils.html create mode 100644 docs_src/_build/html/_modules/cfelpyutils/named_tuples.html create mode 100644 docs_src/_build/html/_modules/index.html create mode 100644 docs_src/_build/html/_sources/cfelpyutils.crystfel_utils.rst.txt create mode 100644 docs_src/_build/html/_sources/cfelpyutils.geometry_utils.rst.txt create mode 100644 docs_src/_build/html/_sources/cfelpyutils.named_tuples.rst.txt create mode 100644 docs_src/_build/html/_sources/cfelpyutils.rst.txt create mode 100644 docs_src/_build/html/_sources/index.rst.txt create mode 100644 docs_src/_build/html/_sources/modules.rst.txt create mode 100644 docs_src/_build/html/_static/ajax-loader.gif create mode 100644 docs_src/_build/html/_static/alabaster.css create mode 100644 docs_src/_build/html/_static/basic.css create mode 100644 docs_src/_build/html/_static/comment-bright.png create mode 100644 docs_src/_build/html/_static/comment-close.png create mode 100644 docs_src/_build/html/_static/comment.png create mode 100644 docs_src/_build/html/_static/custom.css create mode 100644 docs_src/_build/html/_static/doctools.js create mode 100644 docs_src/_build/html/_static/documentation_options.js create mode 100644 docs_src/_build/html/_static/down-pressed.png create mode 100644 docs_src/_build/html/_static/down.png create mode 100644 docs_src/_build/html/_static/file.png create mode 100644 docs_src/_build/html/_static/jquery-3.2.1.js create mode 100644 docs_src/_build/html/_static/jquery.js create mode 100644 docs_src/_build/html/_static/language_data.js create mode 100644 docs_src/_build/html/_static/minus.png create mode 100644 docs_src/_build/html/_static/plus.png create mode 100644 docs_src/_build/html/_static/pygments.css create mode 100644 docs_src/_build/html/_static/searchtools.js create mode 100644 docs_src/_build/html/_static/underscore-1.3.1.js create mode 100644 docs_src/_build/html/_static/underscore.js create mode 100644 docs_src/_build/html/_static/up-pressed.png create mode 100644 docs_src/_build/html/_static/up.png create mode 100644 docs_src/_build/html/_static/websupport.js create mode 100644 docs_src/_build/html/cfelpyutils.crystfel_utils.html create mode 100644 docs_src/_build/html/cfelpyutils.geometry_utils.html create mode 100644 docs_src/_build/html/cfelpyutils.html create mode 100644 docs_src/_build/html/cfelpyutils.named_tuples.html create mode 100644 docs_src/_build/html/genindex.html create mode 100644 docs_src/_build/html/index.html create mode 100644 docs_src/_build/html/modules.html create mode 100644 docs_src/_build/html/objects.inv create mode 100644 docs_src/_build/html/py-modindex.html create mode 100644 docs_src/_build/html/search.html create mode 100644 docs_src/_build/html/searchindex.js rename {docs => docs_src}/cfelpyutils.crystfel_utils.rst (59%) rename {docs => docs_src}/cfelpyutils.geometry_utils.rst (59%) create mode 100644 docs_src/cfelpyutils.named_tuples.rst create mode 100644 docs_src/cfelpyutils.rst create mode 100644 docs_src/conf.py create mode 100644 docs_src/index.rst rename {docs => docs_src}/make.bat (92%) diff --git a/cfelpyutils/__init__.py b/cfelpyutils/__init__.py index 7bbf15c..44b9056 100644 --- a/cfelpyutils/__init__.py +++ b/cfelpyutils/__init__.py @@ -1,29 +1,18 @@ -# This file is part of OnDA. +# This file is part of CFELPyUtils +# CFELPyUtils is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. # -# OnDA is free software: you can redistribute it and/or modify it under the terms of -# the GNU General Public License as published by the Free Software Foundation, either -# version 3 of the License, or (at your option) any later version. +# CFELPyUtils is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more details. # -# OnDA is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -# PURPOSE. See the GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along with OnDA. -# If not, see <http://www.gnu.org/licenses/>. +# You should have received a copy of the GNU General Public License along with OnDA. If +# not, see <http://www.gnu.org/licenses/>. # # Copyright 2014-2019 Deutsches Elektronen-Synchrotron DESY, # a research centre of the Helmholtz Association. """ -Utility functions and classes for CFEL software projects. - -Utility functions and classes used by many software projects developed at the Center -For Free Electron Laser Science (CFEL) in Hamburg. (`Link CFEL: https://www.cfel.de`) - -The 'crystfel_utils' submodule contains the python implementation of some functions -from the CrystFEL software package. (`Link CrystFEL -http://www.desy.de/~twhite/crystfel/`) - -The 'geometry_utils' submodule contains the implementation of functions used to -manipulate detector geometry information. +The main CFELPyUtils package, which contains the whole library. """ -__version__ = "0.92" +__version__ = "1.0.0" diff --git a/cfelpyutils/crystfel_utils.py b/cfelpyutils/crystfel_utils.py index 1ca0934..ac7b96b 100644 --- a/cfelpyutils/crystfel_utils.py +++ b/cfelpyutils/crystfel_utils.py @@ -1,23 +1,23 @@ -# This file is part of OnDA. +# This file is part of CFELPyUtils. # -# OnDA is free software: you can redistribute it and/or modify it under the terms of -# the GNU General Public License as published by the Free Software Foundation, either -# version 3 of the License, or (at your option) any later version. +# CFELPyUtils is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. # -# OnDA is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -# PURPOSE. See the GNU General Public License for more details. +# CFELPyUtils is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License along with OnDA. -# If not, see <http://www.gnu.org/licenses/>. +# You should have received a copy of the GNU General Public License along with OnDA. If +# not, see <http://www.gnu.org/licenses/>. # # Copyright 2014-2019 Deutsches Elektronen-Synchrotron DESY, # a research centre of the Helmholtz Association. """ CrystFEL utilities. -Python implementation of some functions from the `CrystFEL software package -<http://www.desy.de/~twhite/crystfel/>`_. +This module contains Python reimplementations of some functions from the `CrystFEL +<http://www.desy.de/~twhite/crystfel>`_ software package. """ from __future__ import absolute_import, division, print_function @@ -25,11 +25,13 @@ import collections import copy import math import re +from typing import Any, Dict, List, Union, Tuple # pylint: disable=unused-import from future.utils import viewitems def _assplode_algebraic(value): + # type: (str) -> List[str] # Reimplementation of assplode_algegraic from libcrystfel/src/detector.c. items = [item for item in re.split("([+-])", string=value.strip()) if item != ""] if items and items[0] not in ("+", "-"): @@ -38,25 +40,22 @@ def _assplode_algebraic(value): def _dir_conv(direction_x, direction_y, direction_z, value): + # type: (float, float, float, str) -> List[float] # Reimplementation of dir_conv from libcrystfel/src/detector.c. direction = [direction_x, direction_y, direction_z] - items = _assplode_algebraic(value) if not items: raise RuntimeError("Invalid direction: {}.".format(value)) - for item in items: axis = item[-1] if axis != "x" and axis != "y" and axis != "z": raise RuntimeError("Invalid Symbol: {} (must be x, y or z).".format(axis)) - if item[:-1] == "+": value = "1.0" elif item[:-1] == "-": value = "-1.0" else: value = item[:-1] - if axis == "x": direction[0] = float(value) elif axis == "y": @@ -68,23 +67,21 @@ def _dir_conv(direction_x, direction_y, direction_z, value): def _set_dim_structure_entry(key, value, panel): + # type: (str, str, Dict[str, Any]) -> None # Reimplementation of set_dim_structure_entry from libcrystfel/src/events.c. if panel["dim_structure"] is not None: dim = panel["dim_structure"] else: dim = [] - try: dim_index = int(key[3]) except IndexError: raise RuntimeError("'dim' must be followed by a number, e.g. 'dim0')") except ValueError: raise RuntimeError("Invalid dimension number {}".format(key[3])) - if dim_index > len(dim) - 1: for _ in range(len(dim), dim_index + 1): dim.append(None) - if value == "ss" or value == "fs" or value == "%": dim[dim_index] = value elif value.isdigit(): @@ -95,6 +92,7 @@ def _set_dim_structure_entry(key, value, panel): def _parse_field_for_panel(key, value, panel): + # type: (str, str, Dict[str, Any]) -> None # Reimplementation of parse_field_for_panel from libcrystfel/src/detector.c. if key == "min_fs": panel["origin_min_fs"] = int(value) @@ -172,7 +170,6 @@ def _parse_field_for_panel(key, value, panel): print("badrow_direction must be x, t, f, s, or '-'") print("Assuming '-'.") panel["badrow"] = "-" - elif key == "no_index": panel["no_index"] = bool(value) elif key == "fs": @@ -185,7 +182,6 @@ def _parse_field_for_panel(key, value, panel): ) except RuntimeError as exc: raise RuntimeError("Invalid fast scan direction.", exc) - elif key == "ss": try: panel["ssx"], panel["ssy"], panel["ssz"] = _dir_conv( @@ -196,7 +192,6 @@ def _parse_field_for_panel(key, value, panel): ) except RuntimeError as exc: raise RuntimeError("Invalid slow scan direction.", exc) - elif key.startswith("dim"): _set_dim_structure_entry(key=key, value=value, panel=panel) else: @@ -204,6 +199,7 @@ def _parse_field_for_panel(key, value, panel): def _parse_toplevel(key, value, detector, beam, panel): + # type: (str, str, Dict[str, Any], Dict[str, Any], Dict[str, Any]) -> None # Reimplementation of parse_toplevel from libcrystfel/src/detector.c. if key == "mask_bad": try: @@ -237,6 +233,7 @@ def _parse_toplevel(key, value, detector, beam, panel): def _check_bad_fsss(bad_region, is_fsss): + # type: (Dict[str, Any], int) -> None # Reimplementation of check_bad_fsss from libcrystfel/src/detector.c. if bad_region["is_fsss"] == 99: bad_region["is_fsss"] = is_fsss @@ -249,6 +246,7 @@ def _check_bad_fsss(bad_region, is_fsss): def _parse_field_bad(key, value, bad): + # type: (str, str, Dict[str, Any]) -> None # Reimplementation of parse_field_bad from libcrystfel/src/detector.c. if key == "min_x": bad["min_x"] = float(value) @@ -282,7 +280,16 @@ def _parse_field_bad(key, value, bad): return -def _check_point(name, panel, fs_, ss_, min_d, max_d, detector): +def _check_point( + name, # type: str + panel, # type: Dict[str, Any] + fs_, # type: int + ss_, # type: int + min_d, # type: float + max_d, # type: float + detector, # type: Dict[str, Any] +): + # type: (...) -> Tuple[float, float] # Reimplementation of check_point from libcrystfel/src/detector.c. xs_ = fs_ * panel["fsx"] + ss_ * panel["ssx"] ys_ = fs_ * panel["fsy"] + ss_ * panel["ssy"] @@ -304,6 +311,7 @@ def _check_point(name, panel, fs_, ss_, min_d, max_d, detector): def _find_min_max_d(detector): + # type: (Dict[str, Any]) -> None # Reimplementation of find_min_max_d from libcrystfel/src/detector.c. min_d = float("inf") max_d = 0.0 @@ -347,27 +355,37 @@ def _find_min_max_d(detector): def load_crystfel_geometry(filename): + # type: (str) -> Dict[str, Any] """ - Loads a CrystFEL geometry file into a dictionary. + Loads a CrystFEL geometry file. + + This function is a reimplementation of the get_detector_geometry_2 function from + CrystFEL. It reads information from a CrystFEL geometry file. + + For a full documentation of the CrystFEL geometry format, see the relevant `man + page <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html>`_. + + The function returns a dictionary with the geometry information. + + * The CrystFEL geometry file uses a key/value language. The keys in the returned + dictionary match the keys in the geometry file. - Reimplementation of the get_detector_geometry_2 function from CrystFEL in python. - Returns a dictionary with the geometry information read from the file. Converts - entries in the geometry file to keys in the returned dictionary. For a full - documentation of the CrystFEL geometry format, see `CrystFEL's geometry man page - <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry. - html>`_. The code of this function is synced with the code of the function - 'get_detector_geometry_2' in CrystFEL at commit 41a8fa9819010. + * The dictionary values store the corresponding values. - Args: + * The code of this function is currently synchronized with the code of the function + 'get_detector_geometry_2' in CrystFEL at commit 41a8fa9819010. - filename (str): filename of the geometry file. + + Arguments: + + filename (str): the absolute or relative path to a CrystFEL geometry file. Returns: - Dict: dictionary with the geometry information loaded from the file. + Dict[str, Any]: a dictionary with the geometry information loaded from the + file. """ beam = {"photon_energy": 0.0, "photon_energy_from": None, "photon_energy_scale": 1} - detector = { "panels": collections.OrderedDict(), "bad": collections.OrderedDict(), @@ -376,7 +394,6 @@ def load_crystfel_geometry(filename): "rigid_groups": {}, "rigid_group_collections": {}, } - default_panel = { "cnx": None, "cny": None, @@ -405,7 +422,6 @@ def load_crystfel_geometry(filename): "data": None, "dim_structure": None, } - default_bad_region = { "min_x": None, "max_x": None, @@ -417,7 +433,6 @@ def load_crystfel_geometry(filename): "max_ss": 0, "is_fsss": 99, } - default_dim = ["ss", "fs"] fhandle = open(filename, mode="r") @@ -425,18 +440,14 @@ def load_crystfel_geometry(filename): for line in fhlines: if line.startswith(";"): continue - line_without_comments = line.strip().split(";")[0] line_items = re.split(pattern="([ \t])", string=line_without_comments) line_items = [item for item in line_items if item not in ("", " ", "\t")] - if len(line_items) < 3: continue - value = "".join(line_items[2:]) if line_items[1] != "=": continue - path = re.split("(/)", line_items[0]) path = [item for item in path if item not in "/"] if len(path) < 2: @@ -448,7 +459,6 @@ def load_crystfel_geometry(filename): panel=default_panel, ) continue - curr_bad = None curr_panel = None if path[0].startswith("bad"): @@ -467,10 +477,8 @@ def load_crystfel_geometry(filename): _parse_field_for_panel(key=path[1], value=value, panel=curr_panel) else: _parse_field_bad(key=path[1], value=value, bad=curr_bad) - if not detector["panels"]: raise RuntimeError("No panel descriptions in geometry file.") - num_placeholders_in_panels = None for panel in detector["panels"].values(): if panel["dim_structure"] is not None: @@ -486,7 +494,6 @@ def load_crystfel_geometry(filename): "All panels' data and mask entries must have the same number of " "placeholders." ) - num_placeholders_in_masks = None for panel in detector["panels"].values(): if panel["mask"] is not None: @@ -502,12 +509,10 @@ def load_crystfel_geometry(filename): "All panels' data and mask entries must have the same number of " "placeholders." ) - if num_placeholders_in_masks > num_placeholders_in_panels: raise RuntimeError( "Number of placeholders in mask cannot be larger the number than for data." ) - dim_length = None for panel_name, panel in viewitems(detector["panels"]): if panel["dim_structure"] is None: @@ -529,7 +534,6 @@ def load_crystfel_geometry(filename): found_fs += 1 elif entry == "%": found_placeholder += 1 - if found_ss != 1: raise RuntimeError( "Exactly one slow scan dim coordinate is needed (found {} for panel " @@ -547,17 +551,14 @@ def load_crystfel_geometry(filename): found_placeholder, panel_name ) ) - if dim_length is None: dim_length = len(panel["dim_structure"]) elif dim_length != len(panel["dim_structure"]): raise RuntimeError( "Number of dim coordinates must be the same for all panels." ) - if dim_length == 1: raise RuntimeError("Number of dim coordinates must be at least two.") - for panel_name, panel in viewitems(detector["panels"]): if panel["origin_min_fs"] < 0: raise RuntimeError( @@ -565,68 +566,56 @@ def load_crystfel_geometry(filename): panel_name ) ) - if panel["origin_max_fs"] < 0: raise RuntimeError( "Please specify the maximum fs coordinate for panel {}.".format( panel_name ) ) - if panel["origin_min_ss"] < 0: raise RuntimeError( "Please specify the minimum ss coordinate for panel {}.".format( panel_name ) ) - if panel["origin_max_ss"] < 0: raise RuntimeError( "Please specify the maximum ss coordinate for panel {}.".format( panel_name ) ) - if panel["cnx"] is None: raise RuntimeError( "Please specify the corner X coordinate for panel {}.".format( panel_name ) ) - if panel["clen"] is None and panel["clen_from"] is None: raise RuntimeError( "Please specify the camera length for panel {}.".format(panel_name) ) - if panel["res"] < 0: raise RuntimeError( "Please specify the resolution or panel {}.".format(panel_name) ) - if panel["adu_per_eV"] is None and panel["adu_per_photon"] is None: raise RuntimeError( "Please specify either adu_per_eV or adu_per_photon for panel " "{}.".format(panel_name) ) - if panel["clen_for_centering"] is None and panel["rail_x"] is not None: raise RuntimeError( "You must specify clen_for_centering if you specify the rail " "direction (panel {})".format(panel_name) ) - if panel["rail_x"] is None: panel["rail_x"] = 0.0 panel["rail_y"] = 0.0 panel["rail_z"] = 1.0 - if panel["clen_for_centering"] is None: panel["clen_for_centering"] = 0.0 - panel["w"] = panel["origin_max_fs"] - panel["origin_min_fs"] + 1 panel["h"] = panel["origin_max_ss"] - panel["origin_min_ss"] + 1 - for bad_region_name, bad_region in viewitems(detector["bad"]): if bad_region["is_fsss"] == 99: raise RuntimeError( @@ -634,14 +623,12 @@ def load_crystfel_geometry(filename): bad_region_name ) ) - for group in detector["rigid_groups"]: for name in detector["rigid_groups"][group]: if name not in detector["panels"]: raise RuntimeError( "Cannot add panel to rigid_group. Panel not found: {}".format(name) ) - for group_collection in detector["rigid_group_collections"]: for name in detector["rigid_group_collections"][group_collection]: if name not in detector["rigid_groups"]: @@ -649,7 +636,6 @@ def load_crystfel_geometry(filename): "Cannot add rigid_group to collection. Rigid group not " "found: {}".format(name) ) - for panel in detector["panels"].values(): d__ = panel["fsx"] * panel["ssy"] - panel["ssx"] * panel["fsy"] if d__ == 0.0: @@ -658,12 +644,7 @@ def load_crystfel_geometry(filename): panel["yfs"] = panel["ssx"] / d__ panel["xss"] = panel["fsy"] / d__ panel["yss"] = panel["fsx"] / d__ - _find_min_max_d(detector) fhandle.close() - # The code of this function is synced with the code of the function - # 'get_detector_geometry_2' in CrystFEL at commit - # dabbe320ff1d54d8ad24954b1e391f1b58ec0866 - return detector diff --git a/cfelpyutils/geometry_utils.py b/cfelpyutils/geometry_utils.py index 9544f9c..7bf386b 100644 --- a/cfelpyutils/geometry_utils.py +++ b/cfelpyutils/geometry_utils.py @@ -1,63 +1,61 @@ -# This file is part of OnDA. +# This file is part of CFELPyUtils. # -# OnDA is free software: you can redistribute it and/or modify it under the terms of -# the GNU General Public License as published by the Free Software Foundation, either -# version 3 of the License, or (at your option) any later version. +# CFELPyUtils is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. # -# OnDA is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -# PURPOSE. See the GNU General Public License for more details. +# CFELPyUtils is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License along with OnDA. -# If not, see <http://www.gnu.org/licenses/>. +# You should have received a copy of the GNU General Public License along with OnDA. If +# not, see <http://www.gnu.org/licenses/>. # # Copyright 2014-2019 Deutsches Elektronen-Synchrotron DESY, # a research centre of the Helmholtz Association. """ Geometry utilities. -Functions to manipulate geometry information. +This module contains functions that manipulate geometry information. """ from __future__ import absolute_import, division, print_function -import collections +from typing import Any, Dict, Tuple # pylint: disable=unused-import import numpy - -PixelMaps = collections.namedtuple( - typename="PixelMaps", field_names=["x", "y", "z", "r", "phi"] -) -""" -Pixel maps storing geometry information. - -The first three fields, named "x" "y" and "z" respectively, store the pixel maps for -the x,the y and the z coordinates. The fourth field, named "r", is a pixel map storing -the distance of each pixel in the data array from the center of the reference system. -The fifth field, 'phi', is instead a pixel map that stores the angles that vectors -connecting each pixel with the center of the reference system make with respect to the -x axis of the reference system. -""" +from cfelpyutils import named_tuples def compute_pix_maps(geometry): + # type: (Dict[str, Any]) -> PixelMaps """ - Computes pixel maps from a CrystFEL geometry object. + Computes pixel maps from CrystFEL geometry information. + + This function takes as input some geometry information read from a `CrystFEL + <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html>`_ file, and + returns a set of some pre-computed pixel maps. + + The origin and the orientation of the reference system for the pixel maps follow + the same conventions as in CrystFEL: - Takes as input a CrystFEL-style geometry object (A dictionary returned by the - function load_crystfel_geometry function in the crystfel_utils module) and returns a - :obj:`PixelMaps` tuple . The origin the reference system used by the pixel maps is - set at the beam interaction point. + * The center of the reference system is the beam interaction point. - Args: + * +z is the beam direction, and points along the beam (i.e. away from the source). - geometry (Dict): A CrystFEL geometry object (A dictionary returned by the - :obj:`cfelpyutils.crystfel_utils.load_crystfel_geometry` function). + * +y points towards the zenith (ceiling). + + * +x completes the right-handed coordinate system. + + Arguments: + + geometry (Dict[str, Any]): a CrystFEL geometry object (A dictionary returned by + the :func:`~cfelpyutils.crystfel_utils.load_crystfel_geometry` function). Returns: - PixelMaps: A :obj:`PixelMaps` tuple storing the pixel maps (numpy.ndarrays of - float). + :class:`~cfelpyutils.named_tuples.PixelMaps`: a named tuple storing the the + pixel maps. """ max_fs_in_slab = numpy.array( [geometry["panels"][k]["max_fs"] for k in geometry["panels"]] @@ -125,102 +123,93 @@ def compute_pix_maps(geometry): r_map = numpy.sqrt(numpy.square(x_map) + numpy.square(y_map)) phi_map = numpy.arctan2(y_map, x_map) - return PixelMaps(x_map, y_map, z_map, r_map, phi_map) - + return named_tuples.PixelMaps(x_map, y_map, z_map, r_map, phi_map) -def compute_min_array_size(pixel_maps): - """ - Computes the minimum size of an array stroing the applied geometry. - - Returns the minimum size of an array that can store data on which the geometry - information described by the pixel maps has been applied. - - The returned array shape is big enough to display all the input pixel values in the - reference system of the physical detector. The array is also supposed to be - centered at the center of the reference system of the detector (i.e: the beam - interaction point). - - Args: - - pixel_maps (PixelMaps): a :obj:`PixelMaps` tuple. - - Returns: - Tuple[int, int]: a numpy-style shape tuple storing the minimum array size. +def compute_visualization_pix_maps(geometry): + # type: (Dict[str, Any]) -> PixelMaps """ - # Find the largest absolute values of x and y in the maps. Since the returned array - # is centered on the origin, the minimum array size along a certain axis must be at - # least twice the maximum value for that axis. 2 pixels are added for good measure. - x_map, y_map = pixel_maps.x, pixel_maps.y - y_minimum = 2 * int(max(abs(y_map.max()), abs(y_map.min()))) + 2 - x_minimum = 2 * int(max(abs(x_map.max()), abs(x_map.min()))) + 2 + Computes pixel maps for data visualization from CrystFEL geometry information. - return (y_minimum, x_minimum) + This function takes as input some geometry information read from a `CrystFEL + <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html>`_ file, and + returns a set of some pre-computed pixel maps that can be used to display data in + an ImageView widget from the `PyQtGraph <http://pyqtgraph.org/>`_ library. + These pixel maps are different from the ones generated by the + :func:`~compute_pix_maps` function. The main differences are: -def compute_visualization_pix_maps(geometry): - """ - Computes pixel maps for visualization of the data. + * The origin of the reference system is not the beam interaction point, but the top + left corner of the array used to visualize the data. - The pixel maps can be used for to display the data in a Pyqtgraph ImageView widget. + * Only the x and y pixel maps are available. The other entries in the named tuple + (z, r and phi) are set to None. - Args: + Arguments: - geometry (Dict): A CrystFEL geometry object (A dictionary returned by the - :obj:`cfelpyutils.crystfel_utils.load_crystfel_geometry` function). + geometry (Dict[str, Any]): a CrystFEL geometry object (A dictionary returned by + the :func:`~cfelpyutils.crystfel_utils.load_crystfel_geometry` function). Returns: - PixelMaps: A PixelMaps tuple containing the adjusted pixel maps. The first two - fields, named "x" and "y" respectively, store the pixel maps for the x - coordinate and the y coordinates (as ndarrays of type int). The third, fourth - and fifth fields ("z", "r" and "phi") are just set to None. + :class:`PixelMaps`: a named tuple with the pixel maps. """ # Shifts the origin of the reference system from the beam position to the top-left # of the image that will be displayed. Computes the size of the array needed to # display the data, then use this information to estimate the magnitude of the # shift. pixel_maps = compute_pix_maps(geometry) - min_shape = compute_min_array_size(pixel_maps) + x_map, y_map = pixel_maps.x, pixel_maps.y + y_minimum = 2 * int(max(abs(y_map.max()), abs(y_map.min()))) + 2 + x_minimum = 2 * int(max(abs(x_map.max()), abs(x_map.min()))) + 2 + min_shape = (y_minimum, x_minimum) new_x_map = ( numpy.array(object=pixel_maps.x, dtype=numpy.int) + min_shape[1] // 2 - 1 ) - new_y_map = ( numpy.array(object=pixel_maps.y, dtype=numpy.int) + min_shape[0] // 2 - 1 ) - - return PixelMaps(new_x_map, new_y_map, None, None, None) + return named_tuples.PixelMaps(new_x_map, new_y_map, None, None, None) def apply_geometry_to_data(data, geometry): + # type: (numpy.ndarray, Dict[str, Any]) -> numpy.ndarray """ - Applies geometry to data. + Applies CrystFEL geometry information to some data. + + This function takes as input some geometry information read from a `CrystFEL + <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html>`_ file, and + some data on which to apply it. It returns an array that can be displayed using a + library like `matplotlib <https://matplotlib.org/>`_ or + `PyQtGraph <http://pyqtgraph.org/>`_. + + The shape of the returned array is big enough to display all the input pixel + values, and is symmetric around the center of the reference system (i.e: the beam + interaction point). - Returns a new numpy array containing the input data with the geometry applied. - The array is ready to be displayed using a library like matplotlib or pyqtgraph. + NOTE: This restrictions often cause the returned array to be bigger than the minimum + size needed to store the physical layout of the pixels in the detector, + particularly if the detector is not centered at the beam interaction point. - Args: + Arguments: - data (ndarray): a numpy array storing the data to which geometry should be + data (numpy.ndarray): the data on which the geometry information should be applied. - geometry (Dict): A CrystFEL geometry object (A dictionary - returned by the - :obj:`cfelpyutils.crystfel_utils.load_crystfel_geometry` - function). + geometry (Dict[str, Any]): a CrystFEL geometry object (A dictionary returned by + the :func:`~cfelpyutils.crystfel_utils.load_crystfel_geometry` function). Returns: - ndarray: a new array containing the input data to which the geometry has been - applied. The returned array shape is big enough to display all the input data - in the reference system of the physical detector. The array is also supposed to - be centered at the center of the reference system of the detector (i.e: the - beam interaction point). + numpy.ndarray: an array containing the data with the geometry information + applied. """ pixel_maps = compute_pix_maps(geometry) - min_array_shape = compute_min_array_size(pixel_maps) - visualization_array = numpy.zeros(min_array_shape, dtype=float) + x_map, y_map = pixel_maps.x, pixel_maps.y + y_minimum = 2 * int(max(abs(y_map.max()), abs(y_map.min()))) + 2 + x_minimum = 2 * int(max(abs(x_map.max()), abs(x_map.min()))) + 2 + min_shape = (y_minimum, x_minimum) + visualization_array = numpy.zeros(min_shape, dtype=float) visual_pixel_maps = compute_visualization_pix_maps(geometry) visualization_array[ visual_pixel_maps.y.flatten(), visual_pixel_maps.x.flatten() diff --git a/cfelpyutils/named_tuples.py b/cfelpyutils/named_tuples.py new file mode 100644 index 0000000..dc75130 --- /dev/null +++ b/cfelpyutils/named_tuples.py @@ -0,0 +1,41 @@ +# This file is part of CFELPyUtils. +# +# CFELPyUtils is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software Foundation, +# either version 3 of the License, or (at your option) any later version. +# +# CFELPyUtils is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with OnDA. If +# not, see <http://www.gnu.org/licenses/>. +# +# Copyright 2014-2019 Deutsches Elektronen-Synchrotron DESY, +# a research centre of the Helmholtz Association. +""" +CFELPyUtils named tuples. + +This module contains a collection of named tuples used throughout the CFELPyUtils +library. +""" +import collections + +PixelMaps = collections.namedtuple("PixelMaps", ["x", "y", "z", "r", "phi"]) +""" +Pixel maps that store geometry information. + +Arguments: + + x (numpy.ndarray): pixel map for the x coordinate. + + y (numpy.ndarray): pixel map for the y coordinate. + + z (numpy.ndarray): pixel map for the z coordinate. + + r (numpy.ndarray): pixel map storing the distance of each pixel from the center of + the reference system. + + phi (numpy.ndarray): pixel map storing the amplitude of the angle between each + pixel, the center of the reference system, and the x axis through the center. +""" diff --git a/docs/.buildinfo b/docs/.buildinfo new file mode 100644 index 0000000..07914e1 --- /dev/null +++ b/docs/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: fd8cf3500139e539a950fcaee26c3d53 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/_modules/cfelpyutils/crystfel_utils.html b/docs/_modules/cfelpyutils/crystfel_utils.html new file mode 100644 index 0000000..8d1f451 --- /dev/null +++ b/docs/_modules/cfelpyutils/crystfel_utils.html @@ -0,0 +1,754 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>cfelpyutils.crystfel_utils — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script> + <script type="text/javascript" src="../../_static/jquery.js"></script> + <script type="text/javascript" src="../../_static/underscore.js"></script> + <script type="text/javascript" src="../../_static/doctools.js"></script> + <script type="text/javascript" src="../../_static/language_data.js"></script> + <link rel="index" title="Index" href="../../genindex.html" /> + <link rel="search" title="Search" href="../../search.html" /> + + <link rel="stylesheet" href="../../_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <h1>Source code for cfelpyutils.crystfel_utils</h1><div class="highlight"><pre> +<span></span><span class="c1"># This file is part of CFELPyUtils.</span> +<span class="c1">#</span> +<span class="c1"># CFELPyUtils is free software: you can redistribute it and/or modify it under the</span> +<span class="c1"># terms of the GNU General Public License as published by the Free Software Foundation,</span> +<span class="c1"># either version 3 of the License, or (at your option) any later version.</span> +<span class="c1">#</span> +<span class="c1"># CFELPyUtils is distributed in the hope that it will be useful, but WITHOUT ANY</span> +<span class="c1"># WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A</span> +<span class="c1"># PARTICULAR PURPOSE. See the GNU General Public License for more details.</span> +<span class="c1">#</span> +<span class="c1"># You should have received a copy of the GNU General Public License along with OnDA. If</span> +<span class="c1"># not, see <http://www.gnu.org/licenses/>.</span> +<span class="c1">#</span> +<span class="c1"># Copyright 2014-2019 Deutsches Elektronen-Synchrotron DESY,</span> +<span class="c1"># a research centre of the Helmholtz Association.</span> +<span class="sd">"""</span> +<span class="sd">CrystFEL utilities.</span> + +<span class="sd">This module contains Python reimplementations of some functions from the `CrystFEL</span> +<span class="sd"><http://www.desy.de/~twhite/crystfel>`_ software package.</span> +<span class="sd">"""</span> +<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span><span class="p">,</span> <span class="n">division</span><span class="p">,</span> <span class="n">print_function</span> + +<span class="kn">import</span> <span class="nn">collections</span> +<span class="kn">import</span> <span class="nn">copy</span> +<span class="kn">import</span> <span class="nn">math</span> +<span class="kn">import</span> <span class="nn">re</span> +<span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">Union</span><span class="p">,</span> <span class="n">Tuple</span> <span class="c1"># pylint: disable=unused-import</span> + +<span class="kn">from</span> <span class="nn">future.utils</span> <span class="k">import</span> <span class="n">viewitems</span> + + +<span class="k">def</span> <span class="nf">_assplode_algebraic</span><span class="p">(</span><span class="n">value</span><span class="p">):</span> + <span class="c1"># type: (str) -> List[str]</span> + <span class="c1"># Reimplementation of assplode_algegraic from libcrystfel/src/detector.c.</span> + <span class="n">items</span> <span class="o">=</span> <span class="p">[</span><span class="n">item</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"([+-])"</span><span class="p">,</span> <span class="n">string</span><span class="o">=</span><span class="n">value</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span> <span class="k">if</span> <span class="n">item</span> <span class="o">!=</span> <span class="s2">""</span><span class="p">]</span> + <span class="k">if</span> <span class="n">items</span> <span class="ow">and</span> <span class="n">items</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">"+"</span><span class="p">,</span> <span class="s2">"-"</span><span class="p">):</span> + <span class="n">items</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s2">"+"</span><span class="p">)</span> + <span class="k">return</span> <span class="p">[</span><span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">items</span><span class="p">[</span><span class="n">x</span><span class="p">],</span> <span class="n">items</span><span class="p">[</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]))</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">items</span><span class="p">),</span> <span class="mi">2</span><span class="p">)]</span> + + +<span class="k">def</span> <span class="nf">_dir_conv</span><span class="p">(</span><span class="n">direction_x</span><span class="p">,</span> <span class="n">direction_y</span><span class="p">,</span> <span class="n">direction_z</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> + <span class="c1"># type: (float, float, float, str) -> List[float]</span> + <span class="c1"># Reimplementation of dir_conv from libcrystfel/src/detector.c.</span> + <span class="n">direction</span> <span class="o">=</span> <span class="p">[</span><span class="n">direction_x</span><span class="p">,</span> <span class="n">direction_y</span><span class="p">,</span> <span class="n">direction_z</span><span class="p">]</span> + <span class="n">items</span> <span class="o">=</span> <span class="n">_assplode_algebraic</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">if</span> <span class="ow">not</span> <span class="n">items</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid direction: </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> + <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">items</span><span class="p">:</span> + <span class="n">axis</span> <span class="o">=</span> <span class="n">item</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> + <span class="k">if</span> <span class="n">axis</span> <span class="o">!=</span> <span class="s2">"x"</span> <span class="ow">and</span> <span class="n">axis</span> <span class="o">!=</span> <span class="s2">"y"</span> <span class="ow">and</span> <span class="n">axis</span> <span class="o">!=</span> <span class="s2">"z"</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid Symbol: </span><span class="si">{}</span><span class="s2"> (must be x, y or z)."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">axis</span><span class="p">))</span> + <span class="k">if</span> <span class="n">item</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"+"</span><span class="p">:</span> + <span class="n">value</span> <span class="o">=</span> <span class="s2">"1.0"</span> + <span class="k">elif</span> <span class="n">item</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"-"</span><span class="p">:</span> + <span class="n">value</span> <span class="o">=</span> <span class="s2">"-1.0"</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">value</span> <span class="o">=</span> <span class="n">item</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> + <span class="k">if</span> <span class="n">axis</span> <span class="o">==</span> <span class="s2">"x"</span><span class="p">:</span> + <span class="n">direction</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">axis</span> <span class="o">==</span> <span class="s2">"y"</span><span class="p">:</span> + <span class="n">direction</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">axis</span> <span class="o">==</span> <span class="s2">"z"</span><span class="p">:</span> + <span class="n">direction</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + + <span class="k">return</span> <span class="n">direction</span> + + +<span class="k">def</span> <span class="nf">_set_dim_structure_entry</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">panel</span><span class="p">):</span> + <span class="c1"># type: (str, str, Dict[str, Any]) -> None</span> + <span class="c1"># Reimplementation of set_dim_structure_entry from libcrystfel/src/events.c.</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">dim</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">dim</span> <span class="o">=</span> <span class="p">[]</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">dim_index</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">key</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span> + <span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"'dim' must be followed by a number, e.g. 'dim0')"</span><span class="p">)</span> + <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid dimension number </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">[</span><span class="mi">3</span><span class="p">]))</span> + <span class="k">if</span> <span class="n">dim_index</span> <span class="o">></span> <span class="nb">len</span><span class="p">(</span><span class="n">dim</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span> + <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">dim</span><span class="p">),</span> <span class="n">dim_index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span> + <span class="n">dim</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span> + <span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"ss"</span> <span class="ow">or</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"fs"</span> <span class="ow">or</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"%"</span><span class="p">:</span> + <span class="n">dim</span><span class="p">[</span><span class="n">dim_index</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">value</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span> + <span class="n">dim</span><span class="p">[</span><span class="n">dim_index</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">else</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid dim entry: </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span> <span class="o">=</span> <span class="n">dim</span> + + +<span class="k">def</span> <span class="nf">_parse_field_for_panel</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">panel</span><span class="p">):</span> + <span class="c1"># type: (str, str, Dict[str, Any]) -> None</span> + <span class="c1"># Reimplementation of parse_field_for_panel from libcrystfel/src/detector.c.</span> + <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"min_fs"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_min_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"min_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_fs"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_max_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"max_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"min_ss"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_min_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"min_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_ss"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_max_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"max_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"corner_x"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"cnx"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"corner_y"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"cny"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"rail_direction"</span><span class="p">:</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_x"</span><span class="p">],</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_y"</span><span class="p">],</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_z"</span><span class="p">]</span> <span class="o">=</span> <span class="n">_dir_conv</span><span class="p">(</span> + <span class="n">direction_x</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"rail_x"</span><span class="p">],</span> + <span class="n">direction_y</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"rail_y"</span><span class="p">],</span> + <span class="n">direction_z</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"rail_z"</span><span class="p">],</span> + <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> + <span class="p">)</span> + <span class="k">except</span> <span class="ne">RuntimeError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid rail direction. "</span><span class="p">,</span> <span class="n">exc</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"clen_for_centering"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_for_centering"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"adu_per_eV"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"adu_per_eV"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"adu_per_photon"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"adu_per_photon"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"rigid_group"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"rigid_group"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"clen"</span><span class="p">:</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"clen"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_from"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> + <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"clen"</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_from"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"data"</span><span class="p">:</span> + <span class="k">if</span> <span class="ow">not</span> <span class="n">value</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"/"</span><span class="p">):</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid data location: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"data"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"mask"</span><span class="p">:</span> + <span class="k">if</span> <span class="ow">not</span> <span class="n">value</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"/"</span><span class="p">):</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid data location: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"mask"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"mask_file"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"mask_file"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"saturation_map"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"saturation_map"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"saturation_map_file"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"saturation_map_file"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"coffset"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"coffset"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"res"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"res"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_adu"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"max_adu"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"badrow_direction"</span><span class="p">:</span> + <span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"x"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"badrow"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"f"</span> + <span class="k">elif</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"y"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"badrow"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"s"</span> + <span class="k">elif</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"f"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"badrow"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"f"</span> + <span class="k">elif</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"s"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"badrow"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"s"</span> + <span class="k">elif</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"-"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"badrow"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"-"</span> + <span class="k">else</span><span class="p">:</span> + <span class="nb">print</span><span class="p">(</span><span class="s2">"badrow_direction must be x, t, f, s, or '-'"</span><span class="p">)</span> + <span class="nb">print</span><span class="p">(</span><span class="s2">"Assuming '-'."</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"badrow"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"-"</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"no_index"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"no_index"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"fs"</span><span class="p">:</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"fsx"</span><span class="p">],</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsy"</span><span class="p">],</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsz"</span><span class="p">]</span> <span class="o">=</span> <span class="n">_dir_conv</span><span class="p">(</span> + <span class="n">direction_x</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"fsx"</span><span class="p">],</span> + <span class="n">direction_y</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"fsy"</span><span class="p">],</span> + <span class="n">direction_z</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"fsz"</span><span class="p">],</span> + <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> + <span class="p">)</span> + <span class="k">except</span> <span class="ne">RuntimeError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid fast scan direction."</span><span class="p">,</span> <span class="n">exc</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"ss"</span><span class="p">:</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"ssx"</span><span class="p">],</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssy"</span><span class="p">],</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssz"</span><span class="p">]</span> <span class="o">=</span> <span class="n">_dir_conv</span><span class="p">(</span> + <span class="n">direction_x</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"ssx"</span><span class="p">],</span> + <span class="n">direction_y</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"ssy"</span><span class="p">],</span> + <span class="n">direction_z</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"ssz"</span><span class="p">],</span> + <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> + <span class="p">)</span> + <span class="k">except</span> <span class="ne">RuntimeError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid slow scan direction."</span><span class="p">,</span> <span class="n">exc</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"dim"</span><span class="p">):</span> + <span class="n">_set_dim_structure_entry</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> <span class="n">panel</span><span class="o">=</span><span class="n">panel</span><span class="p">)</span> + <span class="k">else</span><span class="p">:</span> + <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Unrecognised field: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">))</span> + + +<span class="k">def</span> <span class="nf">_parse_toplevel</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">detector</span><span class="p">,</span> <span class="n">beam</span><span class="p">,</span> <span class="n">panel</span><span class="p">):</span> + <span class="c1"># type: (str, str, Dict[str, Any], Dict[str, Any], Dict[str, Any]) -> None</span> + <span class="c1"># Reimplementation of parse_toplevel from libcrystfel/src/detector.c.</span> + <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"mask_bad"</span><span class="p">:</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"mask_bad"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"mask_bad"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="mi">16</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"mask_good"</span><span class="p">:</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"mask_good"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"mask_good"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="mi">16</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"coffset"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"coffset"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"photon_energy"</span><span class="p">:</span> + <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"/"</span><span class="p">):</span> + <span class="n">beam</span><span class="p">[</span><span class="s2">"photon_energy"</span><span class="p">]</span> <span class="o">=</span> <span class="mf">0.0</span> + <span class="n">beam</span><span class="p">[</span><span class="s2">"photon_energy_from"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">beam</span><span class="p">[</span><span class="s2">"photon_energy"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">beam</span><span class="p">[</span><span class="s2">"photon_energy_from"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"photon_energy_scale"</span><span class="p">:</span> + <span class="n">beam</span><span class="p">[</span><span class="s2">"photon_energy_scale"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"peak_info_location"</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"peak_info_location"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"rigid_group"</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"rigid_group_collection"</span><span class="p">):</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_groups"</span><span class="p">][</span><span class="n">key</span><span class="p">[</span><span class="mi">12</span><span class="p">:]]</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">","</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"rigid_group_collection"</span><span class="p">):</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_group_collections"</span><span class="p">][</span><span class="n">key</span><span class="p">[</span><span class="mi">23</span><span class="p">:]]</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">","</span><span class="p">)</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">_parse_field_for_panel</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> <span class="n">panel</span><span class="o">=</span><span class="n">panel</span><span class="p">)</span> + + +<span class="k">def</span> <span class="nf">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="p">,</span> <span class="n">is_fsss</span><span class="p">):</span> + <span class="c1"># type: (Dict[str, Any], int) -> None</span> + <span class="c1"># Reimplementation of check_bad_fsss from libcrystfel/src/detector.c.</span> + <span class="k">if</span> <span class="n">bad_region</span><span class="p">[</span><span class="s2">"is_fsss"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">99</span><span class="p">:</span> + <span class="n">bad_region</span><span class="p">[</span><span class="s2">"is_fsss"</span><span class="p">]</span> <span class="o">=</span> <span class="n">is_fsss</span> + <span class="k">return</span> + + <span class="k">if</span> <span class="n">is_fsss</span> <span class="o">!=</span> <span class="n">bad_region</span><span class="p">[</span><span class="s2">"is_fsss"</span><span class="p">]:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"You can't mix x/y and fs/ss in a bad region"</span><span class="p">)</span> + + <span class="k">return</span> + + +<span class="k">def</span> <span class="nf">_parse_field_bad</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">bad</span><span class="p">):</span> + <span class="c1"># type: (str, str, Dict[str, Any]) -> None</span> + <span class="c1"># Reimplementation of parse_field_bad from libcrystfel/src/detector.c.</span> + <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"min_x"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"min_x"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_x"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"max_x"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"min_y"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"min_y"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_y"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"max_y"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"min_fs"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"min_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_fs"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"max_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"min_ss"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"min_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_ss"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"max_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"panel"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"panel"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">else</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Unrecognised field: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">))</span> + + <span class="k">return</span> + + +<span class="k">def</span> <span class="nf">_check_point</span><span class="p">(</span> + <span class="n">name</span><span class="p">,</span> <span class="c1"># type: str</span> + <span class="n">panel</span><span class="p">,</span> <span class="c1"># type: Dict[str, Any]</span> + <span class="n">fs_</span><span class="p">,</span> <span class="c1"># type: int</span> + <span class="n">ss_</span><span class="p">,</span> <span class="c1"># type: int</span> + <span class="n">min_d</span><span class="p">,</span> <span class="c1"># type: float</span> + <span class="n">max_d</span><span class="p">,</span> <span class="c1"># type: float</span> + <span class="n">detector</span><span class="p">,</span> <span class="c1"># type: Dict[str, Any]</span> +<span class="p">):</span> + <span class="c1"># type: (...) -> Tuple[float, float]</span> + <span class="c1"># Reimplementation of check_point from libcrystfel/src/detector.c.</span> + <span class="n">xs_</span> <span class="o">=</span> <span class="n">fs_</span> <span class="o">*</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsx"</span><span class="p">]</span> <span class="o">+</span> <span class="n">ss_</span> <span class="o">*</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssx"</span><span class="p">]</span> + <span class="n">ys_</span> <span class="o">=</span> <span class="n">fs_</span> <span class="o">*</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsy"</span><span class="p">]</span> <span class="o">+</span> <span class="n">ss_</span> <span class="o">*</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssy"</span><span class="p">]</span> + <span class="n">rx_</span> <span class="o">=</span> <span class="p">(</span><span class="n">xs_</span> <span class="o">+</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"cnx"</span><span class="p">])</span> <span class="o">/</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"res"</span><span class="p">]</span> + <span class="n">ry_</span> <span class="o">=</span> <span class="p">(</span><span class="n">ys_</span> <span class="o">+</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"cny"</span><span class="p">])</span> <span class="o">/</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"res"</span><span class="p">]</span> + <span class="n">dist</span> <span class="o">=</span> <span class="n">math</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">rx_</span> <span class="o">*</span> <span class="n">rx_</span> <span class="o">+</span> <span class="n">ry_</span> <span class="o">*</span> <span class="n">ry_</span><span class="p">)</span> + <span class="k">if</span> <span class="n">dist</span> <span class="o">></span> <span class="n">max_d</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"furthest_out_panel"</span><span class="p">]</span> <span class="o">=</span> <span class="n">name</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"furthest_out_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="n">fs_</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"furthest_out_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="n">ss_</span> + <span class="n">max_d</span> <span class="o">=</span> <span class="n">dist</span> + <span class="k">elif</span> <span class="n">dist</span> <span class="o"><</span> <span class="n">min_d</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"furthest_in_panel"</span><span class="p">]</span> <span class="o">=</span> <span class="n">name</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"furthest_in_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="n">fs_</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"furthest_in_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="n">ss_</span> + <span class="n">min_d</span> <span class="o">=</span> <span class="n">dist</span> + + <span class="k">return</span> <span class="n">min_d</span><span class="p">,</span> <span class="n">max_d</span> + + +<span class="k">def</span> <span class="nf">_find_min_max_d</span><span class="p">(</span><span class="n">detector</span><span class="p">):</span> + <span class="c1"># type: (Dict[str, Any]) -> None</span> + <span class="c1"># Reimplementation of find_min_max_d from libcrystfel/src/detector.c.</span> + <span class="n">min_d</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="s2">"inf"</span><span class="p">)</span> + <span class="n">max_d</span> <span class="o">=</span> <span class="mf">0.0</span> + <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">panel</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> + <span class="n">min_d</span><span class="p">,</span> <span class="n">max_d</span> <span class="o">=</span> <span class="n">_check_point</span><span class="p">(</span> + <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span> + <span class="n">panel</span><span class="o">=</span><span class="n">panel</span><span class="p">,</span> + <span class="n">fs_</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> + <span class="n">ss_</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> + <span class="n">min_d</span><span class="o">=</span><span class="n">min_d</span><span class="p">,</span> + <span class="n">max_d</span><span class="o">=</span><span class="n">max_d</span><span class="p">,</span> + <span class="n">detector</span><span class="o">=</span><span class="n">detector</span><span class="p">,</span> + <span class="p">)</span> + <span class="n">min_d</span><span class="p">,</span> <span class="n">max_d</span> <span class="o">=</span> <span class="n">_check_point</span><span class="p">(</span> + <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span> + <span class="n">panel</span><span class="o">=</span><span class="n">panel</span><span class="p">,</span> + <span class="n">fs_</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"w"</span><span class="p">],</span> + <span class="n">ss_</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> + <span class="n">min_d</span><span class="o">=</span><span class="n">min_d</span><span class="p">,</span> + <span class="n">max_d</span><span class="o">=</span><span class="n">max_d</span><span class="p">,</span> + <span class="n">detector</span><span class="o">=</span><span class="n">detector</span><span class="p">,</span> + <span class="p">)</span> + <span class="n">min_d</span><span class="p">,</span> <span class="n">max_d</span> <span class="o">=</span> <span class="n">_check_point</span><span class="p">(</span> + <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span> + <span class="n">panel</span><span class="o">=</span><span class="n">panel</span><span class="p">,</span> + <span class="n">fs_</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> + <span class="n">ss_</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"h"</span><span class="p">],</span> + <span class="n">min_d</span><span class="o">=</span><span class="n">min_d</span><span class="p">,</span> + <span class="n">max_d</span><span class="o">=</span><span class="n">max_d</span><span class="p">,</span> + <span class="n">detector</span><span class="o">=</span><span class="n">detector</span><span class="p">,</span> + <span class="p">)</span> + <span class="n">min_d</span><span class="p">,</span> <span class="n">max_d</span> <span class="o">=</span> <span class="n">_check_point</span><span class="p">(</span> + <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span> + <span class="n">panel</span><span class="o">=</span><span class="n">panel</span><span class="p">,</span> + <span class="n">fs_</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"w"</span><span class="p">],</span> + <span class="n">ss_</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"h"</span><span class="p">],</span> + <span class="n">min_d</span><span class="o">=</span><span class="n">min_d</span><span class="p">,</span> + <span class="n">max_d</span><span class="o">=</span><span class="n">max_d</span><span class="p">,</span> + <span class="n">detector</span><span class="o">=</span><span class="n">detector</span><span class="p">,</span> + <span class="p">)</span> + + +<div class="viewcode-block" id="load_crystfel_geometry"><a class="viewcode-back" href="../../cfelpyutils.crystfel_utils.html#cfelpyutils.crystfel_utils.load_crystfel_geometry">[docs]</a><span class="k">def</span> <span class="nf">load_crystfel_geometry</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span> + <span class="c1"># type: (str) -> Dict[str, Any]</span> + <span class="sd">"""</span> +<span class="sd"> Loads a CrystFEL geometry file.</span> + +<span class="sd"> This function is a reimplementation of the get_detector_geometry_2 function from</span> +<span class="sd"> CrystFEL. It reads information from a CrystFEL geometry file.</span> +<span class="sd"> </span> +<span class="sd"> For a full documentation of the CrystFEL geometry format, see the relevant `man</span> +<span class="sd"> page <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html>`_.</span> + +<span class="sd"> The function returns a dictionary with the geometry information.</span> + +<span class="sd"> * The CrystFEL geometry file uses a key/value language. The keys in the returned</span> +<span class="sd"> dictionary match the keys in the geometry file.</span> + +<span class="sd"> * The dictionary values store the corresponding values.</span> + +<span class="sd"> * The code of this function is currently synchronized with the code of the function</span> +<span class="sd"> 'get_detector_geometry_2' in CrystFEL at commit 41a8fa9819010.</span> + +<span class="sd"> </span> +<span class="sd"> Arguments:</span> + +<span class="sd"> filename (str): the absolute or relative path to a CrystFEL geometry file.</span> + +<span class="sd"> Returns:</span> + +<span class="sd"> Dict[str, Any]: a dictionary with the geometry information loaded from the</span> +<span class="sd"> file.</span> +<span class="sd"> """</span> + <span class="n">beam</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"photon_energy"</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span> <span class="s2">"photon_energy_from"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="s2">"photon_energy_scale"</span><span class="p">:</span> <span class="mi">1</span><span class="p">}</span> + <span class="n">detector</span> <span class="o">=</span> <span class="p">{</span> + <span class="s2">"panels"</span><span class="p">:</span> <span class="n">collections</span><span class="o">.</span><span class="n">OrderedDict</span><span class="p">(),</span> + <span class="s2">"bad"</span><span class="p">:</span> <span class="n">collections</span><span class="o">.</span><span class="n">OrderedDict</span><span class="p">(),</span> + <span class="s2">"mask_good"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> + <span class="s2">"mask_bad"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> + <span class="s2">"rigid_groups"</span><span class="p">:</span> <span class="p">{},</span> + <span class="s2">"rigid_group_collections"</span><span class="p">:</span> <span class="p">{},</span> + <span class="p">}</span> + <span class="n">default_panel</span> <span class="o">=</span> <span class="p">{</span> + <span class="s2">"cnx"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"cny"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"clen"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"coffset"</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="s2">"res"</span><span class="p">:</span> <span class="o">-</span><span class="mf">1.0</span><span class="p">,</span> + <span class="s2">"badrow"</span><span class="p">:</span> <span class="s2">"-"</span><span class="p">,</span> + <span class="s2">"no_index"</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span> + <span class="s2">"fsx"</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> + <span class="s2">"fsy"</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="s2">"fsz"</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="s2">"ssx"</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="s2">"ssy"</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> + <span class="s2">"ssz"</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="s2">"rail_x"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"rail_y"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"rail_z"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"clen_for_centering"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"adu_per_eV"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"adu_per_photon"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"max_adu"</span><span class="p">:</span> <span class="nb">float</span><span class="p">(</span><span class="s2">"inf"</span><span class="p">),</span> + <span class="s2">"mask"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"mask_file"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"satmap"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"satmap_file"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"data"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"dim_structure"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="p">}</span> + <span class="n">default_bad_region</span> <span class="o">=</span> <span class="p">{</span> + <span class="s2">"min_x"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"max_x"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"min_y"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"max_y"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"min_fs"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> + <span class="s2">"max_fs"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> + <span class="s2">"min_ss"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> + <span class="s2">"max_ss"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> + <span class="s2">"is_fsss"</span><span class="p">:</span> <span class="mi">99</span><span class="p">,</span> + <span class="p">}</span> + <span class="n">default_dim</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"ss"</span><span class="p">,</span> <span class="s2">"fs"</span><span class="p">]</span> + + <span class="n">fhandle</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s2">"r"</span><span class="p">)</span> + <span class="n">fhlines</span> <span class="o">=</span> <span class="n">fhandle</span><span class="o">.</span><span class="n">readlines</span><span class="p">()</span> + <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">fhlines</span><span class="p">:</span> + <span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">";"</span><span class="p">):</span> + <span class="k">continue</span> + <span class="n">line_without_comments</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">";"</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> + <span class="n">line_items</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">pattern</span><span class="o">=</span><span class="s2">"([ </span><span class="se">\t</span><span class="s2">])"</span><span class="p">,</span> <span class="n">string</span><span class="o">=</span><span class="n">line_without_comments</span><span class="p">)</span> + <span class="n">line_items</span> <span class="o">=</span> <span class="p">[</span><span class="n">item</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">line_items</span> <span class="k">if</span> <span class="n">item</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">""</span><span class="p">,</span> <span class="s2">" "</span><span class="p">,</span> <span class="s2">"</span><span class="se">\t</span><span class="s2">"</span><span class="p">)]</span> + <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">line_items</span><span class="p">)</span> <span class="o"><</span> <span class="mi">3</span><span class="p">:</span> + <span class="k">continue</span> + <span class="n">value</span> <span class="o">=</span> <span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">line_items</span><span class="p">[</span><span class="mi">2</span><span class="p">:])</span> + <span class="k">if</span> <span class="n">line_items</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="s2">"="</span><span class="p">:</span> + <span class="k">continue</span> + <span class="n">path</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"(/)"</span><span class="p">,</span> <span class="n">line_items</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> + <span class="n">path</span> <span class="o">=</span> <span class="p">[</span><span class="n">item</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">path</span> <span class="k">if</span> <span class="n">item</span> <span class="ow">not</span> <span class="ow">in</span> <span class="s2">"/"</span><span class="p">]</span> + <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> <span class="o"><</span> <span class="mi">2</span><span class="p">:</span> + <span class="n">_parse_toplevel</span><span class="p">(</span> + <span class="n">key</span><span class="o">=</span><span class="n">line_items</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> + <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> + <span class="n">detector</span><span class="o">=</span><span class="n">detector</span><span class="p">,</span> + <span class="n">beam</span><span class="o">=</span><span class="n">beam</span><span class="p">,</span> + <span class="n">panel</span><span class="o">=</span><span class="n">default_panel</span><span class="p">,</span> + <span class="p">)</span> + <span class="k">continue</span> + <span class="n">curr_bad</span> <span class="o">=</span> <span class="kc">None</span> + <span class="n">curr_panel</span> <span class="o">=</span> <span class="kc">None</span> + <span class="k">if</span> <span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"bad"</span><span class="p">):</span> + <span class="k">if</span> <span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"bad"</span><span class="p">]:</span> + <span class="n">curr_bad</span> <span class="o">=</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"bad"</span><span class="p">][</span><span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">curr_bad</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">default_bad_region</span><span class="p">)</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"bad"</span><span class="p">][</span><span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="n">curr_bad</span> + <span class="k">else</span><span class="p">:</span> + <span class="k">if</span> <span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]:</span> + <span class="n">curr_panel</span> <span class="o">=</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">curr_panel</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">default_panel</span><span class="p">)</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="n">curr_panel</span> + <span class="k">if</span> <span class="n">curr_panel</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">_parse_field_for_panel</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">path</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> <span class="n">panel</span><span class="o">=</span><span class="n">curr_panel</span><span class="p">)</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">_parse_field_bad</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">path</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> <span class="n">bad</span><span class="o">=</span><span class="n">curr_bad</span><span class="p">)</span> + <span class="k">if</span> <span class="ow">not</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"No panel descriptions in geometry file."</span><span class="p">)</span> + <span class="n">num_placeholders_in_panels</span> <span class="o">=</span> <span class="kc">None</span> + <span class="k">for</span> <span class="n">panel</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">curr_num_placeholders</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="s2">"%"</span><span class="p">)</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">curr_num_placeholders</span> <span class="o">=</span> <span class="mi">0</span> + + <span class="k">if</span> <span class="n">num_placeholders_in_panels</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">num_placeholders_in_panels</span> <span class="o">=</span> <span class="n">curr_num_placeholders</span> + <span class="k">else</span><span class="p">:</span> + <span class="k">if</span> <span class="n">curr_num_placeholders</span> <span class="o">!=</span> <span class="n">num_placeholders_in_panels</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"All panels' data and mask entries must have the same number of "</span> + <span class="s2">"placeholders."</span> + <span class="p">)</span> + <span class="n">num_placeholders_in_masks</span> <span class="o">=</span> <span class="kc">None</span> + <span class="k">for</span> <span class="n">panel</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"mask"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">curr_num_placeholders</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"mask"</span><span class="p">]</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="s2">"%"</span><span class="p">)</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">curr_num_placeholders</span> <span class="o">=</span> <span class="mi">0</span> + + <span class="k">if</span> <span class="n">num_placeholders_in_masks</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">num_placeholders_in_masks</span> <span class="o">=</span> <span class="n">curr_num_placeholders</span> + <span class="k">else</span><span class="p">:</span> + <span class="k">if</span> <span class="n">curr_num_placeholders</span> <span class="o">!=</span> <span class="n">num_placeholders_in_masks</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"All panels' data and mask entries must have the same number of "</span> + <span class="s2">"placeholders."</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">num_placeholders_in_masks</span> <span class="o">></span> <span class="n">num_placeholders_in_panels</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Number of placeholders in mask cannot be larger the number than for data."</span> + <span class="p">)</span> + <span class="n">dim_length</span> <span class="o">=</span> <span class="kc">None</span> + <span class="k">for</span> <span class="n">panel_name</span><span class="p">,</span> <span class="n">panel</span> <span class="ow">in</span> <span class="n">viewitems</span><span class="p">(</span><span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]):</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">default_dim</span><span class="p">)</span> + + <span class="n">found_ss</span> <span class="o">=</span> <span class="mi">0</span> + <span class="n">found_fs</span> <span class="o">=</span> <span class="mi">0</span> + <span class="n">found_placeholder</span> <span class="o">=</span> <span class="mi">0</span> + <span class="k">for</span> <span class="n">dim_index</span><span class="p">,</span> <span class="n">entry</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]):</span> + <span class="k">if</span> <span class="n">entry</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Dimension </span><span class="si">{}</span><span class="s2"> for panel </span><span class="si">{}</span><span class="s2"> is undefined."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">dim_index</span><span class="p">,</span> <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">elif</span> <span class="n">entry</span> <span class="o">==</span> <span class="s2">"ss"</span><span class="p">:</span> + <span class="n">found_ss</span> <span class="o">+=</span> <span class="mi">1</span> + <span class="k">elif</span> <span class="n">entry</span> <span class="o">==</span> <span class="s2">"fs"</span><span class="p">:</span> + <span class="n">found_fs</span> <span class="o">+=</span> <span class="mi">1</span> + <span class="k">elif</span> <span class="n">entry</span> <span class="o">==</span> <span class="s2">"%"</span><span class="p">:</span> + <span class="n">found_placeholder</span> <span class="o">+=</span> <span class="mi">1</span> + <span class="k">if</span> <span class="n">found_ss</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Exactly one slow scan dim coordinate is needed (found </span><span class="si">{}</span><span class="s2"> for panel "</span> + <span class="s2">"</span><span class="si">{}</span><span class="s2">)."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">found_ss</span><span class="p">,</span> <span class="n">panel_name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">found_fs</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Exactly one fast scan dim coordinate is needed (found </span><span class="si">{}</span><span class="s2"> for panel "</span> + <span class="s2">"</span><span class="si">{}</span><span class="s2">)."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">found_fs</span><span class="p">,</span> <span class="n">panel_name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">found_placeholder</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Only one placeholder dim coordinate is allowed. Maximum one "</span> + <span class="s2">"placeholder dim coordinate is allowed (found </span><span class="si">{}</span><span class="s2"> for panel </span><span class="si">{}</span><span class="s2">)"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">found_placeholder</span><span class="p">,</span> <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">dim_length</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">dim_length</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">])</span> + <span class="k">elif</span> <span class="n">dim_length</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]):</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Number of dim coordinates must be the same for all panels."</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">dim_length</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Number of dim coordinates must be at least two."</span><span class="p">)</span> + <span class="k">for</span> <span class="n">panel_name</span><span class="p">,</span> <span class="n">panel</span> <span class="ow">in</span> <span class="n">viewitems</span><span class="p">(</span><span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]):</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_min_fs"</span><span class="p">]</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the minimum fs coordinate for panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_max_fs"</span><span class="p">]</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the maximum fs coordinate for panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_min_ss"</span><span class="p">]</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the minimum ss coordinate for panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_max_ss"</span><span class="p">]</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the maximum ss coordinate for panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"cnx"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the corner X coordinate for panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"clen"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_from"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the camera length for panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">panel_name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"res"</span><span class="p">]</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the resolution or panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">panel_name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"adu_per_eV"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"adu_per_photon"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify either adu_per_eV or adu_per_photon for panel "</span> + <span class="s2">"</span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">panel_name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_for_centering"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_x"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"You must specify clen_for_centering if you specify the rail "</span> + <span class="s2">"direction (panel </span><span class="si">{}</span><span class="s2">)"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">panel_name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_x"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_x"</span><span class="p">]</span> <span class="o">=</span> <span class="mf">0.0</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_y"</span><span class="p">]</span> <span class="o">=</span> <span class="mf">0.0</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_z"</span><span class="p">]</span> <span class="o">=</span> <span class="mf">1.0</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_for_centering"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_for_centering"</span><span class="p">]</span> <span class="o">=</span> <span class="mf">0.0</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"w"</span><span class="p">]</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_max_fs"</span><span class="p">]</span> <span class="o">-</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_min_fs"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"h"</span><span class="p">]</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_max_ss"</span><span class="p">]</span> <span class="o">-</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_min_ss"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span> + <span class="k">for</span> <span class="n">bad_region_name</span><span class="p">,</span> <span class="n">bad_region</span> <span class="ow">in</span> <span class="n">viewitems</span><span class="p">(</span><span class="n">detector</span><span class="p">[</span><span class="s2">"bad"</span><span class="p">]):</span> + <span class="k">if</span> <span class="n">bad_region</span><span class="p">[</span><span class="s2">"is_fsss"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">99</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the coordinate ranges for bad region </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">bad_region_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">for</span> <span class="n">group</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_groups"</span><span class="p">]:</span> + <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_groups"</span><span class="p">][</span><span class="n">group</span><span class="p">]:</span> + <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Cannot add panel to rigid_group. Panel not found: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">for</span> <span class="n">group_collection</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_group_collections"</span><span class="p">]:</span> + <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_group_collections"</span><span class="p">][</span><span class="n">group_collection</span><span class="p">]:</span> + <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_groups"</span><span class="p">]:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Cannot add rigid_group to collection. Rigid group not "</span> + <span class="s2">"found: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">for</span> <span class="n">panel</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> + <span class="n">d__</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsx"</span><span class="p">]</span> <span class="o">*</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssy"</span><span class="p">]</span> <span class="o">-</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssx"</span><span class="p">]</span> <span class="o">*</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsy"</span><span class="p">]</span> + <span class="k">if</span> <span class="n">d__</span> <span class="o">==</span> <span class="mf">0.0</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Panel </span><span class="si">{}</span><span class="s2"> transformation is singluar."</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"xfs"</span><span class="p">]</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssy"</span><span class="p">]</span> <span class="o">/</span> <span class="n">d__</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"yfs"</span><span class="p">]</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssx"</span><span class="p">]</span> <span class="o">/</span> <span class="n">d__</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"xss"</span><span class="p">]</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsy"</span><span class="p">]</span> <span class="o">/</span> <span class="n">d__</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"yss"</span><span class="p">]</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsx"</span><span class="p">]</span> <span class="o">/</span> <span class="n">d__</span> + <span class="n">_find_min_max_d</span><span class="p">(</span><span class="n">detector</span><span class="p">)</span> + <span class="n">fhandle</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> + + <span class="k">return</span> <span class="n">detector</span></div> +</pre></div> + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="../../index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="../../cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="../../index.html">Documentation overview</a><ul> + <li><a href="../index.html">Module code</a><ul> + </ul></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="../../search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs/_modules/cfelpyutils/geometry_utils.html b/docs/_modules/cfelpyutils/geometry_utils.html new file mode 100644 index 0000000..479e596 --- /dev/null +++ b/docs/_modules/cfelpyutils/geometry_utils.html @@ -0,0 +1,321 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>cfelpyutils.geometry_utils — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script> + <script type="text/javascript" src="../../_static/jquery.js"></script> + <script type="text/javascript" src="../../_static/underscore.js"></script> + <script type="text/javascript" src="../../_static/doctools.js"></script> + <script type="text/javascript" src="../../_static/language_data.js"></script> + <link rel="index" title="Index" href="../../genindex.html" /> + <link rel="search" title="Search" href="../../search.html" /> + + <link rel="stylesheet" href="../../_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <h1>Source code for cfelpyutils.geometry_utils</h1><div class="highlight"><pre> +<span></span><span class="c1"># This file is part of CFELPyUtils.</span> +<span class="c1">#</span> +<span class="c1"># CFELPyUtils is free software: you can redistribute it and/or modify it under the</span> +<span class="c1"># terms of the GNU General Public License as published by the Free Software Foundation,</span> +<span class="c1"># either version 3 of the License, or (at your option) any later version.</span> +<span class="c1">#</span> +<span class="c1"># CFELPyUtils is distributed in the hope that it will be useful, but WITHOUT ANY</span> +<span class="c1"># WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A</span> +<span class="c1"># PARTICULAR PURPOSE. See the GNU General Public License for more details.</span> +<span class="c1">#</span> +<span class="c1"># You should have received a copy of the GNU General Public License along with OnDA. If</span> +<span class="c1"># not, see <http://www.gnu.org/licenses/>.</span> +<span class="c1">#</span> +<span class="c1"># Copyright 2014-2019 Deutsches Elektronen-Synchrotron DESY,</span> +<span class="c1"># a research centre of the Helmholtz Association.</span> +<span class="sd">"""</span> +<span class="sd">Geometry utilities.</span> + +<span class="sd">This module contains functions that manipulate geometry information.</span> +<span class="sd">"""</span> +<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span><span class="p">,</span> <span class="n">division</span><span class="p">,</span> <span class="n">print_function</span> + +<span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Tuple</span> <span class="c1"># pylint: disable=unused-import</span> + +<span class="kn">import</span> <span class="nn">numpy</span> + +<span class="kn">from</span> <span class="nn">cfelpyutils</span> <span class="k">import</span> <span class="n">named_tuples</span> + + +<div class="viewcode-block" id="compute_pix_maps"><a class="viewcode-back" href="../../cfelpyutils.geometry_utils.html#cfelpyutils.geometry_utils.compute_pix_maps">[docs]</a><span class="k">def</span> <span class="nf">compute_pix_maps</span><span class="p">(</span><span class="n">geometry</span><span class="p">):</span> + <span class="c1"># type: (Dict[str, Any]) -> PixelMaps</span> + <span class="sd">"""</span> +<span class="sd"> Computes pixel maps from CrystFEL geometry information.</span> + +<span class="sd"> This function takes as input some geometry information read from a `CrystFEL</span> +<span class="sd"> <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html>`_ file, and</span> +<span class="sd"> returns a set of some pre-computed pixel maps.</span> + +<span class="sd"> The origin and the orientation of the reference system for the pixel maps follow</span> +<span class="sd"> the same conventions as in CrystFEL:</span> + +<span class="sd"> * The center of the reference system is the beam interaction point.</span> + +<span class="sd"> * +z is the beam direction, and points along the beam (i.e. away from the source).</span> + +<span class="sd"> * +y points towards the zenith (ceiling).</span> + +<span class="sd"> * +x completes the right-handed coordinate system.</span> + +<span class="sd"> Arguments:</span> + +<span class="sd"> geometry (Dict[str, Any]): a CrystFEL geometry object (A dictionary returned by</span> +<span class="sd"> the :func:`~cfelpyutils.crystfel_utils.load_crystfel_geometry` function).</span> + +<span class="sd"> Returns:</span> + +<span class="sd"> :class:`~cfelpyutils.named_tuples.PixelMaps`: a named tuple storing the the</span> +<span class="sd"> pixel maps.</span> +<span class="sd"> """</span> + <span class="n">max_fs_in_slab</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">(</span> + <span class="p">[</span><span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">k</span><span class="p">][</span><span class="s2">"max_fs"</span><span class="p">]</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]]</span> + <span class="p">)</span><span class="o">.</span><span class="n">max</span><span class="p">()</span> + <span class="n">max_ss_in_slab</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">(</span> + <span class="p">[</span><span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">k</span><span class="p">][</span><span class="s2">"max_ss"</span><span class="p">]</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]]</span> + <span class="p">)</span><span class="o">.</span><span class="n">max</span><span class="p">()</span> + + <span class="n">x_map</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span> + <span class="n">shape</span><span class="o">=</span><span class="p">(</span><span class="n">max_ss_in_slab</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">max_fs_in_slab</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">float32</span> + <span class="p">)</span> + <span class="n">y_map</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span> + <span class="n">shape</span><span class="o">=</span><span class="p">(</span><span class="n">max_ss_in_slab</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">max_fs_in_slab</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">float32</span> + <span class="p">)</span> + <span class="n">z_map</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span> + <span class="n">shape</span><span class="o">=</span><span class="p">(</span><span class="n">max_ss_in_slab</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">max_fs_in_slab</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">float32</span> + <span class="p">)</span> + + <span class="c1"># Iterates over the panels. For each panel, determines the pixel indices, then</span> + <span class="c1"># computes the x,y vectors. Finally, copies the panel pixel maps into the</span> + <span class="c1"># detector-wide pixel maps.</span> + <span class="k">for</span> <span class="n">pan</span> <span class="ow">in</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]:</span> + + <span class="k">if</span> <span class="s2">"clen"</span> <span class="ow">in</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">]:</span> + <span class="n">pan_clen</span> <span class="o">=</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"clen"</span><span class="p">]</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">pan_clen</span> <span class="o">=</span> <span class="mf">0.0</span> + + <span class="n">ss_grid</span><span class="p">,</span> <span class="n">fs_grid</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">meshgrid</span><span class="p">(</span> + <span class="n">numpy</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_ss"</span><span class="p">]</span> + <span class="o">-</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_ss"</span><span class="p">]</span> + <span class="o">+</span> <span class="mi">1</span> + <span class="p">),</span> + <span class="n">numpy</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_fs"</span><span class="p">]</span> + <span class="o">-</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_fs"</span><span class="p">]</span> + <span class="o">+</span> <span class="mi">1</span> + <span class="p">),</span> + <span class="n">indexing</span><span class="o">=</span><span class="s2">"ij"</span><span class="p">,</span> + <span class="p">)</span> + <span class="n">y_panel</span> <span class="o">=</span> <span class="p">(</span> + <span class="n">ss_grid</span> <span class="o">*</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"ssy"</span><span class="p">]</span> + <span class="o">+</span> <span class="n">fs_grid</span> <span class="o">*</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"fsy"</span><span class="p">]</span> + <span class="o">+</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"cny"</span><span class="p">]</span> + <span class="p">)</span> + <span class="n">x_panel</span> <span class="o">=</span> <span class="p">(</span> + <span class="n">ss_grid</span> <span class="o">*</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"ssx"</span><span class="p">]</span> + <span class="o">+</span> <span class="n">fs_grid</span> <span class="o">*</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"fsx"</span><span class="p">]</span> + <span class="o">+</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"cnx"</span><span class="p">]</span> + <span class="p">)</span> + <span class="n">x_map</span><span class="p">[</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_ss"</span><span class="p">]</span> <span class="p">:</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_ss"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_fs"</span><span class="p">]</span> <span class="p">:</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_fs"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> + <span class="p">]</span> <span class="o">=</span> <span class="n">x_panel</span> + <span class="n">y_map</span><span class="p">[</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_ss"</span><span class="p">]</span> <span class="p">:</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_ss"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_fs"</span><span class="p">]</span> <span class="p">:</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_fs"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> + <span class="p">]</span> <span class="o">=</span> <span class="n">y_panel</span> + <span class="n">z_map</span><span class="p">[</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_ss"</span><span class="p">]</span> <span class="p">:</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_ss"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_fs"</span><span class="p">]</span> <span class="p">:</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_fs"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> + <span class="p">]</span> <span class="o">=</span> <span class="n">pan_clen</span> + + <span class="n">r_map</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">numpy</span><span class="o">.</span><span class="n">square</span><span class="p">(</span><span class="n">x_map</span><span class="p">)</span> <span class="o">+</span> <span class="n">numpy</span><span class="o">.</span><span class="n">square</span><span class="p">(</span><span class="n">y_map</span><span class="p">))</span> + <span class="n">phi_map</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">arctan2</span><span class="p">(</span><span class="n">y_map</span><span class="p">,</span> <span class="n">x_map</span><span class="p">)</span> + + <span class="k">return</span> <span class="n">named_tuples</span><span class="o">.</span><span class="n">PixelMaps</span><span class="p">(</span><span class="n">x_map</span><span class="p">,</span> <span class="n">y_map</span><span class="p">,</span> <span class="n">z_map</span><span class="p">,</span> <span class="n">r_map</span><span class="p">,</span> <span class="n">phi_map</span><span class="p">)</span></div> + + +<div class="viewcode-block" id="compute_visualization_pix_maps"><a class="viewcode-back" href="../../cfelpyutils.geometry_utils.html#cfelpyutils.geometry_utils.compute_visualization_pix_maps">[docs]</a><span class="k">def</span> <span class="nf">compute_visualization_pix_maps</span><span class="p">(</span><span class="n">geometry</span><span class="p">):</span> + <span class="c1"># type: (Dict[str, Any]) -> PixelMaps</span> + <span class="sd">"""</span> +<span class="sd"> Computes pixel maps for data visualization from CrystFEL geometry information.</span> + +<span class="sd"> This function takes as input some geometry information read from a `CrystFEL</span> +<span class="sd"> <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html>`_ file, and</span> +<span class="sd"> returns a set of some pre-computed pixel maps that can be used to display data in</span> +<span class="sd"> an ImageView widget from the `PyQtGraph <http://pyqtgraph.org/>`_ library.</span> + +<span class="sd"> These pixel maps are different from the ones generated by the</span> +<span class="sd"> :func:`~compute_pix_maps` function. The main differences are:</span> + +<span class="sd"> * The origin of the reference system is not the beam interaction point, but the top</span> +<span class="sd"> left corner of the array used to visualize the data.</span> + +<span class="sd"> * Only the x and y pixel maps are available. The other entries in the named tuple</span> +<span class="sd"> (z, r and phi) are set to None.</span> + +<span class="sd"> Arguments:</span> + +<span class="sd"> geometry (Dict[str, Any]): a CrystFEL geometry object (A dictionary returned by</span> +<span class="sd"> the :func:`~cfelpyutils.crystfel_utils.load_crystfel_geometry` function).</span> + +<span class="sd"> Returns:</span> + +<span class="sd"> :class:`PixelMaps`: a named tuple with the pixel maps.</span> +<span class="sd"> """</span> + <span class="c1"># Shifts the origin of the reference system from the beam position to the top-left</span> + <span class="c1"># of the image that will be displayed. Computes the size of the array needed to</span> + <span class="c1"># display the data, then use this information to estimate the magnitude of the</span> + <span class="c1"># shift.</span> + <span class="n">pixel_maps</span> <span class="o">=</span> <span class="n">compute_pix_maps</span><span class="p">(</span><span class="n">geometry</span><span class="p">)</span> + <span class="n">x_map</span><span class="p">,</span> <span class="n">y_map</span> <span class="o">=</span> <span class="n">pixel_maps</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">pixel_maps</span><span class="o">.</span><span class="n">y</span> + <span class="n">y_minimum</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="nb">int</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">y_map</span><span class="o">.</span><span class="n">max</span><span class="p">()),</span> <span class="nb">abs</span><span class="p">(</span><span class="n">y_map</span><span class="o">.</span><span class="n">min</span><span class="p">())))</span> <span class="o">+</span> <span class="mi">2</span> + <span class="n">x_minimum</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="nb">int</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">x_map</span><span class="o">.</span><span class="n">max</span><span class="p">()),</span> <span class="nb">abs</span><span class="p">(</span><span class="n">x_map</span><span class="o">.</span><span class="n">min</span><span class="p">())))</span> <span class="o">+</span> <span class="mi">2</span> + <span class="n">min_shape</span> <span class="o">=</span> <span class="p">(</span><span class="n">y_minimum</span><span class="p">,</span> <span class="n">x_minimum</span><span class="p">)</span> + <span class="n">new_x_map</span> <span class="o">=</span> <span class="p">(</span> + <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="nb">object</span><span class="o">=</span><span class="n">pixel_maps</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">int</span><span class="p">)</span> <span class="o">+</span> <span class="n">min_shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">//</span> <span class="mi">2</span> <span class="o">-</span> <span class="mi">1</span> + <span class="p">)</span> + <span class="n">new_y_map</span> <span class="o">=</span> <span class="p">(</span> + <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="nb">object</span><span class="o">=</span><span class="n">pixel_maps</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">int</span><span class="p">)</span> <span class="o">+</span> <span class="n">min_shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">//</span> <span class="mi">2</span> <span class="o">-</span> <span class="mi">1</span> + <span class="p">)</span> + <span class="k">return</span> <span class="n">named_tuples</span><span class="o">.</span><span class="n">PixelMaps</span><span class="p">(</span><span class="n">new_x_map</span><span class="p">,</span> <span class="n">new_y_map</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span></div> + + +<div class="viewcode-block" id="apply_geometry_to_data"><a class="viewcode-back" href="../../cfelpyutils.geometry_utils.html#cfelpyutils.geometry_utils.apply_geometry_to_data">[docs]</a><span class="k">def</span> <span class="nf">apply_geometry_to_data</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">geometry</span><span class="p">):</span> + <span class="c1"># type: (numpy.ndarray, Dict[str, Any]) -> numpy.ndarray</span> + <span class="sd">"""</span> +<span class="sd"> Applies CrystFEL geometry information to some data.</span> + +<span class="sd"> This function takes as input some geometry information read from a `CrystFEL</span> +<span class="sd"> <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html>`_ file, and</span> +<span class="sd"> some data on which to apply it. It returns an array that can be displayed using a</span> +<span class="sd"> library like `matplotlib <https://matplotlib.org/>`_ or </span> +<span class="sd"> `PyQtGraph <http://pyqtgraph.org/>`_.</span> + +<span class="sd"> The shape of the returned array is big enough to display all the input pixel</span> +<span class="sd"> values, and is symmetric around the center of the reference system (i.e: the beam</span> +<span class="sd"> interaction point).</span> + +<span class="sd"> NOTE: This restrictions often cause the returned array to be bigger than the minimum</span> +<span class="sd"> size needed to store the physical layout of the pixels in the detector,</span> +<span class="sd"> particularly if the detector is not centered at the beam interaction point.</span> + +<span class="sd"> Arguments:</span> + +<span class="sd"> data (numpy.ndarray): the data on which the geometry information should be</span> +<span class="sd"> applied.</span> + +<span class="sd"> geometry (Dict[str, Any]): a CrystFEL geometry object (A dictionary returned by</span> +<span class="sd"> the :func:`~cfelpyutils.crystfel_utils.load_crystfel_geometry` function).</span> + +<span class="sd"> Returns:</span> + +<span class="sd"> numpy.ndarray: an array containing the data with the geometry information</span> +<span class="sd"> applied. </span> +<span class="sd"> """</span> + <span class="n">pixel_maps</span> <span class="o">=</span> <span class="n">compute_pix_maps</span><span class="p">(</span><span class="n">geometry</span><span class="p">)</span> + <span class="n">x_map</span><span class="p">,</span> <span class="n">y_map</span> <span class="o">=</span> <span class="n">pixel_maps</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">pixel_maps</span><span class="o">.</span><span class="n">y</span> + <span class="n">y_minimum</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="nb">int</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">y_map</span><span class="o">.</span><span class="n">max</span><span class="p">()),</span> <span class="nb">abs</span><span class="p">(</span><span class="n">y_map</span><span class="o">.</span><span class="n">min</span><span class="p">())))</span> <span class="o">+</span> <span class="mi">2</span> + <span class="n">x_minimum</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="nb">int</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">x_map</span><span class="o">.</span><span class="n">max</span><span class="p">()),</span> <span class="nb">abs</span><span class="p">(</span><span class="n">x_map</span><span class="o">.</span><span class="n">min</span><span class="p">())))</span> <span class="o">+</span> <span class="mi">2</span> + <span class="n">min_shape</span> <span class="o">=</span> <span class="p">(</span><span class="n">y_minimum</span><span class="p">,</span> <span class="n">x_minimum</span><span class="p">)</span> + <span class="n">visualization_array</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span><span class="n">min_shape</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">float</span><span class="p">)</span> + <span class="n">visual_pixel_maps</span> <span class="o">=</span> <span class="n">compute_visualization_pix_maps</span><span class="p">(</span><span class="n">geometry</span><span class="p">)</span> + <span class="n">visualization_array</span><span class="p">[</span> + <span class="n">visual_pixel_maps</span><span class="o">.</span><span class="n">y</span><span class="o">.</span><span class="n">flatten</span><span class="p">(),</span> <span class="n">visual_pixel_maps</span><span class="o">.</span><span class="n">x</span><span class="o">.</span><span class="n">flatten</span><span class="p">()</span> + <span class="p">]</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">ravel</span><span class="p">()</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">visualization_array</span><span class="o">.</span><span class="n">dtype</span><span class="p">)</span> + <span class="k">return</span> <span class="n">visualization_array</span></div> +</pre></div> + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="../../index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="../../cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="../../index.html">Documentation overview</a><ul> + <li><a href="../index.html">Module code</a><ul> + </ul></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="../../search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs/_modules/cfelpyutils/named_tuples.html b/docs/_modules/cfelpyutils/named_tuples.html new file mode 100644 index 0000000..7649063 --- /dev/null +++ b/docs/_modules/cfelpyutils/named_tuples.html @@ -0,0 +1,145 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>cfelpyutils.named_tuples — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script> + <script type="text/javascript" src="../../_static/jquery.js"></script> + <script type="text/javascript" src="../../_static/underscore.js"></script> + <script type="text/javascript" src="../../_static/doctools.js"></script> + <script type="text/javascript" src="../../_static/language_data.js"></script> + <link rel="index" title="Index" href="../../genindex.html" /> + <link rel="search" title="Search" href="../../search.html" /> + + <link rel="stylesheet" href="../../_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <h1>Source code for cfelpyutils.named_tuples</h1><div class="highlight"><pre> +<span></span><span class="c1"># This file is part of CFELPyUtils.</span> +<span class="c1">#</span> +<span class="c1"># CFELPyUtils is free software: you can redistribute it and/or modify it under the</span> +<span class="c1"># terms of the GNU General Public License as published by the Free Software Foundation,</span> +<span class="c1"># either version 3 of the License, or (at your option) any later version.</span> +<span class="c1">#</span> +<span class="c1"># CFELPyUtils is distributed in the hope that it will be useful, but WITHOUT ANY</span> +<span class="c1"># WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A</span> +<span class="c1"># PARTICULAR PURPOSE. See the GNU General Public License for more details.</span> +<span class="c1">#</span> +<span class="c1"># You should have received a copy of the GNU General Public License along with OnDA. If</span> +<span class="c1"># not, see <http://www.gnu.org/licenses/>.</span> +<span class="c1">#</span> +<span class="c1"># Copyright 2014-2019 Deutsches Elektronen-Synchrotron DESY,</span> +<span class="c1"># a research centre of the Helmholtz Association.</span> +<span class="sd">"""</span> +<span class="sd">CFELPyUtils named tuples.</span> + +<span class="sd">This module contains a collection of named tuples used throughout the CFELPyUtils</span> +<span class="sd">library.</span> +<span class="sd">"""</span> +<span class="kn">import</span> <span class="nn">collections</span> + +<span class="n">PixelMaps</span> <span class="o">=</span> <span class="n">collections</span><span class="o">.</span><span class="n">namedtuple</span><span class="p">(</span><span class="s2">"PixelMaps"</span><span class="p">,</span> <span class="p">[</span><span class="s2">"x"</span><span class="p">,</span> <span class="s2">"y"</span><span class="p">,</span> <span class="s2">"z"</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">,</span> <span class="s2">"phi"</span><span class="p">])</span> +<span class="sd">"""</span> +<span class="sd">Pixel maps that store geometry information.</span> + +<span class="sd">Arguments:</span> + +<span class="sd"> x (numpy.ndarray): pixel map for the x coordinate.</span> + +<span class="sd"> y (numpy.ndarray): pixel map for the y coordinate.</span> + +<span class="sd"> z (numpy.ndarray): pixel map for the z coordinate.</span> + +<span class="sd"> r (numpy.ndarray): pixel map storing the distance of each pixel from the center of</span> +<span class="sd"> the reference system.</span> + +<span class="sd"> phi (numpy.ndarray): pixel map storing the amplitude of the angle between each</span> +<span class="sd"> pixel, the center of the reference system, and the x axis through the center.</span> +<span class="sd">"""</span> +</pre></div> + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="../../index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="../../cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="../../index.html">Documentation overview</a><ul> + <li><a href="../index.html">Module code</a><ul> + </ul></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="../../search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs/_modules/index.html b/docs/_modules/index.html new file mode 100644 index 0000000..0426bf5 --- /dev/null +++ b/docs/_modules/index.html @@ -0,0 +1,105 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>Overview: module code — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="../_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script> + <script type="text/javascript" src="../_static/jquery.js"></script> + <script type="text/javascript" src="../_static/underscore.js"></script> + <script type="text/javascript" src="../_static/doctools.js"></script> + <script type="text/javascript" src="../_static/language_data.js"></script> + <link rel="index" title="Index" href="../genindex.html" /> + <link rel="search" title="Search" href="../search.html" /> + + <link rel="stylesheet" href="../_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <h1>All modules for which code is available</h1> +<ul><li><a href="cfelpyutils/crystfel_utils.html">cfelpyutils.crystfel_utils</a></li> +<li><a href="cfelpyutils/geometry_utils.html">cfelpyutils.geometry_utils</a></li> +<li><a href="cfelpyutils/named_tuples.html">cfelpyutils.named_tuples</a></li> +</ul> + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="../index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="../cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="../index.html">Documentation overview</a><ul> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="../search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs/_sources/cfelpyutils.crystfel_utils.rst.txt b/docs/_sources/cfelpyutils.crystfel_utils.rst.txt new file mode 100644 index 0000000..8533f9d --- /dev/null +++ b/docs/_sources/cfelpyutils.crystfel_utils.rst.txt @@ -0,0 +1,7 @@ +The crystfel\_utils Module +========================== + +.. automodule:: cfelpyutils.crystfel_utils + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/cfelpyutils.geometry_utils.rst.txt b/docs/_sources/cfelpyutils.geometry_utils.rst.txt new file mode 100644 index 0000000..005d68a --- /dev/null +++ b/docs/_sources/cfelpyutils.geometry_utils.rst.txt @@ -0,0 +1,7 @@ +The geometry\_utils Module +========================== + +.. automodule:: cfelpyutils.geometry_utils + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/cfelpyutils.named_tuples.rst.txt b/docs/_sources/cfelpyutils.named_tuples.rst.txt new file mode 100644 index 0000000..42965bb --- /dev/null +++ b/docs/_sources/cfelpyutils.named_tuples.rst.txt @@ -0,0 +1,7 @@ +The named\_tuples Module +======================== + +.. automodule:: cfelpyutils.named_tuples + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/cfelpyutils.rst.txt b/docs/_sources/cfelpyutils.rst.txt new file mode 100644 index 0000000..9e74d51 --- /dev/null +++ b/docs/_sources/cfelpyutils.rst.txt @@ -0,0 +1,13 @@ +The cfelpyutils Package +======================= + +.. automodule:: cfelpyutils + :members: + :undoc-members: + :show-inheritance: + +.. toctree:: + + crystfel_utils <cfelpyutils.crystfel_utils> + geometry_utils <cfelpyutils.geometry_utils> + named_tuples <cfelpyutils.named_tuples> diff --git a/docs/_sources/index.rst.txt b/docs/_sources/index.rst.txt new file mode 100644 index 0000000..929f41c --- /dev/null +++ b/docs/_sources/index.rst.txt @@ -0,0 +1,53 @@ +.. cfelpyutils documentation master file, created by + sphinx-quickstart on Tue Jul 10 12:10:05 2018. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +CFELPyUtils +=========== + +.. toctree:: + :hidden: + + cfelpyutils + + +Introduction +------------ + +CFELPyUtils is a utility library written in Python and developed at the Center For Free +Electron Laser Science (CFEL) in Hamburg. It contains several functions and classes +that perform various tasks related to the processing of x-ray imaging data (currently, +mostly reading and applying geometry information to x-ray detector data). It is used by +several internal and released CFEL software projects. + + +Installation +------------ + +The CFELPyUtils library is available on PyPI and can be installed using the pip +command: + +.. code-block:: bash + + python3 -m pip install cfelpyutils + +Or, for python2: + +.. code-block:: bash + + python -m pip install cfelpyutils + + +It is also available as an Anaconda package in the 'ondateam' channel. It can be +installed using the 'conda' command: + +.. code-block:: bash + + conda install -c ondateam cfelpyutils + + +Code Documentation +------------------ + +Code documentation for the CFELPyUtils library can be found :doc:`here <cfelpyutils>`. \ No newline at end of file diff --git a/docs/_sources/modules.rst.txt b/docs/_sources/modules.rst.txt new file mode 100644 index 0000000..31f2701 --- /dev/null +++ b/docs/_sources/modules.rst.txt @@ -0,0 +1,7 @@ +cfelpyutils +=========== + +.. toctree:: + :maxdepth: 4 + + cfelpyutils diff --git a/docs/_static/ajax-loader.gif b/docs/_static/ajax-loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..61faf8cab23993bd3e1560bff0668bd628642330 GIT binary patch literal 673 zcmZ?wbhEHb6krfw_{6~Q|Nno%(3)e{?)x>&1u}A`t?OF7Z|1gRivOgXi&7IyQd1Pl zGfOfQ60;I3a`F>X^fL3(@);C=vM_KlFfb_o=k{|A33hf2a5d61U}gjg=>Rd%XaNQW zW@C<Bcm5fi^2`=a=CI<BoWt%nBaPE_qv4@lA~O$e(@QvVsPKYrw1nl|W$cy`JnUZC z&pm)ff{kWGHpc{Hj$e<Wf^-Yd?hVhnTne26LlO)n6%u@0qor2V$ZRdW|29#Ay+Pr+ z#G^K6$xW&%T0&5Rn2-%J<Je`StbNMy#Dp_b!t~i%lV$k6Ncw&BbV{7Dx<KXw*O|?G zWsa@TW{P|({)e&oFu&2t6sh_9S)fKSBO3+uTav2wDWkTDZ{~!>w{|b%Y*pl8F?4B9 zlo4Fz*0kZGJabY|>}Okf0}CCg{u4`zEPY^pV?j2@h+|igy0+Kz6p;@SpM4s6)XEMg z#3Y4GX>Hjlml5ftdH$4x0JGdn8~MX(U~_^d!Hi)=HU{V%g+mi8#UGbE-*ao8f#h+S z2a0-5+vc7MU$e-NhmBjLIC1v|)9+Im8x1yacJ7{^tLX(ZhYi^rpmXm0`@ku9b53aN zEXH@Y3JaztblgpxbJt{AtE1ad1Ca>{v$rwwvK(>{m~Gf_=-Ro7Fk{#;i~+{{>QtvI yb2P8Zac~?~=sRA>$6{!(^3;ZP0TPFR(G_-UDU(8Jl0?(IXu$~#4A!880|o%~Al1tN literal 0 HcmV?d00001 diff --git a/docs/_static/alabaster.css b/docs/_static/alabaster.css new file mode 100644 index 0000000..0eddaeb --- /dev/null +++ b/docs/_static/alabaster.css @@ -0,0 +1,701 @@ +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: Georgia, serif; + font-size: 17px; + background-color: #fff; + color: #000; + margin: 0; + padding: 0; +} + + +div.document { + width: 940px; + margin: 30px auto 0 auto; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 220px; +} + +div.sphinxsidebar { + width: 220px; + font-size: 14px; + line-height: 1.5; +} + +hr { + border: 1px solid #B1B4B6; +} + +div.body { + background-color: #fff; + color: #3E4349; + padding: 0 30px 0 30px; +} + +div.body > .section { + text-align: left; +} + +div.footer { + width: 940px; + margin: 20px auto 30px auto; + font-size: 14px; + color: #888; + text-align: right; +} + +div.footer a { + color: #888; +} + +p.caption { + font-family: inherit; + font-size: inherit; +} + + +div.relations { + display: none; +} + + +div.sphinxsidebar a { + color: #444; + text-decoration: none; + border-bottom: 1px dotted #999; +} + +div.sphinxsidebar a:hover { + border-bottom: 1px solid #999; +} + +div.sphinxsidebarwrapper { + padding: 18px 10px; +} + +div.sphinxsidebarwrapper p.logo { + padding: 0; + margin: -10px 0 0 0px; + text-align: center; +} + +div.sphinxsidebarwrapper h1.logo { + margin-top: -10px; + text-align: center; + margin-bottom: 5px; + text-align: left; +} + +div.sphinxsidebarwrapper h1.logo-name { + margin-top: 0px; +} + +div.sphinxsidebarwrapper p.blurb { + margin-top: 0; + font-style: normal; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4 { + font-family: Georgia, serif; + color: #444; + font-size: 24px; + font-weight: normal; + margin: 0 0 5px 0; + padding: 0; +} + +div.sphinxsidebar h4 { + font-size: 20px; +} + +div.sphinxsidebar h3 a { + color: #444; +} + +div.sphinxsidebar p.logo a, +div.sphinxsidebar h3 a, +div.sphinxsidebar p.logo a:hover, +div.sphinxsidebar h3 a:hover { + border: none; +} + +div.sphinxsidebar p { + color: #555; + margin: 10px 0; +} + +div.sphinxsidebar ul { + margin: 10px 0; + padding: 0; + color: #000; +} + +div.sphinxsidebar ul li.toctree-l1 > a { + font-size: 120%; +} + +div.sphinxsidebar ul li.toctree-l2 > a { + font-size: 110%; +} + +div.sphinxsidebar input { + border: 1px solid #CCC; + font-family: Georgia, serif; + font-size: 1em; +} + +div.sphinxsidebar hr { + border: none; + height: 1px; + color: #AAA; + background: #AAA; + + text-align: left; + margin-left: 0; + width: 50%; +} + +div.sphinxsidebar .badge { + border-bottom: none; +} + +div.sphinxsidebar .badge:hover { + border-bottom: none; +} + +/* To address an issue with donation coming after search */ +div.sphinxsidebar h3.donation { + margin-top: 10px; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #004B6B; + text-decoration: underline; +} + +a:hover { + color: #6D4100; + text-decoration: underline; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: Georgia, serif; + font-weight: normal; + margin: 30px 0px 10px 0px; + padding: 0; +} + +div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } +div.body h2 { font-size: 180%; } +div.body h3 { font-size: 150%; } +div.body h4 { font-size: 130%; } +div.body h5 { font-size: 100%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #DDD; + padding: 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + color: #444; + background: #EAEAEA; +} + +div.body p, div.body dd, div.body li { + line-height: 1.4em; +} + +div.admonition { + margin: 20px 0px; + padding: 10px 30px; + background-color: #EEE; + border: 1px solid #CCC; +} + +div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fafafa; +} + +div.admonition p.admonition-title { + font-family: Georgia, serif; + font-weight: normal; + font-size: 24px; + margin: 0 0 10px 0; + padding: 0; + line-height: 1; +} + +div.admonition p.last { + margin-bottom: 0; +} + +div.highlight { + background-color: #fff; +} + +dt:target, .highlight { + background: #FAF3E8; +} + +div.warning { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.danger { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.error { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.caution { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.attention { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.important { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.note { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.tip { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.hint { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.seealso { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.topic { + background-color: #EEE; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre, tt, code { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; + font-size: 0.9em; +} + +.hll { + background-color: #FFC; + margin: 0 -12px; + padding: 0 12px; + display: block; +} + +img.screenshot { +} + +tt.descname, tt.descclassname, code.descname, code.descclassname { + font-size: 0.95em; +} + +tt.descname, code.descname { + padding-right: 0.08em; +} + +img.screenshot { + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils { + border: 1px solid #888; + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils td, table.docutils th { + border: 1px solid #888; + padding: 0.25em 0.7em; +} + +table.field-list, table.footnote { + border: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +table.footnote { + margin: 15px 0; + width: 100%; + border: 1px solid #EEE; + background: #FDFDFD; + font-size: 0.9em; +} + +table.footnote + table.footnote { + margin-top: -15px; + border-top: none; +} + +table.field-list th { + padding: 0 0.8em 0 0; +} + +table.field-list td { + padding: 0; +} + +table.field-list p { + margin-bottom: 0.8em; +} + +/* Cloned from + * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 + */ +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +table.footnote td.label { + width: .1px; + padding: 0.3em 0 0.3em 0.5em; +} + +table.footnote td { + padding: 0.3em 0.5em; +} + +dl { + margin: 0; + padding: 0; +} + +dl dd { + margin-left: 30px; +} + +blockquote { + margin: 0 0 0 30px; + padding: 0; +} + +ul, ol { + /* Matches the 30px from the narrow-screen "li > ul" selector below */ + margin: 10px 0 10px 30px; + padding: 0; +} + +pre { + background: #EEE; + padding: 7px 30px; + margin: 15px 0px; + line-height: 1.3em; +} + +div.viewcode-block:target { + background: #ffd; +} + +dl pre, blockquote pre, li pre { + margin-left: 0; + padding-left: 30px; +} + +tt, code { + background-color: #ecf0f3; + color: #222; + /* padding: 1px 2px; */ +} + +tt.xref, code.xref, a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fff; +} + +a.reference { + text-decoration: none; + border-bottom: 1px dotted #004B6B; +} + +/* Don't put an underline on images */ +a.image-reference, a.image-reference:hover { + border-bottom: none; +} + +a.reference:hover { + border-bottom: 1px solid #6D4100; +} + +a.footnote-reference { + text-decoration: none; + font-size: 0.7em; + vertical-align: top; + border-bottom: 1px dotted #004B6B; +} + +a.footnote-reference:hover { + border-bottom: 1px solid #6D4100; +} + +a:hover tt, a:hover code { + background: #EEE; +} + + +@media screen and (max-width: 870px) { + + div.sphinxsidebar { + display: none; + } + + div.document { + width: 100%; + + } + + div.documentwrapper { + margin-left: 0; + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + } + + div.bodywrapper { + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + margin-left: 0; + } + + ul { + margin-left: 0; + } + + li > ul { + /* Matches the 30px from the "ul, ol" selector above */ + margin-left: 30px; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .bodywrapper { + margin: 0; + } + + .footer { + width: auto; + } + + .github { + display: none; + } + + + +} + + + +@media screen and (max-width: 875px) { + + body { + margin: 0; + padding: 20px 30px; + } + + div.documentwrapper { + float: none; + background: #fff; + } + + div.sphinxsidebar { + display: block; + float: none; + width: 102.5%; + margin: 50px -30px -20px -30px; + padding: 10px 20px; + background: #333; + color: #FFF; + } + + div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, + div.sphinxsidebar h3 a { + color: #fff; + } + + div.sphinxsidebar a { + color: #AAA; + } + + div.sphinxsidebar p.logo { + display: none; + } + + div.document { + width: 100%; + margin: 0; + } + + div.footer { + display: none; + } + + div.bodywrapper { + margin: 0; + } + + div.body { + min-height: 0; + padding: 0; + } + + .rtd_doc_footer { + display: none; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .footer { + width: auto; + } + + .github { + display: none; + } +} + + +/* misc. */ + +.revsys-inline { + display: none!important; +} + +/* Make nested-list/multi-paragraph items look better in Releases changelog + * pages. Without this, docutils' magical list fuckery causes inconsistent + * formatting between different release sub-lists. + */ +div#changelog > div.section > ul > li > p:only-child { + margin-bottom: 0; +} + +/* Hide fugly table cell borders in ..bibliography:: directive output */ +table.docutils.citation, table.docutils.citation td, table.docutils.citation th { + border: none; + /* Below needed in some edge cases; if not applied, bottom shadows appear */ + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + + +/* relbar */ + +.related { + line-height: 30px; + width: 100%; + font-size: 0.9rem; +} + +.related.top { + border-bottom: 1px solid #EEE; + margin-bottom: 20px; +} + +.related.bottom { + border-top: 1px solid #EEE; +} + +.related ul { + padding: 0; + margin: 0; + list-style: none; +} + +.related li { + display: inline; +} + +nav#rellinks { + float: right; +} + +nav#rellinks li+li:before { + content: "|"; +} + +nav#breadcrumbs li+li:before { + content: "\00BB"; +} + +/* Hide certain items when printing */ +@media print { + div.related { + display: none; + } +} \ No newline at end of file diff --git a/docs/_static/basic.css b/docs/_static/basic.css new file mode 100644 index 0000000..0807176 --- /dev/null +++ b/docs/_static/basic.css @@ -0,0 +1,676 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 450px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist td { + vertical-align: top; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +div.code-block-caption { + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +div.code-block-caption + div > div.highlight > pre { + margin-top: 0; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + padding: 1em 1em 0; +} + +div.literal-block-wrapper div.highlight { + margin: 0; +} + +code.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +code.descclassname { + background-color: transparent; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: relative; + left: 0px; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/_static/comment-bright.png b/docs/_static/comment-bright.png new file mode 100644 index 0000000000000000000000000000000000000000..15e27edb12ac25701ac0ac21b97b52bb4e45415e GIT binary patch literal 756 zcmV<Q0t@|#P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0008JNkl<Zcmaiz z1Hj}w5Qg8Gq}}~(+qP}nwsE#?+qP}nwr!&y+D+z~J^P8B5f1Z2p}9E7<MeddjkkYX zd-EIb)!Fph8#Oll|7xX;pFUA;-4hpnGx`#oio0{nM4Efs-uiF5ty3!w*}J>gfIX78 z$8Pzv({A~p%??+>KickCb#0FM1rYN=mBmQ&Nwp<#JXUhU;{|)}%&s>suq6lXw*~s{ zvHx}3C%<;wE5CH!BR{p<CEvB*W&e*ae5&H6TsQ>5@ml9ws}y)=QN-kL2?#`S5d*6j zk`h<}j1>tD$b?4D^N9w}-k)bx<r``%#N@BubkHRi`8NiUJ1QcYNoj^+f{t5;yOfCu z025_fkz23uZryUlH?8%X)iz&u&N=GVtpN}jfHhN+0n&st2CyuMEP+D?lNAvnV{r9d zcU*Hd8>XxFg>+#kme^xx#qg6FI-%iv2U{<p;QMgJt&^`Ag7_W6#X2)I$;?RfMG1!X z06%V(20R6@MOywSVz5Sxg}7Rrcw!_)k>0h(Y)cs%5a|m%Pn_K3X_bDJ>EH#(Fb73Z zfUt2Q3B>N+ot3qb*DqbTZpFIn4a!#_R-}{?-~Hs=xSS6p&$sZ-k1zDdtqU`Y@`#qL z&zv-~)Q#JCU(dI)Hf;$CEnK=6CK50}q7~wdbI->?E07bJ0R;!GSQTs<U-;V35W~fW z36@m9t>5Am`#;*WHjvHRvY?&$Lm-vq1a_BzocI^ULXV!lbMd%|^B#fY;XX)n<&R^L z=84u1e_3ziq;Hz-*k5~zwY3*oDKt0;bM@M@@89;@m*4RFgvvM_4;5LB!@OB@^WbVT zjl{t;<hC4hUbrL2lKb#<%ZqWCYg*v6+?;pq-M_TowLXr*A-JpI`8bZ>a8_>od-~P4 m{5|DvB&z#xT;*OnJqG}gk~_7HcNkCr0000<MNUMnLSTXfh<FSD literal 0 HcmV?d00001 diff --git a/docs/_static/comment-close.png b/docs/_static/comment-close.png new file mode 100644 index 0000000000000000000000000000000000000000..4d91bcf57de866a901a89a2a68c0f36af1114841 GIT binary patch literal 829 zcmV-D1H$}?P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00097Nkl<ZcmZwB z1Dy3Z6o&ElB<&b$^RsQ+wr$(CZQHhO+qT_7?@i8TaM%C-o;rX}=B^hIClh5G@FY>W zanA~u9RIXo;n7c96&U)YLgs-FGlx~*_c{Jgvesu1E5(8YEf&5wF=YFPcRe@1=MJmi zag(L*xc2<lF}aNwyuSNG>r0(slpcN!vC5CUju;vHJkHc*&70_n2OZsK%O~A=!+YIw z<wtI?<OA1V_MYo5e9JW#z16MEgjt6?ZHst>7zLLl7~Z+~RgWOQ=MI6$#0pvpu$Q43 zP@36QAmu6!_9NPM?o<1_!+stoVRRZbW9#SPe!n;#A_6m8f}|xN1;H{`0RoXQ2LM47 zt(g;iZ6|pCb@h2xk&(}S3=EVBUO0e90m2Lp5CB<(SPIaB;n4))3JB87Or#XPOPcum z?<^(g+m9}VNn4Y&B`g8h{t_$+R<w(NPp`pR;bZXUAU_*$1^F@H_u_HjklAf2Sdp#@ zi1e@(?k`~3fS<Wa3$P{d`>B1%HKRY6fjtd-<7&EsU;vs0GM(Lmbhi%Gwcfs0FTF}T zL{_M6Go&E0Eg8FuB*(Yn+Z*RVTBE@10eIOb3El^MhO`GabDll(V0&FlJi2k^;q8af zkENdk2}x2)_KVp`5OAwXZM;dG0?M-S)xE1IKDi6BY@5%Or?#aZ9$gcX)dPZ&wA1a< z$rFXHPn|TBf`e?>Are8sKtKrKcjF$i^lp!zkL?C|y^vlHr1HXeVJd;1I~g&Ob-q)& z(fn7s-KI}G{wnK<H<)KWVxE4VdETD8{2*;k)&R4~T%#E%j&$o0>zg_U5G(V%bX6uk zIa+<@>rdmZYd!9Y=C0cuchrbIjuRB_Wq{-RXlic?flu1*_ux}x%(HDH&nT`k^xCeC ziHi1!ChH*sQ6|UqJpTTzX$aw8e(UfcS^f;6yB<A{y1b}M;$`2cPs0I(nH<v~(<#$j z(=R3u{_U4$r@s5W+3{rXALYlulK55cnX3D?%s|HYcaeVp)Om4$BmFtO00000NkvXX Hu0mjf1x1rJ literal 0 HcmV?d00001 diff --git a/docs/_static/comment.png b/docs/_static/comment.png new file mode 100644 index 0000000000000000000000000000000000000000..dfbc0cbd512bdeefcb1984c99d8e577efb77f006 GIT binary patch literal 641 zcmV-{0)G98P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0006=Nkl<Zcmaiw z1B@MC6vpR|+E!HCR@|_TQOC6vt435es%^Vn@9aE}%}s;a?Y%wcJ|ydte7XF72V6cT zZcVcF@Zn4UJS$fQ6bbsQH-fg}6|b#&$*T*WmdO*(Ka6+c>Wd+(1-70zU(rtxtqR%j z-lsH|CKQJXqD{+F7V0OTv8@{~(wp(`oIP^ZykMWgR>&|RsklFMCnOo&Bd{le<WL>} zV5F6424Qzl;o2G%oVvmHgRDP9!=rK8fy^!yV8y*4p=??uIRrrr0?>O!(z*g5Av<N7 z9bjgfR9%u#U0Oo`L>L2!4z0{sq%vhG*Po}`a<6%<Pg--|g3yQn3VWI{Jf@U}Du56| zc#*aA;RUY^;9$z*60-XpjVP=_G=rKle45s4K(Lh`;GMuduTZ8zf4`a8$eLw4pbALM zt+G`Eg6-g7ze4q+xrfElKq%=0lu6(d!Oxl#Qr!)y;YPS3r~qN@C@#(*d{QcR<Idg_ zT0$>kTK5TNhtC8}rXNu&h^QH4A&Sk~Autm*s~45(H7+0bi^MraaRVzr05hQ3iK?j` zR#U@^i0WhkIHTg29u~|ypU?sXCQEQgXfObPW;+0YAF;|5XyaMAEM0sQ@4-xCZe=0e z7r$ofiAxn@O5#RodD8rh5D@nKQ;?lcf@tg4o+Wp44aMl~c47azN_(im0N)7OqdPBC zGw;353_o$DqGRDhuhU$Eaj!@m0<HM3c<s^gb7gJ08nJ?FGHyIi^#lz$dc34LhtZ?q bY#4t557cxjxf?U>00000NkvXXu0mjfjZ7Z_ literal 0 HcmV?d00001 diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 0000000..2a924f1 --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1 @@ +/* This file intentionally left blank. */ diff --git a/docs/_static/doctools.js b/docs/_static/doctools.js new file mode 100644 index 0000000..344db17 --- /dev/null +++ b/docs/_static/doctools.js @@ -0,0 +1,315 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var bbox = span.getBBox(); + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + var parentOfText = node.parentNode.parentNode; + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { + this.initOnKeyListeners(); + } + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('<a class="headerlink">\u00B6</a>'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('<a class="headerlink">\u00B6</a>'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('<p class="highlight-link"><a href="javascript:Documentation.' + + 'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keyup(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box or textarea + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/docs/_static/documentation_options.js b/docs/_static/documentation_options.js new file mode 100644 index 0000000..0c2ef7c --- /dev/null +++ b/docs/_static/documentation_options.js @@ -0,0 +1,10 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '1.0.0', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + FILE_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, +}; \ No newline at end of file diff --git a/docs/_static/down-pressed.png b/docs/_static/down-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..5756c8cad8854722893dc70b9eb4bb0400343a39 GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`OFdm2Ln;`PZ^+1>KjR?B@S0W7 z%OS_REiHONoJ6{+Ks@6k3590|7k9F+ddB6!zw3#&!aw#S`x}3V3&=A(a#84O-&F7T z^k3tZB;&iR9siw0|F|E|DAL<8r-F4!1H-;1{e*~yAKZN5f0|Ei6yUmR#Is)EM(Po_ zi`qJR6|P<~+)N+kSDgL7AjdIC_!O7Q?eGb+L+qOjm{~LLinM4NHn7U%HcK%uoMYO5 VJ~8zD2B3o(JYD@<);T3K0RV0%P>BEl literal 0 HcmV?d00001 diff --git a/docs/_static/down.png b/docs/_static/down.png new file mode 100644 index 0000000000000000000000000000000000000000..1b3bdad2ceffae91cee61b32f3295f9bbe646e48 GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6CVIL!hEy=F?b*7pIY7kW{q%Rg zx!yQ<9v8bmJwa`TQk7YSw}WVQ()mRdQ;TC;*<T*?<?OIJF4)K~*`+^EdvW@{fRyJ( z?weB&PpGe(dw+-5<oNH&JW|0z@kgId=L!~9O|3`?{k1Umt465Dp9i1pCaQ@{=WpF| zklotk)=&P-c9F*_Q}bpRPq*XX{4Fk5IYl~|@#V*s^(ig4#DI=t@O1TaS?83{1OQnY BO{f3> literal 0 HcmV?d00001 diff --git a/docs/_static/file.png b/docs/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..a858a410e4faa62ce324d814e4b816fff83a6fb3 GIT binary patch literal 286 zcmV+(0pb3MP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0002xNkl<Zcmb`G zgHi?o6ovOGdxdP*AltSE*&JruJwUGI3!FN?xxO>s`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHD<M{a4P!N^sPbQKi=?mBx zoos%BSoiGXjr-;%$QixXMOVNSUNp6L0a1Oz&cgu)wqE?07u5I7qrQIu4Fij)Y3c&0 z@0u_#NH6I?Mk(n;dT}d~^J<WkTLqp|RW-hV56tKpXqu)k@V{?amI+5DOlEU@funz+ kySsbM>fiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( literal 0 HcmV?d00001 diff --git a/docs/_static/jquery-3.2.1.js b/docs/_static/jquery-3.2.1.js new file mode 100644 index 0000000..d2d8ca4 --- /dev/null +++ b/docs/_static/jquery-3.2.1.js @@ -0,0 +1,10253 @@ +/*! + * jQuery JavaScript Library v3.2.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2017-03-20T18:59Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var document = window.document; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + + + + function DOMEval( code, doc ) { + doc = doc || document; + + var script = doc.createElement( "script" ); + + script.text = code; + doc.head.appendChild( script ).parentNode.removeChild( script ); + } +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.2.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android <=4.0 only + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + + if ( copyIsArray ) { + copyIsArray = false; + clone = src && Array.isArray( src ) ? src : []; + + } else { + clone = src && jQuery.isPlainObject( src ) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isFunction: function( obj ) { + return jQuery.type( obj ) === "function"; + }, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + + // As of jQuery 3.0, isNumeric is limited to + // strings and numbers (primitives or objects) + // that can be coerced to finite numbers (gh-2662) + var type = jQuery.type( obj ); + return ( type === "number" || type === "string" ) && + + // parseFloat NaNs numeric-cast false positives ("") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + !isNaN( obj - parseFloat( obj ) ); + }, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + + /* eslint-disable no-unused-vars */ + // See https://github.com/eslint/eslint/issues/6125 + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + DOMEval( code ); + }, + + // Convert dashed to camelCase; used by the css and data modules + // Support: IE <=9 - 11, Edge 12 - 13 + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android <=4.0 only + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.3 + * https://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-08-08 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + disabledAncestor = addCombinator( + function( elem ) { + return elem.disabled === true && ("form" in elem || "label" in elem); + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[i] = "#" + nid + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement("fieldset"); + + try { + return !!fn( el ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + disabledAncestor( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( preferredDoc !== document && + (subWindow = document.defaultView) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( el ) { + el.className = "i"; + return !el.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( el ) { + el.appendChild( document.createComment("") ); + return !el.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + }); + + // ID filter and find + if ( support.getById ) { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( (elem = elems[i++]) ) { + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( el ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + + "<select id='" + expando + "-\r\\' msallowcapture=''>" + + "<option selected=''></option></select>"; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( el ) { + el.innerHTML = "<a href='' disabled='disabled'></a>" + + "<select disabled='disabled'><option/></select>"; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll(":enabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll(":disabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( el ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === document ? -1 : + b === document ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + !compilerCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return (sel + "").replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( (oldCache = uniqueCache[ key ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context === document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context || document, xml) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( el ) { + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( el ) { + el.innerHTML = "<a href='#'></a>"; + return el.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( el ) { + el.innerHTML = "<input/>"; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( el ) { + return el.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Simple selector that can be filtered directly, removing non-Elements + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + // Complex selector, compare the two sets, removing non-Elements + qualifier = jQuery.filter( qualifier, elements ); + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1; + } ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( nodeName( elem, "iframe" ) ) { + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( jQuery.isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && jQuery.isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( jQuery.isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + jQuery.isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + jQuery.isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + jQuery.isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ jQuery.camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ jQuery.camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( jQuery.camelCase ); + } else { + key = jQuery.camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + jQuery.contains( elem.ownerDocument, elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + +var swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, + scale = 1, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + do { + + // If previous iteration zeroed out, double until we get *something*. + // Use string for doubling so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + initialInUnit = initialInUnit / scale; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // Break the loop if scale is unchanged or perfect, or if we've just had enough. + } while ( + scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations + ); + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i ); + +var rscriptType = ( /^$|\/(?:java|ecma)script/i ); + + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE <=9 only + option: [ 1, "<select multiple='multiple'>", "</select>" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting <tbody> or other required elements. + thead: [ 1, "<table>", "</table>" ], + col: [ 2, "<table><colgroup>", "</colgroup></table>" ], + tr: [ 2, "<table><tbody>", "</tbody></table>" ], + td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], + + _default: [ 0, "", "" ] +}; + +// Support: IE <=9 only +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = "<textarea>x</textarea>"; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +} )(); +var documentElement = document.documentElement; + + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 only +// See #13393 for more info +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + // Make a writable jQuery.Event from the native event object + var event = jQuery.event.fix( nativeEvent ); + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG <use> instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: jQuery.isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + /* eslint-disable max-len */ + + // See https://github.com/eslint/eslint/issues/3229 + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, + + /* eslint-enable */ + + // Support: IE <=10 - 11, Edge 12 - 13 + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /<script|<style|<link/i, + + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptTypeMasked = /^true\/(.*)/, + rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( ">tbody", elem )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1></$2>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rmargin = ( /^margin/ ); + +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + div.style.cssText = + "box-sizing:border-box;" + + "position:relative;display:block;" + + "margin:auto;border:1px;padding:1px;" + + "top:1%;width:50%"; + div.innerHTML = ""; + documentElement.appendChild( container ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = divStyle.marginLeft === "2px"; + boxSizingReliableVal = divStyle.width === "4px"; + + // Support: Android 4.0 - 4.3 only + // Some styles come back with percentage values, even though they shouldn't + div.style.marginRight = "50%"; + pixelMarginRightVal = divStyle.marginRight === "4px"; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + + "padding:0;margin-top:1px;position:absolute"; + container.appendChild( div ); + + jQuery.extend( support, { + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelMarginRight: function() { + computeStyleTests(); + return pixelMarginRightVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }, + + cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style; + +// Return a css property mapped to a potentially vendor prefixed property +function vendorPropName( name ) { + + // Shortcut for names that are not vendor prefixed + if ( name in emptyStyle ) { + return name; + } + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a property mapped along what jQuery.cssProps suggests or to +// a vendor prefixed property. +function finalPropName( name ) { + var ret = jQuery.cssProps[ name ]; + if ( !ret ) { + ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name; + } + return ret; +} + +function setPositiveNumber( elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i, + val = 0; + + // If we already have the right measurement, avoid augmentation + if ( extra === ( isBorderBox ? "border" : "content" ) ) { + i = 4; + + // Otherwise initialize for horizontal or vertical properties + } else { + i = name === "width" ? 1 : 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // At this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + + // At this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // At this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with computed style + var valueIsBorderBox, + styles = getStyles( elem ), + val = curCSS( elem, name, styles ), + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test( val ) ) { + return val; + } + + // Check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && + ( support.boxSizingReliable() || val === elem.style[ name ] ); + + // Fall back to offsetWidth/Height when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + if ( val === "auto" ) { + val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ]; + } + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + + // Use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + "float": "cssFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + if ( type === "number" ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = jQuery.camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + } ) : + getWidthOrHeight( elem, name, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = extra && getStyles( elem ), + subtract = extra && augmentWidthOrHeight( + elem, + name, + extra, + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + styles + ); + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ name ] = value; + value = jQuery.css( elem, name ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && + ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || + jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = jQuery.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 13 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( jQuery.isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + jQuery.proxy( result.stop, result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = jQuery.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( jQuery.isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( typeof value === "string" && value ) { + classes = value.match( rnothtmlwhite ) || []; + + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( jQuery.isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + if ( typeof value === "string" && value ) { + classes = value.match( rnothtmlwhite ) || []; + + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value; + + if ( typeof stateVal === "boolean" && type === "string" ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( jQuery.isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( type === "string" ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = value.match( rnothtmlwhite ) || []; + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, isFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup contextmenu" ).split( " " ), + function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; +} ); + +jQuery.fn.extend( { + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +} ); + + + + +support.focusin = "onfocusin" in window; + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = jQuery.now(); + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = jQuery.isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( jQuery.isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match == null ? null : match; + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 13 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available, append data to url + if ( s.data ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + + +jQuery._evalUrl = function( url ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + "throws": true + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( jQuery.isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( "<script>" ).prop( { + charset: s.scriptCharset, + src: s.url + } ).on( + "load error", + callback = function( evt ) { + script.remove(); + callback = null; + if ( evt ) { + complete( evt.type === "error" ? 404 : 200, evt.type ); + } + } + ); + + // Use native DOM manipulation to avoid our domManip AJAX trickery + document.head.appendChild( script[ 0 ] ); + }, + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +var oldCallbacks = [], + rjsonp = /(=)\?(?=&|$)|\?\?/; + +// Default jsonp settings +jQuery.ajaxSetup( { + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +} ); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? + "url" : + typeof s.data === "string" && + ( s.contentType || "" ) + .indexOf( "application/x-www-form-urlencoded" ) === 0 && + rjsonp.test( s.data ) && "data" + ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + + // Insert callback into url or form data + if ( jsonProp ) { + s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); + } else if ( s.jsonp !== false ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters[ "script json" ] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // Force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + overwritten = window[ callbackName ]; + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always( function() { + + // If previous value didn't exist - remove it + if ( overwritten === undefined ) { + jQuery( window ).removeProp( callbackName ); + + // Otherwise restore preexisting value + } else { + window[ callbackName ] = overwritten; + } + + // Save back as free + if ( s[ callbackName ] ) { + + // Make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // Save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + } ); + + // Delegate to script + return "script"; + } +} ); + + + + +// Support: Safari 8 only +// In Safari 8 documents created via document.implementation.createHTMLDocument +// collapse sibling forms: the second one becomes a child of the first one. +// Because of that, this security measure has to be disabled in Safari 8. +// https://bugs.webkit.org/show_bug.cgi?id=137337 +support.createHTMLDocument = ( function() { + var body = document.implementation.createHTMLDocument( "" ).body; + body.innerHTML = "<form></form><form></form>"; + return body.childNodes.length === 2; +} )(); + + +// Argument "data" should be string of html +// context (optional): If specified, the fragment will be created in this context, +// defaults to document +// keepScripts (optional): If true, will include scripts passed in the html string +jQuery.parseHTML = function( data, context, keepScripts ) { + if ( typeof data !== "string" ) { + return []; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + + var base, parsed, scripts; + + if ( !context ) { + + // Stop scripts or inline event handlers from being executed immediately + // by using document.implementation + if ( support.createHTMLDocument ) { + context = document.implementation.createHTMLDocument( "" ); + + // Set the base href for the created document + // so any parsed elements with URLs + // are based on the document's URL (gh-2965) + base = context.createElement( "base" ); + base.href = document.location.href; + context.head.appendChild( base ); + } else { + context = document; + } + } + + parsed = rsingleTag.exec( data ); + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[ 1 ] ) ]; + } + + parsed = buildFragment( [ data ], context, scripts ); + + if ( scripts && scripts.length ) { + jQuery( scripts ).remove(); + } + + return jQuery.merge( [], parsed.childNodes ); +}; + + +/** + * Load a url into a page + */ +jQuery.fn.load = function( url, params, callback ) { + var selector, type, response, + self = this, + off = url.indexOf( " " ); + + if ( off > -1 ) { + selector = stripAndCollapse( url.slice( off ) ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // If we have elements to modify, make the request + if ( self.length > 0 ) { + jQuery.ajax( { + url: url, + + // If "type" variable is undefined, then "GET" method will be used. + // Make value of this field explicit since + // user can override it through ajaxSetup method + type: type || "GET", + dataType: "html", + data: params + } ).done( function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + self.html( selector ? + + // If a selector was specified, locate the right elements in a dummy div + // Exclude scripts to avoid IE 'Permission Denied' errors + jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : + + // Otherwise use the full result + responseText ); + + // If the request succeeds, this function gets "data", "status", "jqXHR" + // but they are ignored because response was set above. + // If it fails, this function gets "jqXHR", "status", "error" + } ).always( callback && function( jqXHR, status ) { + self.each( function() { + callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); + } ); + } ); + } + + return this; +}; + + + + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( [ + "ajaxStart", + "ajaxStop", + "ajaxComplete", + "ajaxError", + "ajaxSuccess", + "ajaxSend" +], function( i, type ) { + jQuery.fn[ type ] = function( fn ) { + return this.on( type, fn ); + }; +} ); + + + + +jQuery.expr.pseudos.animated = function( elem ) { + return jQuery.grep( jQuery.timers, function( fn ) { + return elem === fn.elem; + } ).length; +}; + + + + +jQuery.offset = { + setOffset: function( elem, options, i ) { + var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, + position = jQuery.css( elem, "position" ), + curElem = jQuery( elem ), + props = {}; + + // Set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + curOffset = curElem.offset(); + curCSSTop = jQuery.css( elem, "top" ); + curCSSLeft = jQuery.css( elem, "left" ); + calculatePosition = ( position === "absolute" || position === "fixed" ) && + ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; + + // Need to be able to calculate position if either + // top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + + // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) + options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + + } else { + curElem.css( props ); + } + } +}; + +jQuery.fn.extend( { + offset: function( options ) { + + // Preserve chaining for setter + if ( arguments.length ) { + return options === undefined ? + this : + this.each( function( i ) { + jQuery.offset.setOffset( this, options, i ); + } ); + } + + var doc, docElem, rect, win, + elem = this[ 0 ]; + + if ( !elem ) { + return; + } + + // Return zeros for disconnected and hidden (display: none) elements (gh-2310) + // Support: IE <=11 only + // Running getBoundingClientRect on a + // disconnected node in IE throws an error + if ( !elem.getClientRects().length ) { + return { top: 0, left: 0 }; + } + + rect = elem.getBoundingClientRect(); + + doc = elem.ownerDocument; + docElem = doc.documentElement; + win = doc.defaultView; + + return { + top: rect.top + win.pageYOffset - docElem.clientTop, + left: rect.left + win.pageXOffset - docElem.clientLeft + }; + }, + + position: function() { + if ( !this[ 0 ] ) { + return; + } + + var offsetParent, offset, + elem = this[ 0 ], + parentOffset = { top: 0, left: 0 }; + + // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, + // because it is its only offset parent + if ( jQuery.css( elem, "position" ) === "fixed" ) { + + // Assume getBoundingClientRect is there when computed position is fixed + offset = elem.getBoundingClientRect(); + + } else { + + // Get *real* offsetParent + offsetParent = this.offsetParent(); + + // Get correct offsets + offset = this.offset(); + if ( !nodeName( offsetParent[ 0 ], "html" ) ) { + parentOffset = offsetParent.offset(); + } + + // Add offsetParent borders + parentOffset = { + top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ), + left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ) + }; + } + + // Subtract parent offsets and element margins + return { + top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), + left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) + }; + }, + + // This method will return documentElement in the following cases: + // 1) For the element inside the iframe without offsetParent, this method will return + // documentElement of the parent window + // 2) For the hidden or detached element + // 3) For body or html element, i.e. in case of the html node - it will return itself + // + // but those exceptions were never presented as a real life use-cases + // and might be considered as more preferable results. + // + // This logic, however, is not guaranteed and can change at any point in the future + offsetParent: function() { + return this.map( function() { + var offsetParent = this.offsetParent; + + while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { + offsetParent = offsetParent.offsetParent; + } + + return offsetParent || documentElement; + } ); + } +} ); + +// Create scrollLeft and scrollTop methods +jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { + var top = "pageYOffset" === prop; + + jQuery.fn[ method ] = function( val ) { + return access( this, function( elem, method, val ) { + + // Coalesce documents and windows + var win; + if ( jQuery.isWindow( elem ) ) { + win = elem; + } else if ( elem.nodeType === 9 ) { + win = elem.defaultView; + } + + if ( val === undefined ) { + return win ? win[ prop ] : elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : win.pageXOffset, + top ? val : win.pageYOffset + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length ); + }; +} ); + +// Support: Safari <=7 - 9.1, Chrome <=37 - 49 +// Add the top/left cssHooks using jQuery.fn.position +// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 +// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 +// getComputedStyle returns percent when specified for top/left/bottom/right; +// rather than make the css module depend on the offset module, just check for it here +jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, + function( elem, computed ) { + if ( computed ) { + computed = curCSS( elem, prop ); + + // If curCSS returns percentage, fallback to offset + return rnumnonpx.test( computed ) ? + jQuery( elem ).position()[ prop ] + "px" : + computed; + } + } + ); +} ); + + +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, + function( defaultExtra, funcName ) { + + // Margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + + // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) + return funcName.indexOf( "outer" ) === 0 ? + elem[ "inner" + name ] : + elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], + // whichever is greatest + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable ); + }; + } ); +} ); + + +jQuery.fn.extend( { + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? + this.off( selector, "**" ) : + this.off( types, selector || "**", fn ); + } +} ); + +jQuery.holdReady = function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } +}; +jQuery.isArray = Array.isArray; +jQuery.parseJSON = JSON.parse; +jQuery.nodeName = nodeName; + + + + +// Register as a named AMD module, since jQuery can be concatenated with other +// files that may use define, but not via a proper concatenation script that +// understands anonymous AMD modules. A named AMD is safest and most robust +// way to register. Lowercase jquery is used because AMD module names are +// derived from file names, and jQuery is normally delivered in a lowercase +// file name. Do this after creating the global so that if an AMD module wants +// to call noConflict to hide this version of jQuery, it will work. + +// Note that for maximum portability, libraries that are not jQuery should +// declare themselves as anonymous modules, and avoid setting a global if an +// AMD loader is present. jQuery is a special case. For more information, see +// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon + +if ( typeof define === "function" && define.amd ) { + define( "jquery", [], function() { + return jQuery; + } ); +} + + + + +var + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$; + +jQuery.noConflict = function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; +}; + +// Expose jQuery and $ identifiers, even in AMD +// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) +// and CommonJS for browser emulators (#13566) +if ( !noGlobal ) { + window.jQuery = window.$ = jQuery; +} + + + + +return jQuery; +} ); diff --git a/docs/_static/jquery.js b/docs/_static/jquery.js new file mode 100644 index 0000000..644d35e --- /dev/null +++ b/docs/_static/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=Array.isArray(d)))?(e?(e=!1,f=c&&Array.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,N,e),g(f,c,O,e)):(f++,j.call(a,g(f,c,N,e),g(f,c,O,e),g(f,c,N,c.notifyWith))):(d!==N&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},U=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function V(){this.expando=r.expando+V.uid++}V.uid=1,V.prototype={cache:function(a){var b=a[this.expando];return b||(b={},U(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){Array.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(L)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var W=new V,X=new V,Y=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function $(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Y.test(a)?JSON.parse(a):a)}function _(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Z,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=$(c)}catch(e){}X.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return X.hasData(a)||W.hasData(a)},data:function(a,b,c){return X.access(a,b,c)},removeData:function(a,b){X.remove(a,b)},_data:function(a,b,c){return W.access(a,b,c)},_removeData:function(a,b){W.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=X.get(f),1===f.nodeType&&!W.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),_(f,d,e[d])));W.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){X.set(this,a)}):T(this,function(b){var c;if(f&&void 0===b){if(c=X.get(f,a),void 0!==c)return c;if(c=_(f,a),void 0!==c)return c}else this.each(function(){X.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=W.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ba=new RegExp("^(?:([+-])=|)("+aa+")([a-z%]*)$","i"),ca=["Top","Right","Bottom","Left"],da=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ea=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function fa(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&ba.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ga={};function ha(a){var b,c=a.ownerDocument,d=a.nodeName,e=ga[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ga[d]=e,e)}function ia(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=W.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&da(d)&&(e[f]=ha(d))):"none"!==c&&(e[f]="none",W.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ia(this,!0)},hide:function(){return ia(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){da(this)?r(this).show():r(this).hide()})}});var ja=/^(?:checkbox|radio)$/i,ka=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c<d;c++)W.set(a[c],"globalEval",!b||W.get(b[c],"globalEval"))}var pa=/<|&#?\w+;/;function qa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(pa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ka.exec(f)||["",""])[1].toLowerCase(),i=ma[h]||ma._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===xa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&B(this,"input"))return this.click(),!1},_default:function(a){return B(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?va:wa,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:wa,isPropagationStopped:wa,isImmediatePropagationStopped:wa,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=va,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=va,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=va,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&sa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ta.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return ya(this,a,b,c,d)},one:function(a,b,c,d){return ya(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=wa),this.each(function(){r.event.remove(this,a,c,b)})}});var za=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/<script|<style|<link/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,Ca=/^true\/(.*)/,Da=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}X.hasData(a)&&(h=X.access(a),i=r.extend({},h),X.set(b,i))}}function Ia(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ja.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ja(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,na(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ga),l=0;l<i;l++)j=h[l],la.test(j.type||"")&&!W.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Da,""),k))}return a}function Ka(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(na(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&oa(na(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(za,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d<e;d++)Ia(f[d],g[d]);if(b)if(c)for(f=f||na(a),g=g||na(h),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);else Ha(a,h);return g=na(h,"script"),g.length>0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(na(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ja(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(na(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var La=/^margin/,Ma=new RegExp("^("+aa+")(?!px)[a-z%]+$","i"),Na=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",ra.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,ra.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Oa(a,b,c){var d,e,f,g,h=a.style;return c=c||Na(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ma.test(g)&&La.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Pa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Qa=/^(none|table(?!-c[ea]).+)/,Ra=/^--/,Sa={position:"absolute",visibility:"hidden",display:"block"},Ta={letterSpacing:"0",fontWeight:"400"},Ua=["Webkit","Moz","ms"],Va=d.createElement("div").style;function Wa(a){if(a in Va)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ua.length;while(c--)if(a=Ua[c]+b,a in Va)return a}function Xa(a){var b=r.cssProps[a];return b||(b=r.cssProps[a]=Wa(a)||a),b}function Ya(a,b,c){var d=ba.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Za(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ca[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ca[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ca[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ca[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ca[f]+"Width",!0,e)));return g}function $a(a,b,c){var d,e=Na(a),f=Oa(a,b,e),g="border-box"===r.css(a,"boxSizing",!1,e);return Ma.test(f)?f:(d=g&&(o.boxSizingReliable()||f===a.style[b]),"auto"===f&&(f=a["offset"+b[0].toUpperCase()+b.slice(1)]),f=parseFloat(f)||0,f+Za(a,b,c||(g?"border":"content"),d,e)+"px")}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Oa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=Ra.test(b),j=a.style;return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:j[b]:(f=typeof c,"string"===f&&(e=ba.exec(c))&&e[1]&&(c=fa(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(j[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i?j.setProperty(b,c):j[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b),i=Ra.test(b);return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Oa(a,b,d)),"normal"===e&&b in Ta&&(e=Ta[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Qa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?$a(a,b,d):ea(a,Sa,function(){return $a(a,b,d)})},set:function(a,c,d){var e,f=d&&Na(a),g=d&&Za(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=ba.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ya(a,c,g)}}}),r.cssHooks.marginLeft=Pa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Oa(a,"marginLeft"))||a.getBoundingClientRect().left-ea(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ca[d]+b]=f[d]||f[d-2]||f[0];return e}},La.test(a)||(r.cssHooks[a+b].set=Ya)}),r.fn.extend({css:function(a,b){return T(this,function(a,b,c){var d,e,f={},g=0;if(Array.isArray(b)){for(d=Na(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&da(a),q=W.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],cb.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=W.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ia([a],!0),j=a.style.display||j,k=r.css(a,"display"),ia([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=W.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ia([a],!0),m.done(function(){p||ia([a]),W.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=hb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],Array.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=kb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=ab||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(i||h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:ab||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);f<g;f++)if(d=kb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,hb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j}r.Animation=r.extend(kb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return fa(c.elem,a,ba.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(L);for(var c,d=0,e=a.length;d<e;d++)c=a[d],kb.tweeners[c]=kb.tweeners[c]||[],kb.tweeners[c].unshift(b)},prefilters:[ib],prefilter:function(a,b){b?kb.prefilters.unshift(a):kb.prefilters.push(a)}}),r.speed=function(a,b,c){var d=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off?d.duration=0:"number"!=typeof d.duration&&(d.duration in r.fx.speeds?d.duration=r.fx.speeds[d.duration]:d.duration=r.fx.speeds._default),null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){r.isFunction(d.old)&&d.old.call(this),d.queue&&r.dequeue(this,d.queue)},d},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(da).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=kb(this,r.extend({},a),f);(e||W.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=W.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&db.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=W.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),r.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(ab=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),ab=void 0},r.fx.timer=function(a){r.timers.push(a),r.fx.start()},r.fx.interval=13,r.fx.start=function(){bb||(bb=!0,eb())},r.fx.stop=function(){bb=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var lb,mb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!B(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Tb=[],Ub=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Tb.pop()||r.expando+"_"+ub++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Ub.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ub.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Ub,"$1"+e):b.jsonp!==!1&&(b.url+=(vb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Tb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=pb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Vb=a.jQuery,Wb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Wb),b&&a.jQuery===r&&(a.jQuery=Vb),r},b||(a.jQuery=a.$=r),r}); diff --git a/docs/_static/language_data.js b/docs/_static/language_data.js new file mode 100644 index 0000000..5266fb1 --- /dev/null +++ b/docs/_static/language_data.js @@ -0,0 +1,297 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"]; + + +/* Non-minified version JS is _stemmer.js if file is provided */ +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + + + + + +var splitChars = (function() { + var result = {}; + var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648, + 1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702, + 2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971, + 2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345, + 3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761, + 3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823, + 4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125, + 8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695, + 11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587, + 43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141]; + var i, j, start, end; + for (i = 0; i < singles.length; i++) { + result[singles[i]] = true; + } + var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709], + [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161], + [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568], + [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807], + [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047], + [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383], + [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450], + [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547], + [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673], + [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820], + [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946], + [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023], + [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173], + [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332], + [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481], + [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718], + [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791], + [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095], + [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205], + [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687], + [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968], + [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869], + [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102], + [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271], + [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592], + [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822], + [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167], + [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959], + [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143], + [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318], + [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483], + [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101], + [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567], + [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292], + [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444], + [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783], + [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311], + [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511], + [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774], + [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071], + [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263], + [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519], + [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647], + [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967], + [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295], + [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274], + [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007], + [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381], + [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]]; + for (i = 0; i < ranges.length; i++) { + start = ranges[i][0]; + end = ranges[i][1]; + for (j = start; j <= end; j++) { + result[j] = true; + } + } + return result; +})(); + +function splitQuery(query) { + var result = []; + var start = -1; + for (var i = 0; i < query.length; i++) { + if (splitChars[query.charCodeAt(i)]) { + if (start !== -1) { + result.push(query.slice(start, i)); + start = -1; + } + } else if (start === -1) { + start = i; + } + } + if (start !== -1) { + result.push(query.slice(start)); + } + return result; +} + + diff --git a/docs/_static/minus.png b/docs/_static/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..d96755fdaf8bb2214971e0db9c1fd3077d7c419d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu=nj kDsEF_5m^0CR;1wuP-*O&G^0G}KYk!hp00i_>zopr08q^qX#fBK literal 0 HcmV?d00001 diff --git a/docs/_static/plus.png b/docs/_static/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..7107cec93a979b9a5f64843235a16651d563ce2d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu>-2 m3q%Vub%g%s<8sJhVPMczOq}xhg9DJoz~JfX=d#Wzp$Pyb1r*Kz literal 0 HcmV?d00001 diff --git a/docs/_static/pygments.css b/docs/_static/pygments.css new file mode 100644 index 0000000..dd6621d --- /dev/null +++ b/docs/_static/pygments.css @@ -0,0 +1,77 @@ +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #8f5902; font-style: italic } /* Comment */ +.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ +.highlight .g { color: #000000 } /* Generic */ +.highlight .k { color: #004461; font-weight: bold } /* Keyword */ +.highlight .l { color: #000000 } /* Literal */ +.highlight .n { color: #000000 } /* Name */ +.highlight .o { color: #582800 } /* Operator */ +.highlight .x { color: #000000 } /* Other */ +.highlight .p { color: #000000; font-weight: bold } /* Punctuation */ +.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #8f5902 } /* Comment.Preproc */ +.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #a40000 } /* Generic.Deleted */ +.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #ef2929 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #745334 } /* Generic.Prompt */ +.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ +.highlight .kc { color: #004461; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #004461; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #004461; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #004461; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #004461; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #004461; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #000000 } /* Literal.Date */ +.highlight .m { color: #990000 } /* Literal.Number */ +.highlight .s { color: #4e9a06 } /* Literal.String */ +.highlight .na { color: #c4a000 } /* Name.Attribute */ +.highlight .nb { color: #004461 } /* Name.Builtin */ +.highlight .nc { color: #000000 } /* Name.Class */ +.highlight .no { color: #000000 } /* Name.Constant */ +.highlight .nd { color: #888888 } /* Name.Decorator */ +.highlight .ni { color: #ce5c00 } /* Name.Entity */ +.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #000000 } /* Name.Function */ +.highlight .nl { color: #f57900 } /* Name.Label */ +.highlight .nn { color: #000000 } /* Name.Namespace */ +.highlight .nx { color: #000000 } /* Name.Other */ +.highlight .py { color: #000000 } /* Name.Property */ +.highlight .nt { color: #004461; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #000000 } /* Name.Variable */ +.highlight .ow { color: #004461; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */ +.highlight .mb { color: #990000 } /* Literal.Number.Bin */ +.highlight .mf { color: #990000 } /* Literal.Number.Float */ +.highlight .mh { color: #990000 } /* Literal.Number.Hex */ +.highlight .mi { color: #990000 } /* Literal.Number.Integer */ +.highlight .mo { color: #990000 } /* Literal.Number.Oct */ +.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */ +.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ +.highlight .sc { color: #4e9a06 } /* Literal.String.Char */ +.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ +.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ +.highlight .se { color: #4e9a06 } /* Literal.String.Escape */ +.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ +.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ +.highlight .sx { color: #4e9a06 } /* Literal.String.Other */ +.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ +.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ +.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ +.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #000000 } /* Name.Function.Magic */ +.highlight .vc { color: #000000 } /* Name.Variable.Class */ +.highlight .vg { color: #000000 } /* Name.Variable.Global */ +.highlight .vi { color: #000000 } /* Name.Variable.Instance */ +.highlight .vm { color: #000000 } /* Name.Variable.Magic */ +.highlight .il { color: #990000 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/_static/searchtools.js b/docs/_static/searchtools.js new file mode 100644 index 0000000..5ff3180 --- /dev/null +++ b/docs/_static/searchtools.js @@ -0,0 +1,481 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +if (!Scorer) { + /** + * Simple result scoring code. + */ + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [filename, title, anchor, descr, score] + // and returns the new score. + /* + score: function(result) { + return result[4]; + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: {0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5}, // used to be unimportantResults + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + // query found in terms + term: 5 + }; +} + +if (!splitQuery) { + function splitQuery(query) { + return query.split(/\s+/); + } +} + +/** + * Search Module + */ +var Search = { + + _index : null, + _queued_query : null, + _pulse_status : -1, + + init : function() { + var params = $.getQueryParameters(); + if (params.q) { + var query = params.q[0]; + $('input[name="q"]')[0].value = query; + this.performSearch(query); + } + }, + + loadIndex : function(url) { + $.ajax({type: "GET", url: url, data: null, + dataType: "script", cache: true, + complete: function(jqxhr, textstatus) { + if (textstatus != "success") { + document.getElementById("searchindexloader").src = url; + } + }}); + }, + + setIndex : function(index) { + var q; + this._index = index; + if ((q = this._queued_query) !== null) { + this._queued_query = null; + Search.query(q); + } + }, + + hasIndex : function() { + return this._index !== null; + }, + + deferQuery : function(query) { + this._queued_query = query; + }, + + stopPulse : function() { + this._pulse_status = 0; + }, + + startPulse : function() { + if (this._pulse_status >= 0) + return; + function pulse() { + var i; + Search._pulse_status = (Search._pulse_status + 1) % 4; + var dotString = ''; + for (i = 0; i < Search._pulse_status; i++) + dotString += '.'; + Search.dots.text(dotString); + if (Search._pulse_status > -1) + window.setTimeout(pulse, 500); + } + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch : function(query) { + // create the required interface elements + this.out = $('#search-results'); + this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out); + this.dots = $('<span></span>').appendTo(this.title); + this.status = $('<p style="display: none"></p>').appendTo(this.out); + this.output = $('<ul class="search"/>').appendTo(this.out); + + $('#search-progress').text(_('Preparing search...')); + this.startPulse(); + + // index already loaded, the browser was quick! + if (this.hasIndex()) + this.query(query); + else + this.deferQuery(query); + }, + + /** + * execute search (requires search index to be loaded) + */ + query : function(query) { + var i; + + // stem the searchterms and add them to the correct list + var stemmer = new Stemmer(); + var searchterms = []; + var excluded = []; + var hlterms = []; + var tmp = splitQuery(query); + var objectterms = []; + for (i = 0; i < tmp.length; i++) { + if (tmp[i] !== "") { + objectterms.push(tmp[i].toLowerCase()); + } + + if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) || + tmp[i] === "") { + // skip this "word" + continue; + } + // stem the word + var word = stemmer.stemWord(tmp[i].toLowerCase()); + // prevent stemmer from cutting word smaller than two chars + if(word.length < 3 && tmp[i].length >= 3) { + word = tmp[i]; + } + var toAppend; + // select the correct list + if (word[0] == '-') { + toAppend = excluded; + word = word.substr(1); + } + else { + toAppend = searchterms; + hlterms.push(tmp[i].toLowerCase()); + } + // only add if not already in the list + if (!$u.contains(toAppend, word)) + toAppend.push(word); + } + var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" ")); + + // console.debug('SEARCH: searching for:'); + // console.info('required: ', searchterms); + // console.info('excluded: ', excluded); + + // prepare search + var terms = this._index.terms; + var titleterms = this._index.titleterms; + + // array of [filename, title, anchor, descr, score] + var results = []; + $('#search-progress').empty(); + + // lookup as object + for (i = 0; i < objectterms.length; i++) { + var others = [].concat(objectterms.slice(0, i), + objectterms.slice(i+1, objectterms.length)); + results = results.concat(this.performObjectSearch(objectterms[i], others)); + } + + // lookup as search terms in fulltext + results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + for (i = 0; i < results.length; i++) + results[i][4] = Scorer.score(results[i]); + } + + // now sort the results by score (in opposite order of appearance, since the + // display function below uses pop() to retrieve items) and then + // alphabetically + results.sort(function(a, b) { + var left = a[4]; + var right = b[4]; + if (left > right) { + return 1; + } else if (left < right) { + return -1; + } else { + // same score: sort alphabetically + left = a[1].toLowerCase(); + right = b[1].toLowerCase(); + return (left > right) ? -1 : ((left < right) ? 1 : 0); + } + }); + + // for debugging + //Search.lastresults = results.slice(); // a copy + //console.info('search results:', Search.lastresults); + + // print the results + var resultCount = results.length; + function displayNextItem() { + // results left, load the summary and display it + if (results.length) { + var item = results.pop(); + var listItem = $('<li style="display:none"></li>'); + if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') { + // dirhtml builder + var dirname = item[0] + '/'; + if (dirname.match(/\/index\/$/)) { + dirname = dirname.substring(0, dirname.length-6); + } else if (dirname == 'index/') { + dirname = ''; + } + listItem.append($('<a/>').attr('href', + DOCUMENTATION_OPTIONS.URL_ROOT + dirname + + highlightstring + item[2]).html(item[1])); + } else { + // normal html builders + listItem.append($('<a/>').attr('href', + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX + + highlightstring + item[2]).html(item[1])); + } + if (item[3]) { + listItem.append($('<span> (' + item[3] + ')</span>')); + Search.output.append(listItem); + listItem.slideDown(5, function() { + displayNextItem(); + }); + } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) { + var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX; + if (suffix === undefined) { + suffix = '.txt'; + } + $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix), + dataType: "text", + complete: function(jqxhr, textstatus) { + var data = jqxhr.responseText; + if (data !== '' && data !== undefined) { + listItem.append(Search.makeSearchSummary(data, searchterms, hlterms)); + } + Search.output.append(listItem); + listItem.slideDown(5, function() { + displayNextItem(); + }); + }}); + } else { + // no source available, just display title + Search.output.append(listItem); + listItem.slideDown(5, function() { + displayNextItem(); + }); + } + } + // search finished, update title and status message + else { + Search.stopPulse(); + Search.title.text(_('Search Results')); + if (!resultCount) + Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.')); + else + Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount)); + Search.status.fadeIn(500); + } + } + displayNextItem(); + }, + + /** + * search for object names + */ + performObjectSearch : function(object, otherterms) { + var filenames = this._index.filenames; + var docnames = this._index.docnames; + var objects = this._index.objects; + var objnames = this._index.objnames; + var titles = this._index.titles; + + var i; + var results = []; + + for (var prefix in objects) { + for (var name in objects[prefix]) { + var fullname = (prefix ? prefix + '.' : '') + name; + if (fullname.toLowerCase().indexOf(object) > -1) { + var score = 0; + var parts = fullname.split('.'); + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullname == object || parts[parts.length - 1] == object) { + score += Scorer.objNameMatch; + // matches in last name + } else if (parts[parts.length - 1].indexOf(object) > -1) { + score += Scorer.objPartialMatch; + } + var match = objects[prefix][name]; + var objname = objnames[match[1]][2]; + var title = titles[match[0]]; + // If more than one term searched for, we require other words to be + // found in the name/title/description + if (otherterms.length > 0) { + var haystack = (prefix + ' ' + name + ' ' + + objname + ' ' + title).toLowerCase(); + var allfound = true; + for (i = 0; i < otherterms.length; i++) { + if (haystack.indexOf(otherterms[i]) == -1) { + allfound = false; + break; + } + } + if (!allfound) { + continue; + } + } + var descr = objname + _(', in ') + title; + + var anchor = match[3]; + if (anchor === '') + anchor = fullname; + else if (anchor == '-') + anchor = objnames[match[1]][1] + '-' + fullname; + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) { + score += Scorer.objPrio[match[2]]; + } else { + score += Scorer.objPrioDefault; + } + results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]); + } + } + } + + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch : function(searchterms, excluded, terms, titleterms) { + var docnames = this._index.docnames; + var filenames = this._index.filenames; + var titles = this._index.titles; + + var i, j, file; + var fileMap = {}; + var scoreMap = {}; + var results = []; + + // perform the search on the required terms + for (i = 0; i < searchterms.length; i++) { + var word = searchterms[i]; + var files = []; + var _o = [ + {files: terms[word], score: Scorer.term}, + {files: titleterms[word], score: Scorer.title} + ]; + + // no match but word was a required one + if ($u.every(_o, function(o){return o.files === undefined;})) { + break; + } + // found search word in contents + $u.each(_o, function(o) { + var _files = o.files; + if (_files === undefined) + return + + if (_files.length === undefined) + _files = [_files]; + files = files.concat(_files); + + // set score for the word in each file to Scorer.term + for (j = 0; j < _files.length; j++) { + file = _files[j]; + if (!(file in scoreMap)) + scoreMap[file] = {} + scoreMap[file][word] = o.score; + } + }); + + // create the mapping + for (j = 0; j < files.length; j++) { + file = files[j]; + if (file in fileMap) + fileMap[file].push(word); + else + fileMap[file] = [word]; + } + } + + // now check if the files don't contain excluded terms + for (file in fileMap) { + var valid = true; + + // check if all requirements are matched + if (fileMap[file].length != searchterms.length) + continue; + + // ensure that none of the excluded terms is in the search result + for (i = 0; i < excluded.length; i++) { + if (terms[excluded[i]] == file || + titleterms[excluded[i]] == file || + $u.contains(terms[excluded[i]] || [], file) || + $u.contains(titleterms[excluded[i]] || [], file)) { + valid = false; + break; + } + } + + // if we have still a valid result we can add it to the result list + if (valid) { + // select one (max) score for the file. + // for better ranking, we should calculate ranking by using words statistics like basic tf-idf... + var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]})); + results.push([docnames[file], titles[file], '', null, score, filenames[file]]); + } + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words, hlwords is the list of normal, unstemmed + * words. the first one is used to find the occurrence, the + * latter for highlighting it. + */ + makeSearchSummary : function(text, keywords, hlwords) { + var textLower = text.toLowerCase(); + var start = 0; + $.each(keywords, function() { + var i = textLower.indexOf(this.toLowerCase()); + if (i > -1) + start = i; + }); + start = Math.max(start - 120, 0); + var excerpt = ((start > 0) ? '...' : '') + + $.trim(text.substr(start, 240)) + + ((start + 240 - text.length) ? '...' : ''); + var rv = $('<div class="context"></div>').text(excerpt); + $.each(hlwords, function() { + rv = rv.highlightText(this, 'highlighted'); + }); + return rv; + } +}; + +$(document).ready(function() { + Search.init(); +}); diff --git a/docs/_static/underscore-1.3.1.js b/docs/_static/underscore-1.3.1.js new file mode 100644 index 0000000..208d4cd --- /dev/null +++ b/docs/_static/underscore-1.3.1.js @@ -0,0 +1,999 @@ +// Underscore.js 1.3.1 +// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore is freely distributable under the MIT license. +// Portions of Underscore are inspired or borrowed from Prototype, +// Oliver Steele's Functional, and John Resig's Micro-Templating. +// For all details and documentation: +// http://documentcloud.github.com/underscore + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `global` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Establish the object that gets returned to break out of a loop iteration. + var breaker = {}; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var slice = ArrayProto.slice, + unshift = ArrayProto.unshift, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeForEach = ArrayProto.forEach, + nativeMap = ArrayProto.map, + nativeReduce = ArrayProto.reduce, + nativeReduceRight = ArrayProto.reduceRight, + nativeFilter = ArrayProto.filter, + nativeEvery = ArrayProto.every, + nativeSome = ArrayProto.some, + nativeIndexOf = ArrayProto.indexOf, + nativeLastIndexOf = ArrayProto.lastIndexOf, + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { return new wrapper(obj); }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object via a string identifier, + // for Closure Compiler "advanced" mode. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root['_'] = _; + } + + // Current version. + _.VERSION = '1.3.1'; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles objects with the built-in `forEach`, arrays, and raw objects. + // Delegates to **ECMAScript 5**'s native `forEach` if available. + var each = _.each = _.forEach = function(obj, iterator, context) { + if (obj == null) return; + if (nativeForEach && obj.forEach === nativeForEach) { + obj.forEach(iterator, context); + } else if (obj.length === +obj.length) { + for (var i = 0, l = obj.length; i < l; i++) { + if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return; + } + } else { + for (var key in obj) { + if (_.has(obj, key)) { + if (iterator.call(context, obj[key], key, obj) === breaker) return; + } + } + } + }; + + // Return the results of applying the iterator to each element. + // Delegates to **ECMAScript 5**'s native `map` if available. + _.map = _.collect = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); + each(obj, function(value, index, list) { + results[results.length] = iterator.call(context, value, index, list); + }); + if (obj.length === +obj.length) results.length = obj.length; + return results; + }; + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. + _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduce && obj.reduce === nativeReduce) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); + } + each(obj, function(value, index, list) { + if (!initial) { + memo = value; + initial = true; + } else { + memo = iterator.call(context, memo, value, index, list); + } + }); + if (!initial) throw new TypeError('Reduce of empty array with no initial value'); + return memo; + }; + + // The right-associative version of reduce, also known as `foldr`. + // Delegates to **ECMAScript 5**'s native `reduceRight` if available. + _.reduceRight = _.foldr = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); + } + var reversed = _.toArray(obj).reverse(); + if (context && !initial) iterator = _.bind(iterator, context); + return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator); + }; + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, iterator, context) { + var result; + any(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) { + result = value; + return true; + } + }); + return result; + }; + + // Return all the elements that pass a truth test. + // Delegates to **ECMAScript 5**'s native `filter` if available. + // Aliased as `select`. + _.filter = _.select = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); + each(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + each(obj, function(value, index, list) { + if (!iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Determine whether all of the elements match a truth test. + // Delegates to **ECMAScript 5**'s native `every` if available. + // Aliased as `all`. + _.every = _.all = function(obj, iterator, context) { + var result = true; + if (obj == null) return result; + if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); + each(obj, function(value, index, list) { + if (!(result = result && iterator.call(context, value, index, list))) return breaker; + }); + return result; + }; + + // Determine if at least one element in the object matches a truth test. + // Delegates to **ECMAScript 5**'s native `some` if available. + // Aliased as `any`. + var any = _.some = _.any = function(obj, iterator, context) { + iterator || (iterator = _.identity); + var result = false; + if (obj == null) return result; + if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); + each(obj, function(value, index, list) { + if (result || (result = iterator.call(context, value, index, list))) return breaker; + }); + return !!result; + }; + + // Determine if a given value is included in the array or object using `===`. + // Aliased as `contains`. + _.include = _.contains = function(obj, target) { + var found = false; + if (obj == null) return found; + if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; + found = any(obj, function(value) { + return value === target; + }); + return found; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + return _.map(obj, function(value) { + return (_.isFunction(method) ? method || value : value[method]).apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, function(value){ return value[key]; }); + }; + + // Return the maximum element or (element-based computation). + _.max = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj); + if (!iterator && _.isEmpty(obj)) return -Infinity; + var result = {computed : -Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed >= result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj); + if (!iterator && _.isEmpty(obj)) return Infinity; + var result = {computed : Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed < result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Shuffle an array. + _.shuffle = function(obj) { + var shuffled = [], rand; + each(obj, function(value, index, list) { + if (index == 0) { + shuffled[0] = value; + } else { + rand = Math.floor(Math.random() * (index + 1)); + shuffled[index] = shuffled[rand]; + shuffled[rand] = value; + } + }); + return shuffled; + }; + + // Sort the object's values by a criterion produced by an iterator. + _.sortBy = function(obj, iterator, context) { + return _.pluck(_.map(obj, function(value, index, list) { + return { + value : value, + criteria : iterator.call(context, value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }), 'value'); + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = function(obj, val) { + var result = {}; + var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; }; + each(obj, function(value, index) { + var key = iterator(value, index); + (result[key] || (result[key] = [])).push(value); + }); + return result; + }; + + // Use a comparator function to figure out at what index an object should + // be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iterator) { + iterator || (iterator = _.identity); + var low = 0, high = array.length; + while (low < high) { + var mid = (low + high) >> 1; + iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid; + } + return low; + }; + + // Safely convert anything iterable into a real, live array. + _.toArray = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) return iterable.toArray(); + if (_.isArray(iterable)) return slice.call(iterable); + if (_.isArguments(iterable)) return slice.call(iterable); + return _.values(iterable); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + return _.toArray(obj).length; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head`. The **guard** check allows it to work + // with `_.map`. + _.first = _.head = function(array, n, guard) { + return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; + }; + + // Returns everything but the last entry of the array. Especcialy useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. The **guard** check allows it to work with + // `_.map`. + _.initial = function(array, n, guard) { + return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. The **guard** check allows it to work with `_.map`. + _.last = function(array, n, guard) { + if ((n != null) && !guard) { + return slice.call(array, Math.max(array.length - n, 0)); + } else { + return array[array.length - 1]; + } + }; + + // Returns everything but the first entry of the array. Aliased as `tail`. + // Especially useful on the arguments object. Passing an **index** will return + // the rest of the values in the array from that index onward. The **guard** + // check allows it to work with `_.map`. + _.rest = _.tail = function(array, index, guard) { + return slice.call(array, (index == null) || guard ? 1 : index); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, function(value){ return !!value; }); + }; + + // Return a completely flattened version of an array. + _.flatten = function(array, shallow) { + return _.reduce(array, function(memo, value) { + if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value)); + memo[memo.length] = value; + return memo; + }, []); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iterator) { + var initial = iterator ? _.map(array, iterator) : array; + var result = []; + _.reduce(initial, function(memo, el, i) { + if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) { + memo[memo.length] = el; + result[result.length] = array[i]; + } + return memo; + }, []); + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(_.flatten(arguments, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. (Aliased as "intersect" for back-compat.) + _.intersection = _.intersect = function(array) { + var rest = slice.call(arguments, 1); + return _.filter(_.uniq(array), function(item) { + return _.every(rest, function(other) { + return _.indexOf(other, item) >= 0; + }); + }); + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = _.flatten(slice.call(arguments, 1)); + return _.filter(array, function(value){ return !_.include(rest, value); }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + var args = slice.call(arguments); + var length = _.max(_.pluck(args, 'length')); + var results = new Array(length); + for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i); + return results; + }; + + // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), + // we need this function. Return the position of the first occurrence of an + // item in an array, or -1 if the item is not included in the array. + // Delegates to **ECMAScript 5**'s native `indexOf` if available. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = function(array, item, isSorted) { + if (array == null) return -1; + var i, l; + if (isSorted) { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item); + for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i; + return -1; + }; + + // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. + _.lastIndexOf = function(array, item) { + if (array == null) return -1; + if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item); + var i = array.length; + while (i--) if (i in array && array[i] === item) return i; + return -1; + }; + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (arguments.length <= 1) { + stop = start || 0; + start = 0; + } + step = arguments[2] || 1; + + var len = Math.max(Math.ceil((stop - start) / step), 0); + var idx = 0; + var range = new Array(len); + + while(idx < len) { + range[idx++] = start; + start += step; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Reusable constructor function for prototype setting. + var ctor = function(){}; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Binding with arguments is also known as `curry`. + // Delegates to **ECMAScript 5**'s native `Function.bind` if available. + // We check for `func.bind` first, to fail fast when `func` is undefined. + _.bind = function bind(func, context) { + var bound, args; + if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError; + args = slice.call(arguments, 2); + return bound = function() { + if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); + ctor.prototype = func.prototype; + var self = new ctor; + var result = func.apply(self, args.concat(slice.call(arguments))); + if (Object(result) === result) return result; + return self; + }; + }; + + // Bind all of an object's methods to that object. Useful for ensuring that + // all callbacks defined on an object belong to it. + _.bindAll = function(obj) { + var funcs = slice.call(arguments, 1); + if (funcs.length == 0) funcs = _.functions(obj); + each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memo = {}; + hasher || (hasher = _.identity); + return function() { + var key = hasher.apply(this, arguments); + return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); + }; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ return func.apply(func, args); }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = function(func) { + return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); + }; + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. + _.throttle = function(func, wait) { + var context, args, timeout, throttling, more; + var whenDone = _.debounce(function(){ more = throttling = false; }, wait); + return function() { + context = this; args = arguments; + var later = function() { + timeout = null; + if (more) func.apply(context, args); + whenDone(); + }; + if (!timeout) timeout = setTimeout(later, wait); + if (throttling) { + more = true; + } else { + func.apply(context, args); + } + whenDone(); + throttling = true; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. + _.debounce = function(func, wait) { + var timeout; + return function() { + var context = this, args = arguments; + var later = function() { + timeout = null; + func.apply(context, args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = function(func) { + var ran = false, memo; + return function() { + if (ran) return memo; + ran = true; + return memo = func.apply(this, arguments); + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return function() { + var args = [func].concat(slice.call(arguments, 0)); + return wrapper.apply(this, args); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var funcs = arguments; + return function() { + var args = arguments; + for (var i = funcs.length - 1; i >= 0; i--) { + args = [funcs[i].apply(this, args)]; + } + return args[0]; + }; + }; + + // Returns a function that will only be executed after being called N times. + _.after = function(times, func) { + if (times <= 0) return func(); + return function() { + if (--times < 1) { return func.apply(this, arguments); } + }; + }; + + // Object Functions + // ---------------- + + // Retrieve the names of an object's properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = nativeKeys || function(obj) { + if (obj !== Object(obj)) throw new TypeError('Invalid object'); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + return _.map(obj, _.identity); + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Fill in a given object with default properties. + _.defaults = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + if (obj[prop] == null) obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Internal recursive comparison function. + function eq(a, b, stack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal. + if (a === b) return a !== 0 || 1 / a == 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a._chain) a = a._wrapped; + if (b._chain) b = b._wrapped; + // Invoke a custom `isEqual` method if one is provided. + if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b); + if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a); + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className != toString.call(b)) return false; + switch (className) { + // Strings, numbers, dates, and booleans are compared by value. + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return a == String(b); + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for + // other numeric values. + return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a == +b; + // RegExps are compared by their source patterns and flags. + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') return false; + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + var length = stack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (stack[length] == a) return true; + } + // Add the first object to the stack of traversed objects. + stack.push(a); + var size = 0, result = true; + // Recursively compare objects and arrays. + if (className == '[object Array]') { + // Compare array lengths to determine if a deep comparison is necessary. + size = a.length; + result = size == b.length; + if (result) { + // Deep compare the contents, ignoring non-numeric properties. + while (size--) { + // Ensure commutative equality for sparse arrays. + if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break; + } + } + } else { + // Objects with different constructors are not equivalent. + if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false; + // Deep compare objects. + for (var key in a) { + if (_.has(a, key)) { + // Count the expected number of properties. + size++; + // Deep compare each member. + if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break; + } + } + // Ensure that both objects contain the same number of properties. + if (result) { + for (key in b) { + if (_.has(b, key) && !(size--)) break; + } + result = !size; + } + } + // Remove the first object from the stack of traversed objects. + stack.pop(); + return result; + } + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b, []); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; + for (var key in obj) if (_.has(obj, key)) return false; + return true; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType == 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) == '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + return obj === Object(obj); + }; + + // Is a given variable an arguments object? + _.isArguments = function(obj) { + return toString.call(obj) == '[object Arguments]'; + }; + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return !!(obj && _.has(obj, 'callee')); + }; + } + + // Is a given value a function? + _.isFunction = function(obj) { + return toString.call(obj) == '[object Function]'; + }; + + // Is a given value a string? + _.isString = function(obj) { + return toString.call(obj) == '[object String]'; + }; + + // Is a given value a number? + _.isNumber = function(obj) { + return toString.call(obj) == '[object Number]'; + }; + + // Is the given value `NaN`? + _.isNaN = function(obj) { + // `NaN` is the only value for which `===` is not reflexive. + return obj !== obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; + }; + + // Is a given value a date? + _.isDate = function(obj) { + return toString.call(obj) == '[object Date]'; + }; + + // Is the given value a regular expression? + _.isRegExp = function(obj) { + return toString.call(obj) == '[object RegExp]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Has own property? + _.has = function(obj, key) { + return hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iterators. + _.identity = function(value) { + return value; + }; + + // Run a function **n** times. + _.times = function (n, iterator, context) { + for (var i = 0; i < n; i++) iterator.call(context, i); + }; + + // Escape a string for HTML interpolation. + _.escape = function(string) { + return (''+string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/'); + }; + + // Add your own custom functions to the Underscore object, ensuring that + // they're correctly added to the OOP wrapper as well. + _.mixin = function(obj) { + each(_.functions(obj), function(name){ + addToWrapper(name, _[name] = obj[name]); + }); + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = idCounter++; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /.^/; + + // Within an interpolation, evaluation, or escaping, remove HTML escaping + // that had been previously added. + var unescape = function(code) { + return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'"); + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + _.template = function(str, data) { + var c = _.templateSettings; + var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + + 'with(obj||{}){__p.push(\'' + + str.replace(/\\/g, '\\\\') + .replace(/'/g, "\\'") + .replace(c.escape || noMatch, function(match, code) { + return "',_.escape(" + unescape(code) + "),'"; + }) + .replace(c.interpolate || noMatch, function(match, code) { + return "'," + unescape(code) + ",'"; + }) + .replace(c.evaluate || noMatch, function(match, code) { + return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('"; + }) + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t') + + "');}return __p.join('');"; + var func = new Function('obj', '_', tmpl); + if (data) return func(data, _); + return function(data) { + return func.call(this, data, _); + }; + }; + + // Add a "chain" function, which will delegate to the wrapper. + _.chain = function(obj) { + return _(obj).chain(); + }; + + // The OOP Wrapper + // --------------- + + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + var wrapper = function(obj) { this._wrapped = obj; }; + + // Expose `wrapper.prototype` as `_.prototype` + _.prototype = wrapper.prototype; + + // Helper function to continue chaining intermediate results. + var result = function(obj, chain) { + return chain ? _(obj).chain() : obj; + }; + + // A method to easily add functions to the OOP wrapper. + var addToWrapper = function(name, func) { + wrapper.prototype[name] = function() { + var args = slice.call(arguments); + unshift.call(args, this._wrapped); + return result(func.apply(_, args), this._chain); + }; + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + var wrapped = this._wrapped; + method.apply(wrapped, arguments); + var length = wrapped.length; + if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0]; + return result(wrapped, this._chain); + }; + }); + + // Add all accessor Array functions to the wrapper. + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + return result(method.apply(this._wrapped, arguments), this._chain); + }; + }); + + // Start chaining a wrapped Underscore object. + wrapper.prototype.chain = function() { + this._chain = true; + return this; + }; + + // Extracts the result from a wrapped and chained object. + wrapper.prototype.value = function() { + return this._wrapped; + }; + +}).call(this); diff --git a/docs/_static/underscore.js b/docs/_static/underscore.js new file mode 100644 index 0000000..5b55f32 --- /dev/null +++ b/docs/_static/underscore.js @@ -0,0 +1,31 @@ +// Underscore.js 1.3.1 +// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore is freely distributable under the MIT license. +// Portions of Underscore are inspired or borrowed from Prototype, +// Oliver Steele's Functional, and John Resig's Micro-Templating. +// For all details and documentation: +// http://documentcloud.github.com/underscore +(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== +c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c, +h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each= +b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a== +null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect= +function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e= +e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= +function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})}); +return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a, +c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest= +b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]); +return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c, +d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g}; +var F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a, +c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true: +a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}}; +b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments, +1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)}; +b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"}; +b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a), +function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+ +u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]= +function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain= +true;return this};m.prototype.value=function(){return this._wrapped}}).call(this); diff --git a/docs/_static/up-pressed.png b/docs/_static/up-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..acee3b68efbbfb9de3bfa73fce2531380f4bd820 GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`b3I)gLn;`PCGIF3$k*oP2u^Cy z1QG|_1=PYnb1D4eKdS9<Rfpq9eZvoV4(FRqOC&yU<ykZBR|+eZ3^{Bs(0fczS?$)o z1zBzqOjDB&rXLWUki_(ZOYf}S3_te-6HD<NwmmIcKX{MqZ}`C=pw3iiGvzP0)_49T zVzHmSR(wuwn8DsJUb!G^UBj0HEK?h9OzUY$<G#e5WDq>z%1p*-hql&#Z9G*2bSQ(T LtDnm{r-UW|Tp3Nf literal 0 HcmV?d00001 diff --git a/docs/_static/up.png b/docs/_static/up.png new file mode 100644 index 0000000000000000000000000000000000000000..2a940a7da7c14e6a36901e83306849ba7efad4d4 GIT binary patch literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6CV9FzhEy=Fov?Lbi-SbV{M7eb zSgRCN7I%METfw=?;;+>WH3cj0g7WUX+WNUO*ZcGT`ytIgVd8OSIh$j5tP~Z0O{ng4 zcW5}i$^L-SndMiXU*q89_#FKDQg!+}n<sY{bt~lf29~d`d|30$ek+#&XF;JwVZw1v z_UR0p3#2)&`AF%iuMw0u8SEq};^+A5QF+L(`y7{#wyduS<qiY7j=|H_&t;ucLK6TJ CK~C2I literal 0 HcmV?d00001 diff --git a/docs/_static/websupport.js b/docs/_static/websupport.js new file mode 100644 index 0000000..3b4999e --- /dev/null +++ b/docs/_static/websupport.js @@ -0,0 +1,808 @@ +/* + * websupport.js + * ~~~~~~~~~~~~~ + * + * sphinx.websupport utilities for all documentation. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +(function($) { + $.fn.autogrow = function() { + return this.each(function() { + var textarea = this; + + $.fn.autogrow.resize(textarea); + + $(textarea) + .focus(function() { + textarea.interval = setInterval(function() { + $.fn.autogrow.resize(textarea); + }, 500); + }) + .blur(function() { + clearInterval(textarea.interval); + }); + }); + }; + + $.fn.autogrow.resize = function(textarea) { + var lineHeight = parseInt($(textarea).css('line-height'), 10); + var lines = textarea.value.split('\n'); + var columns = textarea.cols; + var lineCount = 0; + $.each(lines, function() { + lineCount += Math.ceil(this.length / columns) || 1; + }); + var height = lineHeight * (lineCount + 1); + $(textarea).css('height', height); + }; +})(jQuery); + +(function($) { + var comp, by; + + function init() { + initEvents(); + initComparator(); + } + + function initEvents() { + $(document).on("click", 'a.comment-close', function(event) { + event.preventDefault(); + hide($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.vote', function(event) { + event.preventDefault(); + handleVote($(this)); + }); + $(document).on("click", 'a.reply', function(event) { + event.preventDefault(); + openReply($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.close-reply', function(event) { + event.preventDefault(); + closeReply($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.sort-option', function(event) { + event.preventDefault(); + handleReSort($(this)); + }); + $(document).on("click", 'a.show-proposal', function(event) { + event.preventDefault(); + showProposal($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.hide-proposal', function(event) { + event.preventDefault(); + hideProposal($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.show-propose-change', function(event) { + event.preventDefault(); + showProposeChange($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.hide-propose-change', function(event) { + event.preventDefault(); + hideProposeChange($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.accept-comment', function(event) { + event.preventDefault(); + acceptComment($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.delete-comment', function(event) { + event.preventDefault(); + deleteComment($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.comment-markup', function(event) { + event.preventDefault(); + toggleCommentMarkupBox($(this).attr('id').substring(2)); + }); + } + + /** + * Set comp, which is a comparator function used for sorting and + * inserting comments into the list. + */ + function setComparator() { + // If the first three letters are "asc", sort in ascending order + // and remove the prefix. + if (by.substring(0,3) == 'asc') { + var i = by.substring(3); + comp = function(a, b) { return a[i] - b[i]; }; + } else { + // Otherwise sort in descending order. + comp = function(a, b) { return b[by] - a[by]; }; + } + + // Reset link styles and format the selected sort option. + $('a.sel').attr('href', '#').removeClass('sel'); + $('a.by' + by).removeAttr('href').addClass('sel'); + } + + /** + * Create a comp function. If the user has preferences stored in + * the sortBy cookie, use those, otherwise use the default. + */ + function initComparator() { + by = 'rating'; // Default to sort by rating. + // If the sortBy cookie is set, use that instead. + if (document.cookie.length > 0) { + var start = document.cookie.indexOf('sortBy='); + if (start != -1) { + start = start + 7; + var end = document.cookie.indexOf(";", start); + if (end == -1) { + end = document.cookie.length; + by = unescape(document.cookie.substring(start, end)); + } + } + } + setComparator(); + } + + /** + * Show a comment div. + */ + function show(id) { + $('#ao' + id).hide(); + $('#ah' + id).show(); + var context = $.extend({id: id}, opts); + var popup = $(renderTemplate(popupTemplate, context)).hide(); + popup.find('textarea[name="proposal"]').hide(); + popup.find('a.by' + by).addClass('sel'); + var form = popup.find('#cf' + id); + form.submit(function(event) { + event.preventDefault(); + addComment(form); + }); + $('#s' + id).after(popup); + popup.slideDown('fast', function() { + getComments(id); + }); + } + + /** + * Hide a comment div. + */ + function hide(id) { + $('#ah' + id).hide(); + $('#ao' + id).show(); + var div = $('#sc' + id); + div.slideUp('fast', function() { + div.remove(); + }); + } + + /** + * Perform an ajax request to get comments for a node + * and insert the comments into the comments tree. + */ + function getComments(id) { + $.ajax({ + type: 'GET', + url: opts.getCommentsURL, + data: {node: id}, + success: function(data, textStatus, request) { + var ul = $('#cl' + id); + var speed = 100; + $('#cf' + id) + .find('textarea[name="proposal"]') + .data('source', data.source); + + if (data.comments.length === 0) { + ul.html('<li>No comments yet.</li>'); + ul.data('empty', true); + } else { + // If there are comments, sort them and put them in the list. + var comments = sortComments(data.comments); + speed = data.comments.length * 100; + appendComments(comments, ul); + ul.data('empty', false); + } + $('#cn' + id).slideUp(speed + 200); + ul.slideDown(speed); + }, + error: function(request, textStatus, error) { + showError('Oops, there was a problem retrieving the comments.'); + }, + dataType: 'json' + }); + } + + /** + * Add a comment via ajax and insert the comment into the comment tree. + */ + function addComment(form) { + var node_id = form.find('input[name="node"]').val(); + var parent_id = form.find('input[name="parent"]').val(); + var text = form.find('textarea[name="comment"]').val(); + var proposal = form.find('textarea[name="proposal"]').val(); + + if (text == '') { + showError('Please enter a comment.'); + return; + } + + // Disable the form that is being submitted. + form.find('textarea,input').attr('disabled', 'disabled'); + + // Send the comment to the server. + $.ajax({ + type: "POST", + url: opts.addCommentURL, + dataType: 'json', + data: { + node: node_id, + parent: parent_id, + text: text, + proposal: proposal + }, + success: function(data, textStatus, error) { + // Reset the form. + if (node_id) { + hideProposeChange(node_id); + } + form.find('textarea') + .val('') + .add(form.find('input')) + .removeAttr('disabled'); + var ul = $('#cl' + (node_id || parent_id)); + if (ul.data('empty')) { + $(ul).empty(); + ul.data('empty', false); + } + insertComment(data.comment); + var ao = $('#ao' + node_id); + ao.find('img').attr({'src': opts.commentBrightImage}); + if (node_id) { + // if this was a "root" comment, remove the commenting box + // (the user can get it back by reopening the comment popup) + $('#ca' + node_id).slideUp(); + } + }, + error: function(request, textStatus, error) { + form.find('textarea,input').removeAttr('disabled'); + showError('Oops, there was a problem adding the comment.'); + } + }); + } + + /** + * Recursively append comments to the main comment list and children + * lists, creating the comment tree. + */ + function appendComments(comments, ul) { + $.each(comments, function() { + var div = createCommentDiv(this); + ul.append($(document.createElement('li')).html(div)); + appendComments(this.children, div.find('ul.comment-children')); + // To avoid stagnating data, don't store the comments children in data. + this.children = null; + div.data('comment', this); + }); + } + + /** + * After adding a new comment, it must be inserted in the correct + * location in the comment tree. + */ + function insertComment(comment) { + var div = createCommentDiv(comment); + + // To avoid stagnating data, don't store the comments children in data. + comment.children = null; + div.data('comment', comment); + + var ul = $('#cl' + (comment.node || comment.parent)); + var siblings = getChildren(ul); + + var li = $(document.createElement('li')); + li.hide(); + + // Determine where in the parents children list to insert this comment. + for(var i=0; i < siblings.length; i++) { + if (comp(comment, siblings[i]) <= 0) { + $('#cd' + siblings[i].id) + .parent() + .before(li.html(div)); + li.slideDown('fast'); + return; + } + } + + // If we get here, this comment rates lower than all the others, + // or it is the only comment in the list. + ul.append(li.html(div)); + li.slideDown('fast'); + } + + function acceptComment(id) { + $.ajax({ + type: 'POST', + url: opts.acceptCommentURL, + data: {id: id}, + success: function(data, textStatus, request) { + $('#cm' + id).fadeOut('fast'); + $('#cd' + id).removeClass('moderate'); + }, + error: function(request, textStatus, error) { + showError('Oops, there was a problem accepting the comment.'); + } + }); + } + + function deleteComment(id) { + $.ajax({ + type: 'POST', + url: opts.deleteCommentURL, + data: {id: id}, + success: function(data, textStatus, request) { + var div = $('#cd' + id); + if (data == 'delete') { + // Moderator mode: remove the comment and all children immediately + div.slideUp('fast', function() { + div.remove(); + }); + return; + } + // User mode: only mark the comment as deleted + div + .find('span.user-id:first') + .text('[deleted]').end() + .find('div.comment-text:first') + .text('[deleted]').end() + .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id + + ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id) + .remove(); + var comment = div.data('comment'); + comment.username = '[deleted]'; + comment.text = '[deleted]'; + div.data('comment', comment); + }, + error: function(request, textStatus, error) { + showError('Oops, there was a problem deleting the comment.'); + } + }); + } + + function showProposal(id) { + $('#sp' + id).hide(); + $('#hp' + id).show(); + $('#pr' + id).slideDown('fast'); + } + + function hideProposal(id) { + $('#hp' + id).hide(); + $('#sp' + id).show(); + $('#pr' + id).slideUp('fast'); + } + + function showProposeChange(id) { + $('#pc' + id).hide(); + $('#hc' + id).show(); + var textarea = $('#pt' + id); + textarea.val(textarea.data('source')); + $.fn.autogrow.resize(textarea[0]); + textarea.slideDown('fast'); + } + + function hideProposeChange(id) { + $('#hc' + id).hide(); + $('#pc' + id).show(); + var textarea = $('#pt' + id); + textarea.val('').removeAttr('disabled'); + textarea.slideUp('fast'); + } + + function toggleCommentMarkupBox(id) { + $('#mb' + id).toggle(); + } + + /** Handle when the user clicks on a sort by link. */ + function handleReSort(link) { + var classes = link.attr('class').split(/\s+/); + for (var i=0; i<classes.length; i++) { + if (classes[i] != 'sort-option') { + by = classes[i].substring(2); + } + } + setComparator(); + // Save/update the sortBy cookie. + var expiration = new Date(); + expiration.setDate(expiration.getDate() + 365); + document.cookie= 'sortBy=' + escape(by) + + ';expires=' + expiration.toUTCString(); + $('ul.comment-ul').each(function(index, ul) { + var comments = getChildren($(ul), true); + comments = sortComments(comments); + appendComments(comments, $(ul).empty()); + }); + } + + /** + * Function to process a vote when a user clicks an arrow. + */ + function handleVote(link) { + if (!opts.voting) { + showError("You'll need to login to vote."); + return; + } + + var id = link.attr('id'); + if (!id) { + // Didn't click on one of the voting arrows. + return; + } + // If it is an unvote, the new vote value is 0, + // Otherwise it's 1 for an upvote, or -1 for a downvote. + var value = 0; + if (id.charAt(1) != 'u') { + value = id.charAt(0) == 'u' ? 1 : -1; + } + // The data to be sent to the server. + var d = { + comment_id: id.substring(2), + value: value + }; + + // Swap the vote and unvote links. + link.hide(); + $('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id) + .show(); + + // The div the comment is displayed in. + var div = $('div#cd' + d.comment_id); + var data = div.data('comment'); + + // If this is not an unvote, and the other vote arrow has + // already been pressed, unpress it. + if ((d.value !== 0) && (data.vote === d.value * -1)) { + $('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide(); + $('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show(); + } + + // Update the comments rating in the local data. + data.rating += (data.vote === 0) ? d.value : (d.value - data.vote); + data.vote = d.value; + div.data('comment', data); + + // Change the rating text. + div.find('.rating:first') + .text(data.rating + ' point' + (data.rating == 1 ? '' : 's')); + + // Send the vote information to the server. + $.ajax({ + type: "POST", + url: opts.processVoteURL, + data: d, + error: function(request, textStatus, error) { + showError('Oops, there was a problem casting that vote.'); + } + }); + } + + /** + * Open a reply form used to reply to an existing comment. + */ + function openReply(id) { + // Swap out the reply link for the hide link + $('#rl' + id).hide(); + $('#cr' + id).show(); + + // Add the reply li to the children ul. + var div = $(renderTemplate(replyTemplate, {id: id})).hide(); + $('#cl' + id) + .prepend(div) + // Setup the submit handler for the reply form. + .find('#rf' + id) + .submit(function(event) { + event.preventDefault(); + addComment($('#rf' + id)); + closeReply(id); + }) + .find('input[type=button]') + .click(function() { + closeReply(id); + }); + div.slideDown('fast', function() { + $('#rf' + id).find('textarea').focus(); + }); + } + + /** + * Close the reply form opened with openReply. + */ + function closeReply(id) { + // Remove the reply div from the DOM. + $('#rd' + id).slideUp('fast', function() { + $(this).remove(); + }); + + // Swap out the hide link for the reply link + $('#cr' + id).hide(); + $('#rl' + id).show(); + } + + /** + * Recursively sort a tree of comments using the comp comparator. + */ + function sortComments(comments) { + comments.sort(comp); + $.each(comments, function() { + this.children = sortComments(this.children); + }); + return comments; + } + + /** + * Get the children comments from a ul. If recursive is true, + * recursively include childrens' children. + */ + function getChildren(ul, recursive) { + var children = []; + ul.children().children("[id^='cd']") + .each(function() { + var comment = $(this).data('comment'); + if (recursive) + comment.children = getChildren($(this).find('#cl' + comment.id), true); + children.push(comment); + }); + return children; + } + + /** Create a div to display a comment in. */ + function createCommentDiv(comment) { + if (!comment.displayed && !opts.moderator) { + return $('<div class="moderate">Thank you! Your comment will show up ' + + 'once it is has been approved by a moderator.</div>'); + } + // Prettify the comment rating. + comment.pretty_rating = comment.rating + ' point' + + (comment.rating == 1 ? '' : 's'); + // Make a class (for displaying not yet moderated comments differently) + comment.css_class = comment.displayed ? '' : ' moderate'; + // Create a div for this comment. + var context = $.extend({}, opts, comment); + var div = $(renderTemplate(commentTemplate, context)); + + // If the user has voted on this comment, highlight the correct arrow. + if (comment.vote) { + var direction = (comment.vote == 1) ? 'u' : 'd'; + div.find('#' + direction + 'v' + comment.id).hide(); + div.find('#' + direction + 'u' + comment.id).show(); + } + + if (opts.moderator || comment.text != '[deleted]') { + div.find('a.reply').show(); + if (comment.proposal_diff) + div.find('#sp' + comment.id).show(); + if (opts.moderator && !comment.displayed) + div.find('#cm' + comment.id).show(); + if (opts.moderator || (opts.username == comment.username)) + div.find('#dc' + comment.id).show(); + } + return div; + } + + /** + * A simple template renderer. Placeholders such as <%id%> are replaced + * by context['id'] with items being escaped. Placeholders such as <#id#> + * are not escaped. + */ + function renderTemplate(template, context) { + var esc = $(document.createElement('div')); + + function handle(ph, escape) { + var cur = context; + $.each(ph.split('.'), function() { + cur = cur[this]; + }); + return escape ? esc.text(cur || "").html() : cur; + } + + return template.replace(/<([%#])([\w\.]*)\1>/g, function() { + return handle(arguments[2], arguments[1] == '%' ? true : false); + }); + } + + /** Flash an error message briefly. */ + function showError(message) { + $(document.createElement('div')).attr({'class': 'popup-error'}) + .append($(document.createElement('div')) + .attr({'class': 'error-message'}).text(message)) + .appendTo('body') + .fadeIn("slow") + .delay(2000) + .fadeOut("slow"); + } + + /** Add a link the user uses to open the comments popup. */ + $.fn.comment = function() { + return this.each(function() { + var id = $(this).attr('id').substring(1); + var count = COMMENT_METADATA[id]; + var title = count + ' comment' + (count == 1 ? '' : 's'); + var image = count > 0 ? opts.commentBrightImage : opts.commentImage; + var addcls = count == 0 ? ' nocomment' : ''; + $(this) + .append( + $(document.createElement('a')).attr({ + href: '#', + 'class': 'sphinx-comment-open' + addcls, + id: 'ao' + id + }) + .append($(document.createElement('img')).attr({ + src: image, + alt: 'comment', + title: title + })) + .click(function(event) { + event.preventDefault(); + show($(this).attr('id').substring(2)); + }) + ) + .append( + $(document.createElement('a')).attr({ + href: '#', + 'class': 'sphinx-comment-close hidden', + id: 'ah' + id + }) + .append($(document.createElement('img')).attr({ + src: opts.closeCommentImage, + alt: 'close', + title: 'close' + })) + .click(function(event) { + event.preventDefault(); + hide($(this).attr('id').substring(2)); + }) + ); + }); + }; + + var opts = { + processVoteURL: '/_process_vote', + addCommentURL: '/_add_comment', + getCommentsURL: '/_get_comments', + acceptCommentURL: '/_accept_comment', + deleteCommentURL: '/_delete_comment', + commentImage: '/static/_static/comment.png', + closeCommentImage: '/static/_static/comment-close.png', + loadingImage: '/static/_static/ajax-loader.gif', + commentBrightImage: '/static/_static/comment-bright.png', + upArrow: '/static/_static/up.png', + downArrow: '/static/_static/down.png', + upArrowPressed: '/static/_static/up-pressed.png', + downArrowPressed: '/static/_static/down-pressed.png', + voting: false, + moderator: false + }; + + if (typeof COMMENT_OPTIONS != "undefined") { + opts = jQuery.extend(opts, COMMENT_OPTIONS); + } + + var popupTemplate = '\ + <div class="sphinx-comments" id="sc<%id%>">\ + <p class="sort-options">\ + Sort by:\ + <a href="#" class="sort-option byrating">best rated</a>\ + <a href="#" class="sort-option byascage">newest</a>\ + <a href="#" class="sort-option byage">oldest</a>\ + </p>\ + <div class="comment-header">Comments</div>\ + <div class="comment-loading" id="cn<%id%>">\ + loading comments... <img src="<%loadingImage%>" alt="" /></div>\ + <ul id="cl<%id%>" class="comment-ul"></ul>\ + <div id="ca<%id%>">\ + <p class="add-a-comment">Add a comment\ + (<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\ + <div class="comment-markup-box" id="mb<%id%>">\ + reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \ + <code>``code``</code>, \ + code blocks: <code>::</code> and an indented block after blank line</div>\ + <form method="post" id="cf<%id%>" class="comment-form" action="">\ + <textarea name="comment" cols="80"></textarea>\ + <p class="propose-button">\ + <a href="#" id="pc<%id%>" class="show-propose-change">\ + Propose a change ▹\ + </a>\ + <a href="#" id="hc<%id%>" class="hide-propose-change">\ + Propose a change ▿\ + </a>\ + </p>\ + <textarea name="proposal" id="pt<%id%>" cols="80"\ + spellcheck="false"></textarea>\ + <input type="submit" value="Add comment" />\ + <input type="hidden" name="node" value="<%id%>" />\ + <input type="hidden" name="parent" value="" />\ + </form>\ + </div>\ + </div>'; + + var commentTemplate = '\ + <div id="cd<%id%>" class="sphinx-comment<%css_class%>">\ + <div class="vote">\ + <div class="arrow">\ + <a href="#" id="uv<%id%>" class="vote" title="vote up">\ + <img src="<%upArrow%>" />\ + </a>\ + <a href="#" id="uu<%id%>" class="un vote" title="vote up">\ + <img src="<%upArrowPressed%>" />\ + </a>\ + </div>\ + <div class="arrow">\ + <a href="#" id="dv<%id%>" class="vote" title="vote down">\ + <img src="<%downArrow%>" id="da<%id%>" />\ + </a>\ + <a href="#" id="du<%id%>" class="un vote" title="vote down">\ + <img src="<%downArrowPressed%>" />\ + </a>\ + </div>\ + </div>\ + <div class="comment-content">\ + <p class="tagline comment">\ + <span class="user-id"><%username%></span>\ + <span class="rating"><%pretty_rating%></span>\ + <span class="delta"><%time.delta%></span>\ + </p>\ + <div class="comment-text comment"><#text#></div>\ + <p class="comment-opts comment">\ + <a href="#" class="reply hidden" id="rl<%id%>">reply ▹</a>\ + <a href="#" class="close-reply" id="cr<%id%>">reply ▿</a>\ + <a href="#" id="sp<%id%>" class="show-proposal">proposal ▹</a>\ + <a href="#" id="hp<%id%>" class="hide-proposal">proposal ▿</a>\ + <a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\ + <span id="cm<%id%>" class="moderation hidden">\ + <a href="#" id="ac<%id%>" class="accept-comment">accept</a>\ + </span>\ + </p>\ + <pre class="proposal" id="pr<%id%>">\ +<#proposal_diff#>\ + </pre>\ + <ul class="comment-children" id="cl<%id%>"></ul>\ + </div>\ + <div class="clearleft"></div>\ + </div>\ + </div>'; + + var replyTemplate = '\ + <li>\ + <div class="reply-div" id="rd<%id%>">\ + <form id="rf<%id%>">\ + <textarea name="comment" cols="80"></textarea>\ + <input type="submit" value="Add reply" />\ + <input type="button" value="Cancel" />\ + <input type="hidden" name="parent" value="<%id%>" />\ + <input type="hidden" name="node" value="" />\ + </form>\ + </div>\ + </li>'; + + $(document).ready(function() { + init(); + }); +})(jQuery); + +$(document).ready(function() { + // add comment anchors for all paragraphs that are commentable + $('.sphinx-has-comment').comment(); + + // highlight search words in search results + $("div.context").each(function() { + var params = $.getQueryParameters(); + var terms = (params.q) ? params.q[0].split(/\s+/) : []; + var result = $(this); + $.each(terms, function() { + result.highlightText(this.toLowerCase(), 'highlighted'); + }); + }); + + // directly open comment window if requested + var anchor = document.location.hash; + if (anchor.substring(0, 9) == '#comment-') { + $('#ao' + anchor.substring(9)).click(); + document.location.hash = '#s' + anchor.substring(9); + } +}); diff --git a/docs/cfelpyutils.crystfel_utils.html b/docs/cfelpyutils.crystfel_utils.html new file mode 100644 index 0000000..d162d9e --- /dev/null +++ b/docs/cfelpyutils.crystfel_utils.html @@ -0,0 +1,148 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>The crystfel_utils Module — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + <link rel="next" title="The geometry_utils Module" href="cfelpyutils.geometry_utils.html" /> + <link rel="prev" title="The cfelpyutils Package" href="cfelpyutils.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <div class="section" id="module-cfelpyutils.crystfel_utils"> +<span id="the-crystfel-utils-module"></span><h1>The crystfel_utils Module<a class="headerlink" href="#module-cfelpyutils.crystfel_utils" title="Permalink to this headline">¶</a></h1> +<p>CrystFEL utilities.</p> +<p>This module contains Python reimplementations of some functions from the <a class="reference external" href="http://www.desy.de/~twhite/crystfel">CrystFEL</a> software package.</p> +<dl class="function"> +<dt id="cfelpyutils.crystfel_utils.load_crystfel_geometry"> +<code class="descname">load_crystfel_geometry</code><span class="sig-paren">(</span><em>filename</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/cfelpyutils/crystfel_utils.html#load_crystfel_geometry"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#cfelpyutils.crystfel_utils.load_crystfel_geometry" title="Permalink to this definition">¶</a></dt> +<dd><p>Loads a CrystFEL geometry file.</p> +<p>This function is a reimplementation of the get_detector_geometry_2 function from +CrystFEL. It reads information from a CrystFEL geometry file.</p> +<p>For a full documentation of the CrystFEL geometry format, see the relevant <a class="reference external" href="http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html">man +page</a>.</p> +<p>The function returns a dictionary with the geometry information.</p> +<ul class="simple"> +<li>The CrystFEL geometry file uses a key/value language. The keys in the returned +dictionary match the keys in the geometry file.</li> +<li>The dictionary values store the corresponding values.</li> +<li>The code of this function is currently synchronized with the code of the function +‘get_detector_geometry_2’ in CrystFEL at commit 41a8fa9819010.</li> +</ul> +<table class="docutils field-list" frame="void" rules="none"> +<col class="field-name" /> +<col class="field-body" /> +<tbody valign="top"> +<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>filename</strong> (<em>str</em>) – the absolute or relative path to a CrystFEL geometry file.</td> +</tr> +<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">a dictionary with the geometry information loaded from the +file.</td> +</tr> +<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">Dict[str, Any]</td> +</tr> +</tbody> +</table> +</dd></dl> + +</div> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul class="current"> +<li class="toctree-l1 current"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a><ul class="current"> +<li class="toctree-l2 current"><a class="current reference internal" href="#">crystfel_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.geometry_utils.html">geometry_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.named_tuples.html">named_tuples</a></li> +</ul> +</li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + <li><a href="cfelpyutils.html">The cfelpyutils Package</a><ul> + <li>Previous: <a href="cfelpyutils.html" title="previous chapter">The cfelpyutils Package</a></li> + <li>Next: <a href="cfelpyutils.geometry_utils.html" title="next chapter">The geometry_utils Module</a></li> + </ul></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs/cfelpyutils.geometry_utils.html b/docs/cfelpyutils.geometry_utils.html new file mode 100644 index 0000000..77c72d0 --- /dev/null +++ b/docs/cfelpyutils.geometry_utils.html @@ -0,0 +1,214 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>The geometry_utils Module — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + <link rel="next" title="The named_tuples Module" href="cfelpyutils.named_tuples.html" /> + <link rel="prev" title="The crystfel_utils Module" href="cfelpyutils.crystfel_utils.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <div class="section" id="module-cfelpyutils.geometry_utils"> +<span id="the-geometry-utils-module"></span><h1>The geometry_utils Module<a class="headerlink" href="#module-cfelpyutils.geometry_utils" title="Permalink to this headline">¶</a></h1> +<p>Geometry utilities.</p> +<p>This module contains functions that manipulate geometry information.</p> +<dl class="function"> +<dt id="cfelpyutils.geometry_utils.compute_pix_maps"> +<code class="descname">compute_pix_maps</code><span class="sig-paren">(</span><em>geometry</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/cfelpyutils/geometry_utils.html#compute_pix_maps"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#cfelpyutils.geometry_utils.compute_pix_maps" title="Permalink to this definition">¶</a></dt> +<dd><p>Computes pixel maps from CrystFEL geometry information.</p> +<p>This function takes as input some geometry information read from a <a class="reference external" href="http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html">CrystFEL</a> file, and +returns a set of some pre-computed pixel maps.</p> +<p>The origin and the orientation of the reference system for the pixel maps follow +the same conventions as in CrystFEL:</p> +<ul class="simple"> +<li>The center of the reference system is the beam interaction point.</li> +<li>+z is the beam direction, and points along the beam (i.e. away from the source).</li> +<li>+y points towards the zenith (ceiling).</li> +<li>+x completes the right-handed coordinate system.</li> +</ul> +<table class="docutils field-list" frame="void" rules="none"> +<col class="field-name" /> +<col class="field-body" /> +<tbody valign="top"> +<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>geometry</strong> (<em>Dict</em><em>[</em><em>str</em><em>, </em><em>Any</em><em>]</em>) – a CrystFEL geometry object (A dictionary returned by +the <a class="reference internal" href="cfelpyutils.crystfel_utils.html#cfelpyutils.crystfel_utils.load_crystfel_geometry" title="cfelpyutils.crystfel_utils.load_crystfel_geometry"><code class="xref py py-func docutils literal notranslate"><span class="pre">load_crystfel_geometry()</span></code></a> function).</td> +</tr> +<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">a named tuple storing the the +pixel maps.</td> +</tr> +<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><a class="reference internal" href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps" title="cfelpyutils.named_tuples.PixelMaps"><code class="xref py py-class docutils literal notranslate"><span class="pre">PixelMaps</span></code></a></td> +</tr> +</tbody> +</table> +</dd></dl> + +<dl class="function"> +<dt id="cfelpyutils.geometry_utils.compute_visualization_pix_maps"> +<code class="descname">compute_visualization_pix_maps</code><span class="sig-paren">(</span><em>geometry</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/cfelpyutils/geometry_utils.html#compute_visualization_pix_maps"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#cfelpyutils.geometry_utils.compute_visualization_pix_maps" title="Permalink to this definition">¶</a></dt> +<dd><p>Computes pixel maps for data visualization from CrystFEL geometry information.</p> +<p>This function takes as input some geometry information read from a <a class="reference external" href="http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html">CrystFEL</a> file, and +returns a set of some pre-computed pixel maps that can be used to display data in +an ImageView widget from the <a class="reference external" href="http://pyqtgraph.org/">PyQtGraph</a> library.</p> +<p>These pixel maps are different from the ones generated by the +<a class="reference internal" href="#cfelpyutils.geometry_utils.compute_pix_maps" title="cfelpyutils.geometry_utils.compute_pix_maps"><code class="xref py py-func docutils literal notranslate"><span class="pre">compute_pix_maps()</span></code></a> function. The main differences are:</p> +<ul class="simple"> +<li>The origin of the reference system is not the beam interaction point, but the top +left corner of the array used to visualize the data.</li> +<li>Only the x and y pixel maps are available. The other entries in the named tuple +(z, r and phi) are set to None.</li> +</ul> +<table class="docutils field-list" frame="void" rules="none"> +<col class="field-name" /> +<col class="field-body" /> +<tbody valign="top"> +<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>geometry</strong> (<em>Dict</em><em>[</em><em>str</em><em>, </em><em>Any</em><em>]</em>) – a CrystFEL geometry object (A dictionary returned by +the <a class="reference internal" href="cfelpyutils.crystfel_utils.html#cfelpyutils.crystfel_utils.load_crystfel_geometry" title="cfelpyutils.crystfel_utils.load_crystfel_geometry"><code class="xref py py-func docutils literal notranslate"><span class="pre">load_crystfel_geometry()</span></code></a> function).</td> +</tr> +<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">a named tuple with the pixel maps.</td> +</tr> +<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><code class="xref py py-class docutils literal notranslate"><span class="pre">PixelMaps</span></code></td> +</tr> +</tbody> +</table> +</dd></dl> + +<dl class="function"> +<dt id="cfelpyutils.geometry_utils.apply_geometry_to_data"> +<code class="descname">apply_geometry_to_data</code><span class="sig-paren">(</span><em>data</em>, <em>geometry</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/cfelpyutils/geometry_utils.html#apply_geometry_to_data"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#cfelpyutils.geometry_utils.apply_geometry_to_data" title="Permalink to this definition">¶</a></dt> +<dd><p>Applies CrystFEL geometry information to some data.</p> +<p>This function takes as input some geometry information read from a <a class="reference external" href="http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html">CrystFEL</a> file, and +some data on which to apply it. It returns an array that can be displayed using a +library like <a class="reference external" href="https://matplotlib.org/">matplotlib</a> or +<a class="reference external" href="http://pyqtgraph.org/">PyQtGraph</a>.</p> +<p>The shape of the returned array is big enough to display all the input pixel +values, and is symmetric around the center of the reference system (i.e: the beam +interaction point).</p> +<p>NOTE: This restrictions often cause the returned array to be bigger than the minimum +size needed to store the physical layout of the pixels in the detector, +particularly if the detector is not centered at the beam interaction point.</p> +<table class="docutils field-list" frame="void" rules="none"> +<col class="field-name" /> +<col class="field-body" /> +<tbody valign="top"> +<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> +<li><strong>data</strong> (<em>numpy.ndarray</em>) – the data on which the geometry information should be +applied.</li> +<li><strong>geometry</strong> (<em>Dict</em><em>[</em><em>str</em><em>, </em><em>Any</em><em>]</em>) – a CrystFEL geometry object (A dictionary returned by +the <a class="reference internal" href="cfelpyutils.crystfel_utils.html#cfelpyutils.crystfel_utils.load_crystfel_geometry" title="cfelpyutils.crystfel_utils.load_crystfel_geometry"><code class="xref py py-func docutils literal notranslate"><span class="pre">load_crystfel_geometry()</span></code></a> function).</li> +</ul> +</td> +</tr> +<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">an array containing the data with the geometry information +applied.</p> +</td> +</tr> +<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">numpy.ndarray</p> +</td> +</tr> +</tbody> +</table> +</dd></dl> + +</div> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul class="current"> +<li class="toctree-l1 current"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a><ul class="current"> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.crystfel_utils.html">crystfel_utils</a></li> +<li class="toctree-l2 current"><a class="current reference internal" href="#">geometry_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.named_tuples.html">named_tuples</a></li> +</ul> +</li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + <li><a href="cfelpyutils.html">The cfelpyutils Package</a><ul> + <li>Previous: <a href="cfelpyutils.crystfel_utils.html" title="previous chapter">The crystfel_utils Module</a></li> + <li>Next: <a href="cfelpyutils.named_tuples.html" title="next chapter">The named_tuples Module</a></li> + </ul></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs/cfelpyutils.html b/docs/cfelpyutils.html new file mode 100644 index 0000000..24ffb50 --- /dev/null +++ b/docs/cfelpyutils.html @@ -0,0 +1,121 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>The cfelpyutils Package — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + <link rel="next" title="The crystfel_utils Module" href="cfelpyutils.crystfel_utils.html" /> + <link rel="prev" title="CFELPyUtils" href="index.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <div class="section" id="module-cfelpyutils"> +<span id="the-cfelpyutils-package"></span><h1>The cfelpyutils Package<a class="headerlink" href="#module-cfelpyutils" title="Permalink to this headline">¶</a></h1> +<p>The main CFELPyUtils package, which contains the whole library.</p> +<div class="toctree-wrapper compound"> +<ul> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.crystfel_utils.html">crystfel_utils</a></li> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.geometry_utils.html">geometry_utils</a></li> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.named_tuples.html">named_tuples</a></li> +</ul> +</div> +</div> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul class="current"> +<li class="toctree-l1 current"><a class="current reference internal" href="#">The cfelpyutils Package</a><ul> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.crystfel_utils.html">crystfel_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.geometry_utils.html">geometry_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.named_tuples.html">named_tuples</a></li> +</ul> +</li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + <li>Previous: <a href="index.html" title="previous chapter">CFELPyUtils</a></li> + <li>Next: <a href="cfelpyutils.crystfel_utils.html" title="next chapter">The crystfel_utils Module</a></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs/cfelpyutils.named_tuples.html b/docs/cfelpyutils.named_tuples.html new file mode 100644 index 0000000..d992c10 --- /dev/null +++ b/docs/cfelpyutils.named_tuples.html @@ -0,0 +1,170 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>The named_tuples Module — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + <link rel="prev" title="The geometry_utils Module" href="cfelpyutils.geometry_utils.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <div class="section" id="module-cfelpyutils.named_tuples"> +<span id="the-named-tuples-module"></span><h1>The named_tuples Module<a class="headerlink" href="#module-cfelpyutils.named_tuples" title="Permalink to this headline">¶</a></h1> +<p>CFELPyUtils named tuples.</p> +<p>This module contains a collection of named tuples used throughout the CFELPyUtils +library.</p> +<dl class="class"> +<dt id="cfelpyutils.named_tuples.PixelMaps"> +<em class="property">class </em><code class="descname">PixelMaps</code><a class="headerlink" href="#cfelpyutils.named_tuples.PixelMaps" title="Permalink to this definition">¶</a></dt> +<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">tuple</span></code></p> +<p>Pixel maps that store geometry information.</p> +<table class="docutils field-list" frame="void" rules="none"> +<col class="field-name" /> +<col class="field-body" /> +<tbody valign="top"> +<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple"> +<li><strong>x</strong> (<em>numpy.ndarray</em>) – pixel map for the x coordinate.</li> +<li><strong>y</strong> (<em>numpy.ndarray</em>) – pixel map for the y coordinate.</li> +<li><strong>z</strong> (<em>numpy.ndarray</em>) – pixel map for the z coordinate.</li> +<li><strong>r</strong> (<em>numpy.ndarray</em>) – pixel map storing the distance of each pixel from the center of +the reference system.</li> +<li><strong>phi</strong> (<em>numpy.ndarray</em>) – pixel map storing the amplitude of the angle between each +pixel, the center of the reference system, and the x axis through the center.</li> +</ul> +</td> +</tr> +</tbody> +</table> +<dl class="attribute"> +<dt id="cfelpyutils.named_tuples.PixelMaps.phi"> +<code class="descname">phi</code><a class="headerlink" href="#cfelpyutils.named_tuples.PixelMaps.phi" title="Permalink to this definition">¶</a></dt> +<dd><p>Alias for field number 4</p> +</dd></dl> + +<dl class="attribute"> +<dt id="cfelpyutils.named_tuples.PixelMaps.r"> +<code class="descname">r</code><a class="headerlink" href="#cfelpyutils.named_tuples.PixelMaps.r" title="Permalink to this definition">¶</a></dt> +<dd><p>Alias for field number 3</p> +</dd></dl> + +<dl class="attribute"> +<dt id="cfelpyutils.named_tuples.PixelMaps.x"> +<code class="descname">x</code><a class="headerlink" href="#cfelpyutils.named_tuples.PixelMaps.x" title="Permalink to this definition">¶</a></dt> +<dd><p>Alias for field number 0</p> +</dd></dl> + +<dl class="attribute"> +<dt id="cfelpyutils.named_tuples.PixelMaps.y"> +<code class="descname">y</code><a class="headerlink" href="#cfelpyutils.named_tuples.PixelMaps.y" title="Permalink to this definition">¶</a></dt> +<dd><p>Alias for field number 1</p> +</dd></dl> + +<dl class="attribute"> +<dt id="cfelpyutils.named_tuples.PixelMaps.z"> +<code class="descname">z</code><a class="headerlink" href="#cfelpyutils.named_tuples.PixelMaps.z" title="Permalink to this definition">¶</a></dt> +<dd><p>Alias for field number 2</p> +</dd></dl> + +</dd></dl> + +</div> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul class="current"> +<li class="toctree-l1 current"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a><ul class="current"> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.crystfel_utils.html">crystfel_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.geometry_utils.html">geometry_utils</a></li> +<li class="toctree-l2 current"><a class="current reference internal" href="#">named_tuples</a></li> +</ul> +</li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + <li><a href="cfelpyutils.html">The cfelpyutils Package</a><ul> + <li>Previous: <a href="cfelpyutils.geometry_utils.html" title="previous chapter">The geometry_utils Module</a></li> + </ul></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs/cfelpyutils.rst b/docs/cfelpyutils.rst deleted file mode 100644 index 59efdc8..0000000 --- a/docs/cfelpyutils.rst +++ /dev/null @@ -1,16 +0,0 @@ -cfelpyutils package -=================== - -.. automodule:: cfelpyutils - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -.. toctree:: - - cfelpyutils.crystfel_utils - cfelpyutils.geometry_utils - diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index 7211d42..0000000 --- a/docs/conf.py +++ /dev/null @@ -1,84 +0,0 @@ -# pylint: disable=C0111 -# -*- coding: utf-8 -*- -# -# Configuration file for the Sphinx documentation builder. -# -# This file does only contain a selection of the most common options. For a -# full list see the documentation: -# http://www.sphinx-doc.org/en/master/config - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('..')) -import os -import sys -sys.path.insert(0, os.path.abspath('..')) - - -# -- Project information ----------------------------------------------------- -project = "cfelpyutils" # pylint: disable=C0103 -copyright = ( # pylint: disable=C0103, W0622 - """ - Copyright © 2018 Deutsches Elektronen-Synchrotron DESY,' - 'a research centre of the Helmholtz Association.' - """ -) -author = "OnDA Team" # pylint: disable=C0103 - -# The short X.Y version -version = "0.9" # pylint: disable=C0103 -# The full version, including alpha/beta/rc tags -release = "0.9" # pylint: disable=C0103 - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ # pylint: disable=C0103 - 'sphinx.ext.autodoc', - 'sphinx.ext.viewcode', - 'sphinx.ext.todo', - 'sphinx.ext.napoleon', -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] # pylint: disable=C0103 - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -source_suffix = ".rst" # pylint: disable=C0103 - -# The master toctree document. -master_doc = "index" # pylint: disable=C0103 - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = "en" # pylint: disable=C0103 - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path . -exclude_patterns = [ # pylint: disable=C0103 - '_build', - 'Thumbs.db', - '.DS_Store' -] - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' # pylint: disable=C0103 - -# -- Extension configuration ------------------------------------------------- -add_module_names = False # pylint: disable=C0103 -autodoc_member_order = 'bysource' # pylint: disable=C0103 -autoclass_content = 'init' # pylint: disable=C0103 diff --git a/docs/genindex.html b/docs/genindex.html new file mode 100644 index 0000000..c2a43c1 --- /dev/null +++ b/docs/genindex.html @@ -0,0 +1,196 @@ + + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>Index — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="#" /> + <link rel="search" title="Search" href="search.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + +<h1 id="index">Index</h1> + +<div class="genindex-jumpbox"> + <a href="#A"><strong>A</strong></a> + | <a href="#C"><strong>C</strong></a> + | <a href="#L"><strong>L</strong></a> + | <a href="#P"><strong>P</strong></a> + | <a href="#R"><strong>R</strong></a> + | <a href="#X"><strong>X</strong></a> + | <a href="#Y"><strong>Y</strong></a> + | <a href="#Z"><strong>Z</strong></a> + +</div> +<h2 id="A">A</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.geometry_utils.html#cfelpyutils.geometry_utils.apply_geometry_to_data">apply_geometry_to_data() (in module cfelpyutils.geometry_utils)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="C">C</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.html#module-cfelpyutils">cfelpyutils (module)</a> +</li> + <li><a href="cfelpyutils.crystfel_utils.html#module-cfelpyutils.crystfel_utils">cfelpyutils.crystfel_utils (module)</a> +</li> + <li><a href="cfelpyutils.geometry_utils.html#module-cfelpyutils.geometry_utils">cfelpyutils.geometry_utils (module)</a> +</li> + </ul></td> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#module-cfelpyutils.named_tuples">cfelpyutils.named_tuples (module)</a> +</li> + <li><a href="cfelpyutils.geometry_utils.html#cfelpyutils.geometry_utils.compute_pix_maps">compute_pix_maps() (in module cfelpyutils.geometry_utils)</a> +</li> + <li><a href="cfelpyutils.geometry_utils.html#cfelpyutils.geometry_utils.compute_visualization_pix_maps">compute_visualization_pix_maps() (in module cfelpyutils.geometry_utils)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="L">L</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.crystfel_utils.html#cfelpyutils.crystfel_utils.load_crystfel_geometry">load_crystfel_geometry() (in module cfelpyutils.crystfel_utils)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="P">P</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps.phi">phi (PixelMaps attribute)</a> +</li> + </ul></td> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps">PixelMaps (class in cfelpyutils.named_tuples)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="R">R</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps.r">r (PixelMaps attribute)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="X">X</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps.x">x (PixelMaps attribute)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="Y">Y</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps.y">y (PixelMaps attribute)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="Z">Z</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps.z">z (PixelMaps attribute)</a> +</li> + </ul></td> +</tr></table> + + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..ea167f9 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,117 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>CFELPyUtils — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + <link rel="next" title="The cfelpyutils Package" href="cfelpyutils.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <div class="section" id="cfelpyutils"> +<h1>CFELPyUtils<a class="headerlink" href="#cfelpyutils" title="Permalink to this headline">¶</a></h1> +<div class="toctree-wrapper compound"> +</div> +<div class="section" id="introduction"> +<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2> +<p>CFELPyUtils is a utility library written in Python and developed at the Center For Free +Electron Laser Science (CFEL) in Hamburg. It contains several functions and classes +that perform various tasks related to the processing of x-ray imaging data (currently, +mostly reading and applying geometry information to x-ray detector data). It is used by +several internal and released CFEL software projects.</p> +</div> +<div class="section" id="installation"> +<h2>Installation<a class="headerlink" href="#installation" title="Permalink to this headline">¶</a></h2> +<p>The CFELPyUtils library is available on PyPI and can be installed using the pip +command:</p> +<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>python3 -m pip install cfelpyutils +</pre></div> +</div> +<p>Or, for python2:</p> +<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>python -m pip install cfelpyutils +</pre></div> +</div> +<p>It is also available as an Anaconda package in the ‘ondateam’ channel. It can be +installed using the ‘conda’ command:</p> +<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>conda install -c ondateam cfelpyutils +</pre></div> +</div> +</div> +<div class="section" id="code-documentation"> +<h2>Code Documentation<a class="headerlink" href="#code-documentation" title="Permalink to this headline">¶</a></h2> +<p>Code documentation for the CFELPyUtils library can be found <a class="reference internal" href="cfelpyutils.html"><span class="doc">here</span></a>.</p> +</div> +</div> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> + <h3><a href="#">Table of Contents</a></h3> + <ul> +<li><a class="reference internal" href="#">CFELPyUtils</a><ul> +<li><a class="reference internal" href="#introduction">Introduction</a></li> +<li><a class="reference internal" href="#installation">Installation</a></li> +<li><a class="reference internal" href="#code-documentation">Code Documentation</a></li> +</ul> +</li> +</ul> + +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index b4d8093..0000000 --- a/docs/index.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. cfelpyutils documentation master file, created by - sphinx-quickstart on Tue Jul 10 12:10:05 2018. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to cfelpyutils's documentation! -======================================= - -CfelPyUtils is a library of several utility functions and -classes used by several software projects developed at the -Center For Free Electron Laser Science (CFEL) in Hamburg. - - -.. toctree:: - :maxdepth: 4 - :caption: Contents: - - cfelpyutils - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/modules.html b/docs/modules.html new file mode 100644 index 0000000..c6b1e68 --- /dev/null +++ b/docs/modules.html @@ -0,0 +1,114 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>cfelpyutils — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <div class="section" id="cfelpyutils"> +<h1>cfelpyutils<a class="headerlink" href="#cfelpyutils" title="Permalink to this headline">¶</a></h1> +<div class="toctree-wrapper compound"> +<ul> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a><ul> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.crystfel_utils.html">crystfel_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.geometry_utils.html">geometry_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.named_tuples.html">named_tuples</a></li> +</ul> +</li> +</ul> +</div> +</div> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs/objects.inv b/docs/objects.inv new file mode 100644 index 0000000..34d0743 --- /dev/null +++ b/docs/objects.inv @@ -0,0 +1,8 @@ +# Sphinx inventory version 2 +# Project: CFELPyUtils +# Version: 1.0.0 +# The remainder of this file is compressed using zlib. +xÚµ”Ánƒ0†ï}ŠHÛ•j½ö:mÒ¤MBÚvŽÜÄ-щH˜HŸ~ ¡-¡@7ÜÀþýý–Áf[”ÚUVHC´[çŠWÉaçø2³¹¼™äž$‹nŽ•ÎØÃ;FIJ?—R§§ØUŽ¶tÞh[Ì +UÕU«¾Çs¥ëX6ÙuO +ZKwê–ZE9X˜èzÈêŠS¹®,R-jšƒ6óп…©@Š=xì¼ +È‘S[i‰ãÓïŠ&g SQ£|k[dŒéõw‰ýo©3á™`m)6‡ÑÜŠ[ÎBg¡ºY¨ûQ‰±|Í#Éêâl‘»A’û‚NÝ°ÜÀ] ô¸úùG§®Í`o~¯z€mÓýbŠ ;ªlÉ;,DÁ±nH6(=ë µ/þqq–µ†ÅãóÓkê>½÷â°¶Dí’c"”ÿ–mJ–Å!Äï!Ÿúoù›aŒ& \ No newline at end of file diff --git a/docs/py-modindex.html b/docs/py-modindex.html new file mode 100644 index 0000000..02294c3 --- /dev/null +++ b/docs/py-modindex.html @@ -0,0 +1,137 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>Python Module Index — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + + <h1>Python Module Index</h1> + + <div class="modindex-jumpbox"> + <a href="#cap-c"><strong>c</strong></a> + </div> + + <table class="indextable modindextable"> + <tr class="pcap"><td></td><td> </td><td></td></tr> + <tr class="cap" id="cap-c"><td></td><td> + <strong>c</strong></td><td></td></tr> + <tr> + <td><img src="_static/minus.png" class="toggler" + id="toggle-1" style="display: none" alt="-" /></td> + <td> + <a href="cfelpyutils.html#module-cfelpyutils"><code class="xref">cfelpyutils</code></a></td><td> + <em></em></td></tr> + <tr class="cg-1"> + <td></td> + <td>    + <a href="cfelpyutils.crystfel_utils.html#module-cfelpyutils.crystfel_utils"><code class="xref">cfelpyutils.crystfel_utils</code></a></td><td> + <em></em></td></tr> + <tr class="cg-1"> + <td></td> + <td>    + <a href="cfelpyutils.geometry_utils.html#module-cfelpyutils.geometry_utils"><code class="xref">cfelpyutils.geometry_utils</code></a></td><td> + <em></em></td></tr> + <tr class="cg-1"> + <td></td> + <td>    + <a href="cfelpyutils.named_tuples.html#module-cfelpyutils.named_tuples"><code class="xref">cfelpyutils.named_tuples</code></a></td><td> + <em></em></td></tr> + </table> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs/search.html b/docs/search.html new file mode 100644 index 0000000..a117965 --- /dev/null +++ b/docs/search.html @@ -0,0 +1,120 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>Search — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <script type="text/javascript" src="_static/searchtools.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="#" /> + <script type="text/javascript"> + jQuery(function() { Search.loadIndex("searchindex.js"); }); + </script> + + <script type="text/javascript" id="searchindexloader"></script> + + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <h1 id="search-documentation">Search</h1> + <div id="fallback" class="admonition warning"> + <script type="text/javascript">$('#fallback').hide();</script> + <p> + Please activate JavaScript to enable the search + functionality. + </p> + </div> + <p> + From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. + </p> + <form action="" method="get"> + <input type="text" name="q" value="" /> + <input type="submit" value="search" /> + <span id="search-progress" style="padding-left: 10px"></span> + </form> + + <div id="search-results"> + + </div> + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + </ul></li> +</ul> +</div> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs/searchindex.js b/docs/searchindex.js new file mode 100644 index 0000000..be933e7 --- /dev/null +++ b/docs/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({docnames:["cfelpyutils","cfelpyutils.crystfel_utils","cfelpyutils.geometry_utils","cfelpyutils.named_tuples","index"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,"sphinx.ext.todo":1,"sphinx.ext.viewcode":1,sphinx:55},filenames:["cfelpyutils.rst","cfelpyutils.crystfel_utils.rst","cfelpyutils.geometry_utils.rst","cfelpyutils.named_tuples.rst","index.rst"],objects:{"":{cfelpyutils:[0,0,0,"-"]},"cfelpyutils.crystfel_utils":{load_crystfel_geometry:[1,1,1,""]},"cfelpyutils.geometry_utils":{apply_geometry_to_data:[2,1,1,""],compute_pix_maps:[2,1,1,""],compute_visualization_pix_maps:[2,1,1,""]},"cfelpyutils.named_tuples":{PixelMaps:[3,2,1,""]},"cfelpyutils.named_tuples.PixelMaps":{phi:[3,3,1,""],r:[3,3,1,""],x:[3,3,1,""],y:[3,3,1,""],z:[3,3,1,""]},cfelpyutils:{crystfel_utils:[1,0,0,"-"],geometry_utils:[2,0,0,"-"],named_tuples:[3,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","attribute","Python attribute"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:attribute"},terms:{"41a8fa9819010":1,"class":[3,4],"float":[],"function":[1,2,4],"int":[],"new":[],"return":[1,2],For:[1,4],The:4,These:2,absolut:1,adjust:[],alia:3,all:2,along:2,also:4,amplitud:3,anaconda:4,angl:3,ani:[1,2],appli:[2,4],apply_geometry_to_data:2,around:2,arrai:2,assum:[],avail:[2,4],awai:2,axi:3,base:3,beam:2,been:[],between:3,big:2,bigger:2,can:[2,4],caus:2,ceil:2,center:[2,3,4],cfel:4,cfelpyutil:3,channel:4,code:1,collect:3,command:4,commit:1,complet:2,comput:2,compute_min_array_s:[],compute_pix_map:2,compute_visualization_pix_map:2,conda:4,connect:[],contain:[0,1,2,3,4],convent:2,convert:[],coordin:[2,3],corner:2,correspond:1,crystfel:[1,2],crystfel_util:0,current:[1,4],data:[2,4],describ:[],desi:[],detector:[2,4],develop:4,dict:[1,2],dictionari:[1,2],differ:2,direct:2,displai:2,displayedus:[],distanc:3,document:1,each:3,electron:4,enough:2,entri:2,field:3,fifth:[],file:[1,2],filenam:1,first:[],follow:2,format:1,found:4,fourth:[],free:4,from:[1,2,3],full:1,gener:2,geometri:[1,2,3,4],geometry_util:0,get_detector_geometry_2:1,hamburg:4,hand:2,has:[],here:4,http:[],imag:4,imageview:2,implement:[],inform:[1,2,3,4],input:2,instead:[],interact:2,intern:4,just:[],kei:1,languag:1,laser:4,layout:2,left:2,librari:[0,2,3,4],like:2,link:[],load:1,load_crystfel_geometri:[1,2],main:[0,2],make:[],man:1,mani:[],manipul:2,map:[2,3],match:1,matplotlib:2,minimum:2,mostli:4,name:[2,3],named_tupl:0,ndarrai:[2,3],need:2,none:2,note:2,number:3,numpi:[2,3],object:2,often:2,ondateam:4,ones:2,onli:2,org:[],orient:2,origin:2,other:2,packag:[1,4],page:1,paramet:[1,2,3],particularli:2,path:1,perform:4,phi:[2,3],physic:2,pip:4,pixel:[2,3],pixel_map:[],pixelmap:[2,3],point:2,pre:2,prepar:[],process:4,project:4,provid:[],pypi:4,pyqtgraph:2,python2:4,python3:4,python:[1,4],rai:4,read:[1,2,4],readi:[],refer:[2,3],reimplement:1,rel:1,relat:4,releas:4,relev:1,respect:[],restrict:2,result:[],right:2,same:2,scienc:4,see:1,set:2,sever:4,shape:2,should:2,size:2,softwar:[1,4],some:[1,2],sourc:[1,2],standard:[],store:[1,2,3],str:[1,2],stro:[],style:[],submodul:[],suppos:[],symmetr:2,sync:[],synchron:1,system:[2,3],take:2,task:4,than:2,thi:[1,2,3],third:[],three:[],through:3,throughout:3,top:2,toward:2,tupl:[2,3],twhite:[],two:[],type:[1,2],used:[2,3,4],uses:1,using:[2,4],util:[1,2,4],valu:[1,2],variou:4,vector:[],visual:2,which:[0,2],whole:0,widget:2,work:[],written:4,wth:[],www:[],zenith:2},titles:["The cfelpyutils Package","The crystfel_utils Module","The geometry_utils Module","The named_tuples Module","CFELPyUtils"],titleterms:{The:[0,1,2,3],cfelpyutil:[0,4],code:4,crystfel_util:1,document:4,geometry_util:2,instal:4,introduct:4,modul:[1,2,3],named_tupl:3,packag:0,thecfelpyutil:[]}}) \ No newline at end of file diff --git a/docs/Makefile b/docs_src/Makefile similarity index 88% rename from docs/Makefile rename to docs_src/Makefile index fd5b18c..0efd18c 100644 --- a/docs/Makefile +++ b/docs_src/Makefile @@ -4,7 +4,6 @@ # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build -SPHINXPROJ = cfelpyutils SOURCEDIR = . BUILDDIR = _build @@ -17,4 +16,9 @@ help: # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +docs: + @make html + @rm -fr ../docs/* + @cp -a _build/html/. ../docs diff --git a/docs_src/_build/doctrees/cfelpyutils.crystfel_utils.doctree b/docs_src/_build/doctrees/cfelpyutils.crystfel_utils.doctree new file mode 100644 index 0000000000000000000000000000000000000000..8d29dd98494645cf126a414bd4b62b95ca1e1b62 GIT binary patch literal 11347 zcmd5?TZklA8J?M)p6kx+WRnRdv#S-ONpG^#os}q?RdOLQB+NP+;wtDGD%D-5=TvQV zRi*0G%ydlRDhRu92$Gbt67nDtA4CK%_#i%uph66&AU^1V59))0PriuXe@@-HXL_bL zJGl(>bl0hK`Oo)X&-wpLliz&e<e2)Ci+0dXgyY2xKd@Px${A|tGGC;xrYF9dzL?hK zY-DZ4K@zoDD#y^H%^lB<n4dnA@-aCbv$k*ozv$0ve2Py$lh*OFCLH0h$}4&MdCrV> z)Qd%jd0#Ts+Qw%BJ3%)Zg+Y_&*)}aNZ>#q0@A~yr(Z*|gPAI2B3xtZ4FY$4HNKR$j zSeKKY<Fj-<X<2g45+ZV1iNN-0yN4V*#@6I?+q2>rjrd*jt*-txV<%zx(6ZVWBi5ll ziJTVJ2E9u8B46S2v?4zy*P1-&vgT&jiX6*#nx73iVhdC?+W;W!DFB)PJvQU0U2SaS zDCwOyq8R%)zBZAx<dHb!j=$ZoY&&CH&GBuvT>)D2fPWA>;s#*-Fg_o_=PrEev^&5O zIciUJ;NtijV1T@{Le#+eM!l=JbRv~^=wGYDJEweVU8GjR@8PQzESyoWsLa|NfFSIh zA*4XKzhML&qtbPNT0&|(X+fH1Ap+J$WQDwfj=cF%62ZqmebyibI08sCwEQja{;m)> z{wOx|h-U6OKTaYv6lL1~Ly&=YdEYtW*#E;?hoL9(Ja=M4bIxc7zOWoWHlFGU9{5JY zoNnkb(tC@PIVN;t$gR;ye5Ky8(TRetA)vj_=Ge`BiVG2*X*RdEwi>V=J^X9FB(}IC zAl{jdKlrSPnY7FsA@s%CU>fQ=UzSfE7*%P(p@W<hP(D@VH3<|Hp24cX9Ofnx@SeJE zRB~~f$>A(_0Oeib7xt1YIjJm-EC<Ue(3M0Elz0TLq$HYOpxr4YnG#mC!AhHt4c#>w zcl9oEGXv+4u|2hNlhfCho1dIm?hzqfIah#cr)%RGUCZ+5E}~QNdAGNN3}gE#CqD;M zaR|ed!3G+QTxG7ugz_`;Auq6OGvB|t!Js}O>eWveb;mChuQd7t77KRu)Np&&*nRTd z?W{IS{G^<OQno8nnmgu`@cVdU#ts~oNTNPTHg;dC-f=ueLU%&3ypHK-)g(#~E1GcY z?&EWDANIOns}lb2R+VnJft9n{UGGc`vjXQe6Gkj%(I!*E{T;CM^~?ufde{8UP(G2P z0AxoMWaN?{94zu2IQ0s4Gdai_t(;Fq|2_IH%W`l(mcQ7`knkVzACn6H9B}<?l#V|w zapgZz{*MGL@V#DzxJ-3U%EKY^ZFp;Q8w$R&!<d|Md=-k7AY@~)p9?x%duG5e{&|p0 zxv=T5tu_MKRm^n}rl%6=(B}RGn*TUBs@h3TgFMj-Ns98hQf2AwpbJNt%0scRQ#ns& zYCH6twj<IjszYWu<(;PXt#LJmE4-kN;Sfk-0>@7I8_HZGm`UaB!?j)s^6x?XTYC~e z36i2zPIA%p)Q~qz9%)-pv4W*x=J=W0<66g|`0|RJ(!1E3ELl^rF{}@SF7Z5N0{9yQ z^=nxAs#d#FJPs?Vr=X*HuqY1-Wt8%vvoNBuVHvqoG;%v?kZKe$+P?h?6>x7E9~<K< z?os+uA^E6L+xx+4kS}zPWTf}Sb1$pNDG$#K#CFz>Fpi=)irC=VO&j*6ErO_UOy<Xm z;7-MMb2;P<<4J+3h!2k638JnF33dFpFJs<sWR-Gor<Q{|u2&9RgGQ(rVRufv_IMBh zd{P7>KRs*6GWc^~E3&LmJ!!;@DF#K%W1E&QjAy%+KNliIHb#l9o9LZb-s+B^qd}$s zk#`wruN@$fr9GAhIxR%KIlvwM#XK65=MET~JRq6LAuqQ@A&7e#r0i{Wvk)BPaj@CI zx&NYkWQ5pzZ?5H$xq<>3?-u|(b`Ub5cU{KoAbwR5Uy0X?4VC^OkJsHN2o(z1`3uT6 z5yL>`vK()e_|d~I%&d5!f$IpG5eMa5)d>Dwjo!m_BUISDh#_{xS=BOZM;%hFsAp_B zf@elg2jEpBR``z_pQtn}ZIam)*P^fMaWMIAXZv?MCg)o)B{10o(V-5E=vr---k3OL zcPk;4{0f1yi>-m*G!k570jG<s*W9$cgc+XYZzOaSH)s^v$=GMMh)`wrTm@9PfVM`p z+Oyv^&uP&refdl8Ej_t@zt?1xg7ShEl;@So3_sKiD8oF&V{`u@uF$hTM_)<|Gx@^7 z!%fgw*pW{VUn<O10udWAf&=Z1+ChYqR2Znp-O#TaJJ|d2w>3@9mA5&%1T)p!eFa~8 zS?K{VaWm__y#J8V!F+{KpreP5wGf6C<_W*s36S)K*E8at-{w)^JI^z_v{B{2(yYzh zJtSPan>4i0Z%bg=Zr2gU{im$c9qWP9ryjWP)P0S)9gO<M`;Ek02GWBk?AoQPL(sc+ z>DwdWS9&q`2U^6wzrVaxo!1gX?0fqU*-ONRJ4!jFeM2h8@1aP+4T#3Vagwd5IL<LS z*KwF<5BDTE_u+lTi<C|#8#;KsGxt<}c@gJ)tTq)2s$!_OM!?}s+QEwZTeT57Gp<oU zQIOsW>|JgaN-uLZzcMlENDQ1XR#%l5vs!WBA*W*?Hb-=gczlx~N~72yfFmr_sNaXF z9nsa+B60#OvOE)W2L46`pvpCi%2y4&cX9u@&*s%_LL9QT({bAAW#Z=FH5PwUBN0?h z81+&f6{6XzKjhY2^9vL&<rK4S$gS9kt2E>GBFed?e)qHK(8Rt*)E!43u<3vMZHlhP z^GlP7u(#vRq_}Bu=P_0F3dOBq3HQHfB`i4ZJ=_9_@e{k_uq<oFwM(xW!`_||FwbvO z77C2yjm(nmq8b?vS8wgDR@`g*piHvz7xc;WCTZ<CrTc5$^;c?E_c!?J7oWQOyGom! zep(0Cxx^ID1tLlm9~?nyGUfgx3D2=yx!u23R?7sqROp9C59ifYHT-Fwnu5uy+!5XQ zM8$sPjn4&Eog);k<Aku{o*e<=Ob!U*1D1n%EeD3W7|o1bUt58Xl85dH#Afo~5)vcI z!{TE&++BbHJ83-P_mI9;wFQF)a9K`LzX3b&wS7pcUh%pgK<B|5-r?3NTd&_<y`<Ko z)9{4>O0qXQ$=<~rUwsFuR?7_`dgA1u9UV?JSTV4}AHI`R({e+o9v{dLxSHraEh6Hz z75B^g5L_{`B(K+{TzjtW{u1^N1muw#KepqRe&_v&yPyUQT&@paM^0s4Sj+Wv&~mc` zM}9z|VjpAyRjd0C>`+eofvzLDLXPNL%2rWgbO(KPIYJGHybaE`xSL#6l`gAUdVv+$ zVd_*A1Z71&S*POqiKxLX3F>K-_2l;=NJJgX@FR3l>BH}(vEy<vJBgV^1<>KVMOOmJ znV1QIOciRNZlYUURTKrsLOBa$ex^Q8*Cv&qYH?l8ZZID~BF@bz9&8I0M8fKZc$nAA zAnrywYF*A{k4fa=X+Z>SlPZVkEtacMDGmaqqn#iSejr%o<=VJhpaLsD>6+Vg7mw_? zT!b-nLX(bv7#d^B72SecWYuEQC77AlFJZ-OKvvMSE)Pd63?kexu}$WsYZG#gTVC;4 zlQ*$#M<Dh^ayZUA)nv_Ptz-ksEuw(Qr>q|4WmXq0vm!zcmNu1MmWz%bCc;FCL_oPe zB+?SmSv|dqbaN_?^}jS(6d@_WE#LMSl2}tjD(tvC5+tI3mYSL+mB$C(3{2tPb_k-p zsOK$dsD1AI<Ey8!e*cSs!E%ZA5CbR<h&+{7UdZptfVhne;RH(G<joPoHHnS13S~I4 z4AoMt%PAzeI@l%<acmO_>5j8aX|hEt5rJ7Y$q5HSwO}XR&@2QGz^VoZG8g%lM-v`V zEkM_giT!0$7_-C<Oys}OYY7>^AZBKDq>_@hFgKmp(IR@pw4K;$c?=uLsGQCfg5N6- zV>2;SK;<ql=|a}cq^L@j!7YX?G${qD%3p{U<aa}eE0!kNmIhsa$5};CsA`KELA24d z*=7?x<7O(CX#~wkBTQUj0%f7H_bgof=zaGCmc^*k9$1E2%4Lq_%ZMOA>7v6#M=e8H z4=gb&tQJ(j7Cc>>k;frWU9-@wf_zh#4P248Dr!&-#UiSGg4_~DHUxPdm5;?E6mJQ) zIKtXCxwFANd?2Qi9vu(m;TZLO!h9})`o<V}vwGH#rWdrW48h}Vj^lG1{MBj&j*<N_ zG5TT>BL7MSnW|_qQ}-(nlAuj_xKjU*l0}G<R)4=G)@?BxD%rzYoS~ZMid=4^7~`VJ zki+&&R14x-k1853%R|iHr1D2Oqb&hc4^jl<??A4Fsgv4@=Qm*?NQHnw1U5DmJH7~8 z)z?aQ1gaUcb&3bd8Bi@Hx=&N1{#|$f16Skz8~^w=Pk72x_i4B`_Z<Eua+Z3MOH##{ zs_#1AzRc6hsuxa%21*+B@Ok%NG)s{o$&M0vazni>(i&x|+lk>{)Oj0OjG|DJKM1En zC4&hMK-BAs9`{K_)IwEy)P@#N0HE}Q<W#qihUfh>a@7{y4~3VIp>8Yi3V~EzZy9JT zde8RFIGeAk1|992AI3To<Q<j==gQuU$r;$6qT3>hN}#r2T#Ph;p0F@8ea-VlvyzfI Pn=D^uB*-Brt;YWW@c~Ct literal 0 HcmV?d00001 diff --git a/docs_src/_build/doctrees/cfelpyutils.doctree b/docs_src/_build/doctrees/cfelpyutils.doctree new file mode 100644 index 0000000000000000000000000000000000000000..70a62c54c7fccce2b36f8b4dbd5b1b0a940e9857 GIT binary patch literal 3420 zcmcImO>Y}F5cQX2$+l$2iJKy^5fw#HCylKhdI*Akp+$433pYWX-U5Q!r9{HJ%Pq;Z zq=SRz&>#VLEBhPz+xjco$KBO>B_wEpq5=dgheHl$=FOY=W$pK;ou&L|yP*s+BO-mA z$dGAgTV4>e#JJzwy_fFN9on{{V=XfkFlU#b5pWTOiY4y3<4bm3v%m<MRQkNZn|%Gb zJH%$g2otf|mc4n#SuYr}D4phZdrxR^PDjl7BRH{k#wOnOyA^+R`LkeV*EUm%hZx6q z_%dI$&GMP2b}bSKbEnyW+6`)q5`)aZJ@3w{2sNH=*Mo>^4I#c835|=dR+yz%ivb>| z*wE`_cHPjC-*UXmZ}ClUk>9qT^|_2$|01SJ&_wiqltVMdtNJx3`v|HgS_O6CvC??> z{>e%<u-iK2BAFc1Ff8-X5J|`;wa67g<p*$q-$AH8!2d)1@8bWFcL#A$B6s2tfe^_E zfwwnmujn1dGRz`&&)MDL>!`Ntc=Oaan(=%5LCw9hf8$>5nm!>S5r&ZCbo$7<jYlP; zo*dSb?%iI_21s`s38W)MQ(kk`e(6CHQ<3z(dHn77Po~d2LVIa}ln1>r7Xj}DGBHrm zJp<)2ml5klVxXv+9v5KR`|tN$VeM<g<f|g(r+nW7>z%3aA^ZZ!`2RvT%TFG{Rv_b4 zW=U9!U<sCwfms<C#p)&a4?yC#>}D;W3&83IYN`#&m*my!?5&#a@xtaSXS*YY>M&~h zR{e!d=x_M~3yI0n2vD}~*KeQOdgYki5=jtcAsY&>>=`HELoS$Y#dH#~)NuFRU-+Ta zX_|8sh+!1TfqP?{T!bMw?2YY|w^V{wlEnk2Sm;ic>_*ODS|-udz44hn<G1;J;J1w= zJY9r=-7e#OGzO+qrW~yosXzb2EP3TUoov7=C>_4FGVM)3yk4tEWhpo|qk&wdUShLq z!2?Q$@W%b4R|^#9PJnyfjpK?=`F($O*>;0WdAcPP&2G&k1>M?~X2zi2k-BSDXBjF~ zDg!=k^Cuc*NY$*h@b0N?k66MKHBvb&LJFETG)}SDEX)wxeU9Zuxy)3ARR@74o}T?K z%r!jyO~GtKDNP~`t8Jbv+m7#2$Sau)rHUOSUC&G@LGk!*r*Y-&Lc$`JOUPIlPG(I4 z7Rv)=*EqFXiltH+60r*wxsw&U!D&=28}=HTfC%A@$@EOAVH+VEWFwgCqDv%*6*Ls1 zF(hrHXu!Nv?zQcTB+U$ANgzXLIor<6@aW-@7Wm$u-y}>asR*Y@7y)xg9DECmv)eK= z^S3neTbw;u*jc!O|6#kurB@GVJUe@Q^bp49Hx^FX9q)iflsMuO!69cm5lu!Jx;(-i zV!eXGv)2_1qzVZN72tpw-@Hz36TCizj|hhdNs8_(Cg@GJOEV+MmB_9LAgU8)aY`!G zA*#7R0B|ayk-u;|mmsu>_PM_jrJ7}-B$L?VX@^ZxsTrEr)yW(pfgu+{ivpk9Bovws zBJW7~%Jo?_@cVWP&S>DDmSoc@)yRyYY&T^oflr{9B*^{U@{$3CX%B4M<Hn@=QNKSP zkI_O6m&vhIqkhOP`q0#UXZQRGf1^J^42uzEgQ&J3Kf3$LrwB_|4TA+UUUFq-e`dx= ziQ!K$GtA9!6Gt%7Hgo{|hhWf?mOTKPVp0`W^?ahiLktx9Uj7>NVy3+30IiQv2o!H( zcC41Dx*a`5*PakAMm)kF7+s5`hxeAo1ZBw28ERMK<n?@AEJ-8-T5!BQ2slQD09h(( z3K{d{LvZ>$OYs;#(&nUH);bs-5|Ip%>RIvcdOFbAU|w&Bf%iky;}o_yV+ObF1(BrZ zgkc(q2*xwT@|p3qU1iCIA24mJpaIk!P=u*X0M~{Xszwa7g30U}3;`7e9TTxZyYh3W z-JO#bBPYbTZCEXu9{reBAz$~x;+wzZFSKoYftjWV)}`YwPc^^eN5dBwOfNB5HH!ya zQEfSuSFMI$(pmGEbqL!K8iS#G?dkr{TA%v7nAbAfse>SYS0@l4IPVzVT1b4M&h&}^ z)Fp);!U8D70~uAg%2jVH2rKRO+>Py-)%?)z-2EV2Wjw?0E#6h`EZG)lq*Ci*1V!~> e{?}lr;=+n8=ER$oI8XLQ=n1T>b>CF8!SUaIF+kJ+ literal 0 HcmV?d00001 diff --git a/docs_src/_build/doctrees/cfelpyutils.geometry_utils.doctree b/docs_src/_build/doctrees/cfelpyutils.geometry_utils.doctree new file mode 100644 index 0000000000000000000000000000000000000000..ca1e14957b5fc883079921f36592dd98910a8eb3 GIT binary patch literal 30154 zcmd^IYmgjQb=FGz(2k@<mc5Q)WoU#0BeV}360o+gjgc`B!OA#-qGFp-?@aG@w`Zou z-94)v8Ho8okl+$9p71LvszM3~kMIg4sU$@zKSEMaWe8PCQAzP|Na2K}QWZi7Bt_*r z_tm$1dZv3;Ye`g8rP-O=_i^sI=bn4+IbYxV=;UvHvAc)=V{?t5-i^IxwA>CFPSj`n zDWT=G<No9Q<8SZ3wO?hkp?y9Ix?$bvvpvXBcfDpKblUv~`|ch#6FK$R3)(urJLOKh zGY|HwcsLb%anms#v1gri9c$AGT237H9;orQt=9#OF0xT66q-EiY*X{>nP%Q})_3$d zZSK^_3fXkW2BC4^J?u`n``EPX#u}S!dTpn_)?K$*#g609Tkpo`K6Q7W*ND(HHdAlf zQG`T%pK9AJ@oj&j+ev<`+x3S+XM^%|*-UJ2(xbjR=PtMhs73cEJH6tfvnyLIJM`?f zxAH5&MtmMrt<*Q1W~av)umYw>wJ5BciOY&hqUXzDgnrz7dT)1~JtOM4UVD4lZZzbu zO?mBxvu!Y1jDh=X^vJcq)?@g83;sVJ|EttHuqE_(pQ_-C*WSbcu;&>>W!kr@Ej~)e z`|P>m+tTpNeRp~-?%Q4Wh3=BU3$F|>j9OPREa>!BiBllFy=es-mXS3>Epck1yAElZ zg$UT2q1|x}?y&1$B}LGp0q|mQVp+)FeEu^naPBE|=q@q1Ywpb?LPNPs{l613aE1G= zIFA0mT+Ct2le^ElUSx@pv+6-Rw!L;_ZFJjw_C{9h+OgGwgm$`3J5J`P<+V40uw~O6 z*DTtd$`YR52a@j{i>K}xjPO3Ar^~9R<4C@{%1+jURtJ;6*73G$ExQv{k6Tr*tvQv< z(u{~<BAgg5fXmrx^QVN6Aa{{XLi^SY2~|3D5h@x_YLN%s5_iM2GR-zpRTJho7v?G| zp5?{4UQ!wz(r`FiQVIXygJhJZ!R}tUQDU>(t>$Xfv1!rR-wB<_3Ada+O^EZTC6dbV z!WB~pIpaZd7YsVW8AMtFYmyT-J?L43Q~MQ51&7pl==>w{&a<R&nv3rrr8V4lx)+I2 z?*pS)nT+pBIO<;FDv1OtXg7NXadKKLvV$F`-GBnEZDZvc%&><|du_ftCQOiJ(VzRp z3i@C_-Jj29$z+GNJm-8JHpLR^dZ=%kiw||~)1dj2*-~aEHUskFUWepI)zybB;%qd6 z7Iasi?Tg|@pB+Gov)yTWbuaE;;u&H)+;n2BW;LPiB6C^ItSMOAQGwU!yN|GGUU|LG zo;7@4a}oYHi2vwF;wM2;*k_Y&+-mY7A5O+d%y}nSHGEqy&-kiV=&22lmi$X>TJ&Nx zS!{}%E6_4*|3<gj6o$wn#OjC9bX!cgL_7|1si$?owDl6(Em=5TdP*qB$byD+nph(` zSU19;Wt|FpQGCxUU#so8+_hrI<r5M67xdt%a*BsKOiS+7)hwqcK=D5j#i=#;%X|%1 zYpxaB4>^%#M_?OPAS;5Mn9E8lbnJ#;xow?OT(7*$jpNSh%F6lk=a(^>J$$UZEk5sh zF^o$Z8Z2EaSkb$7b4mTKDQ&h)l6l9unzi9Iokh!TH!7in^#wM8ZADH@<`pLhx_e13 z77arJgeg#U=h>-U=v1OkcBeXU|3{|0kR3>R0-FIWNQq)&XLgyLY8l<HMk(nTl<0!L zcVf?;(TamlT$YsQTB#d)eRkJnk2h%|e-B6?{&4GfTIx!JC3o+JU<p2`-3RuJQXa7o z$el<kP3b(+z|>d&dg2p^y#aq2BvTGuqt9m+(LT>k?p$`YYPp<BvO;EP^vrHcDkb;7 zq|G|08M?I94MJ}dmM7*Sta1Jmx|ti^G#e>NGs226znzu^)0{srRddj62Ini3J%UL? zw*D6Cf%z_Vjn><%N?NZ{>v|OYTe(d7EA)qNn@jGjI7ep;UAu=JSjXz;#I=kar|fAc z0(w$|l5ClZ;1x6gb@0gvhcX-cC*tb5W4EBPk<;dTC#w_S*K$R0Gg&zAy6h^|`0PSW z39o-y@cPyGGfESgGFyS>y1O{P{|Zs{o%DwfBaIKNZ2uHe)c%aU{=@~#WM#t(g$s!< zLxP(S)n<TAzUFt;TXvQ$`@G!~3n4uaw&?Le&fmM+EvSLm{fd)uSr^PZhd*V<<sio8 zf#Uon$EA9rr<flHa8WgcxL<JEUhG=cx&uc^dozdKFDO}1aj|s%ggF-kbGC~+OV%G( z3vj~uadG~V%(?Z%HZ*Cg1JweXjie9C+Krc7Xlti|M?r{96**3XW*!vE7mZtkV%PWu z6TZD)@a=uYe9(M548F1A{6qORd>LfZLO1u>#0$A8aywBcMhhxN8_ZboH$11=7_P&y zH^Os6e<$i)7R@?5D)*`lex&$nCTWgwEA5X;bpH!P`-1;D(FJU~Ph;A`&Xn!12aTNF zcd|J2lp$_a@Am5P{cvh7T6eX34<5IcmSBP_`!U%N1nWN3q*cAkYM=m?b35$8ARwC^ z0=VAeD}FPu8#QHYX=5KQEw$-5t_*iLGT`^b8rH0#ZRlEqn}*+l`{ai@GW@R<aEfow zqmEPeHoSVD+#3E9f^lEwC1J+xwW=8-Sw8xNS~0}n!l!XqQS7ujt{r)iN%JJ}QH`zm zksj55E})f&`<@`~y9HTOeu%xD-hdlIJ1^Ytm@Wzb`>5Fe7CyL#2Yv)!bk=_gX{x_$ z;(pZ+d`ov?@7}`YL3JXZjp>%)LkU$|{Cm2!>&v%xxFD;^GXJOOZPs%$jAiqvxR_;o z7cJEf`kL;>i2~Y;kuSwG%v06aKKh<+?PcX#J6Vu*$4tAU6w@XU45FCZJj1tiC(ag7 zHpntmay(OsWad1ZvYveO@$9JRrzdx;?vnP{WmF<(p}F&Lwen%BtE4+u&%Mob3ThQA zf~Wav_nhD^Vx&@U8S2V^7z~!ozbU_XHOtO!&X`o$B=_Sou7zegy(OZy@0hMs8mow! zTkwOND$J~g*L9Ltl#;+lQ93(qXAzW>4odgiaP{|Ag(Gs!)O+mKv6<J`?pXH;P8BTD zcK;Ik;(lD(3`dNC;~s$n<}#<{nWd7AGVaj<S8VRaeZl`L=&J&w-2Y4DLFHr+bk~O) zK{Obj5m|qqXZ1geKT7pWJI4P*BaO}6Cp>d%vg+Tui`;7YRKeI%%hGE31WChD@&=RD z;(y6#O)j>HrE=W1$e4mpq6_QSiek7a<jxFca3%3P=;+`WC3Fwi7=^&)Kc^0i;VD?~ z|EvUe<PZ{fc6kU7h#|CiKtoRZRGMZ4AIfi*AXX0L-xDWF4(05<<iUR(9QZ<%5+%1N zW^G2x@o}&5agUaDS)tba7!512^?yiIh^546B;BbW<#ej*{~A(-@`CPI61roU_WD6i z4MVh-42PuD*TlX7_2s{p2>-VKKKxnpA0t|hnW`$E1AYH-D)xlm$Dfo+x(TxR@AQnj z{)><S3;w?%Z%M^M13i{hj@Ch+z?@fmu5ya-ACWyBM;hJ&o0d^JVd~9b^CDw;Y9m5W zBLud2s{c|NnVB~HXoO<n9BuOHO*k5<rQMxI_+O=B-CJISScrFlyHs})?>}jZhT6bM zc+TiXMn?ZzY8pxH?}jRYRYzAl5bxjCC7(UIq*_agvZbf+8H`gowX1^Ii1z!Zbt!i7 z$_M=OM;!nm3je=b^D7C}b3OLhum{8U!t3bfsJX0Ig1El_=8}04+BeweKS-S9gnvZQ zC)aDO%H{9RWS$R=-TQCJBjr!?0``6{FKY@_h5&_F;=W{RUiYsDtVYVXlQ6yideC5) zhQc0P@VAOc6A^j$@2CKR@dj73MxcKW>e6v4`AbHq+;3iTzcmsc;C=@q@FXXbnnLj1 ze>Lh8v&I;}@1_T+YCyHtPUS`15$S2zv2CT~d7MD}Zda>Sga3Qf!3F;#x}PP(H`kOp zpva>CyRr*V4cY>J(@89qyAb5w<xulZqn~hI1L;?{+X!S?-G~hP04~L-(?o2AOPJTL z;OT2x_NMbjpm?nFUITcVB<^zV-rnouR}rMrQW%6z@8Ot(ESH0DbA@mPO>aGfhf=v4 zuT`9Y|Amau`V+=x=!)Y5z6feYts!iZJGKpcfPVz^?k+Zf^90+%d6N@Q2P^<k>su2< z03n}Jr~tw#Yec{k#2M^h2@&8w4<CHK(&+K6|AnhJ9SkSb)uaO2YqTuiQfA&NyKq*| z@uYiL*cSXJOG>Cwfe_Jo313O83ImdoD|R;xQ!#>2jWB^5N@}1)pn&~05(h9Q|1nyk zW)l^rS2|`S=J0#?euzu~1Sb8@qfG$<$z5vLBWGPeWeuE_g;xcjoi{iD#?Zk*8)3*z zr;Pwk%)>tvldNc0Wd_rHPCLeyEwlg(A8;nB);fXELPwxM2+?)N<q?qx%w^XE9v_%g z#*;8A4A1N{hjy0>N7_SiBh@236i3w72)-)``A%r&LVgo6XVtLjswnic-jGwl5Kl#p zpY<3@XDnv!sPI1o@iBcBgJ|tM&xDe?{gRzrVct?oBofIlmp^B~N>2(RFR{P;JB-yw zY-*}$9LYOLk|kzp7(NO(lXeg%Fp>e-&Z31kfB5q_=v126l^~Xnh^j^b*<lE~NZCos z_;z>^vX%w|{l9)~(4{o_wL*>-CI23pia-<<%#n=FJb)rEFD{~R3Aa-t+(RtIe*lNn zIRk_|AIEKuxdZwo0XUP|wYO}qX|Fc{JmNzdyATUN#OS>#0Kj-r!!=&1URbn3UKL)? zI?gpWA!%V=uR&c83QBN=2~ZMo#oJAW{>@_OA1EG2bGala&zp*ij2imkTFCzxS(G2g z2bq@wlA<&w$(*5*KAEGE3ZpkB%tS6gW|HO&UwGb9qL<R~-y>EYl^%uSFwWHmocLcg zm{%TP@>l^wG%`TpO5Vc@<l;)?ql~L84Tva2k$kv-AQB>pBKc53R?|f$LLix!S%yI( zK8lKU#}N))@I}{BUGXO=4k5$)Ss2L|3rI71QHE;;Fp?+AxAv8StR~O=KSAb<os<Ny zGsv5-A#Wki*hm=3_X=nmmuaJ6B>!E$wI3E_-7(XCQif^%8x29r;z$lp4O-HsAw0;l z92|+B)44bj{q!;*AX*DwCXR$?F#{yVZsl@uB<bzUBKRsNcUkzza?VhUwW)bwP6g&z zCUcMFY-(;p>C9x!-_+~?D>7==bDdO=G%S4QlY)aJ1D{GZ%Bc9`a0>!53~Ob<e^<dY zBw3db16sUG26MM~)?Gu1tQQO-5h*Q<8nTXIVH`^XMa~my94512RcnMunXJjkl*tYD zM?~&en2=5hUdRC>UhMLKrSKneE~nBo2e@hYSP5d~!2JesqP%HnAT~G|+CXAQ6f9&U z_~WD0TmkswV>#5D%BL9o@!^~rhG?HW@W&sZcq#Q`aATBOxe*fgJJj)#NRJN|kZ&jl z8ose)ZKP`Q1=2(BW6J3>fIV{KmcyI!e~Fw^WRm$W!8dvhS)47=_iv*oPoY=-NqpO7 zc*mV~r_=0dta~jEYUGz0;~0n3f|G%D<X65^ILGtztE&>hiyG>$4sS@n95?2dQycnW zkJAd|r&3y#01QVbDWn2{H-4f^u}7~Qcw<<9GoX#RG~+lws&0ban55^5OX5eGC)Z7n zHcu5N2(xjB=QV22Kt_fmL!L8sE5oOmqKJ?o$=LV@(Zp^eLr&(AosSH8NnX|~j11WW z8gh^!FD@c2iwsG)I)DuMAtpnD3=zM^MTQWWWHAyl<VSjP83Q;18S>)0pzFx{IQV*y zaZC?+9QnKZB>mdv+EH0OTl@`>4T>A|XAC3j=ry4=c&yl#q^GbQuZ36Yn#OkMfwY3Q zg~J`{FscKK>qpCrm#x>t@+B|?@$l|Ak5-rn4~gtRjIc|md|7ryA~O))e8{oR;bf;y zGl-EWBCQcllt|JvoFfP;Wx~hTJlrG7$nVvKd%OkIWaEq}oA!#pJ%}e)2=4I<NpyZR z+=CHK*ovm%9)eOhcYOoy@ifnnBs6?QTZOJ2EvqjmIdzr!Q%PoZ(j~sL{9s8bG;0u; zj-Mk;M~=oYQ5|{G^{nB#Mv$v<9cG()<z?yA0c6LgMhnj*qQ;ek2Tc4fWccpjXa1rj zvv+`>$>Vfc{0yL2FV4)(6nZ9w#rm7k{GC`fn2R4doE>i8l4(RpnGkJAq)gtz%|1&Z z*~qm!zyPSjQRKVOVi82>f8E<eyf)}=@-<Uo9PMV4`=!LGOFZUV*|M8mClUuxpkUN% z(E+7i9SdsEmFKY(oDM=KRIKuf>41>R0MbCdc@5?Dvq*Yk2>u%l%!2=Y`ZJCps77=a zg>y&rskJj_U%84<I|cv;1`_+lsWmt;)oBB<3J?b8uYT!WS~~$DSuxg|2+zax5rO%Z z*Y;Z7RweQ-I9A(n=#&Psi}CuJsHNlfBCl>YE#O`QU_hi4ae2_;{RWPEsH4bY1qc4c zUL9v+h5!wCLgLg@I?jY(CPG5c5CFF1`5bamjMB*ee>$8<&;JPN`SDJr=TJ&|{HH%6 ze`sd3iAF|>bh}oN6`D(I#fL=X3t>$H>Xe|**&ApVXI0zXR;RbzZg83BheVKs@n^}# z04d6UWuC<cJsEVHI3&WU(8j@Y8q!Wr2jvUBCDj66==iD%#^1sV<ObvABkgMz{Z2)& z*`ZXY)wIc^YT4qp%<Tmv(s0S}{Axi~Gio|kc>YdQtXaXs^O_F>ugL2sxuH${^!Cde zY|SHfnH6F75lyDzFIvhM{O1-hn#M#P9rbLUHHGsVm=HgsNS3VvE@+8SlPBZ_awm^` zG;;D3B3a&DK#(z2E*4}pr;2|cGG`(!Nn|*K%6Jd*>W=fNBD$8+10#_vA1WZt=tUW> z6(CtYSH87R7i8Tr&puy<XQPoUUoN0+T&9giviw8&*1l1Yb;nHmW*Mf9M6<cnFg z%R#b85gc+Nihg<xAX$hOQ_VkZNS4F<(U6E9mqoH1L6NN6%nT+M!t>{HDoFX=H1aMF z$#N8>GYU>1S<b<#HR1WGz+$N*V{%UxP&=m^u==WD83)Ot%Ba9!@roUkkoDAxJ+evx zs$K9GO4KUh7Gz4741v$^th<JfxvxMpXqroV{|vGg+53hee@gr3<@F2d7!_{BYq(6F z0iQP8VG`_0U5Qn=E7d_d>%@^UoB|8}xf1M_GC}O#Wtm99ZHgf{Z!bZtl#RC$Ckpn0 zhHPZ^G-())w1DTc`yoAkeCP9l0^)YMbY@#kn``ecXcg0iW8>aioKIonh;?I)^JwKG z;V;VNR89#J{3S0qJG?0Yf4L9JC?Edv74&KZ{3WTl%1Yd?!=8x^;gV7nOZ*hFC3y^& zqmS68OxhtJFHn-1^gRPKKyb<7t|C5f-4k%S;*O!=;1GR_l6!*6PO!OpH>6vZYWjAi zgDOSbvc&e|HJBLM4);r4r!Sns6#_Uzxs59vrr*fDugU3Xb2vOqzS|gtef)righSA7 zb@1bWXa<La;$De0R*^ruVH3X&#X-GBw=&UFG&e=B>)?3CBO5^w!$s#94^L09Lv(o+ zoD8*Xy5k0ii?ccMJ9cV#Ly#`PicsZ(NO77DPpOfjuBp4B(4s6LFN<1Z2ScY5ggAiO z*>alw(|cLPwVV3q6uZvZ_P{F~?A?u2rYSbnaMrt<Xl{<qIRmfgR8IJjkun?OplOFX z)xXH*xYxRdbL<1U!~-{CbmNVs+m>)YOrIT1Kdd=n7=$%CqPFSaHi~H?wT_E1o&kR+ zZX7Ubnc}td+0B_JnJWArLyFm)s5hZu>J4Y_S-K7Frypbrv%}Pf2#j*Uq9(r@=1|ja zZ+3Ce065;jRUdnCtr)u==RxB*-CDz;t4h!e-BY#3rm<{ppqt=`*QnuMf(>t*?z@<? zyTE)UNo=nNp*qxn!>pzS4~*pr+%4a>n^fU5cnY}Nj%fIkq)y~?8$k_M*dW(oT;&l& zPR%UIrKBF$@H(Ie?=aO>LwJGS6+=fPl{0EWxF^^_bSA<S;71Q3`yrXFM%OR!E5_zJ zPN$~NcPCnKQA-Enil#}nnWbWFbl*d#7rVHRi4I$6I9n^o8Ljl$Je8mtsYDGYoP*0T zzktW-EdBh8ei3Y$3peVSW+)|T=BR2W4gy>Y=Q;5PZ-(xRKohgEy^bl+h~56_{p@B4 zRI8@vmL|U@ZvMH%ZsgS9rYQ&B^PmlhBOWy%$Omw%oc@W4cR1?du>0+ri({3WbhI*V zPoX2g`|MzZyVK&@!(B|@2qmxQzs1j5Gk^<UaPa23i!*-fIMY^4D~uTFAH3lkKGf~t zA{Dyqj$cS8r~4%cNl+)?OfvtEkVc5Q>*;)loz}Y3z?AHvE!V;2GMCtV9mh64RCDky zb+d+>*buUy+u|;=eNKCeu9jo_g(kq%gB0OtD}K&-O&oi}$NV}p1gVIjzQLOYT_pEb z=&DpIy<o_bQQL<8LB}G{J$1-FLy6*h)&DxJGGE1q>$|@H9DrN=qx3;X+K7+;rEfo` z4}vd=k3Xh;%NOv`WwTTp9pS?-!{ha>x&B37)kR*zMW3p;$V*=IsVL5}wQ$dzX!n5s z1kqrg9U<)(71QMzbSyWy@5YO;Hi<KWDe8|kN#3F7-hnlVZgcb9NOb2$-6uL*%KuyX z_$qzyj{ShX@!k=X%YU4D_a4<n|I_sC8}#vYe013%Q+zo`58)~yaYh)pEK*3tsC;7R z%oLhXJQYIRS`V6fM)1TNGKo6(Y^ugt)haJ^Bvn6Fi!i3;X+B$*d;+*F6rlVu$>tEP zg5H4SM9{5NA>GC}Cypjp$;o;vZ)`N|(Gz#$ut!A4aGtrkTnX3J(6vhZFvwNwnA*-B z6QKm`Nmh!=Jo)HvsZviq`rAg3nA@+lSu*>E+a1c1e4rp7mj;_n$@O=FO^TD}CSS95 z&ly?-#Z{JkQ!Vd-JiUO*{a;1JF#FW|p0M8KX${i=$J~#H=@Xl-F1H>j;DX}Tc0oQq zI|jMscTujGSBX)rd=xW9yjm=hl4JVNjzqLxR8$C}rHkdr)&~l>pt$vTK|ZcGc9&ZY eJEAQRH8Z&eIG~gH0#a#^Q6%jLvemom%l`+JT+6}$ literal 0 HcmV?d00001 diff --git a/docs_src/_build/doctrees/cfelpyutils.named_tuples.doctree b/docs_src/_build/doctrees/cfelpyutils.named_tuples.doctree new file mode 100644 index 0000000000000000000000000000000000000000..951a3aee914e21348f74f94850fe62bb7a96d8a1 GIT binary patch literal 14526 zcmd5@TZ|k>72VhD)4O(@Z0xXh(pVu{WAAQW5NkgINt8&)WHI0%gorvl(=}V&?&%)) z!#iUsQUF2LP=9H@ka&cLcnCfc1SlVX5RoDQ5)$GE{sM~lMG;XDip06q-PJw4GuyLk zXJbn{?yl#(x6Zj$U3KfZiLbwWZbbeQ3#QkILdywOUC(4eET$=;#oRD{AwK<u_}O?_ z%=pGu;6;9e#bN{{8r*VBpSkhVF&`0A0c(Vo=c@9&#wYpI)A2GgYoQf7tdJ#+U*t@4 zjTSRMuZL0FVS)CfXGSPQbx>vEBI{7+;+QH~D){AC%EfEDG$tn721E>FeuR(maWR=H zupuTK%VqIKR5!$|5r)21k3uL;ijG@m0HwrK!!d#YiFmG&tnz8vjN182-Dq6$S(9=i zF%=q{loj&@zQpIKM}9(lY>j&@wsxgu_?F>XYoGR-;TEJ?Yc!eD?n<+-!Q6o!_>E%X zs<cn4^{O90i<9TaqPjR7w7KPWRt?ikhpT3}ChHUooY<b<34OQ*gPy|Q-T1o)f6JsB zjN)5Tqh(mdayMam@&1BHJ-utoEjc=;V{upVv@)n@%qKU(*ogQC`AWeGY#1vP+Fa{V zzTI6X3qfReQ}dcyp<s`kWTDZh4*bku;Ehe+X!C+q#2t@4@%YCtbe|%qC-Bn}^sOei zTimUL0vvw~ianAH?*>0fAR1_CvcpG!f&<h)vpVeX(S*C;$mcF{E6|d$(;A)|8kQSq z1|A(JVJ_KK8a*|M76r`ILhgIfCikKck4!7rZ`QHuzTtP3>E6vQa@&6j>Rs5A?fEBw zit&O~Rx_*Yg(ZAltX!}<%z4si2imgq4VvW+gd(VNY7k6URYU#Rl7Nbz6%%mAjRJr( zmwFZ+8##Jl!Qq6F-{V_n3av{Ad{!Kmr485hLZjrR#blyNMu6-!xA-JX*B#E{Vy4q_ z)`PY|lf-n}X94rCu$V}&g;s*pC3*+q42o7JlER)d(hkx`XY(57sYuQ_i=tq-UhTzj z+Vki6HmUm6TvdKe`UjT#2is827>}7ht~D)k@Ylp-LeW?p9|RsuMsmae9WmXE97n3d zBkK7wdUg|G)1IO9A*nQRzBr%f^K<Sb79TY*->qxwvV-+!q;GsiB4e2^im5a^R@TXr z(D9FoR-%5}%r)V#^$upp0*J*zpY~}9;aDN_4X03){~{flniM7P7(`g&uaq6{vY3#4 ziLrK<@Yh{QEX9g*AKB?wsQvSD?P4J@1)0Nc8!%3-jr9*}nqCWjGv=>~IlQq>+p!uJ z4ciQ6sC4A`cc|w?#h6F3UTFB6EJRz08e&qm)!22ENdl}B-1r(v{1WDn_kcF%M`>WA zdI7+tr349w36B4rrd|~O0imF0>Nz9*k=7!=8FC}kg3$Asw#l$83jHpeXw&ms(l4pG zWKVSz9Qi*X!0SaAR!_|Dl~FT0jfmN%#T-+2EI5FISCXq|T0G0_9XYhFPHUF@nV7wR zwGV8|{2=q{#iZO^M51?gqX7->|4`^{3@|*|`4PFcO1rIlW_O2JkZP_Dr^Lek3X#|| zq^b_Gw{}*~oza6GZP|@l?e3~;8oqCIPireHTAQX|!jcBi$R$Y!YZ%XmqcK93;Aa`m zXCZYaIu?zdyIJT+jCL}s;Hk$Lwl+Ef6$gVx(mrUjhSjthF*$qtPE_Gb_WNW_ILR?> zxzuQy^>S&|aaJ73WMr*2Hv%gtN;%)7dnR!ywO9Ic71EQqA5O%5prUBe+a=z#<nWY# z<S!OIoV|{Q?N$89nee5eWkyf;H_W1_X|F%`f;K4kuBtItRuGj%Q+bLmqRO=`*~co3 zMRr|888m)W7PW83f2H9r0J}RJu)8~fZQoUBSd4ZvSl~$+fu=_LvXo;mkkt@n_-)Aw zees)SmGEmnR1~Fz%XHQ*rS^*Wl?o9HX#G+}(IQ&yCsDXOJr6?bHp(hfV2)j~l^u4V zRps<WtIF*I!QO#XR_KS;-lC~Idqb;TVXVEP_3ChFy;_OZs|u}GOKAOdg~)1%GPJ%T zEA&NcnsuYm`j-k33uygwMbUku^{;4HnL?sf*<lA-RZd^Ds@y(k?H$Nn(b`)SXr*@d zhSpzJ7;BGcwf)`EN=r}LL!!M56RQxzZ7|ySU`B(dYm27uwPbz+pG(X~?ktt2^**)| zQ9S4dSh}Q3jgm+96~_G%#^=U%Us|Yv%`iSCEA+*9nsuWwu2qOw!1&3EqWi}9DKxB1 zAu+D(umj^Nr!U4;?o;{t;YJRB&Wv}d1MrD-*c+cFDh6hceEKGKnulkU(ZUCD7@3k% zL>hzkm9;txw-|FJ$!6tXob4r;d@B>|ENavKBhxyX(ZS|rx)oWd+Lwdl5IJL^d{zS` zS4N+$FpvUY#>0!ULSG)HSvQ)8tqKtfJhUr{?wf}m8dj!|JXChr!9$hPmxn6%`TjgS zc+e<7h?_<vaGmV5H?DuOV(@oxeb-MN`v^_mOZNN_GxD4)%HOWq7<vnP2XF57K@Ac4 zzfnl;hVT>V#`k_V=<kr;>Vn#(R|k98jK62lermo=yed6M&+%0%mk17c$2t*3?pn8c zKO~pApCyQSrD{^1j!wU(aw{C+A4_-}{IOWr*S23%wcbOU<f7WYgFI?SJ$*|z)%mxs z@o(?4kIrAj&i{AIMkGXH8{K|YDQf?X9_3hkKQnG}5K}l`JN}4c8G+oClKXWUwr}cK zJwBLCMS}|{cVz#II$E;dP+bpsx@iAiN=W;!_CM0fRjm8o038SW2r-#%e<vG4Q(oOp zcF1QG&nR#J=Tb7+9v{bt_>}7<XVY>Q+mQ~A=zb!Vna*YQOZQ_~>?;OnN(hks?jgvI zrFvhgUp{E6Ly#(>&nY!m(=QA~b9<f!oS45TM#~=^ColxXIVC5KI)uu|lAm4K$5k!y zUKt}7)IJJna)u{wnb5;AyvKSOzZaE~_Gx<DC%+%4;`amjccA?cb+lxENOe6dzi*Qg zN`Bv;Rvw1m{d646Z+iqyOK#g^^i-g=J%I%K0{ztRvxCcteAmTg?Di{=@0rWk(Z4yk z3_<q5<@6vT=kh69SEXDopG|DS@O$TSL)AKXE~myQaQSISlXE$F+c%dxGOmE;>SvUa zc1Vx=<np~$T)wx!<u6i4OZIcB>tVU9O9>^HpG_+d!{vTDUI&-Ifv)>=Ig#(WxQqji z{c{<I8aD@*A;=!MoSwzxTn-9cE+5alG&E|8Yww?_S_jYN)EEUW{}9sTTu$Eh&E>A* z@=uhK_HXEMpIpALip%#Excn#TXvzMA>Uvl%|5!>Wx%^sMc^EGD)A2gE{06%2&*enE z>*6wwfA-I19QoWFT!tWf;BtCWm2>&G1umBluihCNHAOD}SJgUrE~myQaQRJ0lXE$F z+c%f5DlWgJl(c6j_Rr<}tGIlBfy>9Kqb2)x`cDR656k8Mkgzg_$-XtMJPeon>3AJn zz7JjZ=W-$+xIDOZ`nJJ$eJKQRaCy1nmj~v_ia!l?OIG_2_myNW+oa1|U9OG^7ss%V zzapcHSCWA1l{8w8WgnulND_dY1^TB&RFovCHv{#?lY!-DFkFa-&vBf!rNSz+cz=F| z>W+$qMd0A1Y!IFzL%_W{Ioz`_tGgt!B7i@FqnBS8wDG-EOO8N-PXHm~Be7B<Ap zCUX(Dh?B(_FDAl}aIV;D<7F=C29Z$iCA`k2uaWQIZ9eoGI^7?jTy$5XkbHzK9&LJF zh(KLd$UHwP=IMe3HkI@aMa#uVS)h3Mw%+hsbWtNflS@eobC^ugx2%xsG6WJLqsO#D zdaYqY9P(M)^AV}Vt}rJ)KPG0m;i%V|xP^5r*a|VjQIHj?iJHmk(I(nkpzuTr@I<@J zXdz`L^bz_?O2yk^!E)PCsN>AkqcG4|%tT>x<=hH_mSb_EH&bW6@A*2%k&nZC*qKCa zAY$?`BF}qUsmWGiak7+CYQnw*{ECI7-CTy+Qx~6DIfwpxGfI`k5z--mp*T$B$Z+O) z2d7z)vB_X@6LFzqxcVY)^;rYKXS&HK*cIK-or(>_RC{g{YQiFxsUr@$Y0)RDSTLf{ z)AJ-TW&u?5Cc@lw1w0s5CRlX*>>3U=cvz;ux^6(jpC`2g7MY%ouxpe$f{0WvV0y8p zL`fsmuULVVK=iPVlW(K$kRqv+QyC%n8F2{81fW0?C=S%5#q_3yYdUlpW}(g6x;m~S zSrF>m23*lKVOwZC4BNr_+S=CE)@r*Oa?f4${LM9!U0FlPU@aDlRD)Wi8amF?VdYQ; zjkEU32kw0kW?Ar?jZ!z1l6P|=>n8L(TwStQ*p%Jyu;rkOnb4?%0%pkL^V8xa0M*hJ zx0LvL60Lqs+%BcTtqA5*h&*shHZlR^Ioy0wuOQx$po{wx9i3a7+`%7UI^j@|p*R%a zmQSc(jzHf4HE)&g$*b;o4I{PS$p%M=W&`7!&<Z0){zpgcOHmu~#B?D`UYbhjehnb; z8Wbs;^ZzJ$gdnQ-mOH|*?`(pSUG&8nqK>bL#fIY<mvn~UWk<)YA;jg=y{2t3&fF_> z2}(>So&eMXim+j80oS3Pge}W4zXcru6(O!G!8Rscd3qMUswb8FyG%xFP4z;t&UB*+ z#iuASd0w_3r}^bk{BWDwa_2tzp&dTC>1WgaK=MOh7q<MNwTVqX2&|^oXscOX+mh{V zaC=*}vMpQKmbJHK&23o=QHdJvL?!*s*^f~7BVsa*&sJVNy}PEO_GLk}KvL67%?dC_ zC2^oXrKZ%aFa9tsC9t<`^B_@+4o(uaXnQqLi#BHxwdm7M3TV^9FcR}cpi0}#BhXw@ zk|>d+kTc23C4*E<Ny>q)fNQJnISTu-=xwD$ReGkU#hI*ES?Op``<NH}kS3zVa$9N6 rh?s_}Q^gi=B?}$`7zyA-lLnPX>q(wd$r6yWCOO&EAJN<&)mQ%yC=pX8 literal 0 HcmV?d00001 diff --git a/docs_src/_build/doctrees/environment.pickle b/docs_src/_build/doctrees/environment.pickle new file mode 100644 index 0000000000000000000000000000000000000000..ab85190b94d6e6c3a55d42111fbf201f24b8a836 GIT binary patch literal 51599 zcmeHwYm8h+cAiK|d<@^zV=3*f_NwW%nj)u%)Y|J6cSmb3MQUk^50j%^$s@XTr~CGF zH+#BUeQ%S~RJe%^do2bR@CNQ655NfGBuIcH$OC~B1V$VfNCN-KpCAZ=JP^bPVmJtp zz_1f12AuCZr>bt<?%VUAs9o&F1UTJYb?VfqQ>RXyI(4e*Pd)i(f9^M*kbmj1xZiAb z*DF!?Zfnr%u0`EsoF4hwu+^zw^pbvQeDY_;560zmSJ>~5ucdSKUM(3!QN1-7r(aoU z_ST|>yKCW~6?R(-w|b4_UO0#rYK^GV9}SaMCtg5-xEc>?3)K}O=Wim2$LVgQ3ZB#3 z!Gm(OUboR&9j6CP8|?4h7c|2Wy{~sS8Vp)>)b?PUJ{3pFP#O`fCs8+U^}6x+HrnQR zv7S`IVbTMM<Me6EAS8Cfey<bty5sb)mrB4q+}&1muhy$a<0#$R3A?Mqa5WmIJ0ld_ z(;xKOQ4LJqf8o-_w{DEyCU?f^zFMz88njlM$T|G#nX|8*4z73KI3FxU;ToC>a+*D` zdY_lL2aO`}XwliqnaUX;A4HufjH7Y0lpac=wSFf|qPW@*lO`IN&Q)F7I0V;v!$B>o z#=}OVwGMh}y-o*|2|LpL*9Y}z5Y^vkfmSf`<~V(_GKiD$wK$zy3*#gjRE0lJwYv2P z#g9bmwa%~}u{LBHmhRTx2H{K1;o3@EsjuLB<&9g_TS;#~1|8~;Rw;E5j%3t{C|k{B zty4{!(HfYxFYJUXQXQ(0j5rCCR?RhP56UrtEz*4S^GY~iS2ru{)`Oj1E$k${T7~)J z^iUjygIaT?x2_3MoE~LP6T(_WT~Rk=&4)bcm6jeNH`l9RvCvCVI;=^^9%>ruYgW?3 zUeOB5jML}6l;8~m4zk&MyU&}>-Mtoehhb-&pe_6G9c^5N$SThL9)@xA((Q3G2(RoQ z=uy<r>Na}p51)+YTg^+&p!rq`Ns59_3x6;IYJ*mv^#;90U}Uj^A#}AB*P;%DHR=sx zp<piR4_B&5D?z6;Ka(DlpSF`5t&UKZ?pJ0iC&Tm^?Sf|SURA{l)!rFDOpk>1dUdT= zA9kWD*&8G6D92c>6UK2BBNrnPqW@&8+rq~)X82XtqO}!BT93jwPWP^i6ze!W#!**o zbyep0BOZU09+K*7z~~56p=f(4homKWpzd%Ds-)WJ4c5X$6y2U!#{!1UE&UdJp2`Yf zLkMoV=Td96B1umr;R<+^?p@-iB+YU3&#yr6?x6fztvG3QSD7<Rci#;=L$v<^B<0iK z>n>>C@wHzVH$R8I`hZ_P+k7#7Qbd)%UTT&!`GonBK84nXqjCDgSTfRm^1Iqt!{AiV z=bJBR)_xKFs0#H;IZF5F?|2+){&8(h)ha1rn~MK)9}arG<U!>_oA=;Ds7s6~p>e)h z(JwDIPbsRyMx8`mv>mO*&>bd?`7h1KP|*r<$bj@QI-$D20>!b=Jfi>y>QN&cc9QA< zYSuI+Jx<YS47;M4FeC;Llx7rzg&%40cOPo$&nAP`8oIETbbCou9YhT%ur4)RKdeP# z19c##aH>9q6e@}zxz<d;?DSX@8n{C(>{tS(8LCVxj%F}D8A(|~eyI6*#dFvy+Ug3X z9VmZ;|KOb{>Q^y0cEKTAdwMh;_WOefQtNUsyvgVEIgA-muoxn1Ydxq0Gz;1q`9km< zRB|=yw>rI5%P&d7$o7(s31^@lFdHP*Mkhqw$~>rFFfAO6pgh*X7PQgM{>apQpo{q( zYFP|~@wIED=ZL0x6XyfuAmae^m8h%gaL}=&?8RX2w`zAr<A(xt$o#IhR=d>xx3%nU z9euWko;HIK0}$V;^{9{O>&g!8si@gd&K$--ZB_w5{SbCKw)9a+k3ImO>~Pjmk?yx8 zAoRBRb4e$zVjgWZMmA|blWLHdK@!`B?2o~t<bxsP%5m<PmsSl$I>+g*58i;bl&*Wm z&o_EghJCuv4k;OvJKG_Y_+GJ!I4U@0?E*KU458SQaWvGH|7i1zMz}=D$^2+%K`Xs( z;;ee2se+<~M4P9d^GuIGY=^+k9Xcl|J~Q9K@JP%&u+@?}g_{Xok?j)#Ae22j7!F8E zBfQ&!`ZtNqYV&=8Z-&hk{qkeYFDZt@0uPo9!hE}*Rn)K&s>6OAlQi^&C_}cqd9L|o zEw5nECN0i?VaH6b&_cqYrv-}+157OSR!#ca%cCOdN0=cvsbMbI`5V7#%Idr`j3XAr zeE*T6Gz{!_T8YVc=x5O6Gt;Cg(R{}MJSW6tQ>e4jo~$I037=xt+UvuP6{}|49Qjpn z8nk7N4pO4ngozAgfT+jJ7|pjt=5^HvCPO<>=5NqtdHIZx-y0_VA=Hzb5uTD6!BBrp zV4&8ZouO_qM{;NhyS1lu{Bw9)6Ln`LFom@OZE~inO$$v!gdbA_L8~<-;~Lb^06Y`* zWS9<P5fTKgxEg^hm@kH^7lq(x9U{=8wFe1e%8yp>4O*~x^I}aqlA6$VhgK^Z2$K>` zYZeei@pO#Ipc4u9*cz`^XrWh=W;<M0iBFfCNz#wcEiBaP-F955b$Y`(^!XsFfRPI! z02ex~m3YCFT6necW0fCWkYzwpX~$nhM?w27E=BLmpTBx*{_54Ys$XBa`c`j%Z-%v^ zSXtww3OQs+X?4LCYVUHo^Sv_0!FwmiAfMBKD_n2ISbdBP&@zE;TOfx>sj-ZE7E4R8 zL9Fm$w{9#&+MfGd&X|=v?S5i)A%Ly=_*(nIjwhaA_A^;_J-Q1!U{%cQr=spWOj`$b zJOeXW+<I!q*$nJZ2Bvz-A@J(Cvx12k)-Bg{M?K{_uM0C*<Vc1LMP#OQc^<k!v_=ai zpZ}?>tXc$Nw+7V=E5f08J_A{6b+OtTtW`TvcNOzz#vYG*ankGGgKZs;n=d#d9*t@( z`k9Bb8gyll9`TwRd>x&avF_6uFzsO&g54_QyNi+|k07rj9GKcDw=-PNWw@mE&<e7w zO%E>&<H5p8tGm!_(bJF>@fhatYMG<1jLpbO1zAOqVOsQ6S~~+y7)h^(wYu6e2W1uE zmW$2Ls2L=wR*>HO@x8{)@+8wmc+Ij(R=4dBAhPm@a;qyWo!7ImXS172&Cl5H>3*q3 zjaV!MUAhuw%?oxMYanu6^neH`+9p+AR>-V}od2QuqAPV+>d`)Hv`{SFGwj~!_U?7Z z4n}E-Yucip^;@)8iVrb5+e}w=rwpjkB{M$hC#?c7vPp*CLF86)3aS+Kd$eQC8dNfx zwPxLt)O@@74TV;IV3lc%$X%MOBr_R)AY%wSP|OK^*l>TruMZ}-P6*Cse@2?N1~sV@ z#l2RYR;p>EQZG{}1~He7MrT?QO@DY6gUdN0n7x&{GH)WEGwz_Zf)(^&BLAqA=bVIT zg==msP3NE}TK7=|-h~Viv}4}qVTAbbY6KU~dcrjaCuc0I_n0IR;UhMm`aygcAGQCs zk+TCfZ^&+c=+ckbbgt};Q^;`s1(%hXW=S|eDve?7-LE!(T*sI3!E{$S1EqWWoc-uw zVQ%w6^9_NTQz$hyCFO{wU~FUZ70b@7JwB}&><Im~hV>^DeP_7VH6z_Pc?beOOWiJJ zo>zFN&`xwW>Qs%tfJ<LpD?OtClNP1WV{m#Bva{RM)zH&gOtQG5!a~OAoaXuF*QE4w z3gVfvb}UG?aa6&i7w-zJGQ$HHGZ?0|I}_`#qqK4~V-P{AVE10xAw|5L1U3&0I@2~U z0~5#{u3N4=HCe<?P#;Og@vIh;k&%(^{OOm*A;FqI(Yzwy2k8LI_@heq@CQ(jzL(BO z>=BbLt|eLR8&mLr$q=myM`;&^|6OZC`gxPqPV;*6hR|`$de^39=ZMYnT!K>OIh#?~ z_s(CJwJzOj-4@za&sqdsc=e(rY;|C84vjprd}76|)}*U5-Sf)g{I^P{-ZyK{g96fx z?$J;~_LIXdoCd1Vo|ZhWWt@TS*0iiwP@8pi&hQpvb#5KLSvVmQOyOqyeyY~*>+)vW zNg-v93P8OI$FQg@P-Mn+`V6zgr&EyI{Hf-$4*&O>x0U#3tz*!7imaia*`J!s&gM}C z__PDSb_A$_hNM{%CiLl<_GHdSxbL9e`&j>G6hCJ%7+*~buB-u+uvKO@yVb=si*+AH zp;qLW{Jh;psIK;UF#IzRi{!Y2KtEuO=x|to7af50fYNVTz1M<E1i;o8^3oI-yghfJ zFSh_0_oG@1HqRu^A96UU5W_m0QnH?=vjvt?h)oCduW`0z1QY<%OXnbecq6pVmFK{Z z=D^XWfvxgbE(fB8{S(tS`K&=Q!aQ&LJXh*YG@@B-Gqdif4Pi2`*|BHcL(QKyE5t+M zl%}4m_PQNR6uKx<Uv;#`9?D#Qx?ZwdMMloB78=o9d&Z?>H$rSs+K&%4GjN#=Y}vq@ zsWOU1tGdf6X~Z%duA~QbjU}5TSp8htk-BXoc%aiGW*<ux6&93)I6j%!#2ywrt_d^k zCYdXN{Xir?KT)O~-VJrHfw^`Q%@*QHa(rcH`s_rh{s`M#-J)u^^;A%MoYaxr{1pBl zNA_;TH@@;?L$FY{$2i8p1oir0+u>L)9R?0Y{zEu<d-Q+OL6`1DQ)xV@x9$kHAfPO{ zI|b7jTzHs1i-mW1ry8M12V<a4=PhLUqx3)@{#`B#Wbu{;cDa7<-o1)8uF@N<F2M3y z0A#!X!<;2N0l$_W7&K}gj?Y*evihjBqNE`>=r3S-Lg&gKYISpNmnQZ_pcG`iR$b>7 z2f09VB_6KiQ|Fr4D8rHw_6+9p^f_@Kfh+KZVhs&X4rLMJ0v(z;M5}gF0UHdmo6+2r zZsv=}rkvRqMc=?eZN88m5R_HxWF4maWVF!p&rQKb4@-T~gyUa?;2!t3!>}*Ah91JE zE>#aUGP7;xar%PytFjtlqdI}NTlS=352(8?4^$hB;shuR(09_ka4&1k95OldZ=U}* zOTWC9{K;z@qEM*OuXHycTVa0g%;zjoCgJ})Xy4uW#1s7Wm;Ul^J^S;+6uTs}V&PV! zrPc&RW-^3f%e`9lB}0J0i(MSGzcl{&@y&6${UPv>cP~^bxvlvsW^d@GDkOCLo%WwF zP{9OLo-GRdz`(vZ0qb{&K-xzA;#gWkDkkyg`$kF))4gVX!wT|eP*?ls@P~~_55j>K zg|I0)_rg&Okx2KVXG3^@Lj(G=08O7XJjodFU@R@f2Z_hWxAcQde!%@X84)t{g<&#w zL|iIeIx!$L0>Mpj4T;z{2=A$<7T&&eZ>@>&2Ke}3<FtQ8Xjp<##eVtJQZouXaSU#R zwL1(A`1!G5YX5bD&xA^M>*m+E{nr3DTnW=T&!VDe?rOo6!)-pX`#~$dKP5IXzwO0p zH~X=Ix@Bo`8;#zRgfN1*>unl0ToEp{|0-(IW(sl5QTuNo1ugrVB=vb|P;R&cS7nno z-=r6Oxc78iS-|$+1E%&r#UHe&{rB;SmbCu?K2giB>c>CQkAJKmza}5U_CLXA``7UY z#Ii3pAy)Y63#O$Y$Nl3ZRiNH83dMpcq5o3qdvro6ZJQ993k=B-m&;Ll{{6?Khho18 zJ<`kh(P?>-qfUC+!WH)N@8pSnWO>!D|0{xRn9g;2aB*^HD;u>kL{x++S}GsxI~ne6 za!nLbTS&rA8?1Cp{i-8%*zR8$A|6I}Cfs137zHxE_i^u{iY<V(8DM1>E(BA-D3POf z<AWCJ>LBblXB1Xq_PH5;7MKjknYzR8sP^Aw>t)zIy=%L}jv86Lp|ApWgR0@6HC9DA zr^|ZLBh8VH&(tGat30&rDh;Lrjw!~yg0a05ABC!FKQf@<G~R3$`?julGBwQkG~EM# zwzy1gLjfPkPm&YX$3*70VZ7PlVhxgwtQEi?@b%Yt18d^jh^#tb=1%JyDz_KGiT024 z&jtKJa2ouV>KXlsKf*uE8=*urz}|XtwbR3bBi-F>)nRJj+d+fQCG1rv0qnsmPo#4? z0Cm}8dd%@0cDclwZ8ucVn=2*uEPayxjPaFy+VQ8*h)0<;(%jJYg(%wg1cc3eH~JOR zu1BP*{f-n=r8QHS_W-C+$`8)UI5sO|J5zZ3UpSr76Ee3m0~YHH+L^FmWD_f=GukIm zgYvSo?YfLv@QOpxdQ=ouhobSQC`^xvaq?a3(Jk3I?SJk1^Dl0@b;bS3R&Lgxe{S1# zP4(yaQBh?5`DY##h3QYR;kMnM<@O^E(VW$no5+95b>ctUc9V)bkxkpI6Mtjdbxn2R zuM3KqQ+Bz%0DwX@_bBtUG|HQ&ujSY9-$wY=<XqYQ9T0%1tgTOwA8mhvY+pkq?d$lH zesMdY?+fC!kQuT4lPGQH!+(eGSPMPwDdNCoSU3{gz&HwD0MmSy>g+!hDn9=FFeQrV z!4t4OGfIq9WwXT}Y`f+u!TkM4MUiQjPp%gb=#B_&*>Iig1usi`A$W4Tw$T<9g7kt{ z-Bd4pcH1>i^}-8}isBRRg<}`s1DXin&-FzSfcD56+iuiWd*ta8^r6nf$1CCgDj`$- za(>(OPxZ^|kBVZlU$$>&i*>Aw)XC!!P-Im6+M^D0V*!ZQWZM?NqZ$BPbilO#r!xm0 zOmx)mA_wlY-_wu(r5}HwAOBZAie-)MEH(#@f`i%}_qSb_k*fm^#l1&GvD=|Y9u>t7 z5rtuT7!Cr4lVg)Z*YnmJbY+Ju$?!o77ayFMt~@F3qboaxIB11}-d6epEbEzsI7?k1 z)3KBuG5!a*+U3Yf=52!CU~*wDRiMAb2pOhFWCf4tGwkz7n7DYVxR{3@U3@R!kyU;6 zi_81$7t!z+3IEP8J;<d!u$l9BaGf8uEBRb1&iHXlOkC<<M!KWMdec3<6&_$?1KL-~ ziYKsDgD?cMMJOQVrw_6VJN;6AKhKp^<I&nm55Y)32@L7(Tl&ko)J3qarTZlC?E2t3 z59=MWM=EY`OBY+O=>eN^et@ky7<Kgse(!;*ziZsltI4|ZT6(w@-;Dg+huB>5{PgL; zYKX{?3z_F0JEz8R?zM7fTYK#vLe|iwd-Ob0juB7F&L()!Hb4iPVO)(q7z$Ncr#}># zdMG0GP&($J2-L%&<0%hfWQZpAoz&yDTPYaBGn8{2O*op=rSKm?H2}~0PL(`h1)G}n zs!OxJDcvwZh>AIb!|G;lzp1O$R95mU^L<y98?E)Ib2aQEAXgTSPid$UQ2+4eWhw|k zH|6%ZEfA9RLt7||csZ$Y`z6;Ox#Z}POWrRmnd@!aPsWERa+G?aamr^(9+*+%*ek}N zO$0cuNpFbC&-L|dTPT0G731V$>%NHjhS+lQH$e?UZ%0*^2!*Hnc~dkE+y6?&V7dJt z@Tocwk@lm9$+-QWB!%83oAO^Ig`I9w{y<WQ)}&;^ZWkjBvT^5z<1U68P`T|#r1xqT zS7ZnJzFLdtP<fUZy5XSx#jSZs*^P6o5kf(UV()5%17JKT(mwtaX>doFO~iG2w7N71 zyRlmPHwL}+5gga$_Va*F4<l0X{-}y$Fai)E#|1txP_r8i5ayXaby;diu(#O$EXuWC z<e$&+Pk=wafbp_|NRz$LAxaBcHkx<8u+{fzfR!i8rU$Od24656d)dRj+nh>iSCBXh z<^Ef8R0G?g*b6P9cOk=w?H;P?jG4kg!^Urq+dmA@$%Y`A)f*bVJ$9Xqy>w~%<dlCK zeY9IoWgryC6aS#B8uuikwe{P)m&<b`IFKvq7AVT?*GbF?52E6ftL!Ly=w6yeHvz2J z4bra`tLpN}pxo*Pip$?>p1^f--2TrP0zz*j>M*1CC7)hjXM5Csu7Fw}G)L>a)Ad1F zw0r;(XH^2q{;Q?TwDoyt`=Fd5aT*`6zcT^*slhDB|2_%1J`3`HOhS%kLH_O}<o#KY zzi%NUYui!zkm;GA<pjkk!L0~N9@sMfrzm}|O=|erB9g}f=Ki52y4)6AZ(3Z%+I}0D z|7Zg9SBo|OHZbl)V^y3H!XY8~h}76`!pq1*nBbRiV1QEkcDMDx8yYJEALB2MS70l4 zbeF6hk!c6tzzGMAFqVjQ%P>8L5PC$NBP3EI{<-l9O}~#;sLoUPwIAx9(PoUJWv)g9 zGJZ&psNaUMU3KAmI*N2o$W7^aH8C!~lPo{+#ED?3*@^=a8sHNf#|aPdd*^Q|b0_9b z_z8q-;FgUbHdk_-3r4+RPz$>O?smY&mB!-+tt1G$^@ZMmssm?XnSgMsXb>dL2q<}y zC}w5&8N7Mz?chzFWr7<#P*MxtLP$NL#DWlHnIk6kU}YrWmstNTQ-5%YVO%m#o(A3s z0jsFQMC1iuuvHj*rvp$_4igeR2z1Up2}(x+1K?e`!e(c!t5e^Q@Fos+;0y4fdG}hK zPOuUM2uy7ZJEsF2r3k)xdFkud-(CvNUwaqCee?Xyo9C}Bz58XrA}kU4h>KH92)OLD zqI!UEPRzo|h;(1Qc=N*70e}8$m*2X)^e#!ibb0C8#ap+6OV@7(=YjFY`I}3ZFTDNM z`J2Iww{PCKe(Pc-2yTHro3Irzd+3+}?{8o%c&rV67d?p(@?obQG{d_QdbAd`?t-c? z;Q39<%Z<8=krUE7xoo5oTyB6$#O0n2Vo>!JMjqm<A%hpOmX)YO^fr4sUU=Pb-5whX zaB0bp%=6}w;EiaQ@H|i)T<k=5;IZxE=-sUmcKQZA{tDi>c<Wtue+Zh@KnQ>p*TGnt zagJ=Q+3O_tgY$9RLmV;<tIAxdRGPcMa3kED5^zu>@;CxF=44>lSr4O+k(|K|2_{7q z>@B&oL+vwG5+e>UunQWFk=~kg!uuBeoZonaeT^#hXyIGQy(Z#37VPkR{r##NSs0HJ z%%xNc!YZyUU|@N*8fb)W5U#{HSps`of1eKOE$C9T?KJM<fOFg3b1*k&N_dyDWJ&#z z{m$j4{XU51v>l^9f>&*o=ewiR0kz#}jM5l?q5W9j5~C%9;6%_LVN*Rh2U6s;+v2c` zAyJ>#`sWm-wxgnRk)e!Qj6pB)+}s=j5Q8c%^5}Qqh(t`@YP2#4TeY&>b#e0CT!4Sj zA_%xX7nGrOP6qR@3pva9aoc3yoaiX_Qw}G>WT0!LjX30LJ7IyB3SnTtC(#>JY8AmI zgawPiGQR{IKk@~N07qp(W-BR|%FCzbZ=Wnd*5x3;q7Yl*kAC^&$)MHHGA}I#rIONU zl42@L$&8oJ+~#<phAEd$0at0hWZKI%3mFv+pe>(4?y1sAp$`WrhJ$XfTq;%Cy;iqe z7RcrG+ouiQ_25)+_BO~M?d!x3MY9?a2_`WGKY2QM_2g~Ke%$fFndfd9U%(4=a&?^o zW`95ovLE+P2Zeppz^n%u$$#WJOtLoWGE2wSI?9p6&T>CCqTF-^B@bn0OP$I=L%WC2 zDu(P9$Pp&1n?syLU5hUA_(r*OxeJE0>KTvD1s^`Blq!su4ih8E+IhY>Nxx;7!*$HK zi_(Y7^JkS*5d?@bvnWjKC6OQZdo=O;eksGZ8MW#-BdM^?aX5i98hRbde-PY1nUT-R zPAc_=91^~K4m1Xfpy|{^ogy4)NC^j+OTtMOi#lcmWCiDE739%pzhoTcTV-o-bhuhj zhq6(4l`rKagadC;<<#_zD=$<!45JAGGYo9{RxnKVM~30mDGWk{8Qc!ej!?v6<0c*) zA4vu{Db9(3lisL|<0fV}Vj92=Oq~LaDOySuId$gg0DAqlsL^YfUZvU-L6HWXQEBn$ zq=A#*6o^rxxFL$<ESGXrmu}Onq}F5AS^oeC3@t7p1j79>1-`6f1Z>D5((`0MhpCDD zS^mOpm0nz=g8N|9`yeAXD^@hBUj|Vx2X<uWaT!=hFipcio!+N|sDg`}2zch@lSVz8 zTE4-nnzm3&raN#<kJGuqjbZ5&h-rkj0wPY9it{0OT{Jp=qdSAMS$n8vU^!ULPqj}V zs&QKsbA&hBaEKzWq9+y0>>XE~8EzO-aa^Ky$PyZp37_|d4DdlMoBAm3QqFWInjt?c zt+<Z0QBwAZnJUPh6ll|tIbkU3JCCb@43ya#xmf5xEvT@g59=iy%fTu34z7p6Sv4v1 z$&S6kDvL+nlmXKSATgqwd6fhDC=(3RT3wG;O*Z>xg2j{v13Mc?w56*G=h-)^O0zeq zY9>&=DzplsxKXQ+y-8JyqW~yh6)4)MD$Opy;xlk2P_8Q6Cj<9ub$z;BweGsKM(n5j zK)^7v9bn4)la}ehT6eUC@)$=rs$^|GkBXdv_1Yx`K$)3&mP?X=s`3f<rEX$Y8&ebj z(b#{k&g%N2q1d6`0C<!GX0;mt-_HSqq-kJLFlx!?Ggax3TBF;2>yLg5BxkZnIFLWn zNMzHXTa0O431Il6yj5&|e?n`Ew&D5~=YhMcUZ2>Wora+-ZY(HaeaO40s?j&55qf!B zN7Qfjl3sT<GLyeKLVC&S)zv|7*q_GcXA;%KY~qFiSmG6)CA>9)6;i|w<i8w?vB(!_ zXE70CgQ<Q3fs~y;n-kDN{4*NGy)3U$kP_NZ0*qBBym>MGOy$yozk(zU8%ZLO2KF8f zPLR&v5X7F%Z%7p?HefyOcD?hxr&6fcgi5&p#v|1<kVQ3XgYq#?{EIt?+n&=%Ci1t8 zX$DPsbemFF>opp%+o#F08Kh@p{Q$?>ba5tbUX+*GK!r>fw;3C7V<oH)a3I~OMh}TK z7R9FVCrEFYX>p;k)bLl2xx)VJIHPbpvv9*BX-47MHTyiBQFwOElS^eIuYQ~7eX{+< zl2k?yVYxKPVz;`%x}UBatQ5s>{__0GW;MgY{3kBPatSWgA?(4`01%Z)5MA#T(3CTC za4m_fT|8cz*0>xB$qMevnrZ6f?95pjz7hMjNh9_RlScd~R*7QFDRJ_~No>`bBwE`B zkj@?vO7ivwaf$~1<c*OAF1`$6?&-KjRAw3^IXie3*W(=5;~dxHN8-9-+<=#k>ss3e zkdEs@$@h%wF)rTN3fFT}JC>vV<c_exnI54<*h0oDWJE}f8MT3}sp;zo-=Zy--tNLW z?X7lU#MZHAh*fXSIskUq2F7!*>r{J_Rc=je*QMAX!%g(t^iNItt0sSM#ebEjZTpL7 zS_4pLo~D|TdfUe3lGqM}ruHgWO>bf>ZiWa<#MK~+XTNB>&s!--)wmF7JCq9eV<B}K z(?+yfGbCFu8SQT~NYlpli7qGL0F4H#{(NpH`rNRYvWO{*%cVRH)`?dTa+;$6uFCx* z>EFyur?SpFCz(=ExY&9kF#i=4$ZB(oj@(3=YeE%Dyc2nnT7*zxw!q*B7u3kJ0CsiY zA<hJ~KMh9Q8E-7PxeoD{aomuv%Tfk9Wfl~?2KI3YUjb%xco<=$E(6u_*;miqcC^?{ zyVKS~%dLpVRG~+lt^3t4Y*@Fic6ohSv14&F6>hYz-n<8`1J_#|m-$8Sti@g+o-IJy z<bD9RbF*ClfOV6tsM35zTUMnRLCYmW5XZq{@Y-vc0+<10Ti`~e?v2dJZ}gzS$9=Iv z3|R$5i(p1T!0vfD3D#Qc!TJKc`VhrNyb#Cqn}@`S4PV~>3$c+pZT-4s?ROnub2A@) zPx4(hUgS@{2e!ieiK@2DeaN`;0{g2bkcasS4$v8HMJgo3xbwD0fKH0mBGR0AEnW)Y zj4zy%)^n~*trN?`PqI!l$)6BhJ7>5*A6Gl4>qI+0$vV-_+!Dw&6sc5u1?I<A`*Ue9 zoYkELRid4rT$Spf&xWyU<!tBvV`yb=mE)xL6RT3JA8&e<8a2^PV4{8UMn;iJ+nU)< zq0ehF9qE0<k|brRih+)&v#1+rElC!ty!5;x6Ocw+^#FiSQt>)TK`Ipx6p0J&5u;Dw z=`1SFv6H@6Y=VkOy<4eNM8!(X(z4WHVpKK?MDbX%HEp{dS82E6?<>}EEZzcy;-K|e zqAX^mk)xs#R2owykSHYv>#U>9s!rKTWNYYTuwZ|Sn@*ue0?leXXy7V@X2>IuGbXGO ze=tbOtn8J5e@_Lt^p4+0Rn_yDdj<S;fTN?b0cv|^xrD2I5SNInjS%{%yQQL+C|E)q zg>VM6(I;T#W{_q~g1-(@2tqqZpCpP2D%5@j6FmfOLuvt#4ZY2X1@P8r1z-`Wq{fme zw3^rtGcKelc9q?L%S?7_CADl>H!1A-v9J}>B9C}$vMvOIa$TjBuuw3DwdKBDN-+vS zb%}75c9o?ZD=@kXF<n(849egB_Zfg{j86CT6Qzg$h<i~ga00+&!K}WHyo(1iwRk3< z1mT%XlIj<gh#X#N-lF`?Be9KIv|qAp9WkWp6K$0=dAW3Na$oZYq<ICMW?I~wZ1E3T z?|qlrsq4uZCxduwfWvH3-M}yq9g|l(GG-WVO{sqiCm|5?8razAz@8M5vj_;kCXk*@ zFh@igAjaTsgbI6+*EYHvH~aHea|zhZPW!#;;;}`82~t}lBGVI~BN=pQFd~ytRuT$4 zn=X<iXf8pAg+Pyp|J)@BmLOY=*D$F=!{8a5&xbYdBGNy2AJ@_gPF~HQi;$lcB))(W zI2$={<CR^DE4;xMA>@vMSwy-q?#RSC*7|5Go@moReNyB2?=iz*c?BI2&FCqfbs$PC zDHp`SgJTr>IB7*nAzjwZ+F%AKM|Ei{w?`Zm;C-zr!SX)5BZ+dBqs1#KmBxs-=2-^T zf^ZiYJAK~HjQuFh&K2gx7TQaYC>yU&>8cG;vYT{9L97Q0x~=;>kbxa^gV`3$xN6$+ z@(lTVnRA;H1)LJWaVOl_9sJ1I@Jo&GwJ)80?abLThB`robLaZr<~bb#ls7xfG|c^+ z&|;(h8FmLjg6!h724A8Hk{-IlRawNtn-VCF*kwa}AhG<J^XJ?)L<DgHVV%1H=Cp%D zseMNB?U1ME5!3dE6F$~+^spj~J@2*@kLo#z2A#??F3sTV1F6jpd*XK0TQlMuIBva! zam9OpwtO<1jJf|=+8U(iQV+b@C-d^7IUeGi3zC~9#d$ezVFqT~rw>?)#?LpBR=#0U z)^bL5O(#n9i}KS0wLt;W2U)u8^al*L_UHwZun!N^IFH~ZyWQDyf%ts9EUt9U@iD+$ z8mVKKXVr19b25z!qUki2&Ew;a-6R}Cspw>yY_6miFh|mfh7NU)F2({)Mp{k6c!5z< z<!zpd_B4K)j1m=*GnqXCC~ZZ>Y&6PLjR*>n*po>rHQhv#OlE2j(NwA*Rh}avFP0Ds z<6F+lCJnBFK46=Rk^x=NGlVWm1~k1+xv@sr=|n)%b29}wm1y12=ir0ZF37hN`>bf- zGGm>gk+{NB{n@}ZC3sj4d3-UkY?bwC9(#-yO9Qh8YTyl6yqf|rQ=mfIL(<B+7~rai zzd2<X=xkAnwKel{dm&%;w>_w7c}TR?9cD{u7LnIBxZLK{!%%#XU{J}aB)ba&Y&Zbn z2Bj30B^cn{0Vnei_aY8D1@9&PNvFc9vQ<tF-Si16FPk2G9<XvppvZ1ULzdo4N;sOt zhVmad0)A&DPX=EJzL0T@FjEXs69p0L=8RNUdKo)I8M%htaszX`j8h%hOeigS?zlqi zGXHwqDwP*_7R;;Uj8}(&o@Rz*Ot1kFd{a#)92@;=zR_m$$Zfqlj*({mgN?PAqbbuk z3a~+#2?6YcTd=IP<vG_c^3ODCnZ{7mo7D0^SuYUVR2R}p<Mso@((Qi=Ak*y}nacqy z$tp;9ZuoH0H!BxQb_SXENf7jQp3AOECB^b&S!{{h%cjDt&j_D))!ItE2Jwt74uwX2 zet|bfd4w8_hRw5v2xip_?pVC8|EH^;)m~vEG~A3PTP|mn+XCBew?$Rla>?DO(Np!> zc1wn9Ioc`Q(Ao-58j+c1<P@CefY%5DbQTfpqCxV}Ga2fP)M;MlkfTevF*pM)au;py zDM~be`f!@zSq~L?{;&1a>4k#&a1K^|vK-4V3(OS7o67LOYAwPsX`IuKvDL2wic^Lg zQJkg>9}C@fy5jQvb|Ph4Kl8<&kk(Jq11hBAsk39aatP-x%cakoh7iMa2h75GCR+!Q z&9j*Rxgi%amb0D>;LQ-6gm6+hO`?_4$s(M7CeyOs$rD7P3S`06%6$8;bRO;t;c5JG zAYtF!?55Qzr=xHXUL!%}E&wjBV|aV)K{Ont&O%EqMt+ujA*xKns7M#Jhc!PoVH4x| zHW&8O=L$*YEO{_8ro}&L(b5)gS+XpH3Tby;{P6`#>iPbZs~KZhIrsXOhS6rjr*v(I z_q%X=2n-8PU(#k^HH;sj$l=^H?heFjo8qy7yt54M3W0eK9m?V64GtX?SY(*jl?zpF zbz;}V-Iw5YezN@&&$QW40Z*&6VkOI&wa`2P%_b0rqe|b@La+=X=bS)lVxuV0W8g#) zu*e<~#Zf4pY9@p6X5|_#BTJ%kF_~VoNe-HBiWVtvLTuLAgyFx^8+@T%PU7NZd^QW> z2Zk?iw!xlRRL{=GyVh&@?621>X@m4?A#`R>*wXnF*~QfM@x(pXv{QIohn!jr@&}D3 zN^|WzqcnPMv(o+nUrVf3?e}mF3;M<phY8L*rc4A|>6g;Qb-X1Ehb^Y%z>l6@gRJ7U zMO>|v$i+t82zPbXgR<1en+>x5o1ULaA3pG|Ij|&}IA!Uqd@p3bT#LZ4$Iv1_3jeXU zsDUFLnfPUGAn&tZu0?(?zWzvkbsf)FN=NyqFcv1d3Kv`T?qM7SS8?CM+Hg&Z6m-&- zuoU(<y4Rg(n-X|7e@bqBPED1_m^H;Zj&wLFR^gT}oZ`KFIA!3?n4!~LohEF-VTF)w zP%J;3w=|%#nJwQl#t_7m=FC72A#|3pAHAt;BQ`)yZ9dMu`E?c**h=X{JfxD`>)8WG zZcKmdX>#%y{8xfAkHE_tq!4<EuioPRGcpcNQITor2Twsc!l9WqnLn}->turL=D!W( z(1?|7mO4sr!*%qynq`LS_qJK;>V2HeGQ9<B=6l;)nAjg@vrKP&Z<?i-78I((EorEN zQKdH=1n+z=ddZv@H|>#NaWmR<_ef8MJl^JF5k9~PZJk((l}Dy0HdhOJg!i#21EAxD zbPT3&t|DKrZHF|wgN7>!WF^nViqB)4Z+6%m%*WT(<{C*`LG%qa#{SakHZvkKRlc1j z7i>DZX8BFWVBsdG<P|$Owlti0-a+m%veVRb{ai%hw#?i_#@Y+qKe*M&TwoEXErS^? zGq$$F2ETbTm#7YC`k0o~m0dl;wdKS?E+0Zq{bFa?&8ld#0hne;CX0DF+o(XkeglcP zJP>AnOwP{plNq|{$w1(29cRiS+^rCiOdLgsB*P-23duGZjP;ZyaM@ktX#fPGhBFp` zWm%yO&h^k(*^+D)s(QDqlgkSc!K1`ukCJC{Hn*TM5{uW}Mf#F;$n7KfZJ}IrhqqZm zaC&Msf?gJUULkS?9F%e#&tUpS?tX&v-&Pn&xY7l6O5wR!l`94cc@3!Gs&x41#aAlp zpWM-2iSlz}gZTJQS>>4HMX}_m_p0$=a{Ei0vMgUvx#y*Am60APx%#z1kH$_9Cz+ZB z994pwytu}Q4m)*v9m|SK+h@3p`#hH=35}{u@4(b?U98hHdj7y2N07tuxFybL5;=&F zolB4l3tY!TJ_VI1vuxnA4Fz&oQi+1MMcx%a7n>MMSVM9X{xBTawHr|w3f380k&&zP zEwExohk+bTLUKARgj^SW=dpkXDheS-laP6w2%#yCxEI=NXh*Hniz9?}NTLbfw}W|3 zo@;oz;F8gCx(iOk@s*dZyo^T__PLv}@K_3N5Wn)um9HWB_^bo|2I}IKWk5Zb+ie8r zbtBKf{PdN74w%CR#s&(Q%-_87+me|-=Vvni+m+u#=8+tBC{&aCzpozOf$Rf*WWHuy z{q&BjUu53l2?m<%*LGZ8VfJ&yk;Vop+Hv(y@BD@F5SO6O2E-ls@rF;=Boi;&*u7Bm z)=BxDUw-M2FGm04i_tmz!pQyq`eO7qBiw1ujh9U?Mz?X)F*mqyb~@~~`a|BRKO?Z5 zLBSF;{IM=H*Qn!Jcav}RI&yRQI5w7W3A$3{Jtbl<J*Np&uO__W++I&^->$GP9hI#r zF-Ebwo;-gLLe56Gw?|}-urbmX^z9@(dBC@<z{bA0NPaq?dpb@(e_SF7?=Ui-;U0L7 zNpGjO^dT*qjTwh%k3GC^>k+E9a$o(XM-e1^{WMpu-fYMt1GuP$JE(GPet!_n8*aip zb!|71@k{WW>gq@qz;vYIC-%Mc$Oe!w3D0Cih~KZl<BIG2%@ys;$nasYz}*EQggFw< zzzfcSOG0CWT`qdwM9Ay;2fc049`Bf{3^olhN{~Cwx57aqryBw}p61RUoVw4A00-z+ z%fcUp1#9F91qW1aRia7|-U~-A${tJ`4r<ZK4DZMmPI`Di0%uxS{63z9!q!6>Z#W>{ zZ`A`|hn326Gzmn6kT7AJ$vh)ju}kLpI+c^AnxeA_PNK>aGR{K;R+us!pzr(z<@5gO z4>gcb@ybYghPEL8k+5@AEa%?;mNy_L-W{6p!rc4rXoqd~^s$F?@^sJyc7L2_Ps+W| z_DEJBDnJgL@PG-4#D7P4CTx1)wH?_Soy?#eyuh^r^H$VNg^zuV^mH|wylnZI?c*=s zxy?(2%z=8YlkU*&p9a)e!;=-jnuubS!b!i6QKuNgTdq@>AdkMe_T7&Ly*O)M+zk8C zVtIlv_#qH3ElqU9@)~MfOU?Hk7L`?Utn>@7N+r7T9Py&X?@m?szdKb)<4)jYnuIvu zc^o`rBO)d%p16XyZU#XV;;@t?fI%3-1MDi9ajepZB?_KY!Tv4;Q%{ziknxUJLUg#V zpB~|X96oMAlzf1wgNwls-oc13O0;126(>|$&&l}-=b4zlhxar+IF)${3@{XnsdwxM z%gGYGYo%gH1e10r*7ZoKvIIJPdH@LgvSQ2vZ>NKyJS6l9x}l4qvN~wtf&rWd<`*Yf zYf;=}LMF!?t9Ag(8yXG?bNFv2c`Ex}G`GSBSc1<kW45-YYOx+Xi^DtA#H5cwq8xCr zXzk}FBo>z0ghaXX5sGxN)M|UjiZU<UNSChYj6C~IZ^2bDlWpQU$nory>)Q>A<$WG( z`>EM=$Q|0Qj*RT}k3%+m4i2T(Z$)xLvZss9WR2{?xjKBZp;DJ!1}mS5gC~4sf;hJU zj7&jrwou1!9j!QaHbE;eIkfZ|8NR!!WRCcLZjh0G*C3gRzMmUp)vxi6<tA3SVnnr8 zj0cVfQCZB1lMtU=s`RS4h#F5h=5U0AS`v0&Eep(P2m~ZL?}{rn@w6&Dbi)Ft1L5=O zV4%NDCBP%MeA$)Xj8_Zoka@i8K+LKVqn)c%*96m+wztA_t0*iz>^eR8L0BHbAmNc} zSQ`51UY+iDT<U_*u#vK=rREPHF0bKm{WtKw7|wIoaaucDOTB+%^pnY(gRtLpXYc!? z4-&i#)^E!DbbOKxkAn?xUf!`1Z_IgSPXI|p#SK}2dZ@8m9YZ(r_1r|(H_n7|>zawj zlCx!to}cGy=?*h&I@Xk1mYQ|(tTiyYocj*6>57-8`br`5;RiNKrV}-IQk~CE*!8Zg zQ+U{4cx)w5qroJSSx56Lc=QiZenht}Yjvzk-D+OA6yAkXEnLBY{$L4EJ%GZZMRYGs zPqdXqy>*tMsEo(Ou>Fq12^fgD9TM!O`vBd|z2P79_2~_=@G5*kQ>##SH$leb{Ic^z zaI4vB;Ls=ex{0jVGyEzk{a%cx5V51GhCjt)o`NAga>B}myju$77>D-tOEUl&!s*;u ztUbnU3bvSvlZnbrdIqN*x`d`s=>mpQhZ-Qso=ziGxJL@r!^KE=3~x9)hVF(2gED68 zl_kO=YIBC6TLq3pNy=PzQcx1jQ~>C#XazT-d%x6Sff>U@iY*4O!XV{^X)yE4xTHa6 zAzhPWJ?o|5g}#&chnY>6w5W0>5+Nst#H36j5tEE-Y?{lCESUrqxmtSN=w4MY5KJ0O zL(i@j=#fxI&7#*-KK$pc#?eO7?keOV*@Xo(AMZ^G#;hipP`6PNUlrV_COp$tP?Ona zn=!Y$7M~9I)y(l!9;Zcx=wCa%&v-gmWpdW!uI$50v~=kdUQ3;W5GGmg(0RO4PX)N) zJWiPxZ>gtnzb|~gj%dVk2YBw3cfH`26117G0-K9?csC5DH(aqw{;5haQ@hhBPzCh4 zg~B^CC1Yy76Y&n61TTdqNYq(8#v`*?nw!UALrLMSO#0bmk2i5Srrac}_t+Rpp_o=$ ztC+)j!&PaRRbvc}rfO0LybL9&TleSH<%`1c2<P%K|J8txFBwajO}x$Y3F}2LoYe*E zl+)SzJ+EC~x_AzgEviCj9xGB`H=a+1Bc&FqdZqt7*DUl9tSYoj4=|x)M9r!iks3vz zJ00#_!P9S!;uh|m#_=b_jft0^WrYK7lDGTex+=s~wn?jo9istdLLK@R!XDvMp1=aZ zWJ7$#2F(V>0LM*G&W*y8%0<b^gcHc^D9=qg=4s@W%-u`9NkPWT&8A|exWeC$Uhy1% z;P$p7k|*(DjasL-u*}&XuEpLQEkfcmNQa))dD+~8x#9os`Pkai`g)KmK)XYr9&|U) z+PP7@;X21^>1rWA^OylrWbNdEr25RkFonG`sx+{(3*~`3ln@vg<0dk%^2&OaEfPSl zjLcXAyeQr&pRC~62E6*^f?6vw?`x~fd|m*h5j008MaG8Dym;kXh$MN@X6F%D4vgD> zo-s8)bLDR_>ZEwSH!y$a%D<JElX5y;W&19|O*XGfpk~&>++jXs#SSMElY)?y<Ngkq zZ{&>2@BB8JazZscub-j5q(0?*bpg+s-x$4(cg;;8gO@<K#sH79$CwJRYls<zVZNMn z2N5PQOci*+9_SLTycRHZ;z}EyWI+PYJIc-ko?Pb+1hy(vX}@{x?chyW@pgh6!xg;k zjz_tnxnaX&bG6Tuxaroy!6nvz%hZqE4d9hQz^B|z2sXAr<kaOCY!wEdyhv2WTmYi6 zPVIA6<HG?XOgkV68yr&3yeXgYfz8fZhex+{W^3a59!x91hvwO}4CY2$@uzF#Z(d&d z`t`S$g7eqj1##azfAi+~YfJBbS?-79EXRj#WnSV9g_sWluoN+>2@btAf~yyAUidoT z&wuUmTbGyKWia`r%S+cT-ntcBx_&b_4~#d?-(0$U;qAB1-wbZNee=fkTNf)qa0~3= zT(<#Rx!bbF+wcB3U}esiZqJJV*`E^w2m(CB05MY;qY$!aO?H!C#&|oLFv?b&>|pkT zSHYa~32{a<K_nSE1c}_R>voyovTNw17THEFmmCZ(3R=cH-ni#z#6S1>XTU%3cp%Jr zj+F?oMumu^>aB-XS@@<38a%mOzdmjHKpSe5i9}JeeGCk+5!S|_8EvK9Xu90}t(3bz zU2d>ZIkwnYAW%^u<2}%Ex+f~lac&G}Lpwu+Eu4(pFs%faw_0z=@$I=9pmSCsR4Y+( zFM<jnDYiyou(&Y-M~%qQBo(?E&>oO?#uJr00oI}w5dlPxBK&doY><qH!<EYa0~%M{ AE&u=k literal 0 HcmV?d00001 diff --git a/docs_src/_build/doctrees/index.doctree b/docs_src/_build/doctrees/index.doctree new file mode 100644 index 0000000000000000000000000000000000000000..40c0debfc498eee782bf01c6988c1be8aa48990d GIT binary patch literal 6796 zcmeHLZEqY`6?Pi0-|aXqu1ZMCC2bNXitRY1D6$F&LL*XFORA<-D-liZ&fMKQ>)Dy< z+&lK}he|0DQ7v5w5Q79C5I+F;1qg)r0f=9KP(Sk<3eUOox|=jOL`Vo>X}vpV?mhRs zKIfkEVEShtpP90MX2px#RQrM23L{Ub%*+vCAVQt}G`sw9_EENB<`aIXqBL<uW~Q*h zm44tQBFye(8*<9by3t^4gKU|<xLpy%Bg>hU9J%(RkPW!fB4J%W5LcO-2(E?4I->;@ zOFtZLewh01zS2C=42$okg1wmrZ08!=xxTw|ZTH%1?E1Bx8(Rw>L@9H5$hgO2&9wBD zWyv5+90)Cf5z`SHL2MTI`+nHF$~viLzGg~BY2Y!gSs)<Gf*XaJ`yqG;mPC<e_jTmz zM2P#$^Aq7}|3GYIa`s*ZWvB0oA(`fXP{SW)*4?rtXUt5@;b5J~#k9lC0@ph6VLk*1 z1;k0;Q*b^!A8@5W#P3$f2l=l#FOBPm4tMtx(Y0&lhl5~O#he0ZE>46J$$`jHGpl)z zc4Ts1uFI41ggj|x%82{gwu}a1`(VHmpNIbTJ5g63Lb~lnh;1Xpl%o=N+Ydc4+)9+r z%yi&~BHL@F9STxKj*P-8s!2`qDMfHg`#KPfS7!0%tvBAfGkTXYBX|AkIIT9;4n*E2 zk>!Q9ywrxh<O?v8d=c?-2A{L|yo3+Cm!<L*xryah^5ycPytFrK#hatBjndF-2$9QY zPUVTQ#XYY`(b*zCA6fgk2g`NSvX+6*;MT;qo@$%Lh7Gfa88=IQ=mx1LC_Bkz@@;PB z27Ks=Sj+6qf8Y;ZN5+vU+h)2KM4jx&%t+t!00^I$<$^&$I5Kl#I_QW*c-h{RS+Isy zQ5cM}BeKR#dBIwN{Qk{J)0tC+qML^ak7JQ!eA1d<AGao~FE8h)Rr`0VB$%b!&^_|f zJQ8e1uTBtaze=#~KAm6PhF@2$U+0lWya(xJ!&&eD_{7vyBfuE2i!;JXUyp!RorEVN zc9{5Di;w}C?u@hq81m3#o;VOe6azAWUxZjU;ZMNntq31r*1{VB0zJX%w>Z*^z2o{K zbOqa>^DYy!@A5$>O?q4Gwgy;Q=u=FAZNdZAO+#xO2!z9m^j^>shr#~cC>gK=<YAO5 zrn%ZzED?bPa9}M-6DN@?lmgtcsLO_%2_G?kz<WgSxaMrbO%p<vV03k15Gj0v1^4JZ zod`DvBYNlwB)x_i{E$w~O9u|gS$Y6?S3_mudD*H08>XtLB!x0QStf*5#2JDD?XiFi z!BhbvByb<BQ~~g-|M$&*qi^c093m?Zj-Qpfz?U^_v)P$;M1_)sb`3n>C0sv3Z@~A) zIN<D2nm-wFaF+>?BLtW=;xvf0Za)F<A01yeswAd?IA<VAT4CM$cL^NoDpuhNfz1K; z1KtS)U9s+r?%d9^9k;2DK*Cw!kSVFnW1H4~jBC<hfJE9YwfN5+P+R0zQ1O??w@B&j zv!!J$1}_6v3EZ4c5V`ve95&};3#_lQ%>j%3xKy1rt774^<1DS^o`C?roh)a~+9l7+ zm(5(j!(PgJxD8ErxRNN&bY%%6g_61={hkc)(GE{~bnl{i`RgK{zueHU_WA1flB*1G z$#T7}SH61mMJ?-}!0L}rZ{wF668xr$y07FXAH$%>SXs+R_Wbj|vZwrAVMh7;Bl(AM zdtGQqTiYu|38ZugRMf}`PQ{OXE99t-9%s0&?!!k^Iw=({5m5_1xWrt^!%zfyCAG=3 z@VMl;WcgtEL;`*EZ=C+=gP)h@fBN7T$CUuPtPFNbDMfAFzri?vefkKv(y(bA0T*(s z6^3A&E-)rH*yGabn5%19DH8tvERj&5=42&kK=N267^6R-5)k}8p%Sd!M1Re`Q#99O z_26-@DvkT|xGc)`{w#exO_$N1u6Ecf_N!y%;XNzPcxO(?K_ULQszI$bibI!r6t;_f zyZ0q-_3ZTqR(|7tev8_WtLF7*;h$C7KO-O5ZN0KW-kr&Bo26KUbmMe}XiS^+;ESKD zSlRy1_@V78%h`x*_0Q7*G#pqp(`1rbcr<Y9{fl@#8Lt~=+8%9AD(wOF@qZI0%|x?A z0Pg#*5byOqdkl}}QZoxh^e9FlIZ1plu@PM_8epoC^>?t@EP^10ap1eYMwdqKF=FWn zw8>*Vpqa5d-AuMEQ#9J>>PVEANR+%;d#x}l0&3Nq*s2w#hsT(_zHyZ|tY$-87H#5M zhU{2wuDQq@vX320<(X4wsC_#=VnUnvggiwa)B=rbUvnKZ$|LOTgrYD8`uCdMq<+;D zLtdoneZs61?T=GTH`->Yq}aG>n>i)4MsQ*jcbaszv$-xBI`o2wm6`W=kfJrO0&uf! z=6fQ<1qb~QTJm`UTVU28#=~NMj04{Lcw8tR(<H#tGP-Mr#xwL5$F*oOFv`qY7elZx z(xUNl?}S;V2@0BdXGjfM2Fi-UBq4UFu3@VJ%P-{=v|5(p9Qs;1<&X#`78{DG5tL6v z93|QbsH@HPo-+%Q2i0TCoEAf0JJ3d_s$A4EEl+gP9*$d~@T5crUsPmJ=5>PU5-Ei! zU-82@)eidKh|(Qtk?QW|jZNj__u286j!2RyaZu5{0D}fN4!XHWk5f^q$GNmDm&}}- zcr(GG{{u?Am7H%aL+jnUw>EF!{P7nPo6RcepkOEo69sl+wp?BpVQ~+s{u~A_=6MV# zqr`JCph0}#7#i)g%?zq=7iz*HzUN@n*7b)O=6WkU)sa(^%yT}1YS~K%u~P*e3~LEx z|4a-|SqiKhDsq2Kij_#c$iZX}t5$(AkrGaGr;QR<I|sh<^AJ7dc)p_c1Bw(<&Xx%w zFPbGNqmTl5rXy;KWllMiGApr&9YQor5-@JS!GQD_;fkXvwhfb7$7*+b`|$8^E5DL% zMM-ZP)01tiRNI+ZryazRb~svKYK+98xul3UFI@X7%(9Yn-HBs}QXg}+JVr+mCg{G< zU3-kwg8)a&Yu-T$c$l2+&6#rusDV@ERwcfZ4@8g53sxFjoJ2z1BI1^8<ROq3F@Ucg zk$9_Wgt^VosagaYc19H8OA2FB?R=ObeHC^-Z=dr=2kj5f$9m=*?ykrb^hJ4E!DEC! z4tDRSF|{AS9y_cn()|cQ61g;tsq=r05J9D#@pY>L^F9wLIl@^|pu`-RbvKCkz9UeP z0tbUkjDBfs{E0a!!h;M`J2RIf0a6c9gi)m(ygPY~va{pUI0#Xp0f?{-CY00?nYA%$ zK6M5e+`82Rl{6YygFZ{d{P#xx`^eA!2UOOM<iq|6`te!+E)n0xztqgrVydck=xvv` z<x$(NY}<wHRKAE&Z_eb3e25XlXVTd1wv?r2x#@2!!ZIqbjckgnoI*KSuFG|8Qu1|} zu*2(vP83ujWS4$nf>^DdALBS*o@zI(jqwM(CYtbkeUex4X3ER~F{))Nm}w%>Fzr|9 ci*kk)FpQBGE3)<Lf=5_Yq&3}T)6UjE0mJXv<^TWy literal 0 HcmV?d00001 diff --git a/docs_src/_build/doctrees/modules.doctree b/docs_src/_build/doctrees/modules.doctree new file mode 100644 index 0000000000000000000000000000000000000000..4199b5bab20782ad04d80ffa107ac54a88f857bf GIT binary patch literal 2565 zcmZ8jOK%%D5O!?qWm~f2G(99S(xM2OxUkg%Jp{e<){6mMlI9i=)RGbj?~+?SED30U z_Rt~*cq{v7d+NvC)moB(g_gtNJihs6xPKh}``=)%`h^kGnRha`*Ge;PW9TPA!Ig{u z#5aG&Pw{ma7`m|9n~cY>2aQa~oEfg-$0+tf&+^Pkty+E25na*y7++(v<D|>^##T7a zW;`!fmCu;epmq43FO$FR&A(#h9_G$Nx1@0BqBs+e#6jpb;Y`9|E)|axKc(S_I%nk6 zJEW1qK9I~J#L&xfYAu9#?<iW-Z++&=hsBg;w}#J>jt@OY=V>d7k$5JKlSlD9yd4W& z@bO(ijigGB-|3lKAgb|3LSukui8a}{(9GxDUK@*`U)=2bDe~-Rx+t|*Yy*%Qt8i*d zA=UDlGS(EL=XB-_-vqDL6&J`(yaaMz<M{^9D?H!gc@}z&Ut|rqjI45<Y~%WOq~S!W zEccAhB!WzJ{F#P+L6?k|PQ;r-fJV!zs(^T&>uJ0XT_G7m)$hZwIo%5S$`?~^IEy!X z;i#&))hb`bdoSLIAH;KU2@no}<`pWnl|VRc^1NCYT9({Ix|vft|J_3sk{uMAw<fkz zqiaZZ#SKEq+5pxL>Y7$jp)}hOZMtunCN9(2M`4tClbA?a2A-@XH4{VMa_6L)qn94H z%{4PxIgY}I?gyHCV7~4yF`9(IoGWgq(<WlUC>ZQ$QDSjiyCJZBi{(+X^d`q@2;@j& zZrX*rPAd5-hVz-$PHD$CHg6t<VQN$qiY#Z^6cLh<1w~2%R;GrxF!{We@SIl?vXD-Y zb^pL)bD(LcNjNdQ)W(sV-|;-&?1v*k^LE(@kNHvpD@UETYo$);Fh2EjxErB?6tIGZ z;k1Bc;0(=pN-BO1BdJR72v?bA(28N;-R$b^m6dpZvAs#SG1?G870W>)6b`v%E{0R> z-L{oZWhI7-ot+&M;`cDBjXng>`StxTS8w5bdt>KhI7<mwpd^4#j)Y<u=2Xo+opZp= zu--=}g(rq*+AxB)13BO(HS8pGGp%OG5pYOGN(?5sjG`Mx)H_WcL}6coQA6g7lC-P? zs+B;3a7NKQ89c2dfL7U5`v*~Jxo4Uzi^QihzAUxnWb<T2k<5`hX=TmNQ^KUB(>x{8 zMA=(+gSZSQNXCNyw3!~mMvbgTO&FEDB*+Q#LS<FHCrL7;aGi)9z7o!r_NVc9u~=M} zD<`zN)@D9t{B8_QJC5OLI*}}<6U6ZXC_A9qhy3c*_df!bk(p&XZj$7|&5N}gr#0?B z$=$4SBV3Wg#lX=i_|MWj?1u}msUU4*wc!(6rt;p0FRN&zvfQN1LE3~71B;JweYQ(< z-I-k}N0&s%xybQ=qldXp^ggk;Tpan$qjxP%KB?CAlH@w0^{@^XnV@JB)VJ;_R4ff2 zg44IYL@?=AucmO*>loRPNHs&L*Uf*P#)0+IZM`#&LC(;REBF$eJ6L;~<(l3SUQn46 zTu_Er*XieQz|~#4dqck-1L!-jNGc}5YeyV4bB?isd-pLMffWwdKCr>PldkA+z9p@1 zV~AmG)-Jk<{kX^>?<HaVE<T8NHVl%$txACPDT)shD_-LNojA5(xLK;|^e~ecL&-fX z){@jtYrQ(mO-ZeX;8Cz*s`Iw`mFgEe!d82*WpS|fS{*vyvX8N7T$;mAcWpI0_+mh_ nw`wDN1ffUp0b?;oYJ+W0Z;6jvaaEEdmc~rek?HF5)9e2MU>^I` literal 0 HcmV?d00001 diff --git a/docs_src/_build/html/.buildinfo b/docs_src/_build/html/.buildinfo new file mode 100644 index 0000000..07914e1 --- /dev/null +++ b/docs_src/_build/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: fd8cf3500139e539a950fcaee26c3d53 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs_src/_build/html/_modules/cfelpyutils/crystfel_utils.html b/docs_src/_build/html/_modules/cfelpyutils/crystfel_utils.html new file mode 100644 index 0000000..8d1f451 --- /dev/null +++ b/docs_src/_build/html/_modules/cfelpyutils/crystfel_utils.html @@ -0,0 +1,754 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>cfelpyutils.crystfel_utils — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script> + <script type="text/javascript" src="../../_static/jquery.js"></script> + <script type="text/javascript" src="../../_static/underscore.js"></script> + <script type="text/javascript" src="../../_static/doctools.js"></script> + <script type="text/javascript" src="../../_static/language_data.js"></script> + <link rel="index" title="Index" href="../../genindex.html" /> + <link rel="search" title="Search" href="../../search.html" /> + + <link rel="stylesheet" href="../../_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <h1>Source code for cfelpyutils.crystfel_utils</h1><div class="highlight"><pre> +<span></span><span class="c1"># This file is part of CFELPyUtils.</span> +<span class="c1">#</span> +<span class="c1"># CFELPyUtils is free software: you can redistribute it and/or modify it under the</span> +<span class="c1"># terms of the GNU General Public License as published by the Free Software Foundation,</span> +<span class="c1"># either version 3 of the License, or (at your option) any later version.</span> +<span class="c1">#</span> +<span class="c1"># CFELPyUtils is distributed in the hope that it will be useful, but WITHOUT ANY</span> +<span class="c1"># WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A</span> +<span class="c1"># PARTICULAR PURPOSE. See the GNU General Public License for more details.</span> +<span class="c1">#</span> +<span class="c1"># You should have received a copy of the GNU General Public License along with OnDA. If</span> +<span class="c1"># not, see <http://www.gnu.org/licenses/>.</span> +<span class="c1">#</span> +<span class="c1"># Copyright 2014-2019 Deutsches Elektronen-Synchrotron DESY,</span> +<span class="c1"># a research centre of the Helmholtz Association.</span> +<span class="sd">"""</span> +<span class="sd">CrystFEL utilities.</span> + +<span class="sd">This module contains Python reimplementations of some functions from the `CrystFEL</span> +<span class="sd"><http://www.desy.de/~twhite/crystfel>`_ software package.</span> +<span class="sd">"""</span> +<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span><span class="p">,</span> <span class="n">division</span><span class="p">,</span> <span class="n">print_function</span> + +<span class="kn">import</span> <span class="nn">collections</span> +<span class="kn">import</span> <span class="nn">copy</span> +<span class="kn">import</span> <span class="nn">math</span> +<span class="kn">import</span> <span class="nn">re</span> +<span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">Union</span><span class="p">,</span> <span class="n">Tuple</span> <span class="c1"># pylint: disable=unused-import</span> + +<span class="kn">from</span> <span class="nn">future.utils</span> <span class="k">import</span> <span class="n">viewitems</span> + + +<span class="k">def</span> <span class="nf">_assplode_algebraic</span><span class="p">(</span><span class="n">value</span><span class="p">):</span> + <span class="c1"># type: (str) -> List[str]</span> + <span class="c1"># Reimplementation of assplode_algegraic from libcrystfel/src/detector.c.</span> + <span class="n">items</span> <span class="o">=</span> <span class="p">[</span><span class="n">item</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"([+-])"</span><span class="p">,</span> <span class="n">string</span><span class="o">=</span><span class="n">value</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span> <span class="k">if</span> <span class="n">item</span> <span class="o">!=</span> <span class="s2">""</span><span class="p">]</span> + <span class="k">if</span> <span class="n">items</span> <span class="ow">and</span> <span class="n">items</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">"+"</span><span class="p">,</span> <span class="s2">"-"</span><span class="p">):</span> + <span class="n">items</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s2">"+"</span><span class="p">)</span> + <span class="k">return</span> <span class="p">[</span><span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">items</span><span class="p">[</span><span class="n">x</span><span class="p">],</span> <span class="n">items</span><span class="p">[</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]))</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">items</span><span class="p">),</span> <span class="mi">2</span><span class="p">)]</span> + + +<span class="k">def</span> <span class="nf">_dir_conv</span><span class="p">(</span><span class="n">direction_x</span><span class="p">,</span> <span class="n">direction_y</span><span class="p">,</span> <span class="n">direction_z</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> + <span class="c1"># type: (float, float, float, str) -> List[float]</span> + <span class="c1"># Reimplementation of dir_conv from libcrystfel/src/detector.c.</span> + <span class="n">direction</span> <span class="o">=</span> <span class="p">[</span><span class="n">direction_x</span><span class="p">,</span> <span class="n">direction_y</span><span class="p">,</span> <span class="n">direction_z</span><span class="p">]</span> + <span class="n">items</span> <span class="o">=</span> <span class="n">_assplode_algebraic</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">if</span> <span class="ow">not</span> <span class="n">items</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid direction: </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> + <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">items</span><span class="p">:</span> + <span class="n">axis</span> <span class="o">=</span> <span class="n">item</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> + <span class="k">if</span> <span class="n">axis</span> <span class="o">!=</span> <span class="s2">"x"</span> <span class="ow">and</span> <span class="n">axis</span> <span class="o">!=</span> <span class="s2">"y"</span> <span class="ow">and</span> <span class="n">axis</span> <span class="o">!=</span> <span class="s2">"z"</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid Symbol: </span><span class="si">{}</span><span class="s2"> (must be x, y or z)."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">axis</span><span class="p">))</span> + <span class="k">if</span> <span class="n">item</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"+"</span><span class="p">:</span> + <span class="n">value</span> <span class="o">=</span> <span class="s2">"1.0"</span> + <span class="k">elif</span> <span class="n">item</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"-"</span><span class="p">:</span> + <span class="n">value</span> <span class="o">=</span> <span class="s2">"-1.0"</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">value</span> <span class="o">=</span> <span class="n">item</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> + <span class="k">if</span> <span class="n">axis</span> <span class="o">==</span> <span class="s2">"x"</span><span class="p">:</span> + <span class="n">direction</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">axis</span> <span class="o">==</span> <span class="s2">"y"</span><span class="p">:</span> + <span class="n">direction</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">axis</span> <span class="o">==</span> <span class="s2">"z"</span><span class="p">:</span> + <span class="n">direction</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + + <span class="k">return</span> <span class="n">direction</span> + + +<span class="k">def</span> <span class="nf">_set_dim_structure_entry</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">panel</span><span class="p">):</span> + <span class="c1"># type: (str, str, Dict[str, Any]) -> None</span> + <span class="c1"># Reimplementation of set_dim_structure_entry from libcrystfel/src/events.c.</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">dim</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">dim</span> <span class="o">=</span> <span class="p">[]</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">dim_index</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">key</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span> + <span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"'dim' must be followed by a number, e.g. 'dim0')"</span><span class="p">)</span> + <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid dimension number </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">[</span><span class="mi">3</span><span class="p">]))</span> + <span class="k">if</span> <span class="n">dim_index</span> <span class="o">></span> <span class="nb">len</span><span class="p">(</span><span class="n">dim</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span> + <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">dim</span><span class="p">),</span> <span class="n">dim_index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span> + <span class="n">dim</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span> + <span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"ss"</span> <span class="ow">or</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"fs"</span> <span class="ow">or</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"%"</span><span class="p">:</span> + <span class="n">dim</span><span class="p">[</span><span class="n">dim_index</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">value</span><span class="o">.</span><span class="n">isdigit</span><span class="p">():</span> + <span class="n">dim</span><span class="p">[</span><span class="n">dim_index</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">else</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid dim entry: </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span> <span class="o">=</span> <span class="n">dim</span> + + +<span class="k">def</span> <span class="nf">_parse_field_for_panel</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">panel</span><span class="p">):</span> + <span class="c1"># type: (str, str, Dict[str, Any]) -> None</span> + <span class="c1"># Reimplementation of parse_field_for_panel from libcrystfel/src/detector.c.</span> + <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"min_fs"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_min_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"min_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_fs"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_max_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"max_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"min_ss"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_min_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"min_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_ss"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_max_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"max_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"corner_x"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"cnx"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"corner_y"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"cny"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"rail_direction"</span><span class="p">:</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_x"</span><span class="p">],</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_y"</span><span class="p">],</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_z"</span><span class="p">]</span> <span class="o">=</span> <span class="n">_dir_conv</span><span class="p">(</span> + <span class="n">direction_x</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"rail_x"</span><span class="p">],</span> + <span class="n">direction_y</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"rail_y"</span><span class="p">],</span> + <span class="n">direction_z</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"rail_z"</span><span class="p">],</span> + <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> + <span class="p">)</span> + <span class="k">except</span> <span class="ne">RuntimeError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid rail direction. "</span><span class="p">,</span> <span class="n">exc</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"clen_for_centering"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_for_centering"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"adu_per_eV"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"adu_per_eV"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"adu_per_photon"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"adu_per_photon"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"rigid_group"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"rigid_group"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"clen"</span><span class="p">:</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"clen"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_from"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> + <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"clen"</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_from"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"data"</span><span class="p">:</span> + <span class="k">if</span> <span class="ow">not</span> <span class="n">value</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"/"</span><span class="p">):</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid data location: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"data"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"mask"</span><span class="p">:</span> + <span class="k">if</span> <span class="ow">not</span> <span class="n">value</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"/"</span><span class="p">):</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid data location: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"mask"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"mask_file"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"mask_file"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"saturation_map"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"saturation_map"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"saturation_map_file"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"saturation_map_file"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"coffset"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"coffset"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"res"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"res"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_adu"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"max_adu"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"badrow_direction"</span><span class="p">:</span> + <span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"x"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"badrow"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"f"</span> + <span class="k">elif</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"y"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"badrow"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"s"</span> + <span class="k">elif</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"f"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"badrow"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"f"</span> + <span class="k">elif</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"s"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"badrow"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"s"</span> + <span class="k">elif</span> <span class="n">value</span> <span class="o">==</span> <span class="s2">"-"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"badrow"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"-"</span> + <span class="k">else</span><span class="p">:</span> + <span class="nb">print</span><span class="p">(</span><span class="s2">"badrow_direction must be x, t, f, s, or '-'"</span><span class="p">)</span> + <span class="nb">print</span><span class="p">(</span><span class="s2">"Assuming '-'."</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"badrow"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"-"</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"no_index"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"no_index"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"fs"</span><span class="p">:</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"fsx"</span><span class="p">],</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsy"</span><span class="p">],</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsz"</span><span class="p">]</span> <span class="o">=</span> <span class="n">_dir_conv</span><span class="p">(</span> + <span class="n">direction_x</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"fsx"</span><span class="p">],</span> + <span class="n">direction_y</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"fsy"</span><span class="p">],</span> + <span class="n">direction_z</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"fsz"</span><span class="p">],</span> + <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> + <span class="p">)</span> + <span class="k">except</span> <span class="ne">RuntimeError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid fast scan direction."</span><span class="p">,</span> <span class="n">exc</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"ss"</span><span class="p">:</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"ssx"</span><span class="p">],</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssy"</span><span class="p">],</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssz"</span><span class="p">]</span> <span class="o">=</span> <span class="n">_dir_conv</span><span class="p">(</span> + <span class="n">direction_x</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"ssx"</span><span class="p">],</span> + <span class="n">direction_y</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"ssy"</span><span class="p">],</span> + <span class="n">direction_z</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"ssz"</span><span class="p">],</span> + <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> + <span class="p">)</span> + <span class="k">except</span> <span class="ne">RuntimeError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Invalid slow scan direction."</span><span class="p">,</span> <span class="n">exc</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"dim"</span><span class="p">):</span> + <span class="n">_set_dim_structure_entry</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> <span class="n">panel</span><span class="o">=</span><span class="n">panel</span><span class="p">)</span> + <span class="k">else</span><span class="p">:</span> + <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Unrecognised field: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">))</span> + + +<span class="k">def</span> <span class="nf">_parse_toplevel</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">detector</span><span class="p">,</span> <span class="n">beam</span><span class="p">,</span> <span class="n">panel</span><span class="p">):</span> + <span class="c1"># type: (str, str, Dict[str, Any], Dict[str, Any], Dict[str, Any]) -> None</span> + <span class="c1"># Reimplementation of parse_toplevel from libcrystfel/src/detector.c.</span> + <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"mask_bad"</span><span class="p">:</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"mask_bad"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"mask_bad"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="mi">16</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"mask_good"</span><span class="p">:</span> + <span class="k">try</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"mask_good"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"mask_good"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="mi">16</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"coffset"</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"coffset"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"photon_energy"</span><span class="p">:</span> + <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"/"</span><span class="p">):</span> + <span class="n">beam</span><span class="p">[</span><span class="s2">"photon_energy"</span><span class="p">]</span> <span class="o">=</span> <span class="mf">0.0</span> + <span class="n">beam</span><span class="p">[</span><span class="s2">"photon_energy_from"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">beam</span><span class="p">[</span><span class="s2">"photon_energy"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">beam</span><span class="p">[</span><span class="s2">"photon_energy_from"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"photon_energy_scale"</span><span class="p">:</span> + <span class="n">beam</span><span class="p">[</span><span class="s2">"photon_energy_scale"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"peak_info_location"</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"peak_info_location"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">elif</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"rigid_group"</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"rigid_group_collection"</span><span class="p">):</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_groups"</span><span class="p">][</span><span class="n">key</span><span class="p">[</span><span class="mi">12</span><span class="p">:]]</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">","</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"rigid_group_collection"</span><span class="p">):</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_group_collections"</span><span class="p">][</span><span class="n">key</span><span class="p">[</span><span class="mi">23</span><span class="p">:]]</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">","</span><span class="p">)</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">_parse_field_for_panel</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> <span class="n">panel</span><span class="o">=</span><span class="n">panel</span><span class="p">)</span> + + +<span class="k">def</span> <span class="nf">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="p">,</span> <span class="n">is_fsss</span><span class="p">):</span> + <span class="c1"># type: (Dict[str, Any], int) -> None</span> + <span class="c1"># Reimplementation of check_bad_fsss from libcrystfel/src/detector.c.</span> + <span class="k">if</span> <span class="n">bad_region</span><span class="p">[</span><span class="s2">"is_fsss"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">99</span><span class="p">:</span> + <span class="n">bad_region</span><span class="p">[</span><span class="s2">"is_fsss"</span><span class="p">]</span> <span class="o">=</span> <span class="n">is_fsss</span> + <span class="k">return</span> + + <span class="k">if</span> <span class="n">is_fsss</span> <span class="o">!=</span> <span class="n">bad_region</span><span class="p">[</span><span class="s2">"is_fsss"</span><span class="p">]:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"You can't mix x/y and fs/ss in a bad region"</span><span class="p">)</span> + + <span class="k">return</span> + + +<span class="k">def</span> <span class="nf">_parse_field_bad</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">bad</span><span class="p">):</span> + <span class="c1"># type: (str, str, Dict[str, Any]) -> None</span> + <span class="c1"># Reimplementation of parse_field_bad from libcrystfel/src/detector.c.</span> + <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"min_x"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"min_x"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_x"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"max_x"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"min_y"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"min_y"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_y"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"max_y"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"min_fs"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"min_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_fs"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"max_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"min_ss"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"min_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"max_ss"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"max_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> + <span class="n">_check_bad_fsss</span><span class="p">(</span><span class="n">bad_region</span><span class="o">=</span><span class="n">bad</span><span class="p">,</span> <span class="n">is_fsss</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> + <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s2">"panel"</span><span class="p">:</span> + <span class="n">bad</span><span class="p">[</span><span class="s2">"panel"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> + <span class="k">else</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Unrecognised field: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">))</span> + + <span class="k">return</span> + + +<span class="k">def</span> <span class="nf">_check_point</span><span class="p">(</span> + <span class="n">name</span><span class="p">,</span> <span class="c1"># type: str</span> + <span class="n">panel</span><span class="p">,</span> <span class="c1"># type: Dict[str, Any]</span> + <span class="n">fs_</span><span class="p">,</span> <span class="c1"># type: int</span> + <span class="n">ss_</span><span class="p">,</span> <span class="c1"># type: int</span> + <span class="n">min_d</span><span class="p">,</span> <span class="c1"># type: float</span> + <span class="n">max_d</span><span class="p">,</span> <span class="c1"># type: float</span> + <span class="n">detector</span><span class="p">,</span> <span class="c1"># type: Dict[str, Any]</span> +<span class="p">):</span> + <span class="c1"># type: (...) -> Tuple[float, float]</span> + <span class="c1"># Reimplementation of check_point from libcrystfel/src/detector.c.</span> + <span class="n">xs_</span> <span class="o">=</span> <span class="n">fs_</span> <span class="o">*</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsx"</span><span class="p">]</span> <span class="o">+</span> <span class="n">ss_</span> <span class="o">*</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssx"</span><span class="p">]</span> + <span class="n">ys_</span> <span class="o">=</span> <span class="n">fs_</span> <span class="o">*</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsy"</span><span class="p">]</span> <span class="o">+</span> <span class="n">ss_</span> <span class="o">*</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssy"</span><span class="p">]</span> + <span class="n">rx_</span> <span class="o">=</span> <span class="p">(</span><span class="n">xs_</span> <span class="o">+</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"cnx"</span><span class="p">])</span> <span class="o">/</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"res"</span><span class="p">]</span> + <span class="n">ry_</span> <span class="o">=</span> <span class="p">(</span><span class="n">ys_</span> <span class="o">+</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"cny"</span><span class="p">])</span> <span class="o">/</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"res"</span><span class="p">]</span> + <span class="n">dist</span> <span class="o">=</span> <span class="n">math</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">rx_</span> <span class="o">*</span> <span class="n">rx_</span> <span class="o">+</span> <span class="n">ry_</span> <span class="o">*</span> <span class="n">ry_</span><span class="p">)</span> + <span class="k">if</span> <span class="n">dist</span> <span class="o">></span> <span class="n">max_d</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"furthest_out_panel"</span><span class="p">]</span> <span class="o">=</span> <span class="n">name</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"furthest_out_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="n">fs_</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"furthest_out_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="n">ss_</span> + <span class="n">max_d</span> <span class="o">=</span> <span class="n">dist</span> + <span class="k">elif</span> <span class="n">dist</span> <span class="o"><</span> <span class="n">min_d</span><span class="p">:</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"furthest_in_panel"</span><span class="p">]</span> <span class="o">=</span> <span class="n">name</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"furthest_in_fs"</span><span class="p">]</span> <span class="o">=</span> <span class="n">fs_</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"furthest_in_ss"</span><span class="p">]</span> <span class="o">=</span> <span class="n">ss_</span> + <span class="n">min_d</span> <span class="o">=</span> <span class="n">dist</span> + + <span class="k">return</span> <span class="n">min_d</span><span class="p">,</span> <span class="n">max_d</span> + + +<span class="k">def</span> <span class="nf">_find_min_max_d</span><span class="p">(</span><span class="n">detector</span><span class="p">):</span> + <span class="c1"># type: (Dict[str, Any]) -> None</span> + <span class="c1"># Reimplementation of find_min_max_d from libcrystfel/src/detector.c.</span> + <span class="n">min_d</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="s2">"inf"</span><span class="p">)</span> + <span class="n">max_d</span> <span class="o">=</span> <span class="mf">0.0</span> + <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">panel</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> + <span class="n">min_d</span><span class="p">,</span> <span class="n">max_d</span> <span class="o">=</span> <span class="n">_check_point</span><span class="p">(</span> + <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span> + <span class="n">panel</span><span class="o">=</span><span class="n">panel</span><span class="p">,</span> + <span class="n">fs_</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> + <span class="n">ss_</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> + <span class="n">min_d</span><span class="o">=</span><span class="n">min_d</span><span class="p">,</span> + <span class="n">max_d</span><span class="o">=</span><span class="n">max_d</span><span class="p">,</span> + <span class="n">detector</span><span class="o">=</span><span class="n">detector</span><span class="p">,</span> + <span class="p">)</span> + <span class="n">min_d</span><span class="p">,</span> <span class="n">max_d</span> <span class="o">=</span> <span class="n">_check_point</span><span class="p">(</span> + <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span> + <span class="n">panel</span><span class="o">=</span><span class="n">panel</span><span class="p">,</span> + <span class="n">fs_</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"w"</span><span class="p">],</span> + <span class="n">ss_</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> + <span class="n">min_d</span><span class="o">=</span><span class="n">min_d</span><span class="p">,</span> + <span class="n">max_d</span><span class="o">=</span><span class="n">max_d</span><span class="p">,</span> + <span class="n">detector</span><span class="o">=</span><span class="n">detector</span><span class="p">,</span> + <span class="p">)</span> + <span class="n">min_d</span><span class="p">,</span> <span class="n">max_d</span> <span class="o">=</span> <span class="n">_check_point</span><span class="p">(</span> + <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span> + <span class="n">panel</span><span class="o">=</span><span class="n">panel</span><span class="p">,</span> + <span class="n">fs_</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> + <span class="n">ss_</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"h"</span><span class="p">],</span> + <span class="n">min_d</span><span class="o">=</span><span class="n">min_d</span><span class="p">,</span> + <span class="n">max_d</span><span class="o">=</span><span class="n">max_d</span><span class="p">,</span> + <span class="n">detector</span><span class="o">=</span><span class="n">detector</span><span class="p">,</span> + <span class="p">)</span> + <span class="n">min_d</span><span class="p">,</span> <span class="n">max_d</span> <span class="o">=</span> <span class="n">_check_point</span><span class="p">(</span> + <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span> + <span class="n">panel</span><span class="o">=</span><span class="n">panel</span><span class="p">,</span> + <span class="n">fs_</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"w"</span><span class="p">],</span> + <span class="n">ss_</span><span class="o">=</span><span class="n">panel</span><span class="p">[</span><span class="s2">"h"</span><span class="p">],</span> + <span class="n">min_d</span><span class="o">=</span><span class="n">min_d</span><span class="p">,</span> + <span class="n">max_d</span><span class="o">=</span><span class="n">max_d</span><span class="p">,</span> + <span class="n">detector</span><span class="o">=</span><span class="n">detector</span><span class="p">,</span> + <span class="p">)</span> + + +<div class="viewcode-block" id="load_crystfel_geometry"><a class="viewcode-back" href="../../cfelpyutils.crystfel_utils.html#cfelpyutils.crystfel_utils.load_crystfel_geometry">[docs]</a><span class="k">def</span> <span class="nf">load_crystfel_geometry</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span> + <span class="c1"># type: (str) -> Dict[str, Any]</span> + <span class="sd">"""</span> +<span class="sd"> Loads a CrystFEL geometry file.</span> + +<span class="sd"> This function is a reimplementation of the get_detector_geometry_2 function from</span> +<span class="sd"> CrystFEL. It reads information from a CrystFEL geometry file.</span> +<span class="sd"> </span> +<span class="sd"> For a full documentation of the CrystFEL geometry format, see the relevant `man</span> +<span class="sd"> page <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html>`_.</span> + +<span class="sd"> The function returns a dictionary with the geometry information.</span> + +<span class="sd"> * The CrystFEL geometry file uses a key/value language. The keys in the returned</span> +<span class="sd"> dictionary match the keys in the geometry file.</span> + +<span class="sd"> * The dictionary values store the corresponding values.</span> + +<span class="sd"> * The code of this function is currently synchronized with the code of the function</span> +<span class="sd"> 'get_detector_geometry_2' in CrystFEL at commit 41a8fa9819010.</span> + +<span class="sd"> </span> +<span class="sd"> Arguments:</span> + +<span class="sd"> filename (str): the absolute or relative path to a CrystFEL geometry file.</span> + +<span class="sd"> Returns:</span> + +<span class="sd"> Dict[str, Any]: a dictionary with the geometry information loaded from the</span> +<span class="sd"> file.</span> +<span class="sd"> """</span> + <span class="n">beam</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"photon_energy"</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span> <span class="s2">"photon_energy_from"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="s2">"photon_energy_scale"</span><span class="p">:</span> <span class="mi">1</span><span class="p">}</span> + <span class="n">detector</span> <span class="o">=</span> <span class="p">{</span> + <span class="s2">"panels"</span><span class="p">:</span> <span class="n">collections</span><span class="o">.</span><span class="n">OrderedDict</span><span class="p">(),</span> + <span class="s2">"bad"</span><span class="p">:</span> <span class="n">collections</span><span class="o">.</span><span class="n">OrderedDict</span><span class="p">(),</span> + <span class="s2">"mask_good"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> + <span class="s2">"mask_bad"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> + <span class="s2">"rigid_groups"</span><span class="p">:</span> <span class="p">{},</span> + <span class="s2">"rigid_group_collections"</span><span class="p">:</span> <span class="p">{},</span> + <span class="p">}</span> + <span class="n">default_panel</span> <span class="o">=</span> <span class="p">{</span> + <span class="s2">"cnx"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"cny"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"clen"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"coffset"</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="s2">"res"</span><span class="p">:</span> <span class="o">-</span><span class="mf">1.0</span><span class="p">,</span> + <span class="s2">"badrow"</span><span class="p">:</span> <span class="s2">"-"</span><span class="p">,</span> + <span class="s2">"no_index"</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span> + <span class="s2">"fsx"</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> + <span class="s2">"fsy"</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="s2">"fsz"</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="s2">"ssx"</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="s2">"ssy"</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> + <span class="s2">"ssz"</span><span class="p">:</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="s2">"rail_x"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"rail_y"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"rail_z"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"clen_for_centering"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"adu_per_eV"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"adu_per_photon"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"max_adu"</span><span class="p">:</span> <span class="nb">float</span><span class="p">(</span><span class="s2">"inf"</span><span class="p">),</span> + <span class="s2">"mask"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"mask_file"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"satmap"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"satmap_file"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"data"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"dim_structure"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="p">}</span> + <span class="n">default_bad_region</span> <span class="o">=</span> <span class="p">{</span> + <span class="s2">"min_x"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"max_x"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"min_y"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"max_y"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> + <span class="s2">"min_fs"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> + <span class="s2">"max_fs"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> + <span class="s2">"min_ss"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> + <span class="s2">"max_ss"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> + <span class="s2">"is_fsss"</span><span class="p">:</span> <span class="mi">99</span><span class="p">,</span> + <span class="p">}</span> + <span class="n">default_dim</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"ss"</span><span class="p">,</span> <span class="s2">"fs"</span><span class="p">]</span> + + <span class="n">fhandle</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s2">"r"</span><span class="p">)</span> + <span class="n">fhlines</span> <span class="o">=</span> <span class="n">fhandle</span><span class="o">.</span><span class="n">readlines</span><span class="p">()</span> + <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">fhlines</span><span class="p">:</span> + <span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">";"</span><span class="p">):</span> + <span class="k">continue</span> + <span class="n">line_without_comments</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">";"</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> + <span class="n">line_items</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">pattern</span><span class="o">=</span><span class="s2">"([ </span><span class="se">\t</span><span class="s2">])"</span><span class="p">,</span> <span class="n">string</span><span class="o">=</span><span class="n">line_without_comments</span><span class="p">)</span> + <span class="n">line_items</span> <span class="o">=</span> <span class="p">[</span><span class="n">item</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">line_items</span> <span class="k">if</span> <span class="n">item</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">""</span><span class="p">,</span> <span class="s2">" "</span><span class="p">,</span> <span class="s2">"</span><span class="se">\t</span><span class="s2">"</span><span class="p">)]</span> + <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">line_items</span><span class="p">)</span> <span class="o"><</span> <span class="mi">3</span><span class="p">:</span> + <span class="k">continue</span> + <span class="n">value</span> <span class="o">=</span> <span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">line_items</span><span class="p">[</span><span class="mi">2</span><span class="p">:])</span> + <span class="k">if</span> <span class="n">line_items</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="s2">"="</span><span class="p">:</span> + <span class="k">continue</span> + <span class="n">path</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"(/)"</span><span class="p">,</span> <span class="n">line_items</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> + <span class="n">path</span> <span class="o">=</span> <span class="p">[</span><span class="n">item</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">path</span> <span class="k">if</span> <span class="n">item</span> <span class="ow">not</span> <span class="ow">in</span> <span class="s2">"/"</span><span class="p">]</span> + <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> <span class="o"><</span> <span class="mi">2</span><span class="p">:</span> + <span class="n">_parse_toplevel</span><span class="p">(</span> + <span class="n">key</span><span class="o">=</span><span class="n">line_items</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> + <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> + <span class="n">detector</span><span class="o">=</span><span class="n">detector</span><span class="p">,</span> + <span class="n">beam</span><span class="o">=</span><span class="n">beam</span><span class="p">,</span> + <span class="n">panel</span><span class="o">=</span><span class="n">default_panel</span><span class="p">,</span> + <span class="p">)</span> + <span class="k">continue</span> + <span class="n">curr_bad</span> <span class="o">=</span> <span class="kc">None</span> + <span class="n">curr_panel</span> <span class="o">=</span> <span class="kc">None</span> + <span class="k">if</span> <span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"bad"</span><span class="p">):</span> + <span class="k">if</span> <span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"bad"</span><span class="p">]:</span> + <span class="n">curr_bad</span> <span class="o">=</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"bad"</span><span class="p">][</span><span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">curr_bad</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">default_bad_region</span><span class="p">)</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"bad"</span><span class="p">][</span><span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="n">curr_bad</span> + <span class="k">else</span><span class="p">:</span> + <span class="k">if</span> <span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]:</span> + <span class="n">curr_panel</span> <span class="o">=</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">curr_panel</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">default_panel</span><span class="p">)</span> + <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">path</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="n">curr_panel</span> + <span class="k">if</span> <span class="n">curr_panel</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">_parse_field_for_panel</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">path</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> <span class="n">panel</span><span class="o">=</span><span class="n">curr_panel</span><span class="p">)</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">_parse_field_bad</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">path</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="p">,</span> <span class="n">bad</span><span class="o">=</span><span class="n">curr_bad</span><span class="p">)</span> + <span class="k">if</span> <span class="ow">not</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"No panel descriptions in geometry file."</span><span class="p">)</span> + <span class="n">num_placeholders_in_panels</span> <span class="o">=</span> <span class="kc">None</span> + <span class="k">for</span> <span class="n">panel</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">curr_num_placeholders</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="s2">"%"</span><span class="p">)</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">curr_num_placeholders</span> <span class="o">=</span> <span class="mi">0</span> + + <span class="k">if</span> <span class="n">num_placeholders_in_panels</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">num_placeholders_in_panels</span> <span class="o">=</span> <span class="n">curr_num_placeholders</span> + <span class="k">else</span><span class="p">:</span> + <span class="k">if</span> <span class="n">curr_num_placeholders</span> <span class="o">!=</span> <span class="n">num_placeholders_in_panels</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"All panels' data and mask entries must have the same number of "</span> + <span class="s2">"placeholders."</span> + <span class="p">)</span> + <span class="n">num_placeholders_in_masks</span> <span class="o">=</span> <span class="kc">None</span> + <span class="k">for</span> <span class="n">panel</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"mask"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">curr_num_placeholders</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"mask"</span><span class="p">]</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="s2">"%"</span><span class="p">)</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">curr_num_placeholders</span> <span class="o">=</span> <span class="mi">0</span> + + <span class="k">if</span> <span class="n">num_placeholders_in_masks</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">num_placeholders_in_masks</span> <span class="o">=</span> <span class="n">curr_num_placeholders</span> + <span class="k">else</span><span class="p">:</span> + <span class="k">if</span> <span class="n">curr_num_placeholders</span> <span class="o">!=</span> <span class="n">num_placeholders_in_masks</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"All panels' data and mask entries must have the same number of "</span> + <span class="s2">"placeholders."</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">num_placeholders_in_masks</span> <span class="o">></span> <span class="n">num_placeholders_in_panels</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Number of placeholders in mask cannot be larger the number than for data."</span> + <span class="p">)</span> + <span class="n">dim_length</span> <span class="o">=</span> <span class="kc">None</span> + <span class="k">for</span> <span class="n">panel_name</span><span class="p">,</span> <span class="n">panel</span> <span class="ow">in</span> <span class="n">viewitems</span><span class="p">(</span><span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]):</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">default_dim</span><span class="p">)</span> + + <span class="n">found_ss</span> <span class="o">=</span> <span class="mi">0</span> + <span class="n">found_fs</span> <span class="o">=</span> <span class="mi">0</span> + <span class="n">found_placeholder</span> <span class="o">=</span> <span class="mi">0</span> + <span class="k">for</span> <span class="n">dim_index</span><span class="p">,</span> <span class="n">entry</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]):</span> + <span class="k">if</span> <span class="n">entry</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Dimension </span><span class="si">{}</span><span class="s2"> for panel </span><span class="si">{}</span><span class="s2"> is undefined."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">dim_index</span><span class="p">,</span> <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">elif</span> <span class="n">entry</span> <span class="o">==</span> <span class="s2">"ss"</span><span class="p">:</span> + <span class="n">found_ss</span> <span class="o">+=</span> <span class="mi">1</span> + <span class="k">elif</span> <span class="n">entry</span> <span class="o">==</span> <span class="s2">"fs"</span><span class="p">:</span> + <span class="n">found_fs</span> <span class="o">+=</span> <span class="mi">1</span> + <span class="k">elif</span> <span class="n">entry</span> <span class="o">==</span> <span class="s2">"%"</span><span class="p">:</span> + <span class="n">found_placeholder</span> <span class="o">+=</span> <span class="mi">1</span> + <span class="k">if</span> <span class="n">found_ss</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Exactly one slow scan dim coordinate is needed (found </span><span class="si">{}</span><span class="s2"> for panel "</span> + <span class="s2">"</span><span class="si">{}</span><span class="s2">)."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">found_ss</span><span class="p">,</span> <span class="n">panel_name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">found_fs</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Exactly one fast scan dim coordinate is needed (found </span><span class="si">{}</span><span class="s2"> for panel "</span> + <span class="s2">"</span><span class="si">{}</span><span class="s2">)."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">found_fs</span><span class="p">,</span> <span class="n">panel_name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">found_placeholder</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Only one placeholder dim coordinate is allowed. Maximum one "</span> + <span class="s2">"placeholder dim coordinate is allowed (found </span><span class="si">{}</span><span class="s2"> for panel </span><span class="si">{}</span><span class="s2">)"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">found_placeholder</span><span class="p">,</span> <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">dim_length</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">dim_length</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">])</span> + <span class="k">elif</span> <span class="n">dim_length</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">panel</span><span class="p">[</span><span class="s2">"dim_structure"</span><span class="p">]):</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Number of dim coordinates must be the same for all panels."</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">dim_length</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Number of dim coordinates must be at least two."</span><span class="p">)</span> + <span class="k">for</span> <span class="n">panel_name</span><span class="p">,</span> <span class="n">panel</span> <span class="ow">in</span> <span class="n">viewitems</span><span class="p">(</span><span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]):</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_min_fs"</span><span class="p">]</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the minimum fs coordinate for panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_max_fs"</span><span class="p">]</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the maximum fs coordinate for panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_min_ss"</span><span class="p">]</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the minimum ss coordinate for panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_max_ss"</span><span class="p">]</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the maximum ss coordinate for panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"cnx"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the corner X coordinate for panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">panel_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"clen"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_from"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the camera length for panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">panel_name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"res"</span><span class="p">]</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the resolution or panel </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">panel_name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"adu_per_eV"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"adu_per_photon"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify either adu_per_eV or adu_per_photon for panel "</span> + <span class="s2">"</span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">panel_name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_for_centering"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_x"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"You must specify clen_for_centering if you specify the rail "</span> + <span class="s2">"direction (panel </span><span class="si">{}</span><span class="s2">)"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">panel_name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_x"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_x"</span><span class="p">]</span> <span class="o">=</span> <span class="mf">0.0</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_y"</span><span class="p">]</span> <span class="o">=</span> <span class="mf">0.0</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"rail_z"</span><span class="p">]</span> <span class="o">=</span> <span class="mf">1.0</span> + <span class="k">if</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_for_centering"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"clen_for_centering"</span><span class="p">]</span> <span class="o">=</span> <span class="mf">0.0</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"w"</span><span class="p">]</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_max_fs"</span><span class="p">]</span> <span class="o">-</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_min_fs"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"h"</span><span class="p">]</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_max_ss"</span><span class="p">]</span> <span class="o">-</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"origin_min_ss"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span> + <span class="k">for</span> <span class="n">bad_region_name</span><span class="p">,</span> <span class="n">bad_region</span> <span class="ow">in</span> <span class="n">viewitems</span><span class="p">(</span><span class="n">detector</span><span class="p">[</span><span class="s2">"bad"</span><span class="p">]):</span> + <span class="k">if</span> <span class="n">bad_region</span><span class="p">[</span><span class="s2">"is_fsss"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">99</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Please specify the coordinate ranges for bad region </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> + <span class="n">bad_region_name</span> + <span class="p">)</span> + <span class="p">)</span> + <span class="k">for</span> <span class="n">group</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_groups"</span><span class="p">]:</span> + <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_groups"</span><span class="p">][</span><span class="n">group</span><span class="p">]:</span> + <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Cannot add panel to rigid_group. Panel not found: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">for</span> <span class="n">group_collection</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_group_collections"</span><span class="p">]:</span> + <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_group_collections"</span><span class="p">][</span><span class="n">group_collection</span><span class="p">]:</span> + <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"rigid_groups"</span><span class="p">]:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span> + <span class="s2">"Cannot add rigid_group to collection. Rigid group not "</span> + <span class="s2">"found: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> + <span class="p">)</span> + <span class="k">for</span> <span class="n">panel</span> <span class="ow">in</span> <span class="n">detector</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> + <span class="n">d__</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsx"</span><span class="p">]</span> <span class="o">*</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssy"</span><span class="p">]</span> <span class="o">-</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssx"</span><span class="p">]</span> <span class="o">*</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsy"</span><span class="p">]</span> + <span class="k">if</span> <span class="n">d__</span> <span class="o">==</span> <span class="mf">0.0</span><span class="p">:</span> + <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Panel </span><span class="si">{}</span><span class="s2"> transformation is singluar."</span><span class="p">)</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"xfs"</span><span class="p">]</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssy"</span><span class="p">]</span> <span class="o">/</span> <span class="n">d__</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"yfs"</span><span class="p">]</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"ssx"</span><span class="p">]</span> <span class="o">/</span> <span class="n">d__</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"xss"</span><span class="p">]</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsy"</span><span class="p">]</span> <span class="o">/</span> <span class="n">d__</span> + <span class="n">panel</span><span class="p">[</span><span class="s2">"yss"</span><span class="p">]</span> <span class="o">=</span> <span class="n">panel</span><span class="p">[</span><span class="s2">"fsx"</span><span class="p">]</span> <span class="o">/</span> <span class="n">d__</span> + <span class="n">_find_min_max_d</span><span class="p">(</span><span class="n">detector</span><span class="p">)</span> + <span class="n">fhandle</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> + + <span class="k">return</span> <span class="n">detector</span></div> +</pre></div> + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="../../index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="../../cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="../../index.html">Documentation overview</a><ul> + <li><a href="../index.html">Module code</a><ul> + </ul></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="../../search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs_src/_build/html/_modules/cfelpyutils/geometry_utils.html b/docs_src/_build/html/_modules/cfelpyutils/geometry_utils.html new file mode 100644 index 0000000..479e596 --- /dev/null +++ b/docs_src/_build/html/_modules/cfelpyutils/geometry_utils.html @@ -0,0 +1,321 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>cfelpyutils.geometry_utils — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script> + <script type="text/javascript" src="../../_static/jquery.js"></script> + <script type="text/javascript" src="../../_static/underscore.js"></script> + <script type="text/javascript" src="../../_static/doctools.js"></script> + <script type="text/javascript" src="../../_static/language_data.js"></script> + <link rel="index" title="Index" href="../../genindex.html" /> + <link rel="search" title="Search" href="../../search.html" /> + + <link rel="stylesheet" href="../../_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <h1>Source code for cfelpyutils.geometry_utils</h1><div class="highlight"><pre> +<span></span><span class="c1"># This file is part of CFELPyUtils.</span> +<span class="c1">#</span> +<span class="c1"># CFELPyUtils is free software: you can redistribute it and/or modify it under the</span> +<span class="c1"># terms of the GNU General Public License as published by the Free Software Foundation,</span> +<span class="c1"># either version 3 of the License, or (at your option) any later version.</span> +<span class="c1">#</span> +<span class="c1"># CFELPyUtils is distributed in the hope that it will be useful, but WITHOUT ANY</span> +<span class="c1"># WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A</span> +<span class="c1"># PARTICULAR PURPOSE. See the GNU General Public License for more details.</span> +<span class="c1">#</span> +<span class="c1"># You should have received a copy of the GNU General Public License along with OnDA. If</span> +<span class="c1"># not, see <http://www.gnu.org/licenses/>.</span> +<span class="c1">#</span> +<span class="c1"># Copyright 2014-2019 Deutsches Elektronen-Synchrotron DESY,</span> +<span class="c1"># a research centre of the Helmholtz Association.</span> +<span class="sd">"""</span> +<span class="sd">Geometry utilities.</span> + +<span class="sd">This module contains functions that manipulate geometry information.</span> +<span class="sd">"""</span> +<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">absolute_import</span><span class="p">,</span> <span class="n">division</span><span class="p">,</span> <span class="n">print_function</span> + +<span class="kn">from</span> <span class="nn">typing</span> <span class="k">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Tuple</span> <span class="c1"># pylint: disable=unused-import</span> + +<span class="kn">import</span> <span class="nn">numpy</span> + +<span class="kn">from</span> <span class="nn">cfelpyutils</span> <span class="k">import</span> <span class="n">named_tuples</span> + + +<div class="viewcode-block" id="compute_pix_maps"><a class="viewcode-back" href="../../cfelpyutils.geometry_utils.html#cfelpyutils.geometry_utils.compute_pix_maps">[docs]</a><span class="k">def</span> <span class="nf">compute_pix_maps</span><span class="p">(</span><span class="n">geometry</span><span class="p">):</span> + <span class="c1"># type: (Dict[str, Any]) -> PixelMaps</span> + <span class="sd">"""</span> +<span class="sd"> Computes pixel maps from CrystFEL geometry information.</span> + +<span class="sd"> This function takes as input some geometry information read from a `CrystFEL</span> +<span class="sd"> <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html>`_ file, and</span> +<span class="sd"> returns a set of some pre-computed pixel maps.</span> + +<span class="sd"> The origin and the orientation of the reference system for the pixel maps follow</span> +<span class="sd"> the same conventions as in CrystFEL:</span> + +<span class="sd"> * The center of the reference system is the beam interaction point.</span> + +<span class="sd"> * +z is the beam direction, and points along the beam (i.e. away from the source).</span> + +<span class="sd"> * +y points towards the zenith (ceiling).</span> + +<span class="sd"> * +x completes the right-handed coordinate system.</span> + +<span class="sd"> Arguments:</span> + +<span class="sd"> geometry (Dict[str, Any]): a CrystFEL geometry object (A dictionary returned by</span> +<span class="sd"> the :func:`~cfelpyutils.crystfel_utils.load_crystfel_geometry` function).</span> + +<span class="sd"> Returns:</span> + +<span class="sd"> :class:`~cfelpyutils.named_tuples.PixelMaps`: a named tuple storing the the</span> +<span class="sd"> pixel maps.</span> +<span class="sd"> """</span> + <span class="n">max_fs_in_slab</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">(</span> + <span class="p">[</span><span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">k</span><span class="p">][</span><span class="s2">"max_fs"</span><span class="p">]</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]]</span> + <span class="p">)</span><span class="o">.</span><span class="n">max</span><span class="p">()</span> + <span class="n">max_ss_in_slab</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">(</span> + <span class="p">[</span><span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">k</span><span class="p">][</span><span class="s2">"max_ss"</span><span class="p">]</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]]</span> + <span class="p">)</span><span class="o">.</span><span class="n">max</span><span class="p">()</span> + + <span class="n">x_map</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span> + <span class="n">shape</span><span class="o">=</span><span class="p">(</span><span class="n">max_ss_in_slab</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">max_fs_in_slab</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">float32</span> + <span class="p">)</span> + <span class="n">y_map</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span> + <span class="n">shape</span><span class="o">=</span><span class="p">(</span><span class="n">max_ss_in_slab</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">max_fs_in_slab</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">float32</span> + <span class="p">)</span> + <span class="n">z_map</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span> + <span class="n">shape</span><span class="o">=</span><span class="p">(</span><span class="n">max_ss_in_slab</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">max_fs_in_slab</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">float32</span> + <span class="p">)</span> + + <span class="c1"># Iterates over the panels. For each panel, determines the pixel indices, then</span> + <span class="c1"># computes the x,y vectors. Finally, copies the panel pixel maps into the</span> + <span class="c1"># detector-wide pixel maps.</span> + <span class="k">for</span> <span class="n">pan</span> <span class="ow">in</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">]:</span> + + <span class="k">if</span> <span class="s2">"clen"</span> <span class="ow">in</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">]:</span> + <span class="n">pan_clen</span> <span class="o">=</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"clen"</span><span class="p">]</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">pan_clen</span> <span class="o">=</span> <span class="mf">0.0</span> + + <span class="n">ss_grid</span><span class="p">,</span> <span class="n">fs_grid</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">meshgrid</span><span class="p">(</span> + <span class="n">numpy</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_ss"</span><span class="p">]</span> + <span class="o">-</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_ss"</span><span class="p">]</span> + <span class="o">+</span> <span class="mi">1</span> + <span class="p">),</span> + <span class="n">numpy</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_fs"</span><span class="p">]</span> + <span class="o">-</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_fs"</span><span class="p">]</span> + <span class="o">+</span> <span class="mi">1</span> + <span class="p">),</span> + <span class="n">indexing</span><span class="o">=</span><span class="s2">"ij"</span><span class="p">,</span> + <span class="p">)</span> + <span class="n">y_panel</span> <span class="o">=</span> <span class="p">(</span> + <span class="n">ss_grid</span> <span class="o">*</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"ssy"</span><span class="p">]</span> + <span class="o">+</span> <span class="n">fs_grid</span> <span class="o">*</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"fsy"</span><span class="p">]</span> + <span class="o">+</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"cny"</span><span class="p">]</span> + <span class="p">)</span> + <span class="n">x_panel</span> <span class="o">=</span> <span class="p">(</span> + <span class="n">ss_grid</span> <span class="o">*</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"ssx"</span><span class="p">]</span> + <span class="o">+</span> <span class="n">fs_grid</span> <span class="o">*</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"fsx"</span><span class="p">]</span> + <span class="o">+</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"cnx"</span><span class="p">]</span> + <span class="p">)</span> + <span class="n">x_map</span><span class="p">[</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_ss"</span><span class="p">]</span> <span class="p">:</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_ss"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_fs"</span><span class="p">]</span> <span class="p">:</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_fs"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> + <span class="p">]</span> <span class="o">=</span> <span class="n">x_panel</span> + <span class="n">y_map</span><span class="p">[</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_ss"</span><span class="p">]</span> <span class="p">:</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_ss"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_fs"</span><span class="p">]</span> <span class="p">:</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_fs"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> + <span class="p">]</span> <span class="o">=</span> <span class="n">y_panel</span> + <span class="n">z_map</span><span class="p">[</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_ss"</span><span class="p">]</span> <span class="p">:</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_ss"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> + <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"min_fs"</span><span class="p">]</span> <span class="p">:</span> <span class="n">geometry</span><span class="p">[</span><span class="s2">"panels"</span><span class="p">][</span><span class="n">pan</span><span class="p">][</span><span class="s2">"max_fs"</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> + <span class="p">]</span> <span class="o">=</span> <span class="n">pan_clen</span> + + <span class="n">r_map</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">numpy</span><span class="o">.</span><span class="n">square</span><span class="p">(</span><span class="n">x_map</span><span class="p">)</span> <span class="o">+</span> <span class="n">numpy</span><span class="o">.</span><span class="n">square</span><span class="p">(</span><span class="n">y_map</span><span class="p">))</span> + <span class="n">phi_map</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">arctan2</span><span class="p">(</span><span class="n">y_map</span><span class="p">,</span> <span class="n">x_map</span><span class="p">)</span> + + <span class="k">return</span> <span class="n">named_tuples</span><span class="o">.</span><span class="n">PixelMaps</span><span class="p">(</span><span class="n">x_map</span><span class="p">,</span> <span class="n">y_map</span><span class="p">,</span> <span class="n">z_map</span><span class="p">,</span> <span class="n">r_map</span><span class="p">,</span> <span class="n">phi_map</span><span class="p">)</span></div> + + +<div class="viewcode-block" id="compute_visualization_pix_maps"><a class="viewcode-back" href="../../cfelpyutils.geometry_utils.html#cfelpyutils.geometry_utils.compute_visualization_pix_maps">[docs]</a><span class="k">def</span> <span class="nf">compute_visualization_pix_maps</span><span class="p">(</span><span class="n">geometry</span><span class="p">):</span> + <span class="c1"># type: (Dict[str, Any]) -> PixelMaps</span> + <span class="sd">"""</span> +<span class="sd"> Computes pixel maps for data visualization from CrystFEL geometry information.</span> + +<span class="sd"> This function takes as input some geometry information read from a `CrystFEL</span> +<span class="sd"> <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html>`_ file, and</span> +<span class="sd"> returns a set of some pre-computed pixel maps that can be used to display data in</span> +<span class="sd"> an ImageView widget from the `PyQtGraph <http://pyqtgraph.org/>`_ library.</span> + +<span class="sd"> These pixel maps are different from the ones generated by the</span> +<span class="sd"> :func:`~compute_pix_maps` function. The main differences are:</span> + +<span class="sd"> * The origin of the reference system is not the beam interaction point, but the top</span> +<span class="sd"> left corner of the array used to visualize the data.</span> + +<span class="sd"> * Only the x and y pixel maps are available. The other entries in the named tuple</span> +<span class="sd"> (z, r and phi) are set to None.</span> + +<span class="sd"> Arguments:</span> + +<span class="sd"> geometry (Dict[str, Any]): a CrystFEL geometry object (A dictionary returned by</span> +<span class="sd"> the :func:`~cfelpyutils.crystfel_utils.load_crystfel_geometry` function).</span> + +<span class="sd"> Returns:</span> + +<span class="sd"> :class:`PixelMaps`: a named tuple with the pixel maps.</span> +<span class="sd"> """</span> + <span class="c1"># Shifts the origin of the reference system from the beam position to the top-left</span> + <span class="c1"># of the image that will be displayed. Computes the size of the array needed to</span> + <span class="c1"># display the data, then use this information to estimate the magnitude of the</span> + <span class="c1"># shift.</span> + <span class="n">pixel_maps</span> <span class="o">=</span> <span class="n">compute_pix_maps</span><span class="p">(</span><span class="n">geometry</span><span class="p">)</span> + <span class="n">x_map</span><span class="p">,</span> <span class="n">y_map</span> <span class="o">=</span> <span class="n">pixel_maps</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">pixel_maps</span><span class="o">.</span><span class="n">y</span> + <span class="n">y_minimum</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="nb">int</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">y_map</span><span class="o">.</span><span class="n">max</span><span class="p">()),</span> <span class="nb">abs</span><span class="p">(</span><span class="n">y_map</span><span class="o">.</span><span class="n">min</span><span class="p">())))</span> <span class="o">+</span> <span class="mi">2</span> + <span class="n">x_minimum</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="nb">int</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">x_map</span><span class="o">.</span><span class="n">max</span><span class="p">()),</span> <span class="nb">abs</span><span class="p">(</span><span class="n">x_map</span><span class="o">.</span><span class="n">min</span><span class="p">())))</span> <span class="o">+</span> <span class="mi">2</span> + <span class="n">min_shape</span> <span class="o">=</span> <span class="p">(</span><span class="n">y_minimum</span><span class="p">,</span> <span class="n">x_minimum</span><span class="p">)</span> + <span class="n">new_x_map</span> <span class="o">=</span> <span class="p">(</span> + <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="nb">object</span><span class="o">=</span><span class="n">pixel_maps</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">int</span><span class="p">)</span> <span class="o">+</span> <span class="n">min_shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">//</span> <span class="mi">2</span> <span class="o">-</span> <span class="mi">1</span> + <span class="p">)</span> + <span class="n">new_y_map</span> <span class="o">=</span> <span class="p">(</span> + <span class="n">numpy</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="nb">object</span><span class="o">=</span><span class="n">pixel_maps</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">int</span><span class="p">)</span> <span class="o">+</span> <span class="n">min_shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">//</span> <span class="mi">2</span> <span class="o">-</span> <span class="mi">1</span> + <span class="p">)</span> + <span class="k">return</span> <span class="n">named_tuples</span><span class="o">.</span><span class="n">PixelMaps</span><span class="p">(</span><span class="n">new_x_map</span><span class="p">,</span> <span class="n">new_y_map</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span></div> + + +<div class="viewcode-block" id="apply_geometry_to_data"><a class="viewcode-back" href="../../cfelpyutils.geometry_utils.html#cfelpyutils.geometry_utils.apply_geometry_to_data">[docs]</a><span class="k">def</span> <span class="nf">apply_geometry_to_data</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">geometry</span><span class="p">):</span> + <span class="c1"># type: (numpy.ndarray, Dict[str, Any]) -> numpy.ndarray</span> + <span class="sd">"""</span> +<span class="sd"> Applies CrystFEL geometry information to some data.</span> + +<span class="sd"> This function takes as input some geometry information read from a `CrystFEL</span> +<span class="sd"> <http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html>`_ file, and</span> +<span class="sd"> some data on which to apply it. It returns an array that can be displayed using a</span> +<span class="sd"> library like `matplotlib <https://matplotlib.org/>`_ or </span> +<span class="sd"> `PyQtGraph <http://pyqtgraph.org/>`_.</span> + +<span class="sd"> The shape of the returned array is big enough to display all the input pixel</span> +<span class="sd"> values, and is symmetric around the center of the reference system (i.e: the beam</span> +<span class="sd"> interaction point).</span> + +<span class="sd"> NOTE: This restrictions often cause the returned array to be bigger than the minimum</span> +<span class="sd"> size needed to store the physical layout of the pixels in the detector,</span> +<span class="sd"> particularly if the detector is not centered at the beam interaction point.</span> + +<span class="sd"> Arguments:</span> + +<span class="sd"> data (numpy.ndarray): the data on which the geometry information should be</span> +<span class="sd"> applied.</span> + +<span class="sd"> geometry (Dict[str, Any]): a CrystFEL geometry object (A dictionary returned by</span> +<span class="sd"> the :func:`~cfelpyutils.crystfel_utils.load_crystfel_geometry` function).</span> + +<span class="sd"> Returns:</span> + +<span class="sd"> numpy.ndarray: an array containing the data with the geometry information</span> +<span class="sd"> applied. </span> +<span class="sd"> """</span> + <span class="n">pixel_maps</span> <span class="o">=</span> <span class="n">compute_pix_maps</span><span class="p">(</span><span class="n">geometry</span><span class="p">)</span> + <span class="n">x_map</span><span class="p">,</span> <span class="n">y_map</span> <span class="o">=</span> <span class="n">pixel_maps</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">pixel_maps</span><span class="o">.</span><span class="n">y</span> + <span class="n">y_minimum</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="nb">int</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">y_map</span><span class="o">.</span><span class="n">max</span><span class="p">()),</span> <span class="nb">abs</span><span class="p">(</span><span class="n">y_map</span><span class="o">.</span><span class="n">min</span><span class="p">())))</span> <span class="o">+</span> <span class="mi">2</span> + <span class="n">x_minimum</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="nb">int</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">x_map</span><span class="o">.</span><span class="n">max</span><span class="p">()),</span> <span class="nb">abs</span><span class="p">(</span><span class="n">x_map</span><span class="o">.</span><span class="n">min</span><span class="p">())))</span> <span class="o">+</span> <span class="mi">2</span> + <span class="n">min_shape</span> <span class="o">=</span> <span class="p">(</span><span class="n">y_minimum</span><span class="p">,</span> <span class="n">x_minimum</span><span class="p">)</span> + <span class="n">visualization_array</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span><span class="n">min_shape</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">float</span><span class="p">)</span> + <span class="n">visual_pixel_maps</span> <span class="o">=</span> <span class="n">compute_visualization_pix_maps</span><span class="p">(</span><span class="n">geometry</span><span class="p">)</span> + <span class="n">visualization_array</span><span class="p">[</span> + <span class="n">visual_pixel_maps</span><span class="o">.</span><span class="n">y</span><span class="o">.</span><span class="n">flatten</span><span class="p">(),</span> <span class="n">visual_pixel_maps</span><span class="o">.</span><span class="n">x</span><span class="o">.</span><span class="n">flatten</span><span class="p">()</span> + <span class="p">]</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">ravel</span><span class="p">()</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">visualization_array</span><span class="o">.</span><span class="n">dtype</span><span class="p">)</span> + <span class="k">return</span> <span class="n">visualization_array</span></div> +</pre></div> + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="../../index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="../../cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="../../index.html">Documentation overview</a><ul> + <li><a href="../index.html">Module code</a><ul> + </ul></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="../../search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs_src/_build/html/_modules/cfelpyutils/named_tuples.html b/docs_src/_build/html/_modules/cfelpyutils/named_tuples.html new file mode 100644 index 0000000..7649063 --- /dev/null +++ b/docs_src/_build/html/_modules/cfelpyutils/named_tuples.html @@ -0,0 +1,145 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>cfelpyutils.named_tuples — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script> + <script type="text/javascript" src="../../_static/jquery.js"></script> + <script type="text/javascript" src="../../_static/underscore.js"></script> + <script type="text/javascript" src="../../_static/doctools.js"></script> + <script type="text/javascript" src="../../_static/language_data.js"></script> + <link rel="index" title="Index" href="../../genindex.html" /> + <link rel="search" title="Search" href="../../search.html" /> + + <link rel="stylesheet" href="../../_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <h1>Source code for cfelpyutils.named_tuples</h1><div class="highlight"><pre> +<span></span><span class="c1"># This file is part of CFELPyUtils.</span> +<span class="c1">#</span> +<span class="c1"># CFELPyUtils is free software: you can redistribute it and/or modify it under the</span> +<span class="c1"># terms of the GNU General Public License as published by the Free Software Foundation,</span> +<span class="c1"># either version 3 of the License, or (at your option) any later version.</span> +<span class="c1">#</span> +<span class="c1"># CFELPyUtils is distributed in the hope that it will be useful, but WITHOUT ANY</span> +<span class="c1"># WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A</span> +<span class="c1"># PARTICULAR PURPOSE. See the GNU General Public License for more details.</span> +<span class="c1">#</span> +<span class="c1"># You should have received a copy of the GNU General Public License along with OnDA. If</span> +<span class="c1"># not, see <http://www.gnu.org/licenses/>.</span> +<span class="c1">#</span> +<span class="c1"># Copyright 2014-2019 Deutsches Elektronen-Synchrotron DESY,</span> +<span class="c1"># a research centre of the Helmholtz Association.</span> +<span class="sd">"""</span> +<span class="sd">CFELPyUtils named tuples.</span> + +<span class="sd">This module contains a collection of named tuples used throughout the CFELPyUtils</span> +<span class="sd">library.</span> +<span class="sd">"""</span> +<span class="kn">import</span> <span class="nn">collections</span> + +<span class="n">PixelMaps</span> <span class="o">=</span> <span class="n">collections</span><span class="o">.</span><span class="n">namedtuple</span><span class="p">(</span><span class="s2">"PixelMaps"</span><span class="p">,</span> <span class="p">[</span><span class="s2">"x"</span><span class="p">,</span> <span class="s2">"y"</span><span class="p">,</span> <span class="s2">"z"</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">,</span> <span class="s2">"phi"</span><span class="p">])</span> +<span class="sd">"""</span> +<span class="sd">Pixel maps that store geometry information.</span> + +<span class="sd">Arguments:</span> + +<span class="sd"> x (numpy.ndarray): pixel map for the x coordinate.</span> + +<span class="sd"> y (numpy.ndarray): pixel map for the y coordinate.</span> + +<span class="sd"> z (numpy.ndarray): pixel map for the z coordinate.</span> + +<span class="sd"> r (numpy.ndarray): pixel map storing the distance of each pixel from the center of</span> +<span class="sd"> the reference system.</span> + +<span class="sd"> phi (numpy.ndarray): pixel map storing the amplitude of the angle between each</span> +<span class="sd"> pixel, the center of the reference system, and the x axis through the center.</span> +<span class="sd">"""</span> +</pre></div> + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="../../index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="../../cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="../../index.html">Documentation overview</a><ul> + <li><a href="../index.html">Module code</a><ul> + </ul></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="../../search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs_src/_build/html/_modules/index.html b/docs_src/_build/html/_modules/index.html new file mode 100644 index 0000000..0426bf5 --- /dev/null +++ b/docs_src/_build/html/_modules/index.html @@ -0,0 +1,105 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>Overview: module code — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="../_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script> + <script type="text/javascript" src="../_static/jquery.js"></script> + <script type="text/javascript" src="../_static/underscore.js"></script> + <script type="text/javascript" src="../_static/doctools.js"></script> + <script type="text/javascript" src="../_static/language_data.js"></script> + <link rel="index" title="Index" href="../genindex.html" /> + <link rel="search" title="Search" href="../search.html" /> + + <link rel="stylesheet" href="../_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <h1>All modules for which code is available</h1> +<ul><li><a href="cfelpyutils/crystfel_utils.html">cfelpyutils.crystfel_utils</a></li> +<li><a href="cfelpyutils/geometry_utils.html">cfelpyutils.geometry_utils</a></li> +<li><a href="cfelpyutils/named_tuples.html">cfelpyutils.named_tuples</a></li> +</ul> + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="../index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="../cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="../index.html">Documentation overview</a><ul> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="../search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs_src/_build/html/_sources/cfelpyutils.crystfel_utils.rst.txt b/docs_src/_build/html/_sources/cfelpyutils.crystfel_utils.rst.txt new file mode 100644 index 0000000..8533f9d --- /dev/null +++ b/docs_src/_build/html/_sources/cfelpyutils.crystfel_utils.rst.txt @@ -0,0 +1,7 @@ +The crystfel\_utils Module +========================== + +.. automodule:: cfelpyutils.crystfel_utils + :members: + :undoc-members: + :show-inheritance: diff --git a/docs_src/_build/html/_sources/cfelpyutils.geometry_utils.rst.txt b/docs_src/_build/html/_sources/cfelpyutils.geometry_utils.rst.txt new file mode 100644 index 0000000..005d68a --- /dev/null +++ b/docs_src/_build/html/_sources/cfelpyutils.geometry_utils.rst.txt @@ -0,0 +1,7 @@ +The geometry\_utils Module +========================== + +.. automodule:: cfelpyutils.geometry_utils + :members: + :undoc-members: + :show-inheritance: diff --git a/docs_src/_build/html/_sources/cfelpyutils.named_tuples.rst.txt b/docs_src/_build/html/_sources/cfelpyutils.named_tuples.rst.txt new file mode 100644 index 0000000..42965bb --- /dev/null +++ b/docs_src/_build/html/_sources/cfelpyutils.named_tuples.rst.txt @@ -0,0 +1,7 @@ +The named\_tuples Module +======================== + +.. automodule:: cfelpyutils.named_tuples + :members: + :undoc-members: + :show-inheritance: diff --git a/docs_src/_build/html/_sources/cfelpyutils.rst.txt b/docs_src/_build/html/_sources/cfelpyutils.rst.txt new file mode 100644 index 0000000..9e74d51 --- /dev/null +++ b/docs_src/_build/html/_sources/cfelpyutils.rst.txt @@ -0,0 +1,13 @@ +The cfelpyutils Package +======================= + +.. automodule:: cfelpyutils + :members: + :undoc-members: + :show-inheritance: + +.. toctree:: + + crystfel_utils <cfelpyutils.crystfel_utils> + geometry_utils <cfelpyutils.geometry_utils> + named_tuples <cfelpyutils.named_tuples> diff --git a/docs_src/_build/html/_sources/index.rst.txt b/docs_src/_build/html/_sources/index.rst.txt new file mode 100644 index 0000000..929f41c --- /dev/null +++ b/docs_src/_build/html/_sources/index.rst.txt @@ -0,0 +1,53 @@ +.. cfelpyutils documentation master file, created by + sphinx-quickstart on Tue Jul 10 12:10:05 2018. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +CFELPyUtils +=========== + +.. toctree:: + :hidden: + + cfelpyutils + + +Introduction +------------ + +CFELPyUtils is a utility library written in Python and developed at the Center For Free +Electron Laser Science (CFEL) in Hamburg. It contains several functions and classes +that perform various tasks related to the processing of x-ray imaging data (currently, +mostly reading and applying geometry information to x-ray detector data). It is used by +several internal and released CFEL software projects. + + +Installation +------------ + +The CFELPyUtils library is available on PyPI and can be installed using the pip +command: + +.. code-block:: bash + + python3 -m pip install cfelpyutils + +Or, for python2: + +.. code-block:: bash + + python -m pip install cfelpyutils + + +It is also available as an Anaconda package in the 'ondateam' channel. It can be +installed using the 'conda' command: + +.. code-block:: bash + + conda install -c ondateam cfelpyutils + + +Code Documentation +------------------ + +Code documentation for the CFELPyUtils library can be found :doc:`here <cfelpyutils>`. \ No newline at end of file diff --git a/docs_src/_build/html/_sources/modules.rst.txt b/docs_src/_build/html/_sources/modules.rst.txt new file mode 100644 index 0000000..31f2701 --- /dev/null +++ b/docs_src/_build/html/_sources/modules.rst.txt @@ -0,0 +1,7 @@ +cfelpyutils +=========== + +.. toctree:: + :maxdepth: 4 + + cfelpyutils diff --git a/docs_src/_build/html/_static/ajax-loader.gif b/docs_src/_build/html/_static/ajax-loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..61faf8cab23993bd3e1560bff0668bd628642330 GIT binary patch literal 673 zcmZ?wbhEHb6krfw_{6~Q|Nno%(3)e{?)x>&1u}A`t?OF7Z|1gRivOgXi&7IyQd1Pl zGfOfQ60;I3a`F>X^fL3(@);C=vM_KlFfb_o=k{|A33hf2a5d61U}gjg=>Rd%XaNQW zW@C<Bcm5fi^2`=a=CI<BoWt%nBaPE_qv4@lA~O$e(@QvVsPKYrw1nl|W$cy`JnUZC z&pm)ff{kWGHpc{Hj$e<Wf^-Yd?hVhnTne26LlO)n6%u@0qor2V$ZRdW|29#Ay+Pr+ z#G^K6$xW&%T0&5Rn2-%J<Je`StbNMy#Dp_b!t~i%lV$k6Ncw&BbV{7Dx<KXw*O|?G zWsa@TW{P|({)e&oFu&2t6sh_9S)fKSBO3+uTav2wDWkTDZ{~!>w{|b%Y*pl8F?4B9 zlo4Fz*0kZGJabY|>}Okf0}CCg{u4`zEPY^pV?j2@h+|igy0+Kz6p;@SpM4s6)XEMg z#3Y4GX>Hjlml5ftdH$4x0JGdn8~MX(U~_^d!Hi)=HU{V%g+mi8#UGbE-*ao8f#h+S z2a0-5+vc7MU$e-NhmBjLIC1v|)9+Im8x1yacJ7{^tLX(ZhYi^rpmXm0`@ku9b53aN zEXH@Y3JaztblgpxbJt{AtE1ad1Ca>{v$rwwvK(>{m~Gf_=-Ro7Fk{#;i~+{{>QtvI yb2P8Zac~?~=sRA>$6{!(^3;ZP0TPFR(G_-UDU(8Jl0?(IXu$~#4A!880|o%~Al1tN literal 0 HcmV?d00001 diff --git a/docs_src/_build/html/_static/alabaster.css b/docs_src/_build/html/_static/alabaster.css new file mode 100644 index 0000000..0eddaeb --- /dev/null +++ b/docs_src/_build/html/_static/alabaster.css @@ -0,0 +1,701 @@ +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: Georgia, serif; + font-size: 17px; + background-color: #fff; + color: #000; + margin: 0; + padding: 0; +} + + +div.document { + width: 940px; + margin: 30px auto 0 auto; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 220px; +} + +div.sphinxsidebar { + width: 220px; + font-size: 14px; + line-height: 1.5; +} + +hr { + border: 1px solid #B1B4B6; +} + +div.body { + background-color: #fff; + color: #3E4349; + padding: 0 30px 0 30px; +} + +div.body > .section { + text-align: left; +} + +div.footer { + width: 940px; + margin: 20px auto 30px auto; + font-size: 14px; + color: #888; + text-align: right; +} + +div.footer a { + color: #888; +} + +p.caption { + font-family: inherit; + font-size: inherit; +} + + +div.relations { + display: none; +} + + +div.sphinxsidebar a { + color: #444; + text-decoration: none; + border-bottom: 1px dotted #999; +} + +div.sphinxsidebar a:hover { + border-bottom: 1px solid #999; +} + +div.sphinxsidebarwrapper { + padding: 18px 10px; +} + +div.sphinxsidebarwrapper p.logo { + padding: 0; + margin: -10px 0 0 0px; + text-align: center; +} + +div.sphinxsidebarwrapper h1.logo { + margin-top: -10px; + text-align: center; + margin-bottom: 5px; + text-align: left; +} + +div.sphinxsidebarwrapper h1.logo-name { + margin-top: 0px; +} + +div.sphinxsidebarwrapper p.blurb { + margin-top: 0; + font-style: normal; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4 { + font-family: Georgia, serif; + color: #444; + font-size: 24px; + font-weight: normal; + margin: 0 0 5px 0; + padding: 0; +} + +div.sphinxsidebar h4 { + font-size: 20px; +} + +div.sphinxsidebar h3 a { + color: #444; +} + +div.sphinxsidebar p.logo a, +div.sphinxsidebar h3 a, +div.sphinxsidebar p.logo a:hover, +div.sphinxsidebar h3 a:hover { + border: none; +} + +div.sphinxsidebar p { + color: #555; + margin: 10px 0; +} + +div.sphinxsidebar ul { + margin: 10px 0; + padding: 0; + color: #000; +} + +div.sphinxsidebar ul li.toctree-l1 > a { + font-size: 120%; +} + +div.sphinxsidebar ul li.toctree-l2 > a { + font-size: 110%; +} + +div.sphinxsidebar input { + border: 1px solid #CCC; + font-family: Georgia, serif; + font-size: 1em; +} + +div.sphinxsidebar hr { + border: none; + height: 1px; + color: #AAA; + background: #AAA; + + text-align: left; + margin-left: 0; + width: 50%; +} + +div.sphinxsidebar .badge { + border-bottom: none; +} + +div.sphinxsidebar .badge:hover { + border-bottom: none; +} + +/* To address an issue with donation coming after search */ +div.sphinxsidebar h3.donation { + margin-top: 10px; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #004B6B; + text-decoration: underline; +} + +a:hover { + color: #6D4100; + text-decoration: underline; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: Georgia, serif; + font-weight: normal; + margin: 30px 0px 10px 0px; + padding: 0; +} + +div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } +div.body h2 { font-size: 180%; } +div.body h3 { font-size: 150%; } +div.body h4 { font-size: 130%; } +div.body h5 { font-size: 100%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #DDD; + padding: 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + color: #444; + background: #EAEAEA; +} + +div.body p, div.body dd, div.body li { + line-height: 1.4em; +} + +div.admonition { + margin: 20px 0px; + padding: 10px 30px; + background-color: #EEE; + border: 1px solid #CCC; +} + +div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fafafa; +} + +div.admonition p.admonition-title { + font-family: Georgia, serif; + font-weight: normal; + font-size: 24px; + margin: 0 0 10px 0; + padding: 0; + line-height: 1; +} + +div.admonition p.last { + margin-bottom: 0; +} + +div.highlight { + background-color: #fff; +} + +dt:target, .highlight { + background: #FAF3E8; +} + +div.warning { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.danger { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.error { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.caution { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.attention { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.important { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.note { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.tip { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.hint { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.seealso { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.topic { + background-color: #EEE; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre, tt, code { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; + font-size: 0.9em; +} + +.hll { + background-color: #FFC; + margin: 0 -12px; + padding: 0 12px; + display: block; +} + +img.screenshot { +} + +tt.descname, tt.descclassname, code.descname, code.descclassname { + font-size: 0.95em; +} + +tt.descname, code.descname { + padding-right: 0.08em; +} + +img.screenshot { + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils { + border: 1px solid #888; + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils td, table.docutils th { + border: 1px solid #888; + padding: 0.25em 0.7em; +} + +table.field-list, table.footnote { + border: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +table.footnote { + margin: 15px 0; + width: 100%; + border: 1px solid #EEE; + background: #FDFDFD; + font-size: 0.9em; +} + +table.footnote + table.footnote { + margin-top: -15px; + border-top: none; +} + +table.field-list th { + padding: 0 0.8em 0 0; +} + +table.field-list td { + padding: 0; +} + +table.field-list p { + margin-bottom: 0.8em; +} + +/* Cloned from + * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 + */ +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +table.footnote td.label { + width: .1px; + padding: 0.3em 0 0.3em 0.5em; +} + +table.footnote td { + padding: 0.3em 0.5em; +} + +dl { + margin: 0; + padding: 0; +} + +dl dd { + margin-left: 30px; +} + +blockquote { + margin: 0 0 0 30px; + padding: 0; +} + +ul, ol { + /* Matches the 30px from the narrow-screen "li > ul" selector below */ + margin: 10px 0 10px 30px; + padding: 0; +} + +pre { + background: #EEE; + padding: 7px 30px; + margin: 15px 0px; + line-height: 1.3em; +} + +div.viewcode-block:target { + background: #ffd; +} + +dl pre, blockquote pre, li pre { + margin-left: 0; + padding-left: 30px; +} + +tt, code { + background-color: #ecf0f3; + color: #222; + /* padding: 1px 2px; */ +} + +tt.xref, code.xref, a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fff; +} + +a.reference { + text-decoration: none; + border-bottom: 1px dotted #004B6B; +} + +/* Don't put an underline on images */ +a.image-reference, a.image-reference:hover { + border-bottom: none; +} + +a.reference:hover { + border-bottom: 1px solid #6D4100; +} + +a.footnote-reference { + text-decoration: none; + font-size: 0.7em; + vertical-align: top; + border-bottom: 1px dotted #004B6B; +} + +a.footnote-reference:hover { + border-bottom: 1px solid #6D4100; +} + +a:hover tt, a:hover code { + background: #EEE; +} + + +@media screen and (max-width: 870px) { + + div.sphinxsidebar { + display: none; + } + + div.document { + width: 100%; + + } + + div.documentwrapper { + margin-left: 0; + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + } + + div.bodywrapper { + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + margin-left: 0; + } + + ul { + margin-left: 0; + } + + li > ul { + /* Matches the 30px from the "ul, ol" selector above */ + margin-left: 30px; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .bodywrapper { + margin: 0; + } + + .footer { + width: auto; + } + + .github { + display: none; + } + + + +} + + + +@media screen and (max-width: 875px) { + + body { + margin: 0; + padding: 20px 30px; + } + + div.documentwrapper { + float: none; + background: #fff; + } + + div.sphinxsidebar { + display: block; + float: none; + width: 102.5%; + margin: 50px -30px -20px -30px; + padding: 10px 20px; + background: #333; + color: #FFF; + } + + div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, + div.sphinxsidebar h3 a { + color: #fff; + } + + div.sphinxsidebar a { + color: #AAA; + } + + div.sphinxsidebar p.logo { + display: none; + } + + div.document { + width: 100%; + margin: 0; + } + + div.footer { + display: none; + } + + div.bodywrapper { + margin: 0; + } + + div.body { + min-height: 0; + padding: 0; + } + + .rtd_doc_footer { + display: none; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .footer { + width: auto; + } + + .github { + display: none; + } +} + + +/* misc. */ + +.revsys-inline { + display: none!important; +} + +/* Make nested-list/multi-paragraph items look better in Releases changelog + * pages. Without this, docutils' magical list fuckery causes inconsistent + * formatting between different release sub-lists. + */ +div#changelog > div.section > ul > li > p:only-child { + margin-bottom: 0; +} + +/* Hide fugly table cell borders in ..bibliography:: directive output */ +table.docutils.citation, table.docutils.citation td, table.docutils.citation th { + border: none; + /* Below needed in some edge cases; if not applied, bottom shadows appear */ + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + + +/* relbar */ + +.related { + line-height: 30px; + width: 100%; + font-size: 0.9rem; +} + +.related.top { + border-bottom: 1px solid #EEE; + margin-bottom: 20px; +} + +.related.bottom { + border-top: 1px solid #EEE; +} + +.related ul { + padding: 0; + margin: 0; + list-style: none; +} + +.related li { + display: inline; +} + +nav#rellinks { + float: right; +} + +nav#rellinks li+li:before { + content: "|"; +} + +nav#breadcrumbs li+li:before { + content: "\00BB"; +} + +/* Hide certain items when printing */ +@media print { + div.related { + display: none; + } +} \ No newline at end of file diff --git a/docs_src/_build/html/_static/basic.css b/docs_src/_build/html/_static/basic.css new file mode 100644 index 0000000..0807176 --- /dev/null +++ b/docs_src/_build/html/_static/basic.css @@ -0,0 +1,676 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 450px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist td { + vertical-align: top; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +div.code-block-caption { + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +div.code-block-caption + div > div.highlight > pre { + margin-top: 0; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + padding: 1em 1em 0; +} + +div.literal-block-wrapper div.highlight { + margin: 0; +} + +code.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +code.descclassname { + background-color: transparent; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: relative; + left: 0px; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs_src/_build/html/_static/comment-bright.png b/docs_src/_build/html/_static/comment-bright.png new file mode 100644 index 0000000000000000000000000000000000000000..15e27edb12ac25701ac0ac21b97b52bb4e45415e GIT binary patch literal 756 zcmV<Q0t@|#P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0008JNkl<Zcmaiz z1Hj}w5Qg8Gq}}~(+qP}nwsE#?+qP}nwr!&y+D+z~J^P8B5f1Z2p}9E7<MeddjkkYX zd-EIb)!Fph8#Oll|7xX;pFUA;-4hpnGx`#oio0{nM4Efs-uiF5ty3!w*}J>gfIX78 z$8Pzv({A~p%??+>KickCb#0FM1rYN=mBmQ&Nwp<#JXUhU;{|)}%&s>suq6lXw*~s{ zvHx}3C%<;wE5CH!BR{p<CEvB*W&e*ae5&H6TsQ>5@ml9ws}y)=QN-kL2?#`S5d*6j zk`h<}j1>tD$b?4D^N9w}-k)bx<r``%#N@BubkHRi`8NiUJ1QcYNoj^+f{t5;yOfCu z025_fkz23uZryUlH?8%X)iz&u&N=GVtpN}jfHhN+0n&st2CyuMEP+D?lNAvnV{r9d zcU*Hd8>XxFg>+#kme^xx#qg6FI-%iv2U{<p;QMgJt&^`Ag7_W6#X2)I$;?RfMG1!X z06%V(20R6@MOywSVz5Sxg}7Rrcw!_)k>0h(Y)cs%5a|m%Pn_K3X_bDJ>EH#(Fb73Z zfUt2Q3B>N+ot3qb*DqbTZpFIn4a!#_R-}{?-~Hs=xSS6p&$sZ-k1zDdtqU`Y@`#qL z&zv-~)Q#JCU(dI)Hf;$CEnK=6CK50}q7~wdbI->?E07bJ0R;!GSQTs<U-;V35W~fW z36@m9t>5Am`#;*WHjvHRvY?&$Lm-vq1a_BzocI^ULXV!lbMd%|^B#fY;XX)n<&R^L z=84u1e_3ziq;Hz-*k5~zwY3*oDKt0;bM@M@@89;@m*4RFgvvM_4;5LB!@OB@^WbVT zjl{t;<hC4hUbrL2lKb#<%ZqWCYg*v6+?;pq-M_TowLXr*A-JpI`8bZ>a8_>od-~P4 m{5|DvB&z#xT;*OnJqG}gk~_7HcNkCr0000<MNUMnLSTXfh<FSD literal 0 HcmV?d00001 diff --git a/docs_src/_build/html/_static/comment-close.png b/docs_src/_build/html/_static/comment-close.png new file mode 100644 index 0000000000000000000000000000000000000000..4d91bcf57de866a901a89a2a68c0f36af1114841 GIT binary patch literal 829 zcmV-D1H$}?P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00097Nkl<ZcmZwB z1Dy3Z6o&ElB<&b$^RsQ+wr$(CZQHhO+qT_7?@i8TaM%C-o;rX}=B^hIClh5G@FY>W zanA~u9RIXo;n7c96&U)YLgs-FGlx~*_c{Jgvesu1E5(8YEf&5wF=YFPcRe@1=MJmi zag(L*xc2<lF}aNwyuSNG>r0(slpcN!vC5CUju;vHJkHc*&70_n2OZsK%O~A=!+YIw z<wtI?<OA1V_MYo5e9JW#z16MEgjt6?ZHst>7zLLl7~Z+~RgWOQ=MI6$#0pvpu$Q43 zP@36QAmu6!_9NPM?o<1_!+stoVRRZbW9#SPe!n;#A_6m8f}|xN1;H{`0RoXQ2LM47 zt(g;iZ6|pCb@h2xk&(}S3=EVBUO0e90m2Lp5CB<(SPIaB;n4))3JB87Or#XPOPcum z?<^(g+m9}VNn4Y&B`g8h{t_$+R<w(NPp`pR;bZXUAU_*$1^F@H_u_HjklAf2Sdp#@ zi1e@(?k`~3fS<Wa3$P{d`>B1%HKRY6fjtd-<7&EsU;vs0GM(Lmbhi%Gwcfs0FTF}T zL{_M6Go&E0Eg8FuB*(Yn+Z*RVTBE@10eIOb3El^MhO`GabDll(V0&FlJi2k^;q8af zkENdk2}x2)_KVp`5OAwXZM;dG0?M-S)xE1IKDi6BY@5%Or?#aZ9$gcX)dPZ&wA1a< z$rFXHPn|TBf`e?>Are8sKtKrKcjF$i^lp!zkL?C|y^vlHr1HXeVJd;1I~g&Ob-q)& z(fn7s-KI}G{wnK<H<)KWVxE4VdETD8{2*;k)&R4~T%#E%j&$o0>zg_U5G(V%bX6uk zIa+<@>rdmZYd!9Y=C0cuchrbIjuRB_Wq{-RXlic?flu1*_ux}x%(HDH&nT`k^xCeC ziHi1!ChH*sQ6|UqJpTTzX$aw8e(UfcS^f;6yB<A{y1b}M;$`2cPs0I(nH<v~(<#$j z(=R3u{_U4$r@s5W+3{rXALYlulK55cnX3D?%s|HYcaeVp)Om4$BmFtO00000NkvXX Hu0mjf1x1rJ literal 0 HcmV?d00001 diff --git a/docs_src/_build/html/_static/comment.png b/docs_src/_build/html/_static/comment.png new file mode 100644 index 0000000000000000000000000000000000000000..dfbc0cbd512bdeefcb1984c99d8e577efb77f006 GIT binary patch literal 641 zcmV-{0)G98P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0006=Nkl<Zcmaiw z1B@MC6vpR|+E!HCR@|_TQOC6vt435es%^Vn@9aE}%}s;a?Y%wcJ|ydte7XF72V6cT zZcVcF@Zn4UJS$fQ6bbsQH-fg}6|b#&$*T*WmdO*(Ka6+c>Wd+(1-70zU(rtxtqR%j z-lsH|CKQJXqD{+F7V0OTv8@{~(wp(`oIP^ZykMWgR>&|RsklFMCnOo&Bd{le<WL>} zV5F6424Qzl;o2G%oVvmHgRDP9!=rK8fy^!yV8y*4p=??uIRrrr0?>O!(z*g5Av<N7 z9bjgfR9%u#U0Oo`L>L2!4z0{sq%vhG*Po}`a<6%<Pg--|g3yQn3VWI{Jf@U}Du56| zc#*aA;RUY^;9$z*60-XpjVP=_G=rKle45s4K(Lh`;GMuduTZ8zf4`a8$eLw4pbALM zt+G`Eg6-g7ze4q+xrfElKq%=0lu6(d!Oxl#Qr!)y;YPS3r~qN@C@#(*d{QcR<Idg_ zT0$>kTK5TNhtC8}rXNu&h^QH4A&Sk~Autm*s~45(H7+0bi^MraaRVzr05hQ3iK?j` zR#U@^i0WhkIHTg29u~|ypU?sXCQEQgXfObPW;+0YAF;|5XyaMAEM0sQ@4-xCZe=0e z7r$ofiAxn@O5#RodD8rh5D@nKQ;?lcf@tg4o+Wp44aMl~c47azN_(im0N)7OqdPBC zGw;353_o$DqGRDhuhU$Eaj!@m0<HM3c<s^gb7gJ08nJ?FGHyIi^#lz$dc34LhtZ?q bY#4t557cxjxf?U>00000NkvXXu0mjfjZ7Z_ literal 0 HcmV?d00001 diff --git a/docs_src/_build/html/_static/custom.css b/docs_src/_build/html/_static/custom.css new file mode 100644 index 0000000..2a924f1 --- /dev/null +++ b/docs_src/_build/html/_static/custom.css @@ -0,0 +1 @@ +/* This file intentionally left blank. */ diff --git a/docs_src/_build/html/_static/doctools.js b/docs_src/_build/html/_static/doctools.js new file mode 100644 index 0000000..344db17 --- /dev/null +++ b/docs_src/_build/html/_static/doctools.js @@ -0,0 +1,315 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var bbox = span.getBBox(); + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + var parentOfText = node.parentNode.parentNode; + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { + this.initOnKeyListeners(); + } + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('<a class="headerlink">\u00B6</a>'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('<a class="headerlink">\u00B6</a>'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('<p class="highlight-link"><a href="javascript:Documentation.' + + 'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keyup(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box or textarea + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/docs_src/_build/html/_static/documentation_options.js b/docs_src/_build/html/_static/documentation_options.js new file mode 100644 index 0000000..0c2ef7c --- /dev/null +++ b/docs_src/_build/html/_static/documentation_options.js @@ -0,0 +1,10 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '1.0.0', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + FILE_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, +}; \ No newline at end of file diff --git a/docs_src/_build/html/_static/down-pressed.png b/docs_src/_build/html/_static/down-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..5756c8cad8854722893dc70b9eb4bb0400343a39 GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`OFdm2Ln;`PZ^+1>KjR?B@S0W7 z%OS_REiHONoJ6{+Ks@6k3590|7k9F+ddB6!zw3#&!aw#S`x}3V3&=A(a#84O-&F7T z^k3tZB;&iR9siw0|F|E|DAL<8r-F4!1H-;1{e*~yAKZN5f0|Ei6yUmR#Is)EM(Po_ zi`qJR6|P<~+)N+kSDgL7AjdIC_!O7Q?eGb+L+qOjm{~LLinM4NHn7U%HcK%uoMYO5 VJ~8zD2B3o(JYD@<);T3K0RV0%P>BEl literal 0 HcmV?d00001 diff --git a/docs_src/_build/html/_static/down.png b/docs_src/_build/html/_static/down.png new file mode 100644 index 0000000000000000000000000000000000000000..1b3bdad2ceffae91cee61b32f3295f9bbe646e48 GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6CVIL!hEy=F?b*7pIY7kW{q%Rg zx!yQ<9v8bmJwa`TQk7YSw}WVQ()mRdQ;TC;*<T*?<?OIJF4)K~*`+^EdvW@{fRyJ( z?weB&PpGe(dw+-5<oNH&JW|0z@kgId=L!~9O|3`?{k1Umt465Dp9i1pCaQ@{=WpF| zklotk)=&P-c9F*_Q}bpRPq*XX{4Fk5IYl~|@#V*s^(ig4#DI=t@O1TaS?83{1OQnY BO{f3> literal 0 HcmV?d00001 diff --git a/docs_src/_build/html/_static/file.png b/docs_src/_build/html/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..a858a410e4faa62ce324d814e4b816fff83a6fb3 GIT binary patch literal 286 zcmV+(0pb3MP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0002xNkl<Zcmb`G zgHi?o6ovOGdxdP*AltSE*&JruJwUGI3!FN?xxO>s`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHD<M{a4P!N^sPbQKi=?mBx zoos%BSoiGXjr-;%$QixXMOVNSUNp6L0a1Oz&cgu)wqE?07u5I7qrQIu4Fij)Y3c&0 z@0u_#NH6I?Mk(n;dT}d~^J<WkTLqp|RW-hV56tKpXqu)k@V{?amI+5DOlEU@funz+ kySsbM>fiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( literal 0 HcmV?d00001 diff --git a/docs_src/_build/html/_static/jquery-3.2.1.js b/docs_src/_build/html/_static/jquery-3.2.1.js new file mode 100644 index 0000000..d2d8ca4 --- /dev/null +++ b/docs_src/_build/html/_static/jquery-3.2.1.js @@ -0,0 +1,10253 @@ +/*! + * jQuery JavaScript Library v3.2.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2017-03-20T18:59Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var document = window.document; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + + + + function DOMEval( code, doc ) { + doc = doc || document; + + var script = doc.createElement( "script" ); + + script.text = code; + doc.head.appendChild( script ).parentNode.removeChild( script ); + } +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.2.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android <=4.0 only + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + + if ( copyIsArray ) { + copyIsArray = false; + clone = src && Array.isArray( src ) ? src : []; + + } else { + clone = src && jQuery.isPlainObject( src ) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isFunction: function( obj ) { + return jQuery.type( obj ) === "function"; + }, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + + // As of jQuery 3.0, isNumeric is limited to + // strings and numbers (primitives or objects) + // that can be coerced to finite numbers (gh-2662) + var type = jQuery.type( obj ); + return ( type === "number" || type === "string" ) && + + // parseFloat NaNs numeric-cast false positives ("") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + !isNaN( obj - parseFloat( obj ) ); + }, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + + /* eslint-disable no-unused-vars */ + // See https://github.com/eslint/eslint/issues/6125 + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + DOMEval( code ); + }, + + // Convert dashed to camelCase; used by the css and data modules + // Support: IE <=9 - 11, Edge 12 - 13 + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android <=4.0 only + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.3 + * https://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-08-08 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + disabledAncestor = addCombinator( + function( elem ) { + return elem.disabled === true && ("form" in elem || "label" in elem); + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[i] = "#" + nid + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement("fieldset"); + + try { + return !!fn( el ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + disabledAncestor( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( preferredDoc !== document && + (subWindow = document.defaultView) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( el ) { + el.className = "i"; + return !el.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( el ) { + el.appendChild( document.createComment("") ); + return !el.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + }); + + // ID filter and find + if ( support.getById ) { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( (elem = elems[i++]) ) { + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( el ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + + "<select id='" + expando + "-\r\\' msallowcapture=''>" + + "<option selected=''></option></select>"; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( el ) { + el.innerHTML = "<a href='' disabled='disabled'></a>" + + "<select disabled='disabled'><option/></select>"; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll(":enabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll(":disabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( el ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === document ? -1 : + b === document ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + !compilerCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return (sel + "").replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( (oldCache = uniqueCache[ key ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context === document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context || document, xml) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( el ) { + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( el ) { + el.innerHTML = "<a href='#'></a>"; + return el.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( el ) { + el.innerHTML = "<input/>"; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( el ) { + return el.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Simple selector that can be filtered directly, removing non-Elements + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + // Complex selector, compare the two sets, removing non-Elements + qualifier = jQuery.filter( qualifier, elements ); + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1; + } ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( nodeName( elem, "iframe" ) ) { + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( jQuery.isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && jQuery.isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( jQuery.isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + jQuery.isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + jQuery.isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + jQuery.isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ jQuery.camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ jQuery.camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( jQuery.camelCase ); + } else { + key = jQuery.camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + jQuery.contains( elem.ownerDocument, elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + +var swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, + scale = 1, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + do { + + // If previous iteration zeroed out, double until we get *something*. + // Use string for doubling so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + initialInUnit = initialInUnit / scale; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // Break the loop if scale is unchanged or perfect, or if we've just had enough. + } while ( + scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations + ); + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i ); + +var rscriptType = ( /^$|\/(?:java|ecma)script/i ); + + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE <=9 only + option: [ 1, "<select multiple='multiple'>", "</select>" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting <tbody> or other required elements. + thead: [ 1, "<table>", "</table>" ], + col: [ 2, "<table><colgroup>", "</colgroup></table>" ], + tr: [ 2, "<table><tbody>", "</tbody></table>" ], + td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], + + _default: [ 0, "", "" ] +}; + +// Support: IE <=9 only +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = "<textarea>x</textarea>"; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +} )(); +var documentElement = document.documentElement; + + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 only +// See #13393 for more info +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + // Make a writable jQuery.Event from the native event object + var event = jQuery.event.fix( nativeEvent ); + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG <use> instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: jQuery.isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + /* eslint-disable max-len */ + + // See https://github.com/eslint/eslint/issues/3229 + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, + + /* eslint-enable */ + + // Support: IE <=10 - 11, Edge 12 - 13 + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /<script|<style|<link/i, + + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptTypeMasked = /^true\/(.*)/, + rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( ">tbody", elem )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1></$2>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rmargin = ( /^margin/ ); + +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + div.style.cssText = + "box-sizing:border-box;" + + "position:relative;display:block;" + + "margin:auto;border:1px;padding:1px;" + + "top:1%;width:50%"; + div.innerHTML = ""; + documentElement.appendChild( container ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = divStyle.marginLeft === "2px"; + boxSizingReliableVal = divStyle.width === "4px"; + + // Support: Android 4.0 - 4.3 only + // Some styles come back with percentage values, even though they shouldn't + div.style.marginRight = "50%"; + pixelMarginRightVal = divStyle.marginRight === "4px"; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + + "padding:0;margin-top:1px;position:absolute"; + container.appendChild( div ); + + jQuery.extend( support, { + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelMarginRight: function() { + computeStyleTests(); + return pixelMarginRightVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }, + + cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style; + +// Return a css property mapped to a potentially vendor prefixed property +function vendorPropName( name ) { + + // Shortcut for names that are not vendor prefixed + if ( name in emptyStyle ) { + return name; + } + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a property mapped along what jQuery.cssProps suggests or to +// a vendor prefixed property. +function finalPropName( name ) { + var ret = jQuery.cssProps[ name ]; + if ( !ret ) { + ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name; + } + return ret; +} + +function setPositiveNumber( elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i, + val = 0; + + // If we already have the right measurement, avoid augmentation + if ( extra === ( isBorderBox ? "border" : "content" ) ) { + i = 4; + + // Otherwise initialize for horizontal or vertical properties + } else { + i = name === "width" ? 1 : 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // At this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + + // At this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // At this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with computed style + var valueIsBorderBox, + styles = getStyles( elem ), + val = curCSS( elem, name, styles ), + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test( val ) ) { + return val; + } + + // Check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && + ( support.boxSizingReliable() || val === elem.style[ name ] ); + + // Fall back to offsetWidth/Height when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + if ( val === "auto" ) { + val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ]; + } + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + + // Use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + "float": "cssFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + if ( type === "number" ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = jQuery.camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + } ) : + getWidthOrHeight( elem, name, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = extra && getStyles( elem ), + subtract = extra && augmentWidthOrHeight( + elem, + name, + extra, + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + styles + ); + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ name ] = value; + value = jQuery.css( elem, name ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && + ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || + jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = jQuery.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 13 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( jQuery.isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + jQuery.proxy( result.stop, result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = jQuery.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( jQuery.isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( typeof value === "string" && value ) { + classes = value.match( rnothtmlwhite ) || []; + + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( jQuery.isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + if ( typeof value === "string" && value ) { + classes = value.match( rnothtmlwhite ) || []; + + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value; + + if ( typeof stateVal === "boolean" && type === "string" ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( jQuery.isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( type === "string" ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = value.match( rnothtmlwhite ) || []; + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, isFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup contextmenu" ).split( " " ), + function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; +} ); + +jQuery.fn.extend( { + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +} ); + + + + +support.focusin = "onfocusin" in window; + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = jQuery.now(); + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = jQuery.isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( jQuery.isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match == null ? null : match; + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 13 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available, append data to url + if ( s.data ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + + +jQuery._evalUrl = function( url ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + "throws": true + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( jQuery.isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( "<script>" ).prop( { + charset: s.scriptCharset, + src: s.url + } ).on( + "load error", + callback = function( evt ) { + script.remove(); + callback = null; + if ( evt ) { + complete( evt.type === "error" ? 404 : 200, evt.type ); + } + } + ); + + // Use native DOM manipulation to avoid our domManip AJAX trickery + document.head.appendChild( script[ 0 ] ); + }, + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +var oldCallbacks = [], + rjsonp = /(=)\?(?=&|$)|\?\?/; + +// Default jsonp settings +jQuery.ajaxSetup( { + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +} ); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? + "url" : + typeof s.data === "string" && + ( s.contentType || "" ) + .indexOf( "application/x-www-form-urlencoded" ) === 0 && + rjsonp.test( s.data ) && "data" + ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + + // Insert callback into url or form data + if ( jsonProp ) { + s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); + } else if ( s.jsonp !== false ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters[ "script json" ] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // Force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + overwritten = window[ callbackName ]; + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always( function() { + + // If previous value didn't exist - remove it + if ( overwritten === undefined ) { + jQuery( window ).removeProp( callbackName ); + + // Otherwise restore preexisting value + } else { + window[ callbackName ] = overwritten; + } + + // Save back as free + if ( s[ callbackName ] ) { + + // Make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // Save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + } ); + + // Delegate to script + return "script"; + } +} ); + + + + +// Support: Safari 8 only +// In Safari 8 documents created via document.implementation.createHTMLDocument +// collapse sibling forms: the second one becomes a child of the first one. +// Because of that, this security measure has to be disabled in Safari 8. +// https://bugs.webkit.org/show_bug.cgi?id=137337 +support.createHTMLDocument = ( function() { + var body = document.implementation.createHTMLDocument( "" ).body; + body.innerHTML = "<form></form><form></form>"; + return body.childNodes.length === 2; +} )(); + + +// Argument "data" should be string of html +// context (optional): If specified, the fragment will be created in this context, +// defaults to document +// keepScripts (optional): If true, will include scripts passed in the html string +jQuery.parseHTML = function( data, context, keepScripts ) { + if ( typeof data !== "string" ) { + return []; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + + var base, parsed, scripts; + + if ( !context ) { + + // Stop scripts or inline event handlers from being executed immediately + // by using document.implementation + if ( support.createHTMLDocument ) { + context = document.implementation.createHTMLDocument( "" ); + + // Set the base href for the created document + // so any parsed elements with URLs + // are based on the document's URL (gh-2965) + base = context.createElement( "base" ); + base.href = document.location.href; + context.head.appendChild( base ); + } else { + context = document; + } + } + + parsed = rsingleTag.exec( data ); + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[ 1 ] ) ]; + } + + parsed = buildFragment( [ data ], context, scripts ); + + if ( scripts && scripts.length ) { + jQuery( scripts ).remove(); + } + + return jQuery.merge( [], parsed.childNodes ); +}; + + +/** + * Load a url into a page + */ +jQuery.fn.load = function( url, params, callback ) { + var selector, type, response, + self = this, + off = url.indexOf( " " ); + + if ( off > -1 ) { + selector = stripAndCollapse( url.slice( off ) ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // If we have elements to modify, make the request + if ( self.length > 0 ) { + jQuery.ajax( { + url: url, + + // If "type" variable is undefined, then "GET" method will be used. + // Make value of this field explicit since + // user can override it through ajaxSetup method + type: type || "GET", + dataType: "html", + data: params + } ).done( function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + self.html( selector ? + + // If a selector was specified, locate the right elements in a dummy div + // Exclude scripts to avoid IE 'Permission Denied' errors + jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : + + // Otherwise use the full result + responseText ); + + // If the request succeeds, this function gets "data", "status", "jqXHR" + // but they are ignored because response was set above. + // If it fails, this function gets "jqXHR", "status", "error" + } ).always( callback && function( jqXHR, status ) { + self.each( function() { + callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); + } ); + } ); + } + + return this; +}; + + + + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( [ + "ajaxStart", + "ajaxStop", + "ajaxComplete", + "ajaxError", + "ajaxSuccess", + "ajaxSend" +], function( i, type ) { + jQuery.fn[ type ] = function( fn ) { + return this.on( type, fn ); + }; +} ); + + + + +jQuery.expr.pseudos.animated = function( elem ) { + return jQuery.grep( jQuery.timers, function( fn ) { + return elem === fn.elem; + } ).length; +}; + + + + +jQuery.offset = { + setOffset: function( elem, options, i ) { + var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, + position = jQuery.css( elem, "position" ), + curElem = jQuery( elem ), + props = {}; + + // Set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + curOffset = curElem.offset(); + curCSSTop = jQuery.css( elem, "top" ); + curCSSLeft = jQuery.css( elem, "left" ); + calculatePosition = ( position === "absolute" || position === "fixed" ) && + ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; + + // Need to be able to calculate position if either + // top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + + // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) + options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + + } else { + curElem.css( props ); + } + } +}; + +jQuery.fn.extend( { + offset: function( options ) { + + // Preserve chaining for setter + if ( arguments.length ) { + return options === undefined ? + this : + this.each( function( i ) { + jQuery.offset.setOffset( this, options, i ); + } ); + } + + var doc, docElem, rect, win, + elem = this[ 0 ]; + + if ( !elem ) { + return; + } + + // Return zeros for disconnected and hidden (display: none) elements (gh-2310) + // Support: IE <=11 only + // Running getBoundingClientRect on a + // disconnected node in IE throws an error + if ( !elem.getClientRects().length ) { + return { top: 0, left: 0 }; + } + + rect = elem.getBoundingClientRect(); + + doc = elem.ownerDocument; + docElem = doc.documentElement; + win = doc.defaultView; + + return { + top: rect.top + win.pageYOffset - docElem.clientTop, + left: rect.left + win.pageXOffset - docElem.clientLeft + }; + }, + + position: function() { + if ( !this[ 0 ] ) { + return; + } + + var offsetParent, offset, + elem = this[ 0 ], + parentOffset = { top: 0, left: 0 }; + + // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, + // because it is its only offset parent + if ( jQuery.css( elem, "position" ) === "fixed" ) { + + // Assume getBoundingClientRect is there when computed position is fixed + offset = elem.getBoundingClientRect(); + + } else { + + // Get *real* offsetParent + offsetParent = this.offsetParent(); + + // Get correct offsets + offset = this.offset(); + if ( !nodeName( offsetParent[ 0 ], "html" ) ) { + parentOffset = offsetParent.offset(); + } + + // Add offsetParent borders + parentOffset = { + top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ), + left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ) + }; + } + + // Subtract parent offsets and element margins + return { + top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), + left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) + }; + }, + + // This method will return documentElement in the following cases: + // 1) For the element inside the iframe without offsetParent, this method will return + // documentElement of the parent window + // 2) For the hidden or detached element + // 3) For body or html element, i.e. in case of the html node - it will return itself + // + // but those exceptions were never presented as a real life use-cases + // and might be considered as more preferable results. + // + // This logic, however, is not guaranteed and can change at any point in the future + offsetParent: function() { + return this.map( function() { + var offsetParent = this.offsetParent; + + while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { + offsetParent = offsetParent.offsetParent; + } + + return offsetParent || documentElement; + } ); + } +} ); + +// Create scrollLeft and scrollTop methods +jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { + var top = "pageYOffset" === prop; + + jQuery.fn[ method ] = function( val ) { + return access( this, function( elem, method, val ) { + + // Coalesce documents and windows + var win; + if ( jQuery.isWindow( elem ) ) { + win = elem; + } else if ( elem.nodeType === 9 ) { + win = elem.defaultView; + } + + if ( val === undefined ) { + return win ? win[ prop ] : elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : win.pageXOffset, + top ? val : win.pageYOffset + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length ); + }; +} ); + +// Support: Safari <=7 - 9.1, Chrome <=37 - 49 +// Add the top/left cssHooks using jQuery.fn.position +// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 +// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 +// getComputedStyle returns percent when specified for top/left/bottom/right; +// rather than make the css module depend on the offset module, just check for it here +jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, + function( elem, computed ) { + if ( computed ) { + computed = curCSS( elem, prop ); + + // If curCSS returns percentage, fallback to offset + return rnumnonpx.test( computed ) ? + jQuery( elem ).position()[ prop ] + "px" : + computed; + } + } + ); +} ); + + +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, + function( defaultExtra, funcName ) { + + // Margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + + // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) + return funcName.indexOf( "outer" ) === 0 ? + elem[ "inner" + name ] : + elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], + // whichever is greatest + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable ); + }; + } ); +} ); + + +jQuery.fn.extend( { + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? + this.off( selector, "**" ) : + this.off( types, selector || "**", fn ); + } +} ); + +jQuery.holdReady = function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } +}; +jQuery.isArray = Array.isArray; +jQuery.parseJSON = JSON.parse; +jQuery.nodeName = nodeName; + + + + +// Register as a named AMD module, since jQuery can be concatenated with other +// files that may use define, but not via a proper concatenation script that +// understands anonymous AMD modules. A named AMD is safest and most robust +// way to register. Lowercase jquery is used because AMD module names are +// derived from file names, and jQuery is normally delivered in a lowercase +// file name. Do this after creating the global so that if an AMD module wants +// to call noConflict to hide this version of jQuery, it will work. + +// Note that for maximum portability, libraries that are not jQuery should +// declare themselves as anonymous modules, and avoid setting a global if an +// AMD loader is present. jQuery is a special case. For more information, see +// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon + +if ( typeof define === "function" && define.amd ) { + define( "jquery", [], function() { + return jQuery; + } ); +} + + + + +var + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$; + +jQuery.noConflict = function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; +}; + +// Expose jQuery and $ identifiers, even in AMD +// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) +// and CommonJS for browser emulators (#13566) +if ( !noGlobal ) { + window.jQuery = window.$ = jQuery; +} + + + + +return jQuery; +} ); diff --git a/docs_src/_build/html/_static/jquery.js b/docs_src/_build/html/_static/jquery.js new file mode 100644 index 0000000..644d35e --- /dev/null +++ b/docs_src/_build/html/_static/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=Array.isArray(d)))?(e?(e=!1,f=c&&Array.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,N,e),g(f,c,O,e)):(f++,j.call(a,g(f,c,N,e),g(f,c,O,e),g(f,c,N,c.notifyWith))):(d!==N&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},U=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function V(){this.expando=r.expando+V.uid++}V.uid=1,V.prototype={cache:function(a){var b=a[this.expando];return b||(b={},U(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){Array.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(L)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var W=new V,X=new V,Y=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function $(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Y.test(a)?JSON.parse(a):a)}function _(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Z,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=$(c)}catch(e){}X.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return X.hasData(a)||W.hasData(a)},data:function(a,b,c){return X.access(a,b,c)},removeData:function(a,b){X.remove(a,b)},_data:function(a,b,c){return W.access(a,b,c)},_removeData:function(a,b){W.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=X.get(f),1===f.nodeType&&!W.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),_(f,d,e[d])));W.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){X.set(this,a)}):T(this,function(b){var c;if(f&&void 0===b){if(c=X.get(f,a),void 0!==c)return c;if(c=_(f,a),void 0!==c)return c}else this.each(function(){X.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=W.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ba=new RegExp("^(?:([+-])=|)("+aa+")([a-z%]*)$","i"),ca=["Top","Right","Bottom","Left"],da=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ea=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function fa(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&ba.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ga={};function ha(a){var b,c=a.ownerDocument,d=a.nodeName,e=ga[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ga[d]=e,e)}function ia(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=W.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&da(d)&&(e[f]=ha(d))):"none"!==c&&(e[f]="none",W.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ia(this,!0)},hide:function(){return ia(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){da(this)?r(this).show():r(this).hide()})}});var ja=/^(?:checkbox|radio)$/i,ka=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c<d;c++)W.set(a[c],"globalEval",!b||W.get(b[c],"globalEval"))}var pa=/<|&#?\w+;/;function qa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(pa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ka.exec(f)||["",""])[1].toLowerCase(),i=ma[h]||ma._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===xa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&B(this,"input"))return this.click(),!1},_default:function(a){return B(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?va:wa,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:wa,isPropagationStopped:wa,isImmediatePropagationStopped:wa,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=va,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=va,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=va,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&sa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ta.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return ya(this,a,b,c,d)},one:function(a,b,c,d){return ya(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=wa),this.each(function(){r.event.remove(this,a,c,b)})}});var za=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/<script|<style|<link/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,Ca=/^true\/(.*)/,Da=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}X.hasData(a)&&(h=X.access(a),i=r.extend({},h),X.set(b,i))}}function Ia(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ja.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ja(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,na(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ga),l=0;l<i;l++)j=h[l],la.test(j.type||"")&&!W.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Da,""),k))}return a}function Ka(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(na(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&oa(na(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(za,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d<e;d++)Ia(f[d],g[d]);if(b)if(c)for(f=f||na(a),g=g||na(h),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);else Ha(a,h);return g=na(h,"script"),g.length>0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(na(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ja(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(na(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var La=/^margin/,Ma=new RegExp("^("+aa+")(?!px)[a-z%]+$","i"),Na=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",ra.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,ra.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Oa(a,b,c){var d,e,f,g,h=a.style;return c=c||Na(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ma.test(g)&&La.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Pa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Qa=/^(none|table(?!-c[ea]).+)/,Ra=/^--/,Sa={position:"absolute",visibility:"hidden",display:"block"},Ta={letterSpacing:"0",fontWeight:"400"},Ua=["Webkit","Moz","ms"],Va=d.createElement("div").style;function Wa(a){if(a in Va)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ua.length;while(c--)if(a=Ua[c]+b,a in Va)return a}function Xa(a){var b=r.cssProps[a];return b||(b=r.cssProps[a]=Wa(a)||a),b}function Ya(a,b,c){var d=ba.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Za(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ca[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ca[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ca[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ca[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ca[f]+"Width",!0,e)));return g}function $a(a,b,c){var d,e=Na(a),f=Oa(a,b,e),g="border-box"===r.css(a,"boxSizing",!1,e);return Ma.test(f)?f:(d=g&&(o.boxSizingReliable()||f===a.style[b]),"auto"===f&&(f=a["offset"+b[0].toUpperCase()+b.slice(1)]),f=parseFloat(f)||0,f+Za(a,b,c||(g?"border":"content"),d,e)+"px")}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Oa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=Ra.test(b),j=a.style;return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:j[b]:(f=typeof c,"string"===f&&(e=ba.exec(c))&&e[1]&&(c=fa(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(j[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i?j.setProperty(b,c):j[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b),i=Ra.test(b);return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Oa(a,b,d)),"normal"===e&&b in Ta&&(e=Ta[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Qa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?$a(a,b,d):ea(a,Sa,function(){return $a(a,b,d)})},set:function(a,c,d){var e,f=d&&Na(a),g=d&&Za(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=ba.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ya(a,c,g)}}}),r.cssHooks.marginLeft=Pa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Oa(a,"marginLeft"))||a.getBoundingClientRect().left-ea(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ca[d]+b]=f[d]||f[d-2]||f[0];return e}},La.test(a)||(r.cssHooks[a+b].set=Ya)}),r.fn.extend({css:function(a,b){return T(this,function(a,b,c){var d,e,f={},g=0;if(Array.isArray(b)){for(d=Na(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&da(a),q=W.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],cb.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=W.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ia([a],!0),j=a.style.display||j,k=r.css(a,"display"),ia([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=W.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ia([a],!0),m.done(function(){p||ia([a]),W.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=hb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],Array.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=kb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=ab||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(i||h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:ab||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);f<g;f++)if(d=kb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,hb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j}r.Animation=r.extend(kb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return fa(c.elem,a,ba.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(L);for(var c,d=0,e=a.length;d<e;d++)c=a[d],kb.tweeners[c]=kb.tweeners[c]||[],kb.tweeners[c].unshift(b)},prefilters:[ib],prefilter:function(a,b){b?kb.prefilters.unshift(a):kb.prefilters.push(a)}}),r.speed=function(a,b,c){var d=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off?d.duration=0:"number"!=typeof d.duration&&(d.duration in r.fx.speeds?d.duration=r.fx.speeds[d.duration]:d.duration=r.fx.speeds._default),null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){r.isFunction(d.old)&&d.old.call(this),d.queue&&r.dequeue(this,d.queue)},d},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(da).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=kb(this,r.extend({},a),f);(e||W.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=W.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&db.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=W.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),r.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(ab=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),ab=void 0},r.fx.timer=function(a){r.timers.push(a),r.fx.start()},r.fx.interval=13,r.fx.start=function(){bb||(bb=!0,eb())},r.fx.stop=function(){bb=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var lb,mb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!B(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Tb=[],Ub=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Tb.pop()||r.expando+"_"+ub++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Ub.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ub.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Ub,"$1"+e):b.jsonp!==!1&&(b.url+=(vb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Tb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=pb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Vb=a.jQuery,Wb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Wb),b&&a.jQuery===r&&(a.jQuery=Vb),r},b||(a.jQuery=a.$=r),r}); diff --git a/docs_src/_build/html/_static/language_data.js b/docs_src/_build/html/_static/language_data.js new file mode 100644 index 0000000..5266fb1 --- /dev/null +++ b/docs_src/_build/html/_static/language_data.js @@ -0,0 +1,297 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"]; + + +/* Non-minified version JS is _stemmer.js if file is provided */ +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + + + + + +var splitChars = (function() { + var result = {}; + var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648, + 1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702, + 2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971, + 2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345, + 3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761, + 3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823, + 4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125, + 8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695, + 11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587, + 43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141]; + var i, j, start, end; + for (i = 0; i < singles.length; i++) { + result[singles[i]] = true; + } + var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709], + [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161], + [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568], + [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807], + [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047], + [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383], + [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450], + [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547], + [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673], + [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820], + [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946], + [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023], + [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173], + [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332], + [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481], + [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718], + [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791], + [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095], + [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205], + [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687], + [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968], + [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869], + [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102], + [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271], + [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592], + [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822], + [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167], + [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959], + [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143], + [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318], + [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483], + [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101], + [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567], + [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292], + [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444], + [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783], + [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311], + [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511], + [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774], + [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071], + [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263], + [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519], + [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647], + [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967], + [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295], + [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274], + [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007], + [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381], + [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]]; + for (i = 0; i < ranges.length; i++) { + start = ranges[i][0]; + end = ranges[i][1]; + for (j = start; j <= end; j++) { + result[j] = true; + } + } + return result; +})(); + +function splitQuery(query) { + var result = []; + var start = -1; + for (var i = 0; i < query.length; i++) { + if (splitChars[query.charCodeAt(i)]) { + if (start !== -1) { + result.push(query.slice(start, i)); + start = -1; + } + } else if (start === -1) { + start = i; + } + } + if (start !== -1) { + result.push(query.slice(start)); + } + return result; +} + + diff --git a/docs_src/_build/html/_static/minus.png b/docs_src/_build/html/_static/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..d96755fdaf8bb2214971e0db9c1fd3077d7c419d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu=nj kDsEF_5m^0CR;1wuP-*O&G^0G}KYk!hp00i_>zopr08q^qX#fBK literal 0 HcmV?d00001 diff --git a/docs_src/_build/html/_static/plus.png b/docs_src/_build/html/_static/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..7107cec93a979b9a5f64843235a16651d563ce2d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu>-2 m3q%Vub%g%s<8sJhVPMczOq}xhg9DJoz~JfX=d#Wzp$Pyb1r*Kz literal 0 HcmV?d00001 diff --git a/docs_src/_build/html/_static/pygments.css b/docs_src/_build/html/_static/pygments.css new file mode 100644 index 0000000..dd6621d --- /dev/null +++ b/docs_src/_build/html/_static/pygments.css @@ -0,0 +1,77 @@ +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #8f5902; font-style: italic } /* Comment */ +.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ +.highlight .g { color: #000000 } /* Generic */ +.highlight .k { color: #004461; font-weight: bold } /* Keyword */ +.highlight .l { color: #000000 } /* Literal */ +.highlight .n { color: #000000 } /* Name */ +.highlight .o { color: #582800 } /* Operator */ +.highlight .x { color: #000000 } /* Other */ +.highlight .p { color: #000000; font-weight: bold } /* Punctuation */ +.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #8f5902 } /* Comment.Preproc */ +.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #a40000 } /* Generic.Deleted */ +.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #ef2929 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #745334 } /* Generic.Prompt */ +.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ +.highlight .kc { color: #004461; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #004461; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #004461; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #004461; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #004461; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #004461; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #000000 } /* Literal.Date */ +.highlight .m { color: #990000 } /* Literal.Number */ +.highlight .s { color: #4e9a06 } /* Literal.String */ +.highlight .na { color: #c4a000 } /* Name.Attribute */ +.highlight .nb { color: #004461 } /* Name.Builtin */ +.highlight .nc { color: #000000 } /* Name.Class */ +.highlight .no { color: #000000 } /* Name.Constant */ +.highlight .nd { color: #888888 } /* Name.Decorator */ +.highlight .ni { color: #ce5c00 } /* Name.Entity */ +.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #000000 } /* Name.Function */ +.highlight .nl { color: #f57900 } /* Name.Label */ +.highlight .nn { color: #000000 } /* Name.Namespace */ +.highlight .nx { color: #000000 } /* Name.Other */ +.highlight .py { color: #000000 } /* Name.Property */ +.highlight .nt { color: #004461; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #000000 } /* Name.Variable */ +.highlight .ow { color: #004461; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */ +.highlight .mb { color: #990000 } /* Literal.Number.Bin */ +.highlight .mf { color: #990000 } /* Literal.Number.Float */ +.highlight .mh { color: #990000 } /* Literal.Number.Hex */ +.highlight .mi { color: #990000 } /* Literal.Number.Integer */ +.highlight .mo { color: #990000 } /* Literal.Number.Oct */ +.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */ +.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ +.highlight .sc { color: #4e9a06 } /* Literal.String.Char */ +.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ +.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ +.highlight .se { color: #4e9a06 } /* Literal.String.Escape */ +.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ +.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ +.highlight .sx { color: #4e9a06 } /* Literal.String.Other */ +.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ +.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ +.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ +.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #000000 } /* Name.Function.Magic */ +.highlight .vc { color: #000000 } /* Name.Variable.Class */ +.highlight .vg { color: #000000 } /* Name.Variable.Global */ +.highlight .vi { color: #000000 } /* Name.Variable.Instance */ +.highlight .vm { color: #000000 } /* Name.Variable.Magic */ +.highlight .il { color: #990000 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs_src/_build/html/_static/searchtools.js b/docs_src/_build/html/_static/searchtools.js new file mode 100644 index 0000000..5ff3180 --- /dev/null +++ b/docs_src/_build/html/_static/searchtools.js @@ -0,0 +1,481 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +if (!Scorer) { + /** + * Simple result scoring code. + */ + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [filename, title, anchor, descr, score] + // and returns the new score. + /* + score: function(result) { + return result[4]; + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: {0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5}, // used to be unimportantResults + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + // query found in terms + term: 5 + }; +} + +if (!splitQuery) { + function splitQuery(query) { + return query.split(/\s+/); + } +} + +/** + * Search Module + */ +var Search = { + + _index : null, + _queued_query : null, + _pulse_status : -1, + + init : function() { + var params = $.getQueryParameters(); + if (params.q) { + var query = params.q[0]; + $('input[name="q"]')[0].value = query; + this.performSearch(query); + } + }, + + loadIndex : function(url) { + $.ajax({type: "GET", url: url, data: null, + dataType: "script", cache: true, + complete: function(jqxhr, textstatus) { + if (textstatus != "success") { + document.getElementById("searchindexloader").src = url; + } + }}); + }, + + setIndex : function(index) { + var q; + this._index = index; + if ((q = this._queued_query) !== null) { + this._queued_query = null; + Search.query(q); + } + }, + + hasIndex : function() { + return this._index !== null; + }, + + deferQuery : function(query) { + this._queued_query = query; + }, + + stopPulse : function() { + this._pulse_status = 0; + }, + + startPulse : function() { + if (this._pulse_status >= 0) + return; + function pulse() { + var i; + Search._pulse_status = (Search._pulse_status + 1) % 4; + var dotString = ''; + for (i = 0; i < Search._pulse_status; i++) + dotString += '.'; + Search.dots.text(dotString); + if (Search._pulse_status > -1) + window.setTimeout(pulse, 500); + } + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch : function(query) { + // create the required interface elements + this.out = $('#search-results'); + this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out); + this.dots = $('<span></span>').appendTo(this.title); + this.status = $('<p style="display: none"></p>').appendTo(this.out); + this.output = $('<ul class="search"/>').appendTo(this.out); + + $('#search-progress').text(_('Preparing search...')); + this.startPulse(); + + // index already loaded, the browser was quick! + if (this.hasIndex()) + this.query(query); + else + this.deferQuery(query); + }, + + /** + * execute search (requires search index to be loaded) + */ + query : function(query) { + var i; + + // stem the searchterms and add them to the correct list + var stemmer = new Stemmer(); + var searchterms = []; + var excluded = []; + var hlterms = []; + var tmp = splitQuery(query); + var objectterms = []; + for (i = 0; i < tmp.length; i++) { + if (tmp[i] !== "") { + objectterms.push(tmp[i].toLowerCase()); + } + + if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) || + tmp[i] === "") { + // skip this "word" + continue; + } + // stem the word + var word = stemmer.stemWord(tmp[i].toLowerCase()); + // prevent stemmer from cutting word smaller than two chars + if(word.length < 3 && tmp[i].length >= 3) { + word = tmp[i]; + } + var toAppend; + // select the correct list + if (word[0] == '-') { + toAppend = excluded; + word = word.substr(1); + } + else { + toAppend = searchterms; + hlterms.push(tmp[i].toLowerCase()); + } + // only add if not already in the list + if (!$u.contains(toAppend, word)) + toAppend.push(word); + } + var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" ")); + + // console.debug('SEARCH: searching for:'); + // console.info('required: ', searchterms); + // console.info('excluded: ', excluded); + + // prepare search + var terms = this._index.terms; + var titleterms = this._index.titleterms; + + // array of [filename, title, anchor, descr, score] + var results = []; + $('#search-progress').empty(); + + // lookup as object + for (i = 0; i < objectterms.length; i++) { + var others = [].concat(objectterms.slice(0, i), + objectterms.slice(i+1, objectterms.length)); + results = results.concat(this.performObjectSearch(objectterms[i], others)); + } + + // lookup as search terms in fulltext + results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + for (i = 0; i < results.length; i++) + results[i][4] = Scorer.score(results[i]); + } + + // now sort the results by score (in opposite order of appearance, since the + // display function below uses pop() to retrieve items) and then + // alphabetically + results.sort(function(a, b) { + var left = a[4]; + var right = b[4]; + if (left > right) { + return 1; + } else if (left < right) { + return -1; + } else { + // same score: sort alphabetically + left = a[1].toLowerCase(); + right = b[1].toLowerCase(); + return (left > right) ? -1 : ((left < right) ? 1 : 0); + } + }); + + // for debugging + //Search.lastresults = results.slice(); // a copy + //console.info('search results:', Search.lastresults); + + // print the results + var resultCount = results.length; + function displayNextItem() { + // results left, load the summary and display it + if (results.length) { + var item = results.pop(); + var listItem = $('<li style="display:none"></li>'); + if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') { + // dirhtml builder + var dirname = item[0] + '/'; + if (dirname.match(/\/index\/$/)) { + dirname = dirname.substring(0, dirname.length-6); + } else if (dirname == 'index/') { + dirname = ''; + } + listItem.append($('<a/>').attr('href', + DOCUMENTATION_OPTIONS.URL_ROOT + dirname + + highlightstring + item[2]).html(item[1])); + } else { + // normal html builders + listItem.append($('<a/>').attr('href', + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX + + highlightstring + item[2]).html(item[1])); + } + if (item[3]) { + listItem.append($('<span> (' + item[3] + ')</span>')); + Search.output.append(listItem); + listItem.slideDown(5, function() { + displayNextItem(); + }); + } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) { + var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX; + if (suffix === undefined) { + suffix = '.txt'; + } + $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix), + dataType: "text", + complete: function(jqxhr, textstatus) { + var data = jqxhr.responseText; + if (data !== '' && data !== undefined) { + listItem.append(Search.makeSearchSummary(data, searchterms, hlterms)); + } + Search.output.append(listItem); + listItem.slideDown(5, function() { + displayNextItem(); + }); + }}); + } else { + // no source available, just display title + Search.output.append(listItem); + listItem.slideDown(5, function() { + displayNextItem(); + }); + } + } + // search finished, update title and status message + else { + Search.stopPulse(); + Search.title.text(_('Search Results')); + if (!resultCount) + Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.')); + else + Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount)); + Search.status.fadeIn(500); + } + } + displayNextItem(); + }, + + /** + * search for object names + */ + performObjectSearch : function(object, otherterms) { + var filenames = this._index.filenames; + var docnames = this._index.docnames; + var objects = this._index.objects; + var objnames = this._index.objnames; + var titles = this._index.titles; + + var i; + var results = []; + + for (var prefix in objects) { + for (var name in objects[prefix]) { + var fullname = (prefix ? prefix + '.' : '') + name; + if (fullname.toLowerCase().indexOf(object) > -1) { + var score = 0; + var parts = fullname.split('.'); + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullname == object || parts[parts.length - 1] == object) { + score += Scorer.objNameMatch; + // matches in last name + } else if (parts[parts.length - 1].indexOf(object) > -1) { + score += Scorer.objPartialMatch; + } + var match = objects[prefix][name]; + var objname = objnames[match[1]][2]; + var title = titles[match[0]]; + // If more than one term searched for, we require other words to be + // found in the name/title/description + if (otherterms.length > 0) { + var haystack = (prefix + ' ' + name + ' ' + + objname + ' ' + title).toLowerCase(); + var allfound = true; + for (i = 0; i < otherterms.length; i++) { + if (haystack.indexOf(otherterms[i]) == -1) { + allfound = false; + break; + } + } + if (!allfound) { + continue; + } + } + var descr = objname + _(', in ') + title; + + var anchor = match[3]; + if (anchor === '') + anchor = fullname; + else if (anchor == '-') + anchor = objnames[match[1]][1] + '-' + fullname; + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) { + score += Scorer.objPrio[match[2]]; + } else { + score += Scorer.objPrioDefault; + } + results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]); + } + } + } + + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch : function(searchterms, excluded, terms, titleterms) { + var docnames = this._index.docnames; + var filenames = this._index.filenames; + var titles = this._index.titles; + + var i, j, file; + var fileMap = {}; + var scoreMap = {}; + var results = []; + + // perform the search on the required terms + for (i = 0; i < searchterms.length; i++) { + var word = searchterms[i]; + var files = []; + var _o = [ + {files: terms[word], score: Scorer.term}, + {files: titleterms[word], score: Scorer.title} + ]; + + // no match but word was a required one + if ($u.every(_o, function(o){return o.files === undefined;})) { + break; + } + // found search word in contents + $u.each(_o, function(o) { + var _files = o.files; + if (_files === undefined) + return + + if (_files.length === undefined) + _files = [_files]; + files = files.concat(_files); + + // set score for the word in each file to Scorer.term + for (j = 0; j < _files.length; j++) { + file = _files[j]; + if (!(file in scoreMap)) + scoreMap[file] = {} + scoreMap[file][word] = o.score; + } + }); + + // create the mapping + for (j = 0; j < files.length; j++) { + file = files[j]; + if (file in fileMap) + fileMap[file].push(word); + else + fileMap[file] = [word]; + } + } + + // now check if the files don't contain excluded terms + for (file in fileMap) { + var valid = true; + + // check if all requirements are matched + if (fileMap[file].length != searchterms.length) + continue; + + // ensure that none of the excluded terms is in the search result + for (i = 0; i < excluded.length; i++) { + if (terms[excluded[i]] == file || + titleterms[excluded[i]] == file || + $u.contains(terms[excluded[i]] || [], file) || + $u.contains(titleterms[excluded[i]] || [], file)) { + valid = false; + break; + } + } + + // if we have still a valid result we can add it to the result list + if (valid) { + // select one (max) score for the file. + // for better ranking, we should calculate ranking by using words statistics like basic tf-idf... + var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]})); + results.push([docnames[file], titles[file], '', null, score, filenames[file]]); + } + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words, hlwords is the list of normal, unstemmed + * words. the first one is used to find the occurrence, the + * latter for highlighting it. + */ + makeSearchSummary : function(text, keywords, hlwords) { + var textLower = text.toLowerCase(); + var start = 0; + $.each(keywords, function() { + var i = textLower.indexOf(this.toLowerCase()); + if (i > -1) + start = i; + }); + start = Math.max(start - 120, 0); + var excerpt = ((start > 0) ? '...' : '') + + $.trim(text.substr(start, 240)) + + ((start + 240 - text.length) ? '...' : ''); + var rv = $('<div class="context"></div>').text(excerpt); + $.each(hlwords, function() { + rv = rv.highlightText(this, 'highlighted'); + }); + return rv; + } +}; + +$(document).ready(function() { + Search.init(); +}); diff --git a/docs_src/_build/html/_static/underscore-1.3.1.js b/docs_src/_build/html/_static/underscore-1.3.1.js new file mode 100644 index 0000000..208d4cd --- /dev/null +++ b/docs_src/_build/html/_static/underscore-1.3.1.js @@ -0,0 +1,999 @@ +// Underscore.js 1.3.1 +// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore is freely distributable under the MIT license. +// Portions of Underscore are inspired or borrowed from Prototype, +// Oliver Steele's Functional, and John Resig's Micro-Templating. +// For all details and documentation: +// http://documentcloud.github.com/underscore + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `global` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Establish the object that gets returned to break out of a loop iteration. + var breaker = {}; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var slice = ArrayProto.slice, + unshift = ArrayProto.unshift, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeForEach = ArrayProto.forEach, + nativeMap = ArrayProto.map, + nativeReduce = ArrayProto.reduce, + nativeReduceRight = ArrayProto.reduceRight, + nativeFilter = ArrayProto.filter, + nativeEvery = ArrayProto.every, + nativeSome = ArrayProto.some, + nativeIndexOf = ArrayProto.indexOf, + nativeLastIndexOf = ArrayProto.lastIndexOf, + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { return new wrapper(obj); }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object via a string identifier, + // for Closure Compiler "advanced" mode. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root['_'] = _; + } + + // Current version. + _.VERSION = '1.3.1'; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles objects with the built-in `forEach`, arrays, and raw objects. + // Delegates to **ECMAScript 5**'s native `forEach` if available. + var each = _.each = _.forEach = function(obj, iterator, context) { + if (obj == null) return; + if (nativeForEach && obj.forEach === nativeForEach) { + obj.forEach(iterator, context); + } else if (obj.length === +obj.length) { + for (var i = 0, l = obj.length; i < l; i++) { + if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return; + } + } else { + for (var key in obj) { + if (_.has(obj, key)) { + if (iterator.call(context, obj[key], key, obj) === breaker) return; + } + } + } + }; + + // Return the results of applying the iterator to each element. + // Delegates to **ECMAScript 5**'s native `map` if available. + _.map = _.collect = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); + each(obj, function(value, index, list) { + results[results.length] = iterator.call(context, value, index, list); + }); + if (obj.length === +obj.length) results.length = obj.length; + return results; + }; + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. + _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduce && obj.reduce === nativeReduce) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); + } + each(obj, function(value, index, list) { + if (!initial) { + memo = value; + initial = true; + } else { + memo = iterator.call(context, memo, value, index, list); + } + }); + if (!initial) throw new TypeError('Reduce of empty array with no initial value'); + return memo; + }; + + // The right-associative version of reduce, also known as `foldr`. + // Delegates to **ECMAScript 5**'s native `reduceRight` if available. + _.reduceRight = _.foldr = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); + } + var reversed = _.toArray(obj).reverse(); + if (context && !initial) iterator = _.bind(iterator, context); + return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator); + }; + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, iterator, context) { + var result; + any(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) { + result = value; + return true; + } + }); + return result; + }; + + // Return all the elements that pass a truth test. + // Delegates to **ECMAScript 5**'s native `filter` if available. + // Aliased as `select`. + _.filter = _.select = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); + each(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + each(obj, function(value, index, list) { + if (!iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Determine whether all of the elements match a truth test. + // Delegates to **ECMAScript 5**'s native `every` if available. + // Aliased as `all`. + _.every = _.all = function(obj, iterator, context) { + var result = true; + if (obj == null) return result; + if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); + each(obj, function(value, index, list) { + if (!(result = result && iterator.call(context, value, index, list))) return breaker; + }); + return result; + }; + + // Determine if at least one element in the object matches a truth test. + // Delegates to **ECMAScript 5**'s native `some` if available. + // Aliased as `any`. + var any = _.some = _.any = function(obj, iterator, context) { + iterator || (iterator = _.identity); + var result = false; + if (obj == null) return result; + if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); + each(obj, function(value, index, list) { + if (result || (result = iterator.call(context, value, index, list))) return breaker; + }); + return !!result; + }; + + // Determine if a given value is included in the array or object using `===`. + // Aliased as `contains`. + _.include = _.contains = function(obj, target) { + var found = false; + if (obj == null) return found; + if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; + found = any(obj, function(value) { + return value === target; + }); + return found; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + return _.map(obj, function(value) { + return (_.isFunction(method) ? method || value : value[method]).apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, function(value){ return value[key]; }); + }; + + // Return the maximum element or (element-based computation). + _.max = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj); + if (!iterator && _.isEmpty(obj)) return -Infinity; + var result = {computed : -Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed >= result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj); + if (!iterator && _.isEmpty(obj)) return Infinity; + var result = {computed : Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed < result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Shuffle an array. + _.shuffle = function(obj) { + var shuffled = [], rand; + each(obj, function(value, index, list) { + if (index == 0) { + shuffled[0] = value; + } else { + rand = Math.floor(Math.random() * (index + 1)); + shuffled[index] = shuffled[rand]; + shuffled[rand] = value; + } + }); + return shuffled; + }; + + // Sort the object's values by a criterion produced by an iterator. + _.sortBy = function(obj, iterator, context) { + return _.pluck(_.map(obj, function(value, index, list) { + return { + value : value, + criteria : iterator.call(context, value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }), 'value'); + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = function(obj, val) { + var result = {}; + var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; }; + each(obj, function(value, index) { + var key = iterator(value, index); + (result[key] || (result[key] = [])).push(value); + }); + return result; + }; + + // Use a comparator function to figure out at what index an object should + // be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iterator) { + iterator || (iterator = _.identity); + var low = 0, high = array.length; + while (low < high) { + var mid = (low + high) >> 1; + iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid; + } + return low; + }; + + // Safely convert anything iterable into a real, live array. + _.toArray = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) return iterable.toArray(); + if (_.isArray(iterable)) return slice.call(iterable); + if (_.isArguments(iterable)) return slice.call(iterable); + return _.values(iterable); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + return _.toArray(obj).length; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head`. The **guard** check allows it to work + // with `_.map`. + _.first = _.head = function(array, n, guard) { + return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; + }; + + // Returns everything but the last entry of the array. Especcialy useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. The **guard** check allows it to work with + // `_.map`. + _.initial = function(array, n, guard) { + return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. The **guard** check allows it to work with `_.map`. + _.last = function(array, n, guard) { + if ((n != null) && !guard) { + return slice.call(array, Math.max(array.length - n, 0)); + } else { + return array[array.length - 1]; + } + }; + + // Returns everything but the first entry of the array. Aliased as `tail`. + // Especially useful on the arguments object. Passing an **index** will return + // the rest of the values in the array from that index onward. The **guard** + // check allows it to work with `_.map`. + _.rest = _.tail = function(array, index, guard) { + return slice.call(array, (index == null) || guard ? 1 : index); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, function(value){ return !!value; }); + }; + + // Return a completely flattened version of an array. + _.flatten = function(array, shallow) { + return _.reduce(array, function(memo, value) { + if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value)); + memo[memo.length] = value; + return memo; + }, []); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iterator) { + var initial = iterator ? _.map(array, iterator) : array; + var result = []; + _.reduce(initial, function(memo, el, i) { + if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) { + memo[memo.length] = el; + result[result.length] = array[i]; + } + return memo; + }, []); + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(_.flatten(arguments, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. (Aliased as "intersect" for back-compat.) + _.intersection = _.intersect = function(array) { + var rest = slice.call(arguments, 1); + return _.filter(_.uniq(array), function(item) { + return _.every(rest, function(other) { + return _.indexOf(other, item) >= 0; + }); + }); + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = _.flatten(slice.call(arguments, 1)); + return _.filter(array, function(value){ return !_.include(rest, value); }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + var args = slice.call(arguments); + var length = _.max(_.pluck(args, 'length')); + var results = new Array(length); + for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i); + return results; + }; + + // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), + // we need this function. Return the position of the first occurrence of an + // item in an array, or -1 if the item is not included in the array. + // Delegates to **ECMAScript 5**'s native `indexOf` if available. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = function(array, item, isSorted) { + if (array == null) return -1; + var i, l; + if (isSorted) { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item); + for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i; + return -1; + }; + + // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. + _.lastIndexOf = function(array, item) { + if (array == null) return -1; + if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item); + var i = array.length; + while (i--) if (i in array && array[i] === item) return i; + return -1; + }; + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (arguments.length <= 1) { + stop = start || 0; + start = 0; + } + step = arguments[2] || 1; + + var len = Math.max(Math.ceil((stop - start) / step), 0); + var idx = 0; + var range = new Array(len); + + while(idx < len) { + range[idx++] = start; + start += step; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Reusable constructor function for prototype setting. + var ctor = function(){}; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Binding with arguments is also known as `curry`. + // Delegates to **ECMAScript 5**'s native `Function.bind` if available. + // We check for `func.bind` first, to fail fast when `func` is undefined. + _.bind = function bind(func, context) { + var bound, args; + if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError; + args = slice.call(arguments, 2); + return bound = function() { + if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); + ctor.prototype = func.prototype; + var self = new ctor; + var result = func.apply(self, args.concat(slice.call(arguments))); + if (Object(result) === result) return result; + return self; + }; + }; + + // Bind all of an object's methods to that object. Useful for ensuring that + // all callbacks defined on an object belong to it. + _.bindAll = function(obj) { + var funcs = slice.call(arguments, 1); + if (funcs.length == 0) funcs = _.functions(obj); + each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memo = {}; + hasher || (hasher = _.identity); + return function() { + var key = hasher.apply(this, arguments); + return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); + }; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ return func.apply(func, args); }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = function(func) { + return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); + }; + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. + _.throttle = function(func, wait) { + var context, args, timeout, throttling, more; + var whenDone = _.debounce(function(){ more = throttling = false; }, wait); + return function() { + context = this; args = arguments; + var later = function() { + timeout = null; + if (more) func.apply(context, args); + whenDone(); + }; + if (!timeout) timeout = setTimeout(later, wait); + if (throttling) { + more = true; + } else { + func.apply(context, args); + } + whenDone(); + throttling = true; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. + _.debounce = function(func, wait) { + var timeout; + return function() { + var context = this, args = arguments; + var later = function() { + timeout = null; + func.apply(context, args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = function(func) { + var ran = false, memo; + return function() { + if (ran) return memo; + ran = true; + return memo = func.apply(this, arguments); + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return function() { + var args = [func].concat(slice.call(arguments, 0)); + return wrapper.apply(this, args); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var funcs = arguments; + return function() { + var args = arguments; + for (var i = funcs.length - 1; i >= 0; i--) { + args = [funcs[i].apply(this, args)]; + } + return args[0]; + }; + }; + + // Returns a function that will only be executed after being called N times. + _.after = function(times, func) { + if (times <= 0) return func(); + return function() { + if (--times < 1) { return func.apply(this, arguments); } + }; + }; + + // Object Functions + // ---------------- + + // Retrieve the names of an object's properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = nativeKeys || function(obj) { + if (obj !== Object(obj)) throw new TypeError('Invalid object'); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + return _.map(obj, _.identity); + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Fill in a given object with default properties. + _.defaults = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + if (obj[prop] == null) obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Internal recursive comparison function. + function eq(a, b, stack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal. + if (a === b) return a !== 0 || 1 / a == 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a._chain) a = a._wrapped; + if (b._chain) b = b._wrapped; + // Invoke a custom `isEqual` method if one is provided. + if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b); + if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a); + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className != toString.call(b)) return false; + switch (className) { + // Strings, numbers, dates, and booleans are compared by value. + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return a == String(b); + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for + // other numeric values. + return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a == +b; + // RegExps are compared by their source patterns and flags. + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') return false; + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + var length = stack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (stack[length] == a) return true; + } + // Add the first object to the stack of traversed objects. + stack.push(a); + var size = 0, result = true; + // Recursively compare objects and arrays. + if (className == '[object Array]') { + // Compare array lengths to determine if a deep comparison is necessary. + size = a.length; + result = size == b.length; + if (result) { + // Deep compare the contents, ignoring non-numeric properties. + while (size--) { + // Ensure commutative equality for sparse arrays. + if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break; + } + } + } else { + // Objects with different constructors are not equivalent. + if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false; + // Deep compare objects. + for (var key in a) { + if (_.has(a, key)) { + // Count the expected number of properties. + size++; + // Deep compare each member. + if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break; + } + } + // Ensure that both objects contain the same number of properties. + if (result) { + for (key in b) { + if (_.has(b, key) && !(size--)) break; + } + result = !size; + } + } + // Remove the first object from the stack of traversed objects. + stack.pop(); + return result; + } + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b, []); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; + for (var key in obj) if (_.has(obj, key)) return false; + return true; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType == 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) == '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + return obj === Object(obj); + }; + + // Is a given variable an arguments object? + _.isArguments = function(obj) { + return toString.call(obj) == '[object Arguments]'; + }; + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return !!(obj && _.has(obj, 'callee')); + }; + } + + // Is a given value a function? + _.isFunction = function(obj) { + return toString.call(obj) == '[object Function]'; + }; + + // Is a given value a string? + _.isString = function(obj) { + return toString.call(obj) == '[object String]'; + }; + + // Is a given value a number? + _.isNumber = function(obj) { + return toString.call(obj) == '[object Number]'; + }; + + // Is the given value `NaN`? + _.isNaN = function(obj) { + // `NaN` is the only value for which `===` is not reflexive. + return obj !== obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; + }; + + // Is a given value a date? + _.isDate = function(obj) { + return toString.call(obj) == '[object Date]'; + }; + + // Is the given value a regular expression? + _.isRegExp = function(obj) { + return toString.call(obj) == '[object RegExp]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Has own property? + _.has = function(obj, key) { + return hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iterators. + _.identity = function(value) { + return value; + }; + + // Run a function **n** times. + _.times = function (n, iterator, context) { + for (var i = 0; i < n; i++) iterator.call(context, i); + }; + + // Escape a string for HTML interpolation. + _.escape = function(string) { + return (''+string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/'); + }; + + // Add your own custom functions to the Underscore object, ensuring that + // they're correctly added to the OOP wrapper as well. + _.mixin = function(obj) { + each(_.functions(obj), function(name){ + addToWrapper(name, _[name] = obj[name]); + }); + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = idCounter++; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /.^/; + + // Within an interpolation, evaluation, or escaping, remove HTML escaping + // that had been previously added. + var unescape = function(code) { + return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'"); + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + _.template = function(str, data) { + var c = _.templateSettings; + var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + + 'with(obj||{}){__p.push(\'' + + str.replace(/\\/g, '\\\\') + .replace(/'/g, "\\'") + .replace(c.escape || noMatch, function(match, code) { + return "',_.escape(" + unescape(code) + "),'"; + }) + .replace(c.interpolate || noMatch, function(match, code) { + return "'," + unescape(code) + ",'"; + }) + .replace(c.evaluate || noMatch, function(match, code) { + return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('"; + }) + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t') + + "');}return __p.join('');"; + var func = new Function('obj', '_', tmpl); + if (data) return func(data, _); + return function(data) { + return func.call(this, data, _); + }; + }; + + // Add a "chain" function, which will delegate to the wrapper. + _.chain = function(obj) { + return _(obj).chain(); + }; + + // The OOP Wrapper + // --------------- + + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + var wrapper = function(obj) { this._wrapped = obj; }; + + // Expose `wrapper.prototype` as `_.prototype` + _.prototype = wrapper.prototype; + + // Helper function to continue chaining intermediate results. + var result = function(obj, chain) { + return chain ? _(obj).chain() : obj; + }; + + // A method to easily add functions to the OOP wrapper. + var addToWrapper = function(name, func) { + wrapper.prototype[name] = function() { + var args = slice.call(arguments); + unshift.call(args, this._wrapped); + return result(func.apply(_, args), this._chain); + }; + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + var wrapped = this._wrapped; + method.apply(wrapped, arguments); + var length = wrapped.length; + if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0]; + return result(wrapped, this._chain); + }; + }); + + // Add all accessor Array functions to the wrapper. + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + return result(method.apply(this._wrapped, arguments), this._chain); + }; + }); + + // Start chaining a wrapped Underscore object. + wrapper.prototype.chain = function() { + this._chain = true; + return this; + }; + + // Extracts the result from a wrapped and chained object. + wrapper.prototype.value = function() { + return this._wrapped; + }; + +}).call(this); diff --git a/docs_src/_build/html/_static/underscore.js b/docs_src/_build/html/_static/underscore.js new file mode 100644 index 0000000..5b55f32 --- /dev/null +++ b/docs_src/_build/html/_static/underscore.js @@ -0,0 +1,31 @@ +// Underscore.js 1.3.1 +// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore is freely distributable under the MIT license. +// Portions of Underscore are inspired or borrowed from Prototype, +// Oliver Steele's Functional, and John Resig's Micro-Templating. +// For all details and documentation: +// http://documentcloud.github.com/underscore +(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== +c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c, +h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each= +b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a== +null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect= +function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e= +e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= +function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})}); +return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a, +c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest= +b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]); +return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c, +d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g}; +var F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a, +c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true: +a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}}; +b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments, +1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)}; +b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"}; +b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a), +function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+ +u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]= +function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain= +true;return this};m.prototype.value=function(){return this._wrapped}}).call(this); diff --git a/docs_src/_build/html/_static/up-pressed.png b/docs_src/_build/html/_static/up-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..acee3b68efbbfb9de3bfa73fce2531380f4bd820 GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`b3I)gLn;`PCGIF3$k*oP2u^Cy z1QG|_1=PYnb1D4eKdS9<Rfpq9eZvoV4(FRqOC&yU<ykZBR|+eZ3^{Bs(0fczS?$)o z1zBzqOjDB&rXLWUki_(ZOYf}S3_te-6HD<NwmmIcKX{MqZ}`C=pw3iiGvzP0)_49T zVzHmSR(wuwn8DsJUb!G^UBj0HEK?h9OzUY$<G#e5WDq>z%1p*-hql&#Z9G*2bSQ(T LtDnm{r-UW|Tp3Nf literal 0 HcmV?d00001 diff --git a/docs_src/_build/html/_static/up.png b/docs_src/_build/html/_static/up.png new file mode 100644 index 0000000000000000000000000000000000000000..2a940a7da7c14e6a36901e83306849ba7efad4d4 GIT binary patch literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6CV9FzhEy=Fov?Lbi-SbV{M7eb zSgRCN7I%METfw=?;;+>WH3cj0g7WUX+WNUO*ZcGT`ytIgVd8OSIh$j5tP~Z0O{ng4 zcW5}i$^L-SndMiXU*q89_#FKDQg!+}n<sY{bt~lf29~d`d|30$ek+#&XF;JwVZw1v z_UR0p3#2)&`AF%iuMw0u8SEq};^+A5QF+L(`y7{#wyduS<qiY7j=|H_&t;ucLK6TJ CK~C2I literal 0 HcmV?d00001 diff --git a/docs_src/_build/html/_static/websupport.js b/docs_src/_build/html/_static/websupport.js new file mode 100644 index 0000000..3b4999e --- /dev/null +++ b/docs_src/_build/html/_static/websupport.js @@ -0,0 +1,808 @@ +/* + * websupport.js + * ~~~~~~~~~~~~~ + * + * sphinx.websupport utilities for all documentation. + * + * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +(function($) { + $.fn.autogrow = function() { + return this.each(function() { + var textarea = this; + + $.fn.autogrow.resize(textarea); + + $(textarea) + .focus(function() { + textarea.interval = setInterval(function() { + $.fn.autogrow.resize(textarea); + }, 500); + }) + .blur(function() { + clearInterval(textarea.interval); + }); + }); + }; + + $.fn.autogrow.resize = function(textarea) { + var lineHeight = parseInt($(textarea).css('line-height'), 10); + var lines = textarea.value.split('\n'); + var columns = textarea.cols; + var lineCount = 0; + $.each(lines, function() { + lineCount += Math.ceil(this.length / columns) || 1; + }); + var height = lineHeight * (lineCount + 1); + $(textarea).css('height', height); + }; +})(jQuery); + +(function($) { + var comp, by; + + function init() { + initEvents(); + initComparator(); + } + + function initEvents() { + $(document).on("click", 'a.comment-close', function(event) { + event.preventDefault(); + hide($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.vote', function(event) { + event.preventDefault(); + handleVote($(this)); + }); + $(document).on("click", 'a.reply', function(event) { + event.preventDefault(); + openReply($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.close-reply', function(event) { + event.preventDefault(); + closeReply($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.sort-option', function(event) { + event.preventDefault(); + handleReSort($(this)); + }); + $(document).on("click", 'a.show-proposal', function(event) { + event.preventDefault(); + showProposal($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.hide-proposal', function(event) { + event.preventDefault(); + hideProposal($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.show-propose-change', function(event) { + event.preventDefault(); + showProposeChange($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.hide-propose-change', function(event) { + event.preventDefault(); + hideProposeChange($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.accept-comment', function(event) { + event.preventDefault(); + acceptComment($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.delete-comment', function(event) { + event.preventDefault(); + deleteComment($(this).attr('id').substring(2)); + }); + $(document).on("click", 'a.comment-markup', function(event) { + event.preventDefault(); + toggleCommentMarkupBox($(this).attr('id').substring(2)); + }); + } + + /** + * Set comp, which is a comparator function used for sorting and + * inserting comments into the list. + */ + function setComparator() { + // If the first three letters are "asc", sort in ascending order + // and remove the prefix. + if (by.substring(0,3) == 'asc') { + var i = by.substring(3); + comp = function(a, b) { return a[i] - b[i]; }; + } else { + // Otherwise sort in descending order. + comp = function(a, b) { return b[by] - a[by]; }; + } + + // Reset link styles and format the selected sort option. + $('a.sel').attr('href', '#').removeClass('sel'); + $('a.by' + by).removeAttr('href').addClass('sel'); + } + + /** + * Create a comp function. If the user has preferences stored in + * the sortBy cookie, use those, otherwise use the default. + */ + function initComparator() { + by = 'rating'; // Default to sort by rating. + // If the sortBy cookie is set, use that instead. + if (document.cookie.length > 0) { + var start = document.cookie.indexOf('sortBy='); + if (start != -1) { + start = start + 7; + var end = document.cookie.indexOf(";", start); + if (end == -1) { + end = document.cookie.length; + by = unescape(document.cookie.substring(start, end)); + } + } + } + setComparator(); + } + + /** + * Show a comment div. + */ + function show(id) { + $('#ao' + id).hide(); + $('#ah' + id).show(); + var context = $.extend({id: id}, opts); + var popup = $(renderTemplate(popupTemplate, context)).hide(); + popup.find('textarea[name="proposal"]').hide(); + popup.find('a.by' + by).addClass('sel'); + var form = popup.find('#cf' + id); + form.submit(function(event) { + event.preventDefault(); + addComment(form); + }); + $('#s' + id).after(popup); + popup.slideDown('fast', function() { + getComments(id); + }); + } + + /** + * Hide a comment div. + */ + function hide(id) { + $('#ah' + id).hide(); + $('#ao' + id).show(); + var div = $('#sc' + id); + div.slideUp('fast', function() { + div.remove(); + }); + } + + /** + * Perform an ajax request to get comments for a node + * and insert the comments into the comments tree. + */ + function getComments(id) { + $.ajax({ + type: 'GET', + url: opts.getCommentsURL, + data: {node: id}, + success: function(data, textStatus, request) { + var ul = $('#cl' + id); + var speed = 100; + $('#cf' + id) + .find('textarea[name="proposal"]') + .data('source', data.source); + + if (data.comments.length === 0) { + ul.html('<li>No comments yet.</li>'); + ul.data('empty', true); + } else { + // If there are comments, sort them and put them in the list. + var comments = sortComments(data.comments); + speed = data.comments.length * 100; + appendComments(comments, ul); + ul.data('empty', false); + } + $('#cn' + id).slideUp(speed + 200); + ul.slideDown(speed); + }, + error: function(request, textStatus, error) { + showError('Oops, there was a problem retrieving the comments.'); + }, + dataType: 'json' + }); + } + + /** + * Add a comment via ajax and insert the comment into the comment tree. + */ + function addComment(form) { + var node_id = form.find('input[name="node"]').val(); + var parent_id = form.find('input[name="parent"]').val(); + var text = form.find('textarea[name="comment"]').val(); + var proposal = form.find('textarea[name="proposal"]').val(); + + if (text == '') { + showError('Please enter a comment.'); + return; + } + + // Disable the form that is being submitted. + form.find('textarea,input').attr('disabled', 'disabled'); + + // Send the comment to the server. + $.ajax({ + type: "POST", + url: opts.addCommentURL, + dataType: 'json', + data: { + node: node_id, + parent: parent_id, + text: text, + proposal: proposal + }, + success: function(data, textStatus, error) { + // Reset the form. + if (node_id) { + hideProposeChange(node_id); + } + form.find('textarea') + .val('') + .add(form.find('input')) + .removeAttr('disabled'); + var ul = $('#cl' + (node_id || parent_id)); + if (ul.data('empty')) { + $(ul).empty(); + ul.data('empty', false); + } + insertComment(data.comment); + var ao = $('#ao' + node_id); + ao.find('img').attr({'src': opts.commentBrightImage}); + if (node_id) { + // if this was a "root" comment, remove the commenting box + // (the user can get it back by reopening the comment popup) + $('#ca' + node_id).slideUp(); + } + }, + error: function(request, textStatus, error) { + form.find('textarea,input').removeAttr('disabled'); + showError('Oops, there was a problem adding the comment.'); + } + }); + } + + /** + * Recursively append comments to the main comment list and children + * lists, creating the comment tree. + */ + function appendComments(comments, ul) { + $.each(comments, function() { + var div = createCommentDiv(this); + ul.append($(document.createElement('li')).html(div)); + appendComments(this.children, div.find('ul.comment-children')); + // To avoid stagnating data, don't store the comments children in data. + this.children = null; + div.data('comment', this); + }); + } + + /** + * After adding a new comment, it must be inserted in the correct + * location in the comment tree. + */ + function insertComment(comment) { + var div = createCommentDiv(comment); + + // To avoid stagnating data, don't store the comments children in data. + comment.children = null; + div.data('comment', comment); + + var ul = $('#cl' + (comment.node || comment.parent)); + var siblings = getChildren(ul); + + var li = $(document.createElement('li')); + li.hide(); + + // Determine where in the parents children list to insert this comment. + for(var i=0; i < siblings.length; i++) { + if (comp(comment, siblings[i]) <= 0) { + $('#cd' + siblings[i].id) + .parent() + .before(li.html(div)); + li.slideDown('fast'); + return; + } + } + + // If we get here, this comment rates lower than all the others, + // or it is the only comment in the list. + ul.append(li.html(div)); + li.slideDown('fast'); + } + + function acceptComment(id) { + $.ajax({ + type: 'POST', + url: opts.acceptCommentURL, + data: {id: id}, + success: function(data, textStatus, request) { + $('#cm' + id).fadeOut('fast'); + $('#cd' + id).removeClass('moderate'); + }, + error: function(request, textStatus, error) { + showError('Oops, there was a problem accepting the comment.'); + } + }); + } + + function deleteComment(id) { + $.ajax({ + type: 'POST', + url: opts.deleteCommentURL, + data: {id: id}, + success: function(data, textStatus, request) { + var div = $('#cd' + id); + if (data == 'delete') { + // Moderator mode: remove the comment and all children immediately + div.slideUp('fast', function() { + div.remove(); + }); + return; + } + // User mode: only mark the comment as deleted + div + .find('span.user-id:first') + .text('[deleted]').end() + .find('div.comment-text:first') + .text('[deleted]').end() + .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id + + ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id) + .remove(); + var comment = div.data('comment'); + comment.username = '[deleted]'; + comment.text = '[deleted]'; + div.data('comment', comment); + }, + error: function(request, textStatus, error) { + showError('Oops, there was a problem deleting the comment.'); + } + }); + } + + function showProposal(id) { + $('#sp' + id).hide(); + $('#hp' + id).show(); + $('#pr' + id).slideDown('fast'); + } + + function hideProposal(id) { + $('#hp' + id).hide(); + $('#sp' + id).show(); + $('#pr' + id).slideUp('fast'); + } + + function showProposeChange(id) { + $('#pc' + id).hide(); + $('#hc' + id).show(); + var textarea = $('#pt' + id); + textarea.val(textarea.data('source')); + $.fn.autogrow.resize(textarea[0]); + textarea.slideDown('fast'); + } + + function hideProposeChange(id) { + $('#hc' + id).hide(); + $('#pc' + id).show(); + var textarea = $('#pt' + id); + textarea.val('').removeAttr('disabled'); + textarea.slideUp('fast'); + } + + function toggleCommentMarkupBox(id) { + $('#mb' + id).toggle(); + } + + /** Handle when the user clicks on a sort by link. */ + function handleReSort(link) { + var classes = link.attr('class').split(/\s+/); + for (var i=0; i<classes.length; i++) { + if (classes[i] != 'sort-option') { + by = classes[i].substring(2); + } + } + setComparator(); + // Save/update the sortBy cookie. + var expiration = new Date(); + expiration.setDate(expiration.getDate() + 365); + document.cookie= 'sortBy=' + escape(by) + + ';expires=' + expiration.toUTCString(); + $('ul.comment-ul').each(function(index, ul) { + var comments = getChildren($(ul), true); + comments = sortComments(comments); + appendComments(comments, $(ul).empty()); + }); + } + + /** + * Function to process a vote when a user clicks an arrow. + */ + function handleVote(link) { + if (!opts.voting) { + showError("You'll need to login to vote."); + return; + } + + var id = link.attr('id'); + if (!id) { + // Didn't click on one of the voting arrows. + return; + } + // If it is an unvote, the new vote value is 0, + // Otherwise it's 1 for an upvote, or -1 for a downvote. + var value = 0; + if (id.charAt(1) != 'u') { + value = id.charAt(0) == 'u' ? 1 : -1; + } + // The data to be sent to the server. + var d = { + comment_id: id.substring(2), + value: value + }; + + // Swap the vote and unvote links. + link.hide(); + $('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id) + .show(); + + // The div the comment is displayed in. + var div = $('div#cd' + d.comment_id); + var data = div.data('comment'); + + // If this is not an unvote, and the other vote arrow has + // already been pressed, unpress it. + if ((d.value !== 0) && (data.vote === d.value * -1)) { + $('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide(); + $('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show(); + } + + // Update the comments rating in the local data. + data.rating += (data.vote === 0) ? d.value : (d.value - data.vote); + data.vote = d.value; + div.data('comment', data); + + // Change the rating text. + div.find('.rating:first') + .text(data.rating + ' point' + (data.rating == 1 ? '' : 's')); + + // Send the vote information to the server. + $.ajax({ + type: "POST", + url: opts.processVoteURL, + data: d, + error: function(request, textStatus, error) { + showError('Oops, there was a problem casting that vote.'); + } + }); + } + + /** + * Open a reply form used to reply to an existing comment. + */ + function openReply(id) { + // Swap out the reply link for the hide link + $('#rl' + id).hide(); + $('#cr' + id).show(); + + // Add the reply li to the children ul. + var div = $(renderTemplate(replyTemplate, {id: id})).hide(); + $('#cl' + id) + .prepend(div) + // Setup the submit handler for the reply form. + .find('#rf' + id) + .submit(function(event) { + event.preventDefault(); + addComment($('#rf' + id)); + closeReply(id); + }) + .find('input[type=button]') + .click(function() { + closeReply(id); + }); + div.slideDown('fast', function() { + $('#rf' + id).find('textarea').focus(); + }); + } + + /** + * Close the reply form opened with openReply. + */ + function closeReply(id) { + // Remove the reply div from the DOM. + $('#rd' + id).slideUp('fast', function() { + $(this).remove(); + }); + + // Swap out the hide link for the reply link + $('#cr' + id).hide(); + $('#rl' + id).show(); + } + + /** + * Recursively sort a tree of comments using the comp comparator. + */ + function sortComments(comments) { + comments.sort(comp); + $.each(comments, function() { + this.children = sortComments(this.children); + }); + return comments; + } + + /** + * Get the children comments from a ul. If recursive is true, + * recursively include childrens' children. + */ + function getChildren(ul, recursive) { + var children = []; + ul.children().children("[id^='cd']") + .each(function() { + var comment = $(this).data('comment'); + if (recursive) + comment.children = getChildren($(this).find('#cl' + comment.id), true); + children.push(comment); + }); + return children; + } + + /** Create a div to display a comment in. */ + function createCommentDiv(comment) { + if (!comment.displayed && !opts.moderator) { + return $('<div class="moderate">Thank you! Your comment will show up ' + + 'once it is has been approved by a moderator.</div>'); + } + // Prettify the comment rating. + comment.pretty_rating = comment.rating + ' point' + + (comment.rating == 1 ? '' : 's'); + // Make a class (for displaying not yet moderated comments differently) + comment.css_class = comment.displayed ? '' : ' moderate'; + // Create a div for this comment. + var context = $.extend({}, opts, comment); + var div = $(renderTemplate(commentTemplate, context)); + + // If the user has voted on this comment, highlight the correct arrow. + if (comment.vote) { + var direction = (comment.vote == 1) ? 'u' : 'd'; + div.find('#' + direction + 'v' + comment.id).hide(); + div.find('#' + direction + 'u' + comment.id).show(); + } + + if (opts.moderator || comment.text != '[deleted]') { + div.find('a.reply').show(); + if (comment.proposal_diff) + div.find('#sp' + comment.id).show(); + if (opts.moderator && !comment.displayed) + div.find('#cm' + comment.id).show(); + if (opts.moderator || (opts.username == comment.username)) + div.find('#dc' + comment.id).show(); + } + return div; + } + + /** + * A simple template renderer. Placeholders such as <%id%> are replaced + * by context['id'] with items being escaped. Placeholders such as <#id#> + * are not escaped. + */ + function renderTemplate(template, context) { + var esc = $(document.createElement('div')); + + function handle(ph, escape) { + var cur = context; + $.each(ph.split('.'), function() { + cur = cur[this]; + }); + return escape ? esc.text(cur || "").html() : cur; + } + + return template.replace(/<([%#])([\w\.]*)\1>/g, function() { + return handle(arguments[2], arguments[1] == '%' ? true : false); + }); + } + + /** Flash an error message briefly. */ + function showError(message) { + $(document.createElement('div')).attr({'class': 'popup-error'}) + .append($(document.createElement('div')) + .attr({'class': 'error-message'}).text(message)) + .appendTo('body') + .fadeIn("slow") + .delay(2000) + .fadeOut("slow"); + } + + /** Add a link the user uses to open the comments popup. */ + $.fn.comment = function() { + return this.each(function() { + var id = $(this).attr('id').substring(1); + var count = COMMENT_METADATA[id]; + var title = count + ' comment' + (count == 1 ? '' : 's'); + var image = count > 0 ? opts.commentBrightImage : opts.commentImage; + var addcls = count == 0 ? ' nocomment' : ''; + $(this) + .append( + $(document.createElement('a')).attr({ + href: '#', + 'class': 'sphinx-comment-open' + addcls, + id: 'ao' + id + }) + .append($(document.createElement('img')).attr({ + src: image, + alt: 'comment', + title: title + })) + .click(function(event) { + event.preventDefault(); + show($(this).attr('id').substring(2)); + }) + ) + .append( + $(document.createElement('a')).attr({ + href: '#', + 'class': 'sphinx-comment-close hidden', + id: 'ah' + id + }) + .append($(document.createElement('img')).attr({ + src: opts.closeCommentImage, + alt: 'close', + title: 'close' + })) + .click(function(event) { + event.preventDefault(); + hide($(this).attr('id').substring(2)); + }) + ); + }); + }; + + var opts = { + processVoteURL: '/_process_vote', + addCommentURL: '/_add_comment', + getCommentsURL: '/_get_comments', + acceptCommentURL: '/_accept_comment', + deleteCommentURL: '/_delete_comment', + commentImage: '/static/_static/comment.png', + closeCommentImage: '/static/_static/comment-close.png', + loadingImage: '/static/_static/ajax-loader.gif', + commentBrightImage: '/static/_static/comment-bright.png', + upArrow: '/static/_static/up.png', + downArrow: '/static/_static/down.png', + upArrowPressed: '/static/_static/up-pressed.png', + downArrowPressed: '/static/_static/down-pressed.png', + voting: false, + moderator: false + }; + + if (typeof COMMENT_OPTIONS != "undefined") { + opts = jQuery.extend(opts, COMMENT_OPTIONS); + } + + var popupTemplate = '\ + <div class="sphinx-comments" id="sc<%id%>">\ + <p class="sort-options">\ + Sort by:\ + <a href="#" class="sort-option byrating">best rated</a>\ + <a href="#" class="sort-option byascage">newest</a>\ + <a href="#" class="sort-option byage">oldest</a>\ + </p>\ + <div class="comment-header">Comments</div>\ + <div class="comment-loading" id="cn<%id%>">\ + loading comments... <img src="<%loadingImage%>" alt="" /></div>\ + <ul id="cl<%id%>" class="comment-ul"></ul>\ + <div id="ca<%id%>">\ + <p class="add-a-comment">Add a comment\ + (<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\ + <div class="comment-markup-box" id="mb<%id%>">\ + reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \ + <code>``code``</code>, \ + code blocks: <code>::</code> and an indented block after blank line</div>\ + <form method="post" id="cf<%id%>" class="comment-form" action="">\ + <textarea name="comment" cols="80"></textarea>\ + <p class="propose-button">\ + <a href="#" id="pc<%id%>" class="show-propose-change">\ + Propose a change ▹\ + </a>\ + <a href="#" id="hc<%id%>" class="hide-propose-change">\ + Propose a change ▿\ + </a>\ + </p>\ + <textarea name="proposal" id="pt<%id%>" cols="80"\ + spellcheck="false"></textarea>\ + <input type="submit" value="Add comment" />\ + <input type="hidden" name="node" value="<%id%>" />\ + <input type="hidden" name="parent" value="" />\ + </form>\ + </div>\ + </div>'; + + var commentTemplate = '\ + <div id="cd<%id%>" class="sphinx-comment<%css_class%>">\ + <div class="vote">\ + <div class="arrow">\ + <a href="#" id="uv<%id%>" class="vote" title="vote up">\ + <img src="<%upArrow%>" />\ + </a>\ + <a href="#" id="uu<%id%>" class="un vote" title="vote up">\ + <img src="<%upArrowPressed%>" />\ + </a>\ + </div>\ + <div class="arrow">\ + <a href="#" id="dv<%id%>" class="vote" title="vote down">\ + <img src="<%downArrow%>" id="da<%id%>" />\ + </a>\ + <a href="#" id="du<%id%>" class="un vote" title="vote down">\ + <img src="<%downArrowPressed%>" />\ + </a>\ + </div>\ + </div>\ + <div class="comment-content">\ + <p class="tagline comment">\ + <span class="user-id"><%username%></span>\ + <span class="rating"><%pretty_rating%></span>\ + <span class="delta"><%time.delta%></span>\ + </p>\ + <div class="comment-text comment"><#text#></div>\ + <p class="comment-opts comment">\ + <a href="#" class="reply hidden" id="rl<%id%>">reply ▹</a>\ + <a href="#" class="close-reply" id="cr<%id%>">reply ▿</a>\ + <a href="#" id="sp<%id%>" class="show-proposal">proposal ▹</a>\ + <a href="#" id="hp<%id%>" class="hide-proposal">proposal ▿</a>\ + <a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\ + <span id="cm<%id%>" class="moderation hidden">\ + <a href="#" id="ac<%id%>" class="accept-comment">accept</a>\ + </span>\ + </p>\ + <pre class="proposal" id="pr<%id%>">\ +<#proposal_diff#>\ + </pre>\ + <ul class="comment-children" id="cl<%id%>"></ul>\ + </div>\ + <div class="clearleft"></div>\ + </div>\ + </div>'; + + var replyTemplate = '\ + <li>\ + <div class="reply-div" id="rd<%id%>">\ + <form id="rf<%id%>">\ + <textarea name="comment" cols="80"></textarea>\ + <input type="submit" value="Add reply" />\ + <input type="button" value="Cancel" />\ + <input type="hidden" name="parent" value="<%id%>" />\ + <input type="hidden" name="node" value="" />\ + </form>\ + </div>\ + </li>'; + + $(document).ready(function() { + init(); + }); +})(jQuery); + +$(document).ready(function() { + // add comment anchors for all paragraphs that are commentable + $('.sphinx-has-comment').comment(); + + // highlight search words in search results + $("div.context").each(function() { + var params = $.getQueryParameters(); + var terms = (params.q) ? params.q[0].split(/\s+/) : []; + var result = $(this); + $.each(terms, function() { + result.highlightText(this.toLowerCase(), 'highlighted'); + }); + }); + + // directly open comment window if requested + var anchor = document.location.hash; + if (anchor.substring(0, 9) == '#comment-') { + $('#ao' + anchor.substring(9)).click(); + document.location.hash = '#s' + anchor.substring(9); + } +}); diff --git a/docs_src/_build/html/cfelpyutils.crystfel_utils.html b/docs_src/_build/html/cfelpyutils.crystfel_utils.html new file mode 100644 index 0000000..d162d9e --- /dev/null +++ b/docs_src/_build/html/cfelpyutils.crystfel_utils.html @@ -0,0 +1,148 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>The crystfel_utils Module — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + <link rel="next" title="The geometry_utils Module" href="cfelpyutils.geometry_utils.html" /> + <link rel="prev" title="The cfelpyutils Package" href="cfelpyutils.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <div class="section" id="module-cfelpyutils.crystfel_utils"> +<span id="the-crystfel-utils-module"></span><h1>The crystfel_utils Module<a class="headerlink" href="#module-cfelpyutils.crystfel_utils" title="Permalink to this headline">¶</a></h1> +<p>CrystFEL utilities.</p> +<p>This module contains Python reimplementations of some functions from the <a class="reference external" href="http://www.desy.de/~twhite/crystfel">CrystFEL</a> software package.</p> +<dl class="function"> +<dt id="cfelpyutils.crystfel_utils.load_crystfel_geometry"> +<code class="descname">load_crystfel_geometry</code><span class="sig-paren">(</span><em>filename</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/cfelpyutils/crystfel_utils.html#load_crystfel_geometry"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#cfelpyutils.crystfel_utils.load_crystfel_geometry" title="Permalink to this definition">¶</a></dt> +<dd><p>Loads a CrystFEL geometry file.</p> +<p>This function is a reimplementation of the get_detector_geometry_2 function from +CrystFEL. It reads information from a CrystFEL geometry file.</p> +<p>For a full documentation of the CrystFEL geometry format, see the relevant <a class="reference external" href="http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html">man +page</a>.</p> +<p>The function returns a dictionary with the geometry information.</p> +<ul class="simple"> +<li>The CrystFEL geometry file uses a key/value language. The keys in the returned +dictionary match the keys in the geometry file.</li> +<li>The dictionary values store the corresponding values.</li> +<li>The code of this function is currently synchronized with the code of the function +‘get_detector_geometry_2’ in CrystFEL at commit 41a8fa9819010.</li> +</ul> +<table class="docutils field-list" frame="void" rules="none"> +<col class="field-name" /> +<col class="field-body" /> +<tbody valign="top"> +<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>filename</strong> (<em>str</em>) – the absolute or relative path to a CrystFEL geometry file.</td> +</tr> +<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">a dictionary with the geometry information loaded from the +file.</td> +</tr> +<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">Dict[str, Any]</td> +</tr> +</tbody> +</table> +</dd></dl> + +</div> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul class="current"> +<li class="toctree-l1 current"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a><ul class="current"> +<li class="toctree-l2 current"><a class="current reference internal" href="#">crystfel_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.geometry_utils.html">geometry_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.named_tuples.html">named_tuples</a></li> +</ul> +</li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + <li><a href="cfelpyutils.html">The cfelpyutils Package</a><ul> + <li>Previous: <a href="cfelpyutils.html" title="previous chapter">The cfelpyutils Package</a></li> + <li>Next: <a href="cfelpyutils.geometry_utils.html" title="next chapter">The geometry_utils Module</a></li> + </ul></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs_src/_build/html/cfelpyutils.geometry_utils.html b/docs_src/_build/html/cfelpyutils.geometry_utils.html new file mode 100644 index 0000000..77c72d0 --- /dev/null +++ b/docs_src/_build/html/cfelpyutils.geometry_utils.html @@ -0,0 +1,214 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>The geometry_utils Module — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + <link rel="next" title="The named_tuples Module" href="cfelpyutils.named_tuples.html" /> + <link rel="prev" title="The crystfel_utils Module" href="cfelpyutils.crystfel_utils.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <div class="section" id="module-cfelpyutils.geometry_utils"> +<span id="the-geometry-utils-module"></span><h1>The geometry_utils Module<a class="headerlink" href="#module-cfelpyutils.geometry_utils" title="Permalink to this headline">¶</a></h1> +<p>Geometry utilities.</p> +<p>This module contains functions that manipulate geometry information.</p> +<dl class="function"> +<dt id="cfelpyutils.geometry_utils.compute_pix_maps"> +<code class="descname">compute_pix_maps</code><span class="sig-paren">(</span><em>geometry</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/cfelpyutils/geometry_utils.html#compute_pix_maps"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#cfelpyutils.geometry_utils.compute_pix_maps" title="Permalink to this definition">¶</a></dt> +<dd><p>Computes pixel maps from CrystFEL geometry information.</p> +<p>This function takes as input some geometry information read from a <a class="reference external" href="http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html">CrystFEL</a> file, and +returns a set of some pre-computed pixel maps.</p> +<p>The origin and the orientation of the reference system for the pixel maps follow +the same conventions as in CrystFEL:</p> +<ul class="simple"> +<li>The center of the reference system is the beam interaction point.</li> +<li>+z is the beam direction, and points along the beam (i.e. away from the source).</li> +<li>+y points towards the zenith (ceiling).</li> +<li>+x completes the right-handed coordinate system.</li> +</ul> +<table class="docutils field-list" frame="void" rules="none"> +<col class="field-name" /> +<col class="field-body" /> +<tbody valign="top"> +<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>geometry</strong> (<em>Dict</em><em>[</em><em>str</em><em>, </em><em>Any</em><em>]</em>) – a CrystFEL geometry object (A dictionary returned by +the <a class="reference internal" href="cfelpyutils.crystfel_utils.html#cfelpyutils.crystfel_utils.load_crystfel_geometry" title="cfelpyutils.crystfel_utils.load_crystfel_geometry"><code class="xref py py-func docutils literal notranslate"><span class="pre">load_crystfel_geometry()</span></code></a> function).</td> +</tr> +<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">a named tuple storing the the +pixel maps.</td> +</tr> +<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><a class="reference internal" href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps" title="cfelpyutils.named_tuples.PixelMaps"><code class="xref py py-class docutils literal notranslate"><span class="pre">PixelMaps</span></code></a></td> +</tr> +</tbody> +</table> +</dd></dl> + +<dl class="function"> +<dt id="cfelpyutils.geometry_utils.compute_visualization_pix_maps"> +<code class="descname">compute_visualization_pix_maps</code><span class="sig-paren">(</span><em>geometry</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/cfelpyutils/geometry_utils.html#compute_visualization_pix_maps"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#cfelpyutils.geometry_utils.compute_visualization_pix_maps" title="Permalink to this definition">¶</a></dt> +<dd><p>Computes pixel maps for data visualization from CrystFEL geometry information.</p> +<p>This function takes as input some geometry information read from a <a class="reference external" href="http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html">CrystFEL</a> file, and +returns a set of some pre-computed pixel maps that can be used to display data in +an ImageView widget from the <a class="reference external" href="http://pyqtgraph.org/">PyQtGraph</a> library.</p> +<p>These pixel maps are different from the ones generated by the +<a class="reference internal" href="#cfelpyutils.geometry_utils.compute_pix_maps" title="cfelpyutils.geometry_utils.compute_pix_maps"><code class="xref py py-func docutils literal notranslate"><span class="pre">compute_pix_maps()</span></code></a> function. The main differences are:</p> +<ul class="simple"> +<li>The origin of the reference system is not the beam interaction point, but the top +left corner of the array used to visualize the data.</li> +<li>Only the x and y pixel maps are available. The other entries in the named tuple +(z, r and phi) are set to None.</li> +</ul> +<table class="docutils field-list" frame="void" rules="none"> +<col class="field-name" /> +<col class="field-body" /> +<tbody valign="top"> +<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>geometry</strong> (<em>Dict</em><em>[</em><em>str</em><em>, </em><em>Any</em><em>]</em>) – a CrystFEL geometry object (A dictionary returned by +the <a class="reference internal" href="cfelpyutils.crystfel_utils.html#cfelpyutils.crystfel_utils.load_crystfel_geometry" title="cfelpyutils.crystfel_utils.load_crystfel_geometry"><code class="xref py py-func docutils literal notranslate"><span class="pre">load_crystfel_geometry()</span></code></a> function).</td> +</tr> +<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">a named tuple with the pixel maps.</td> +</tr> +<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><code class="xref py py-class docutils literal notranslate"><span class="pre">PixelMaps</span></code></td> +</tr> +</tbody> +</table> +</dd></dl> + +<dl class="function"> +<dt id="cfelpyutils.geometry_utils.apply_geometry_to_data"> +<code class="descname">apply_geometry_to_data</code><span class="sig-paren">(</span><em>data</em>, <em>geometry</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/cfelpyutils/geometry_utils.html#apply_geometry_to_data"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#cfelpyutils.geometry_utils.apply_geometry_to_data" title="Permalink to this definition">¶</a></dt> +<dd><p>Applies CrystFEL geometry information to some data.</p> +<p>This function takes as input some geometry information read from a <a class="reference external" href="http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html">CrystFEL</a> file, and +some data on which to apply it. It returns an array that can be displayed using a +library like <a class="reference external" href="https://matplotlib.org/">matplotlib</a> or +<a class="reference external" href="http://pyqtgraph.org/">PyQtGraph</a>.</p> +<p>The shape of the returned array is big enough to display all the input pixel +values, and is symmetric around the center of the reference system (i.e: the beam +interaction point).</p> +<p>NOTE: This restrictions often cause the returned array to be bigger than the minimum +size needed to store the physical layout of the pixels in the detector, +particularly if the detector is not centered at the beam interaction point.</p> +<table class="docutils field-list" frame="void" rules="none"> +<col class="field-name" /> +<col class="field-body" /> +<tbody valign="top"> +<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple"> +<li><strong>data</strong> (<em>numpy.ndarray</em>) – the data on which the geometry information should be +applied.</li> +<li><strong>geometry</strong> (<em>Dict</em><em>[</em><em>str</em><em>, </em><em>Any</em><em>]</em>) – a CrystFEL geometry object (A dictionary returned by +the <a class="reference internal" href="cfelpyutils.crystfel_utils.html#cfelpyutils.crystfel_utils.load_crystfel_geometry" title="cfelpyutils.crystfel_utils.load_crystfel_geometry"><code class="xref py py-func docutils literal notranslate"><span class="pre">load_crystfel_geometry()</span></code></a> function).</li> +</ul> +</td> +</tr> +<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">an array containing the data with the geometry information +applied.</p> +</td> +</tr> +<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">numpy.ndarray</p> +</td> +</tr> +</tbody> +</table> +</dd></dl> + +</div> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul class="current"> +<li class="toctree-l1 current"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a><ul class="current"> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.crystfel_utils.html">crystfel_utils</a></li> +<li class="toctree-l2 current"><a class="current reference internal" href="#">geometry_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.named_tuples.html">named_tuples</a></li> +</ul> +</li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + <li><a href="cfelpyutils.html">The cfelpyutils Package</a><ul> + <li>Previous: <a href="cfelpyutils.crystfel_utils.html" title="previous chapter">The crystfel_utils Module</a></li> + <li>Next: <a href="cfelpyutils.named_tuples.html" title="next chapter">The named_tuples Module</a></li> + </ul></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs_src/_build/html/cfelpyutils.html b/docs_src/_build/html/cfelpyutils.html new file mode 100644 index 0000000..24ffb50 --- /dev/null +++ b/docs_src/_build/html/cfelpyutils.html @@ -0,0 +1,121 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>The cfelpyutils Package — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + <link rel="next" title="The crystfel_utils Module" href="cfelpyutils.crystfel_utils.html" /> + <link rel="prev" title="CFELPyUtils" href="index.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <div class="section" id="module-cfelpyutils"> +<span id="the-cfelpyutils-package"></span><h1>The cfelpyutils Package<a class="headerlink" href="#module-cfelpyutils" title="Permalink to this headline">¶</a></h1> +<p>The main CFELPyUtils package, which contains the whole library.</p> +<div class="toctree-wrapper compound"> +<ul> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.crystfel_utils.html">crystfel_utils</a></li> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.geometry_utils.html">geometry_utils</a></li> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.named_tuples.html">named_tuples</a></li> +</ul> +</div> +</div> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul class="current"> +<li class="toctree-l1 current"><a class="current reference internal" href="#">The cfelpyutils Package</a><ul> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.crystfel_utils.html">crystfel_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.geometry_utils.html">geometry_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.named_tuples.html">named_tuples</a></li> +</ul> +</li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + <li>Previous: <a href="index.html" title="previous chapter">CFELPyUtils</a></li> + <li>Next: <a href="cfelpyutils.crystfel_utils.html" title="next chapter">The crystfel_utils Module</a></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs_src/_build/html/cfelpyutils.named_tuples.html b/docs_src/_build/html/cfelpyutils.named_tuples.html new file mode 100644 index 0000000..d992c10 --- /dev/null +++ b/docs_src/_build/html/cfelpyutils.named_tuples.html @@ -0,0 +1,170 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>The named_tuples Module — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + <link rel="prev" title="The geometry_utils Module" href="cfelpyutils.geometry_utils.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <div class="section" id="module-cfelpyutils.named_tuples"> +<span id="the-named-tuples-module"></span><h1>The named_tuples Module<a class="headerlink" href="#module-cfelpyutils.named_tuples" title="Permalink to this headline">¶</a></h1> +<p>CFELPyUtils named tuples.</p> +<p>This module contains a collection of named tuples used throughout the CFELPyUtils +library.</p> +<dl class="class"> +<dt id="cfelpyutils.named_tuples.PixelMaps"> +<em class="property">class </em><code class="descname">PixelMaps</code><a class="headerlink" href="#cfelpyutils.named_tuples.PixelMaps" title="Permalink to this definition">¶</a></dt> +<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">tuple</span></code></p> +<p>Pixel maps that store geometry information.</p> +<table class="docutils field-list" frame="void" rules="none"> +<col class="field-name" /> +<col class="field-body" /> +<tbody valign="top"> +<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple"> +<li><strong>x</strong> (<em>numpy.ndarray</em>) – pixel map for the x coordinate.</li> +<li><strong>y</strong> (<em>numpy.ndarray</em>) – pixel map for the y coordinate.</li> +<li><strong>z</strong> (<em>numpy.ndarray</em>) – pixel map for the z coordinate.</li> +<li><strong>r</strong> (<em>numpy.ndarray</em>) – pixel map storing the distance of each pixel from the center of +the reference system.</li> +<li><strong>phi</strong> (<em>numpy.ndarray</em>) – pixel map storing the amplitude of the angle between each +pixel, the center of the reference system, and the x axis through the center.</li> +</ul> +</td> +</tr> +</tbody> +</table> +<dl class="attribute"> +<dt id="cfelpyutils.named_tuples.PixelMaps.phi"> +<code class="descname">phi</code><a class="headerlink" href="#cfelpyutils.named_tuples.PixelMaps.phi" title="Permalink to this definition">¶</a></dt> +<dd><p>Alias for field number 4</p> +</dd></dl> + +<dl class="attribute"> +<dt id="cfelpyutils.named_tuples.PixelMaps.r"> +<code class="descname">r</code><a class="headerlink" href="#cfelpyutils.named_tuples.PixelMaps.r" title="Permalink to this definition">¶</a></dt> +<dd><p>Alias for field number 3</p> +</dd></dl> + +<dl class="attribute"> +<dt id="cfelpyutils.named_tuples.PixelMaps.x"> +<code class="descname">x</code><a class="headerlink" href="#cfelpyutils.named_tuples.PixelMaps.x" title="Permalink to this definition">¶</a></dt> +<dd><p>Alias for field number 0</p> +</dd></dl> + +<dl class="attribute"> +<dt id="cfelpyutils.named_tuples.PixelMaps.y"> +<code class="descname">y</code><a class="headerlink" href="#cfelpyutils.named_tuples.PixelMaps.y" title="Permalink to this definition">¶</a></dt> +<dd><p>Alias for field number 1</p> +</dd></dl> + +<dl class="attribute"> +<dt id="cfelpyutils.named_tuples.PixelMaps.z"> +<code class="descname">z</code><a class="headerlink" href="#cfelpyutils.named_tuples.PixelMaps.z" title="Permalink to this definition">¶</a></dt> +<dd><p>Alias for field number 2</p> +</dd></dl> + +</dd></dl> + +</div> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul class="current"> +<li class="toctree-l1 current"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a><ul class="current"> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.crystfel_utils.html">crystfel_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.geometry_utils.html">geometry_utils</a></li> +<li class="toctree-l2 current"><a class="current reference internal" href="#">named_tuples</a></li> +</ul> +</li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + <li><a href="cfelpyutils.html">The cfelpyutils Package</a><ul> + <li>Previous: <a href="cfelpyutils.geometry_utils.html" title="previous chapter">The geometry_utils Module</a></li> + </ul></li> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs_src/_build/html/genindex.html b/docs_src/_build/html/genindex.html new file mode 100644 index 0000000..c2a43c1 --- /dev/null +++ b/docs_src/_build/html/genindex.html @@ -0,0 +1,196 @@ + + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>Index — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="#" /> + <link rel="search" title="Search" href="search.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + +<h1 id="index">Index</h1> + +<div class="genindex-jumpbox"> + <a href="#A"><strong>A</strong></a> + | <a href="#C"><strong>C</strong></a> + | <a href="#L"><strong>L</strong></a> + | <a href="#P"><strong>P</strong></a> + | <a href="#R"><strong>R</strong></a> + | <a href="#X"><strong>X</strong></a> + | <a href="#Y"><strong>Y</strong></a> + | <a href="#Z"><strong>Z</strong></a> + +</div> +<h2 id="A">A</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.geometry_utils.html#cfelpyutils.geometry_utils.apply_geometry_to_data">apply_geometry_to_data() (in module cfelpyutils.geometry_utils)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="C">C</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.html#module-cfelpyutils">cfelpyutils (module)</a> +</li> + <li><a href="cfelpyutils.crystfel_utils.html#module-cfelpyutils.crystfel_utils">cfelpyutils.crystfel_utils (module)</a> +</li> + <li><a href="cfelpyutils.geometry_utils.html#module-cfelpyutils.geometry_utils">cfelpyutils.geometry_utils (module)</a> +</li> + </ul></td> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#module-cfelpyutils.named_tuples">cfelpyutils.named_tuples (module)</a> +</li> + <li><a href="cfelpyutils.geometry_utils.html#cfelpyutils.geometry_utils.compute_pix_maps">compute_pix_maps() (in module cfelpyutils.geometry_utils)</a> +</li> + <li><a href="cfelpyutils.geometry_utils.html#cfelpyutils.geometry_utils.compute_visualization_pix_maps">compute_visualization_pix_maps() (in module cfelpyutils.geometry_utils)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="L">L</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.crystfel_utils.html#cfelpyutils.crystfel_utils.load_crystfel_geometry">load_crystfel_geometry() (in module cfelpyutils.crystfel_utils)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="P">P</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps.phi">phi (PixelMaps attribute)</a> +</li> + </ul></td> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps">PixelMaps (class in cfelpyutils.named_tuples)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="R">R</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps.r">r (PixelMaps attribute)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="X">X</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps.x">x (PixelMaps attribute)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="Y">Y</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps.y">y (PixelMaps attribute)</a> +</li> + </ul></td> +</tr></table> + +<h2 id="Z">Z</h2> +<table style="width: 100%" class="indextable genindextable"><tr> + <td style="width: 33%; vertical-align: top;"><ul> + <li><a href="cfelpyutils.named_tuples.html#cfelpyutils.named_tuples.PixelMaps.z">z (PixelMaps attribute)</a> +</li> + </ul></td> +</tr></table> + + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs_src/_build/html/index.html b/docs_src/_build/html/index.html new file mode 100644 index 0000000..ea167f9 --- /dev/null +++ b/docs_src/_build/html/index.html @@ -0,0 +1,117 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>CFELPyUtils — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + <link rel="next" title="The cfelpyutils Package" href="cfelpyutils.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <div class="section" id="cfelpyutils"> +<h1>CFELPyUtils<a class="headerlink" href="#cfelpyutils" title="Permalink to this headline">¶</a></h1> +<div class="toctree-wrapper compound"> +</div> +<div class="section" id="introduction"> +<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2> +<p>CFELPyUtils is a utility library written in Python and developed at the Center For Free +Electron Laser Science (CFEL) in Hamburg. It contains several functions and classes +that perform various tasks related to the processing of x-ray imaging data (currently, +mostly reading and applying geometry information to x-ray detector data). It is used by +several internal and released CFEL software projects.</p> +</div> +<div class="section" id="installation"> +<h2>Installation<a class="headerlink" href="#installation" title="Permalink to this headline">¶</a></h2> +<p>The CFELPyUtils library is available on PyPI and can be installed using the pip +command:</p> +<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>python3 -m pip install cfelpyutils +</pre></div> +</div> +<p>Or, for python2:</p> +<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>python -m pip install cfelpyutils +</pre></div> +</div> +<p>It is also available as an Anaconda package in the ‘ondateam’ channel. It can be +installed using the ‘conda’ command:</p> +<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>conda install -c ondateam cfelpyutils +</pre></div> +</div> +</div> +<div class="section" id="code-documentation"> +<h2>Code Documentation<a class="headerlink" href="#code-documentation" title="Permalink to this headline">¶</a></h2> +<p>Code documentation for the CFELPyUtils library can be found <a class="reference internal" href="cfelpyutils.html"><span class="doc">here</span></a>.</p> +</div> +</div> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> + <h3><a href="#">Table of Contents</a></h3> + <ul> +<li><a class="reference internal" href="#">CFELPyUtils</a><ul> +<li><a class="reference internal" href="#introduction">Introduction</a></li> +<li><a class="reference internal" href="#installation">Installation</a></li> +<li><a class="reference internal" href="#code-documentation">Code Documentation</a></li> +</ul> +</li> +</ul> + +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs_src/_build/html/modules.html b/docs_src/_build/html/modules.html new file mode 100644 index 0000000..c6b1e68 --- /dev/null +++ b/docs_src/_build/html/modules.html @@ -0,0 +1,114 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>cfelpyutils — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <div class="section" id="cfelpyutils"> +<h1>cfelpyutils<a class="headerlink" href="#cfelpyutils" title="Permalink to this headline">¶</a></h1> +<div class="toctree-wrapper compound"> +<ul> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a><ul> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.crystfel_utils.html">crystfel_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.geometry_utils.html">geometry_utils</a></li> +<li class="toctree-l2"><a class="reference internal" href="cfelpyutils.named_tuples.html">named_tuples</a></li> +</ul> +</li> +</ul> +</div> +</div> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs_src/_build/html/objects.inv b/docs_src/_build/html/objects.inv new file mode 100644 index 0000000..34d0743 --- /dev/null +++ b/docs_src/_build/html/objects.inv @@ -0,0 +1,8 @@ +# Sphinx inventory version 2 +# Project: CFELPyUtils +# Version: 1.0.0 +# The remainder of this file is compressed using zlib. +xÚµ”Ánƒ0†ï}ŠHÛ•j½ö:mÒ¤MBÚvŽÜÄ-щH˜HŸ~ ¡-¡@7ÜÀþýý–Áf[”ÚUVHC´[çŠWÉaçø2³¹¼™äž$‹nŽ•ÎØÃ;FIJ?—R§§ØUŽ¶tÞh[Ì +UÕU«¾Çs¥ëX6ÙuO +ZKwê–ZE9X˜èzÈêŠS¹®,R-jšƒ6óп…©@Š=xì¼ +È‘S[i‰ãÓïŠ&g SQ£|k[dŒéõw‰ýo©3á™`m)6‡ÑÜŠ[ÎBg¡ºY¨ûQ‰±|Í#Éêâl‘»A’û‚NÝ°ÜÀ] ô¸úùG§®Í`o~¯z€mÓýbŠ ;ªlÉ;,DÁ±nH6(=ë µ/þqq–µ†ÅãóÓkê>½÷â°¶Dí’c"”ÿ–mJ–Å!Äï!Ÿúoù›aŒ& \ No newline at end of file diff --git a/docs_src/_build/html/py-modindex.html b/docs_src/_build/html/py-modindex.html new file mode 100644 index 0000000..02294c3 --- /dev/null +++ b/docs_src/_build/html/py-modindex.html @@ -0,0 +1,137 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>Python Module Index — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="search.html" /> + + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + + <h1>Python Module Index</h1> + + <div class="modindex-jumpbox"> + <a href="#cap-c"><strong>c</strong></a> + </div> + + <table class="indextable modindextable"> + <tr class="pcap"><td></td><td> </td><td></td></tr> + <tr class="cap" id="cap-c"><td></td><td> + <strong>c</strong></td><td></td></tr> + <tr> + <td><img src="_static/minus.png" class="toggler" + id="toggle-1" style="display: none" alt="-" /></td> + <td> + <a href="cfelpyutils.html#module-cfelpyutils"><code class="xref">cfelpyutils</code></a></td><td> + <em></em></td></tr> + <tr class="cg-1"> + <td></td> + <td>    + <a href="cfelpyutils.crystfel_utils.html#module-cfelpyutils.crystfel_utils"><code class="xref">cfelpyutils.crystfel_utils</code></a></td><td> + <em></em></td></tr> + <tr class="cg-1"> + <td></td> + <td>    + <a href="cfelpyutils.geometry_utils.html#module-cfelpyutils.geometry_utils"><code class="xref">cfelpyutils.geometry_utils</code></a></td><td> + <em></em></td></tr> + <tr class="cg-1"> + <td></td> + <td>    + <a href="cfelpyutils.named_tuples.html#module-cfelpyutils.named_tuples"><code class="xref">cfelpyutils.named_tuples</code></a></td><td> + <em></em></td></tr> + </table> + + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + </ul></li> +</ul> +</div> +<div id="searchbox" style="display: none" role="search"> + <h3>Quick search</h3> + <div class="searchformwrapper"> + <form class="search" action="search.html" method="get"> + <input type="text" name="q" /> + <input type="submit" value="Go" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs_src/_build/html/search.html b/docs_src/_build/html/search.html new file mode 100644 index 0000000..a117965 --- /dev/null +++ b/docs_src/_build/html/search.html @@ -0,0 +1,120 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" lang="en"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title>Search — CFELPyUtils 1.0.0 documentation</title> + <link rel="stylesheet" href="_static/alabaster.css" type="text/css" /> + <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> + + <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> + <script type="text/javascript" src="_static/jquery.js"></script> + <script type="text/javascript" src="_static/underscore.js"></script> + <script type="text/javascript" src="_static/doctools.js"></script> + <script type="text/javascript" src="_static/language_data.js"></script> + <script type="text/javascript" src="_static/searchtools.js"></script> + <link rel="index" title="Index" href="genindex.html" /> + <link rel="search" title="Search" href="#" /> + <script type="text/javascript"> + jQuery(function() { Search.loadIndex("searchindex.js"); }); + </script> + + <script type="text/javascript" id="searchindexloader"></script> + + + <link rel="stylesheet" href="_static/custom.css" type="text/css" /> + + + <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> + + + </head><body> + + + <div class="document"> + <div class="documentwrapper"> + <div class="bodywrapper"> + + + <div class="body" role="main"> + + <h1 id="search-documentation">Search</h1> + <div id="fallback" class="admonition warning"> + <script type="text/javascript">$('#fallback').hide();</script> + <p> + Please activate JavaScript to enable the search + functionality. + </p> + </div> + <p> + From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. + </p> + <form action="" method="get"> + <input type="text" name="q" value="" /> + <input type="submit" value="search" /> + <span id="search-progress" style="padding-left: 10px"></span> + </form> + + <div id="search-results"> + + </div> + + </div> + + </div> + </div> + <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> + <div class="sphinxsidebarwrapper"> +<h1 class="logo"><a href="index.html">CFELPyUtils</a></h1> + + + + + + + + +<h3>Navigation</h3> +<ul> +<li class="toctree-l1"><a class="reference internal" href="cfelpyutils.html">The cfelpyutils Package</a></li> +</ul> + +<div class="relations"> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + </ul></li> +</ul> +</div> + + + + + + + + + </div> + </div> + <div class="clearer"></div> + </div> + <div class="footer"> + ©2019, OnDA Team. + + | + Powered by <a href="http://sphinx-doc.org/">Sphinx 1.8.5</a> + & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a> + + </div> + + + + + </body> +</html> \ No newline at end of file diff --git a/docs_src/_build/html/searchindex.js b/docs_src/_build/html/searchindex.js new file mode 100644 index 0000000..be933e7 --- /dev/null +++ b/docs_src/_build/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({docnames:["cfelpyutils","cfelpyutils.crystfel_utils","cfelpyutils.geometry_utils","cfelpyutils.named_tuples","index"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,"sphinx.ext.todo":1,"sphinx.ext.viewcode":1,sphinx:55},filenames:["cfelpyutils.rst","cfelpyutils.crystfel_utils.rst","cfelpyutils.geometry_utils.rst","cfelpyutils.named_tuples.rst","index.rst"],objects:{"":{cfelpyutils:[0,0,0,"-"]},"cfelpyutils.crystfel_utils":{load_crystfel_geometry:[1,1,1,""]},"cfelpyutils.geometry_utils":{apply_geometry_to_data:[2,1,1,""],compute_pix_maps:[2,1,1,""],compute_visualization_pix_maps:[2,1,1,""]},"cfelpyutils.named_tuples":{PixelMaps:[3,2,1,""]},"cfelpyutils.named_tuples.PixelMaps":{phi:[3,3,1,""],r:[3,3,1,""],x:[3,3,1,""],y:[3,3,1,""],z:[3,3,1,""]},cfelpyutils:{crystfel_utils:[1,0,0,"-"],geometry_utils:[2,0,0,"-"],named_tuples:[3,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","attribute","Python attribute"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:attribute"},terms:{"41a8fa9819010":1,"class":[3,4],"float":[],"function":[1,2,4],"int":[],"new":[],"return":[1,2],For:[1,4],The:4,These:2,absolut:1,adjust:[],alia:3,all:2,along:2,also:4,amplitud:3,anaconda:4,angl:3,ani:[1,2],appli:[2,4],apply_geometry_to_data:2,around:2,arrai:2,assum:[],avail:[2,4],awai:2,axi:3,base:3,beam:2,been:[],between:3,big:2,bigger:2,can:[2,4],caus:2,ceil:2,center:[2,3,4],cfel:4,cfelpyutil:3,channel:4,code:1,collect:3,command:4,commit:1,complet:2,comput:2,compute_min_array_s:[],compute_pix_map:2,compute_visualization_pix_map:2,conda:4,connect:[],contain:[0,1,2,3,4],convent:2,convert:[],coordin:[2,3],corner:2,correspond:1,crystfel:[1,2],crystfel_util:0,current:[1,4],data:[2,4],describ:[],desi:[],detector:[2,4],develop:4,dict:[1,2],dictionari:[1,2],differ:2,direct:2,displai:2,displayedus:[],distanc:3,document:1,each:3,electron:4,enough:2,entri:2,field:3,fifth:[],file:[1,2],filenam:1,first:[],follow:2,format:1,found:4,fourth:[],free:4,from:[1,2,3],full:1,gener:2,geometri:[1,2,3,4],geometry_util:0,get_detector_geometry_2:1,hamburg:4,hand:2,has:[],here:4,http:[],imag:4,imageview:2,implement:[],inform:[1,2,3,4],input:2,instead:[],interact:2,intern:4,just:[],kei:1,languag:1,laser:4,layout:2,left:2,librari:[0,2,3,4],like:2,link:[],load:1,load_crystfel_geometri:[1,2],main:[0,2],make:[],man:1,mani:[],manipul:2,map:[2,3],match:1,matplotlib:2,minimum:2,mostli:4,name:[2,3],named_tupl:0,ndarrai:[2,3],need:2,none:2,note:2,number:3,numpi:[2,3],object:2,often:2,ondateam:4,ones:2,onli:2,org:[],orient:2,origin:2,other:2,packag:[1,4],page:1,paramet:[1,2,3],particularli:2,path:1,perform:4,phi:[2,3],physic:2,pip:4,pixel:[2,3],pixel_map:[],pixelmap:[2,3],point:2,pre:2,prepar:[],process:4,project:4,provid:[],pypi:4,pyqtgraph:2,python2:4,python3:4,python:[1,4],rai:4,read:[1,2,4],readi:[],refer:[2,3],reimplement:1,rel:1,relat:4,releas:4,relev:1,respect:[],restrict:2,result:[],right:2,same:2,scienc:4,see:1,set:2,sever:4,shape:2,should:2,size:2,softwar:[1,4],some:[1,2],sourc:[1,2],standard:[],store:[1,2,3],str:[1,2],stro:[],style:[],submodul:[],suppos:[],symmetr:2,sync:[],synchron:1,system:[2,3],take:2,task:4,than:2,thi:[1,2,3],third:[],three:[],through:3,throughout:3,top:2,toward:2,tupl:[2,3],twhite:[],two:[],type:[1,2],used:[2,3,4],uses:1,using:[2,4],util:[1,2,4],valu:[1,2],variou:4,vector:[],visual:2,which:[0,2],whole:0,widget:2,work:[],written:4,wth:[],www:[],zenith:2},titles:["The cfelpyutils Package","The crystfel_utils Module","The geometry_utils Module","The named_tuples Module","CFELPyUtils"],titleterms:{The:[0,1,2,3],cfelpyutil:[0,4],code:4,crystfel_util:1,document:4,geometry_util:2,instal:4,introduct:4,modul:[1,2,3],named_tupl:3,packag:0,thecfelpyutil:[]}}) \ No newline at end of file diff --git a/docs/cfelpyutils.crystfel_utils.rst b/docs_src/cfelpyutils.crystfel_utils.rst similarity index 59% rename from docs/cfelpyutils.crystfel_utils.rst rename to docs_src/cfelpyutils.crystfel_utils.rst index 7ffd290..8533f9d 100644 --- a/docs/cfelpyutils.crystfel_utils.rst +++ b/docs_src/cfelpyutils.crystfel_utils.rst @@ -1,5 +1,5 @@ -cfelpyutils.crystfel\_utils module -================================== +The crystfel\_utils Module +========================== .. automodule:: cfelpyutils.crystfel_utils :members: diff --git a/docs/cfelpyutils.geometry_utils.rst b/docs_src/cfelpyutils.geometry_utils.rst similarity index 59% rename from docs/cfelpyutils.geometry_utils.rst rename to docs_src/cfelpyutils.geometry_utils.rst index d75c71f..005d68a 100644 --- a/docs/cfelpyutils.geometry_utils.rst +++ b/docs_src/cfelpyutils.geometry_utils.rst @@ -1,5 +1,5 @@ -cfelpyutils.geometry\_utils module -================================== +The geometry\_utils Module +========================== .. automodule:: cfelpyutils.geometry_utils :members: diff --git a/docs_src/cfelpyutils.named_tuples.rst b/docs_src/cfelpyutils.named_tuples.rst new file mode 100644 index 0000000..42965bb --- /dev/null +++ b/docs_src/cfelpyutils.named_tuples.rst @@ -0,0 +1,7 @@ +The named\_tuples Module +======================== + +.. automodule:: cfelpyutils.named_tuples + :members: + :undoc-members: + :show-inheritance: diff --git a/docs_src/cfelpyutils.rst b/docs_src/cfelpyutils.rst new file mode 100644 index 0000000..9e74d51 --- /dev/null +++ b/docs_src/cfelpyutils.rst @@ -0,0 +1,13 @@ +The cfelpyutils Package +======================= + +.. automodule:: cfelpyutils + :members: + :undoc-members: + :show-inheritance: + +.. toctree:: + + crystfel_utils <cfelpyutils.crystfel_utils> + geometry_utils <cfelpyutils.geometry_utils> + named_tuples <cfelpyutils.named_tuples> diff --git a/docs_src/conf.py b/docs_src/conf.py new file mode 100644 index 0000000..135ef9b --- /dev/null +++ b/docs_src/conf.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config +# pylint: disable=invalid-name,missing-docstring,redefined-builtin,unused-import + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, '/home/vmariani/Work/Software/cfelpyutils/cfelpyutils') + +# -- Project information ----------------------------------------------------- + +project = 'CFELPyUtils' +copyright = '2019, OnDA Team' +author = 'OnDA Team' + +# The short X.Y version +version = '1.0.0' +# The full version, including alpha/beta/rc tags +release = '1.0.0' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.napoleon', + 'sphinx.ext.todo', + 'sphinx.ext.viewcode', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'en' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = None + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +#html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +html_sidebars = { + "index": ["localtoc.html", "searchbox.html"], +} + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'cfelpyutilsdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'cfelpyutils.tex', 'cfelpyutils Documentation', + 'Author', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'cfelpyutils', 'cfelpyutils Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'cfelpyutils', 'cfelpyutils Documentation', + author, 'cfelpyutils', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + + +# -- Extension configuration ------------------------------------------------- +html_show_sourcelink = False +add_module_names = False +autoclass_content = "init" +autodoc_member_order = "bysource" + +# -- Options for todo extension ---------------------------------------------- + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True diff --git a/docs_src/index.rst b/docs_src/index.rst new file mode 100644 index 0000000..929f41c --- /dev/null +++ b/docs_src/index.rst @@ -0,0 +1,53 @@ +.. cfelpyutils documentation master file, created by + sphinx-quickstart on Tue Jul 10 12:10:05 2018. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +CFELPyUtils +=========== + +.. toctree:: + :hidden: + + cfelpyutils + + +Introduction +------------ + +CFELPyUtils is a utility library written in Python and developed at the Center For Free +Electron Laser Science (CFEL) in Hamburg. It contains several functions and classes +that perform various tasks related to the processing of x-ray imaging data (currently, +mostly reading and applying geometry information to x-ray detector data). It is used by +several internal and released CFEL software projects. + + +Installation +------------ + +The CFELPyUtils library is available on PyPI and can be installed using the pip +command: + +.. code-block:: bash + + python3 -m pip install cfelpyutils + +Or, for python2: + +.. code-block:: bash + + python -m pip install cfelpyutils + + +It is also available as an Anaconda package in the 'ondateam' channel. It can be +installed using the 'conda' command: + +.. code-block:: bash + + conda install -c ondateam cfelpyutils + + +Code Documentation +------------------ + +Code documentation for the CFELPyUtils library can be found :doc:`here <cfelpyutils>`. \ No newline at end of file diff --git a/docs/make.bat b/docs_src/make.bat similarity index 92% rename from docs/make.bat rename to docs_src/make.bat index 151ca6b..27f573b 100644 --- a/docs/make.bat +++ b/docs_src/make.bat @@ -9,7 +9,6 @@ if "%SPHINXBUILD%" == "" ( ) set SOURCEDIR=. set BUILDDIR=_build -set SPHINXPROJ=cfelpyutils if "%1" == "" goto help diff --git a/setup.py b/setup.py index 420c5ad..d9f5070 100644 --- a/setup.py +++ b/setup.py @@ -17,12 +17,14 @@ from __future__ import absolute_import, division, print_function, unicode_litera from setuptools import setup -import cfelpyutils +version_fh = open("onda/__init__.py", "r") +version = version_fh.readlines()[-1].split("=")[1].strip().split('"')[1] +version_fh.close() setup( name="cfelpyutils", - version=cfelpyutils.__version__, + version=version, url="https://github.com/ondateam/cfelpyutils", license="GNU General Public License v3.0", author="OnDA Team", @@ -41,7 +43,6 @@ setup( platforms="any", classifiers=[ "Programming Language :: Python", - "Development Status :: 4 - Beta", "Programming Language :: Python :: 3", "Programming Language :: Python :: 2", "Operating System :: OS Independent", -- GitLab