diff --git a/_images/apidocs_plot_mpl-1.svg b/_images/apidocs_plot_mpl-1.svg
new file mode 100644
index 0000000..f97fe57
--- /dev/null
+++ b/_images/apidocs_plot_mpl-1.svg
@@ -0,0 +1,3045 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-2_00.svg b/_images/apidocs_plot_mpl-2_00.svg
new file mode 100644
index 0000000..e89798e
--- /dev/null
+++ b/_images/apidocs_plot_mpl-2_00.svg
@@ -0,0 +1,1604 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-2_01.svg b/_images/apidocs_plot_mpl-2_01.svg
new file mode 100644
index 0000000..acc7c04
--- /dev/null
+++ b/_images/apidocs_plot_mpl-2_01.svg
@@ -0,0 +1,808 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-2_02.svg b/_images/apidocs_plot_mpl-2_02.svg
new file mode 100644
index 0000000..f83c21c
--- /dev/null
+++ b/_images/apidocs_plot_mpl-2_02.svg
@@ -0,0 +1,1390 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-3_00.svg b/_images/apidocs_plot_mpl-3_00.svg
new file mode 100644
index 0000000..2bac8bf
--- /dev/null
+++ b/_images/apidocs_plot_mpl-3_00.svg
@@ -0,0 +1,2008 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-3_01.svg b/_images/apidocs_plot_mpl-3_01.svg
new file mode 100644
index 0000000..89b17b7
--- /dev/null
+++ b/_images/apidocs_plot_mpl-3_01.svg
@@ -0,0 +1,1059 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-3_02.svg b/_images/apidocs_plot_mpl-3_02.svg
new file mode 100644
index 0000000..8ae7352
--- /dev/null
+++ b/_images/apidocs_plot_mpl-3_02.svg
@@ -0,0 +1,1664 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-4_00.svg b/_images/apidocs_plot_mpl-4_00.svg
new file mode 100644
index 0000000..da5ba42
--- /dev/null
+++ b/_images/apidocs_plot_mpl-4_00.svg
@@ -0,0 +1,2811 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-4_01.svg b/_images/apidocs_plot_mpl-4_01.svg
new file mode 100644
index 0000000..ba2a977
--- /dev/null
+++ b/_images/apidocs_plot_mpl-4_01.svg
@@ -0,0 +1,1874 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-4_02.svg b/_images/apidocs_plot_mpl-4_02.svg
new file mode 100644
index 0000000..e725c44
--- /dev/null
+++ b/_images/apidocs_plot_mpl-4_02.svg
@@ -0,0 +1,1186 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-4_03.svg b/_images/apidocs_plot_mpl-4_03.svg
new file mode 100644
index 0000000..fba936e
--- /dev/null
+++ b/_images/apidocs_plot_mpl-4_03.svg
@@ -0,0 +1,1195 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-5_00.svg b/_images/apidocs_plot_mpl-5_00.svg
new file mode 100644
index 0000000..130156e
--- /dev/null
+++ b/_images/apidocs_plot_mpl-5_00.svg
@@ -0,0 +1,3153 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-5_01.svg b/_images/apidocs_plot_mpl-5_01.svg
new file mode 100644
index 0000000..9cf337b
--- /dev/null
+++ b/_images/apidocs_plot_mpl-5_01.svg
@@ -0,0 +1,1169 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-5_02.svg b/_images/apidocs_plot_mpl-5_02.svg
new file mode 100644
index 0000000..27e2a5b
--- /dev/null
+++ b/_images/apidocs_plot_mpl-5_02.svg
@@ -0,0 +1,1914 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-5_03.svg b/_images/apidocs_plot_mpl-5_03.svg
new file mode 100644
index 0000000..1e8e74f
--- /dev/null
+++ b/_images/apidocs_plot_mpl-5_03.svg
@@ -0,0 +1,1257 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-6_00.svg b/_images/apidocs_plot_mpl-6_00.svg
new file mode 100644
index 0000000..15a9eb4
--- /dev/null
+++ b/_images/apidocs_plot_mpl-6_00.svg
@@ -0,0 +1,3721 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-6_01.svg b/_images/apidocs_plot_mpl-6_01.svg
new file mode 100644
index 0000000..851aec5
--- /dev/null
+++ b/_images/apidocs_plot_mpl-6_01.svg
@@ -0,0 +1,1394 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-6_02.svg b/_images/apidocs_plot_mpl-6_02.svg
new file mode 100644
index 0000000..fba5323
--- /dev/null
+++ b/_images/apidocs_plot_mpl-6_02.svg
@@ -0,0 +1,817 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-6_03.svg b/_images/apidocs_plot_mpl-6_03.svg
new file mode 100644
index 0000000..248399e
--- /dev/null
+++ b/_images/apidocs_plot_mpl-6_03.svg
@@ -0,0 +1,1257 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-6_04.svg b/_images/apidocs_plot_mpl-6_04.svg
new file mode 100644
index 0000000..eb5ef5b
--- /dev/null
+++ b/_images/apidocs_plot_mpl-6_04.svg
@@ -0,0 +1,1492 @@
+
+
+
diff --git a/_images/apidocs_plot_mpl-6_05.svg b/_images/apidocs_plot_mpl-6_05.svg
new file mode 100644
index 0000000..00dcd4e
--- /dev/null
+++ b/_images/apidocs_plot_mpl-6_05.svg
@@ -0,0 +1,2232 @@
+
+
+
diff --git a/_images/guide_api-1.svg b/_images/guide_api-1.svg
new file mode 100644
index 0000000..2171d03
--- /dev/null
+++ b/_images/guide_api-1.svg
@@ -0,0 +1,1770 @@
+
+
+
diff --git a/_images/guide_api-2.svg b/_images/guide_api-2.svg
new file mode 100644
index 0000000..57694e9
--- /dev/null
+++ b/_images/guide_api-2.svg
@@ -0,0 +1,3016 @@
+
+
+
diff --git a/_images/guide_api-4.svg b/_images/guide_api-4.svg
new file mode 100644
index 0000000..debfa00
--- /dev/null
+++ b/_images/guide_api-4.svg
@@ -0,0 +1,2596 @@
+
+
+
diff --git a/_images/guide_api-5.svg b/_images/guide_api-5.svg
new file mode 100644
index 0000000..188f6cf
--- /dev/null
+++ b/_images/guide_api-5.svg
@@ -0,0 +1,2852 @@
+
+
+
diff --git a/_images/guide_api-6.svg b/_images/guide_api-6.svg
new file mode 100644
index 0000000..1bf219f
--- /dev/null
+++ b/_images/guide_api-6.svg
@@ -0,0 +1,801 @@
+
+
+
diff --git a/_images/guide_api-7.svg b/_images/guide_api-7.svg
new file mode 100644
index 0000000..0d25162
--- /dev/null
+++ b/_images/guide_api-7.svg
@@ -0,0 +1,3495 @@
+
+
+
diff --git a/_images/guide_api-8.svg b/_images/guide_api-8.svg
new file mode 100644
index 0000000..b19814b
--- /dev/null
+++ b/_images/guide_api-8.svg
@@ -0,0 +1,1562 @@
+
+
+
diff --git a/_images/guide_api-9_00.svg b/_images/guide_api-9_00.svg
new file mode 100644
index 0000000..bb6b1b5
--- /dev/null
+++ b/_images/guide_api-9_00.svg
@@ -0,0 +1,354 @@
+
+
+
diff --git a/_images/guide_api-9_01.svg b/_images/guide_api-9_01.svg
new file mode 100644
index 0000000..b820e56
--- /dev/null
+++ b/_images/guide_api-9_01.svg
@@ -0,0 +1,394 @@
+
+
+
diff --git a/_images/guide_data-1.svg b/_images/guide_data-1.svg
new file mode 100644
index 0000000..9f4f8d3
--- /dev/null
+++ b/_images/guide_data-1.svg
@@ -0,0 +1,302 @@
+
+
+
diff --git a/_images/guide_fitting-1.svg b/_images/guide_fitting-1.svg
new file mode 100644
index 0000000..e88b783
--- /dev/null
+++ b/_images/guide_fitting-1.svg
@@ -0,0 +1,354 @@
+
+
+
diff --git a/_sources/apidocs.rst.txt b/_sources/apidocs.rst.txt
new file mode 100644
index 0000000..ea0229d
--- /dev/null
+++ b/_sources/apidocs.rst.txt
@@ -0,0 +1,58 @@
+.. include:: ./substitutions.rst
+
+API Documentation
+=================
+
+DearEIS includes an API that is primarily intended for batch processing (e.g., importing data into a project or exporting results/plots/tables).
+
+.. doctest::
+
+ >>> import deareis # The main functions, classes, etc.
+ >>> from deareis import mpl # Plotting functions based on matplotlib.
+
+
+.. warning::
+
+ DearEIS provides wrapper functions for some of pyimpspec's functions since DearEIS uses classes that store the relevant arguments/settings in a way that can be serialized and deserialized as part of project files.
+ Consequently, the API might feel somewhat cumbersome to use for some tasks where these settings classes must be instantiated and using pyimpspec directly might be more convenient.
+
+ DearEIS also implements subclasses or entirely new classes to contain some of the information that pyimpspec's various result classes would contain.
+ This has been done so that various results can be serialized and deserialized as part of project files.
+
+ However, DearEIS' classes can in several cases be used directly with functions from pyimpspec (e.g., the various plotting functions) since pyimpspec checks for the presence of attributes and/or methods with specific names rather than whether or not an object is an instance of some class.
+
+.. note::
+
+ The API makes use of multiple processes where possible to perform tasks in parallel.
+ Functions that implement this parallelization have a ``num_procs`` keyword argument that can be used to override the maximum number of processes allowed.
+ Using this keyword argument should not be necessary for most users under most circumstances.
+ Call the |get_default_num_procs| function to get the automatically determined value for your system.
+ There is also a |set_default_num_procs| function that can be used to set a global override rather than using the ``num_procs`` keyword argument when calling various functions.
+
+ If NumPy is linked against a multithreaded linear algebra library like OpenBLAS or MKL, then this may in some circumstances result in unusually poor performance despite heavy CPU utilization.
+ It may be possible to remedy the issue by specifying a lower number of processes via the ``num_procs`` keyword argument and/or limiting the number of threads that, e.g., OpenBLAS should use by setting the appropriate environment variable (e.g., ``OPENBLAS_NUM_THREADS``).
+ Again, this should not be necessary for most users and reporting this as an issue to the DearEIS or pyimpspec repository on GitHub would be preferred.
+
+
+.. automodule:: deareis
+ :members: get_default_num_procs, set_default_num_procs
+
+
+.. raw:: latex
+
+ \clearpage
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents:
+
+ apidocs_data
+ apidocs_project
+ apidocs_kramers_kronig
+ apidocs_zhit
+ apidocs_drt
+ apidocs_circuit
+ apidocs_fitting
+ apidocs_plot_mpl
+ apidocs_typing
+ apidocs_exceptions
diff --git a/_sources/apidocs_circuit.rst.txt b/_sources/apidocs_circuit.rst.txt
new file mode 100644
index 0000000..6e5eda2
--- /dev/null
+++ b/_sources/apidocs_circuit.rst.txt
@@ -0,0 +1,48 @@
+.. include:: ./substitutions.rst
+
+Equivalent circuits
+===================
+
+Functions
+---------
+.. automodule:: deareis
+ :members: parse_cdc, register_element
+
+
+Base classes
+------------
+.. automodule:: deareis
+ :members: Element, Container, Connection
+
+
+Connection classes
+------------------
+.. automodule:: deareis
+ :members: Series, Parallel
+
+
+Circuit classes
+---------------
+.. automodule:: deareis
+ :members: Circuit
+
+.. automodule:: deareis
+ :members: CircuitBuilder
+
+
+Element classes
+---------------
+.. automodule:: deareis.api.circuit.elements
+ :members:
+ :imported-members:
+
+
+Element registration classes
+----------------------------
+.. automodule:: deareis
+ :members: ElementDefinition, ContainerDefinition, ParameterDefinition, SubcircuitDefinition
+
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/apidocs_data.rst.txt b/_sources/apidocs_data.rst.txt
new file mode 100644
index 0000000..c02f422
--- /dev/null
+++ b/_sources/apidocs_data.rst.txt
@@ -0,0 +1,15 @@
+.. include:: ./substitutions.rst
+
+Data parsing
+============
+
+.. automodule:: deareis
+ :members: parse_data
+
+
+.. autoclass:: deareis.DataSet
+ :inherited-members:
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/apidocs_drt.rst.txt b/_sources/apidocs_drt.rst.txt
new file mode 100644
index 0000000..5e587f3
--- /dev/null
+++ b/_sources/apidocs_drt.rst.txt
@@ -0,0 +1,22 @@
+.. include:: ./substitutions.rst
+
+Distribution of relaxation times analysis
+=========================================
+
+.. automodule:: deareis
+ :members: calculate_drt
+
+
+Classes
+-------
+.. automodule:: deareis
+ :members: DRTResult, DRTSettings
+
+Enums
+-----
+.. automodule:: deareis
+ :members: DRTMethod, DRTMode, RBFShape, RBFType
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/apidocs_exceptions.rst.txt b/_sources/apidocs_exceptions.rst.txt
new file mode 100644
index 0000000..b940f60
--- /dev/null
+++ b/_sources/apidocs_exceptions.rst.txt
@@ -0,0 +1,13 @@
+.. include:: ./substitutions.rst
+
+Exceptions
+==========
+
+.. automodule:: deareis.exceptions
+ :members:
+ :imported-members:
+
+.. raw:: latex
+
+ \clearpage
+
diff --git a/_sources/apidocs_fitting.rst.txt b/_sources/apidocs_fitting.rst.txt
new file mode 100644
index 0000000..bd0511a
--- /dev/null
+++ b/_sources/apidocs_fitting.rst.txt
@@ -0,0 +1,22 @@
+.. include:: ./substitutions.rst
+
+Circuit fitting
+===============
+
+.. automodule:: deareis
+ :members: fit_circuit
+
+
+Classes
+-------
+.. automodule:: deareis
+ :members: FitResult, FitSettings
+
+Enums
+-----
+.. automodule:: deareis
+ :members: CNLSMethod, Weight
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/apidocs_kramers_kronig.rst.txt b/_sources/apidocs_kramers_kronig.rst.txt
new file mode 100644
index 0000000..b478336
--- /dev/null
+++ b/_sources/apidocs_kramers_kronig.rst.txt
@@ -0,0 +1,22 @@
+.. include:: ./substitutions.rst
+
+Kramers-Kronig testing
+======================
+
+.. automodule:: deareis
+ :members: perform_test, perform_exploratory_tests
+
+
+Classes
+-------
+.. automodule:: deareis
+ :members: KramersKronigResult, KramersKronigSettings, KramersKronigSuggestionSettings
+
+Enums
+-----
+.. automodule:: deareis
+ :members: CNLSMethod, KramersKronigMode, KramersKronigTest, KramersKronigRepresentation
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/apidocs_plot_mpl.rst.txt b/_sources/apidocs_plot_mpl.rst.txt
new file mode 100644
index 0000000..c773019
--- /dev/null
+++ b/_sources/apidocs_plot_mpl.rst.txt
@@ -0,0 +1,346 @@
+.. include:: ./substitutions.rst
+
+Plotting - matplotlib
+=====================
+
+Wrappers
+--------
+
+These functions provide a high-level API for visualizing various objects/results (e.g., :class:`~deareis.DataSet`).
+Most of them are the same functions included in pyimpspec_ with the notable exception of :func:`~deareis.mpl.plot`.
+
+.. automodule:: deareis.mpl
+ :members: plot, plot_circuit, plot_data, plot_drt, plot_fit, plot_kramers_kronig_tests
+
+
+
+Primitives
+----------
+
+These functions are used by the wrapper functions to make a more complex figure with multiple subplots.
+These are all the same as those included in pyimpspec_.
+
+.. automodule:: deareis.mpl
+ :members: plot_bht_scores, plot_bode, plot_real_imaginary, plot_gamma, plot_imaginary, plot_magnitude, plot_mu_xps, plot_nyquist, plot_phase, plot_real, plot_residuals
+
+
+Examples
+--------
+
+Below are some examples of plots created using the plotting functions listed above.
+The circuit and the data set are based on test circuit 1 (TC-1) from this 1995 article by `Bernard Boukamp`_.
+
+Legends are disabled and colored axes are used instead in the figures generated by the wrapper functions (i.e., the first figure in each series).
+This has been done due to the small size of the figures in this documentation.
+However, the figures generated by the individual primitive functions are also included with the legends enabled and without colored axes.
+
+The default color scheme is based on the *Vibrant qualitative* color scheme presented in `Paul Tol`_'s blog.
+Colors and markers can be defined when calling any of the functions.
+
+.. _Bernard Boukamp: https://doi.org/10.1149/1.2044210
+.. _Paul Tol: https://personal.sron.nl/~pault/
+
+
+plot
+~~~~
+:func:`~deareis.mpl.plot`
+
+.. plot::
+
+ from deareis import Project
+ from deareis import mpl
+ project = Project.from_file("../../tests/example-project-v6.json")
+ for plot in project.get_plots():
+ if "DRT" not in plot.get_label():
+ continue
+ figure, axes = mpl.plot(plot, project)
+ break
+
+.. raw:: latex
+
+ \clearpage
+
+
+plot_circuit
+~~~~~~~~~~~~
+:func:`~deareis.mpl.plot_circuit`
+
+* :func:`~deareis.mpl.plot_nyquist`
+* :func:`~deareis.mpl.plot_bode`
+
+.. plot::
+
+ from deareis import mpl
+ import pyimpspec
+ from numpy import logspace, log10 as log
+
+ data = pyimpspec.generate_mock_data("CIRCUIT_1", noise=5e-2, seed=42)[0]
+ circuit = pyimpspec.generate_mock_circuits("CIRCUIT_1")[0]
+ f = data.get_frequencies()
+ figure, axes = mpl.plot_circuit(circuit, frequencies=f, label="TC-1", title="", legend=False, colored_axes=True)
+ figure.tight_layout()
+ mpl.show()
+
+ data = pyimpspec.simulate_spectrum(
+ circuit,
+ logspace(
+ log(max(f)),
+ log(min(f)),
+ num=int(log(max(f)) - log(min(f))) * 100 + 1,
+ ),
+ label="TC-1",
+ )
+ figure, axes = mpl.plot_nyquist(data, line=True)
+ figure.tight_layout()
+ mpl.show()
+
+ figure, axes = mpl.plot_bode(data, line=True)
+ figure.tight_layout()
+ mpl.show()
+
+.. raw:: latex
+
+ \clearpage
+
+
+plot_data
+~~~~~~~~~
+:func:`~deareis.mpl.plot_data`
+
+* :func:`~deareis.mpl.plot_nyquist`
+* :func:`~deareis.mpl.plot_bode`
+
+.. plot::
+
+ from deareis import mpl
+ import pyimpspec
+ import pyimpspec.plot.colors as colors
+
+ data = pyimpspec.generate_mock_data("CIRCUIT_1", noise=5e-2, seed=42)[0]
+ figure, axes = mpl.plot_data(data, legend=False, colored_axes=True)
+ figure.tight_layout()
+ mpl.show()
+
+ figure, axes = mpl.plot_nyquist(data)
+ figure.tight_layout()
+ mpl.show()
+
+ figure, axes = mpl.plot_bode(data)
+ figure.tight_layout()
+ mpl.show()
+
+.. raw:: latex
+
+ \clearpage
+
+
+plot_drt
+~~~~~~~~
+:func:`~deareis.mpl.plot_drt`
+
+* :func:`~deareis.mpl.plot_real_imaginary`
+* :func:`~deareis.mpl.plot_gamma`
+* :func:`~deareis.mpl.plot_residuals`
+
+.. plot::
+
+ from deareis import mpl
+ import pyimpspec
+ import pyimpspec.plot.colors as colors
+
+ data = pyimpspec.generate_mock_data("CIRCUIT_1", noise=5e-2, seed=42)[0]
+ drt = pyimpspec.analysis.drt.calculate_drt_tr_rbf(data)
+ figure, axes = mpl.plot_drt(
+ drt,
+ data,
+ legend=False,
+ colored_axes=True,
+ )
+ figure.tight_layout()
+ mpl.show()
+
+ figure, axes = mpl.plot_real_imaginary(
+ data,
+ colors={
+ "real": colors.COLOR_BLACK,
+ "imaginary": colors.COLOR_BLACK,
+ },
+ legend=False,
+ )
+ _ = mpl.plot_real_imaginary(
+ drt,
+ line=True,
+ figure=figure,
+ axes=axes,
+ )
+ figure.tight_layout()
+ mpl.show()
+
+ figure, axes = mpl.plot_gamma(drt)
+ figure.tight_layout()
+ mpl.show()
+
+
+ figure, axes = mpl.plot_residuals(drt)
+ figure.tight_layout()
+ mpl.show()
+
+.. raw:: latex
+
+ \clearpage
+
+
+plot_fit
+~~~~~~~~
+:func:`~deareis.mpl.plot_fit`
+
+* :func:`~deareis.mpl.plot_nyquist`
+* :func:`~deareis.mpl.plot_bode`
+* :func:`~deareis.mpl.plot_residuals`
+
+.. plot::
+
+ from deareis import mpl
+ import pyimpspec
+ import pyimpspec.plot.colors as colors
+
+ data = pyimpspec.generate_mock_data("CIRCUIT_1", noise=5e-2, seed=42)[0]
+ circuit = pyimpspec.parse_cdc("R(RC)(RW)")
+ fit = pyimpspec.fit_circuit(circuit, data=data)
+
+ figure, axes = mpl.plot_fit(
+ fit,
+ data,
+ legend=False,
+ colored_axes=True,
+ )
+ figure.tight_layout()
+ mpl.show()
+
+ figure, axes = mpl.plot_nyquist(
+ data,
+ colors={"impedance": colors.COLOR_BLACK},
+ legend=False,
+ )
+ _ = mpl.plot_nyquist(
+ fit,
+ line=True,
+ figure=figure,
+ axes=axes,
+ )
+ figure.tight_layout()
+ mpl.show()
+
+ figure, axes = mpl.plot_bode(
+ data,
+ colors={
+ "magnitude": colors.COLOR_BLACK,
+ "phase": colors.COLOR_BLACK,
+ },
+ legend=False,
+ )
+ _ = mpl.plot_bode(
+ fit,
+ line=True,
+ figure=figure,
+ axes=axes,
+ )
+ figure.tight_layout()
+ mpl.show()
+
+ figure, axes = mpl.plot_residuals(fit)
+ figure.tight_layout()
+ mpl.show()
+
+.. raw:: latex
+
+ \clearpage
+
+
+plot_kramers_kronig_tests
+~~~~~~~~~~~~~~~~~~~~~~~~~
+:func:`~deareis.mpl.plot_kramers_kronig_tests`
+
+* :func:`~deareis.mpl.plot_pseudo_chisqr`
+* :func:`~deareis.mpl.plot_num_RC_suggestion`
+* :func:`~deareis.mpl.plot_residuals`
+* :func:`~deareis.mpl.plot_nyquist`
+* :func:`~deareis.mpl.plot_bode`
+
+
+.. plot::
+
+ from deareis import mpl
+ import pyimpspec
+ import pyimpspec.plot.colors as colors
+
+ data = pyimpspec.generate_mock_data("CIRCUIT_1", noise=5e-2, seed=42)[0]
+ mu_criterion = 0.85
+ tests, suggestion = pyimpspec.perform_exploratory_kramers_kronig_tests(
+ data,
+ mu_criterion=mu_criterion,
+ add_capacitance=True,
+ )
+ test, scores, lower_limit, upper_limit = suggestion
+
+
+ figure, axes = mpl.plot_kramers_kronig_tests(
+ tests,
+ suggestion,
+ data,
+ legend=False,
+ colored_axes=True,
+ )
+ figure.tight_layout()
+ mpl.show()
+
+ figure, axes = mpl.plot_pseudo_chisqr(
+ tests,
+ lower_limit=lower_limit,
+ upper_limit=upper_limit,
+ )
+ figure.tight_layout()
+ mpl.show()
+
+ figure, axes = mpl.plot_num_RC_suggestion(suggestion)
+ figure.tight_layout()
+ mpl.show()
+
+ figure, axes = mpl.plot_residuals(test)
+ figure.tight_layout()
+ mpl.show()
+
+ figure, axes = mpl.plot_nyquist(
+ data,
+ colors={"impedance": colors.COLOR_BLACK},
+ legend=False,
+ )
+ _ = mpl.plot_nyquist(
+ test,
+ line=True,
+ figure=figure,
+ axes=axes,
+ )
+ figure.tight_layout()
+ mpl.show()
+
+ figure, axes = mpl.plot_bode(
+ data,
+ colors={
+ "magnitude": colors.COLOR_BLACK,
+ "phase": colors.COLOR_BLACK,
+ },
+ legend=False,
+ )
+ _ = mpl.plot_bode(
+ test,
+ line=True,
+ figure=figure,
+ axes=axes,
+ )
+ figure.tight_layout()
+ mpl.show()
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/apidocs_project.rst.txt b/_sources/apidocs_project.rst.txt
new file mode 100644
index 0000000..24d075a
--- /dev/null
+++ b/_sources/apidocs_project.rst.txt
@@ -0,0 +1,12 @@
+.. include:: ./substitutions.rst
+
+Projects
+========
+
+.. automodule:: deareis
+ :members: Project
+
+.. raw:: latex
+
+ \clearpage
+
diff --git a/_sources/apidocs_typing.rst.txt b/_sources/apidocs_typing.rst.txt
new file mode 100644
index 0000000..44ec6a8
--- /dev/null
+++ b/_sources/apidocs_typing.rst.txt
@@ -0,0 +1,33 @@
+.. include:: ./substitutions.rst
+
+Typing
+======
+
+Some type hints/annotations that are used throughout DearEIS.
+
+
+Aliases
+-------
+
+.. autoclass:: deareis.ComplexImpedance
+.. autoclass:: deareis.ComplexImpedances
+.. autoclass:: deareis.ComplexResidual
+.. autoclass:: deareis.ComplexResiduals
+.. autoclass:: deareis.Frequencies
+.. autoclass:: deareis.Frequency
+.. autoclass:: deareis.Gamma
+.. autoclass:: deareis.Gammas
+.. autoclass:: deareis.Impedance
+.. autoclass:: deareis.Impedances
+.. autoclass:: deareis.Indices
+.. autoclass:: deareis.Phase
+.. autoclass:: deareis.Phases
+.. autoclass:: deareis.Residual
+.. autoclass:: deareis.Residuals
+.. autoclass:: deareis.TimeConstant
+.. autoclass:: deareis.TimeConstants
+
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/apidocs_zhit.rst.txt b/_sources/apidocs_zhit.rst.txt
new file mode 100644
index 0000000..de9c244
--- /dev/null
+++ b/_sources/apidocs_zhit.rst.txt
@@ -0,0 +1,22 @@
+.. include:: ./substitutions.rst
+
+Z-HIT analysis
+==============
+
+.. automodule:: deareis
+ :members: perform_zhit
+
+
+Classes
+-------
+.. automodule:: deareis
+ :members: ZHITResult, ZHITSettings
+
+Enums
+-----
+.. automodule:: deareis
+ :members: ZHITInterpolation, ZHITSmoothing, ZHITWindow
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/guide.rst.txt b/_sources/guide.rst.txt
new file mode 100644
index 0000000..c3f3d18
--- /dev/null
+++ b/_sources/guide.rst.txt
@@ -0,0 +1,26 @@
+Getting started
+===============
+
+Here are some quick guides to getting started with DearEIS.
+
+.. note::
+
+ There are numerous tooltips available throughout the GUI.
+ These can be viewed by hovering the mouse cursor over, e.g., labels next to settings.
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents:
+
+ guide_installing
+ guide_projects
+ guide_data
+ guide_validation
+ guide_drt
+ guide_fitting
+ guide_simulation
+ guide_plotting
+ guide_batch
+ guide_settings
+ guide_palettes
+ guide_api
diff --git a/_sources/guide_api.rst.txt b/_sources/guide_api.rst.txt
new file mode 100644
index 0000000..08a721d
--- /dev/null
+++ b/_sources/guide_api.rst.txt
@@ -0,0 +1,530 @@
+.. include:: ./substitutions.rst
+
+Application programming interface
+=================================
+
+The GUI is the primary interface of DearEIS but an API is also included for some batch processing capabilities.
+However, if an API is the desired interface for performing various tasks, then using pyimpspec_ directly may be preferable.
+
+
+Creating/loading a project
+--------------------------
+
+
+.. doctest::
+
+ >>> from deareis import Project
+ >>>
+ >>> # Create a new project
+ >>> project: Project = Project()
+ >>>
+ >>> # Load an existing project
+ >>> project = Project.from_file("./tests/example-project-v6.json")
+
+
+Batch importing data sets
+-------------------------
+
+.. doctest::
+
+ >>> from deareis import DataSet, Project, parse_data
+ >>>
+ >>> project: Project = Project()
+ >>>
+ >>> data: DataSet
+ >>> for data in parse_data("./tests/data-1.idf"):
+ ... project.add_data_set(data)
+ >>>
+ >>> # Remember to save the project somewhere as well!
+ >>> # project.save("./tests/batch-imported-data.json")
+
+
+Batch plotting results
+----------------------
+
+In the following example we will load a project, iterate over data sets, various results, simulations, and plots.
+A single example of each of these will be plotted.
+
+.. doctest::
+
+ >>> from deareis import (
+ ... DRTResult,
+ ... DataSet,
+ ... FitResult,
+ ... PlotSettings,
+ ... Project,
+ ... SimulationResult,
+ ... KramersKronigResult,
+ ... ZHITResult,
+ ... mpl,
+ ... )
+ >>> import matplotlib.pyplot as plt
+ >>>
+ >>> project: Project = Project.from_file("./tests/example-project-v6.json")
+ >>>
+ >>> data: DataSet
+ >>> for data in project.get_data_sets():
+ ... figure, axes = mpl.plot_data(
+ ... data,
+ ... colored_axes=True,
+ ... legend=False,
+ ... )
+ ...
+ ... # Iterate over Kramers-Kronig results
+ ... test: KramersKronigResult
+ ... for test in project.get_tests(data):
+ ... figure, axes = mpl.plot_fit(
+ ... test,
+ ... data=data,
+ ... colored_axes=True,
+ ... legend=False,
+ ... )
+ ... break
+ ...
+ ... # Iterate over Z-HIT results
+ ... zhit: ZHITResult
+ ... for zhit in project.get_zhits(data):
+ ... figure, axes = mpl.plot_fit(
+ ... zhit,
+ ... data=data,
+ ... colored_axes=True,
+ ... legend=False,
+ ... )
+ ... break
+ ...
+ ... # Iterate over DRT results
+ ... drt: DRTResult
+ ... for drt in project.get_drts(data):
+ ... figure, axes = mpl.plot_drt(
+ ... drt,
+ ... data=data,
+ ... colored_axes=True,
+ ... legend=False,
+ ... )
+ ... break
+ ...
+ ... # Iterate over circuit fits
+ ... fit: FitResult
+ ... for fit in project.get_fits(data):
+ ... figure, axes = mpl.plot_fit(
+ ... fit,
+ ... data=data,
+ ... colored_axes=True,
+ ... legend=False,
+ ... )
+ ... break
+ ... break
+ >>>
+ >>> # Iterate over simulations
+ >>> sim: SimulationResult
+ >>> for sim in project.get_simulations():
+ ... figure, axes = mpl.plot_nyquist(
+ ... sim,
+ ... line=True,
+ ... colored_axes=True,
+ ... legend=False,
+ ... )
+ ... break
+ >>>
+ >>> # Iterate over plots
+ >>> plot: PlotSettings
+ >>> for plot in project.get_plots():
+ ... figure, axes = mpl.plot(plot, project)
+ ... break
+ >>>
+ >>> plt.close("all")
+
+.. raw:: latex
+
+ \clearpage
+
+
+.. plot::
+
+ from deareis import Project, mpl
+ project = Project.from_file("../../tests/example-project-v6.json")
+ for data in project.get_data_sets():
+ figure, axes = mpl.plot_data(
+ data,
+ colored_axes=True,
+ legend=False,
+ )
+ figure.tight_layout()
+ break
+
+
+.. plot::
+
+ from deareis import Project, mpl
+ project = Project.from_file("../../tests/example-project-v6.json")
+ for data in project.get_data_sets():
+ for test in project.get_tests(data):
+ figure, axes = mpl.plot_fit(
+ test,
+ data=data,
+ colored_axes=True,
+ legend=False,
+ )
+ figure.tight_layout()
+ break
+ break
+
+
+.. plot::
+
+ from deareis import Project, mpl
+ project = Project.from_file("../../tests/example-project-v6.json")
+ for data in project.get_data_sets():
+ for zhit in project.get_zhits(data):
+ figure, axes = mpl.plot_fit(
+ zhit,
+ data=data,
+ colored_axes=True,
+ legend=False,
+ )
+ figure.tight_layout()
+ break
+ break
+
+
+.. plot::
+
+ from deareis import Project, mpl
+ project = Project.from_file("../../tests/example-project-v6.json")
+ for data in project.get_data_sets():
+ for drt in project.get_drts(data):
+ figure, axes = mpl.plot_drt(
+ drt,
+ data=data,
+ colored_axes=True,
+ legend=False,
+ )
+ figure.tight_layout()
+ break
+ break
+
+
+.. plot::
+
+ from deareis import Project, mpl
+ project = Project.from_file("../../tests/example-project-v6.json")
+ for data in project.get_data_sets():
+ for fit in project.get_fits(data):
+ figure, axes = mpl.plot_fit(
+ fit,
+ data=data,
+ colored_axes=True,
+ legend=False,
+ )
+ figure.tight_layout()
+ break
+ break
+
+
+.. plot::
+
+ from deareis import Project, mpl
+ project = Project.from_file("../../tests/example-project-v6.json")
+ for sim in project.get_simulations():
+ figure, axes = mpl.plot_nyquist(
+ sim,
+ line=True,
+ colored_axes=True,
+ legend=False,
+ )
+ figure.tight_layout()
+ break
+
+
+.. plot::
+
+ from deareis import Project, mpl
+ project = Project.from_file("../../tests/example-project-v6.json")
+ for plot in project.get_plots():
+ figure, axes = mpl.plot(plot, project)
+ figure.tight_layout()
+ break
+
+
+.. raw:: latex
+
+ \clearpage
+
+
+Customized plots
+----------------
+
+The approach used in the previous example could be used as the basis for creating more complicated plots (i.e., select the data sets and results programmatically).
+However, it may be more convenient to use DearEIS' GUI to select the data sets, results, etc. and assign colors, markers, etc.
+The resulting |PlotSettings| and |PlotSeries| objects can then be used as the foundation for generating the final plot using either the plotting functions included with DearEIS or another plotting library.
+
+.. doctest::
+
+ >>> from deareis import (
+ ... PlotSeries, # Wrapper class for DataSet, KramersKronigResult, etc.
+ ... PlotSettings, # The settings class for plots created via DearEIS' GUI
+ ... PlotType, # Enum for different types of plots (e.g., Nyquist)
+ ... Project,
+ ... mpl,
+ ... )
+ >>> import matplotlib.pyplot as plt
+ >>> from matplotlib.figure import Figure
+ >>> from typing import (
+ ... Optional,
+ ... Tuple,
+ ... )
+ >>>
+ >>> # Prepare the figure that will be used to create a custom Nyquist plot.
+ >>> figure, axis = plt.subplots()
+ >>> axes = [axis]
+ >>>
+ >>> # Load the project of interest.
+ >>> project: Project = Project.from_file("./tests/example-project-v6.json")
+ >>>
+ >>> # Get the settings for the plot that contains the series (data sets,
+ >>> # fit results, etc.) that we wish to plot.
+ >>> plot: PlotSettings = [
+ ... plot for plot in project.get_plots()
+ ... if plot.get_label() == "Noisy"
+ ... ][0]
+ >>>
+ >>> # Each data set, fit result, etc. can be represented as a PlotSeries
+ >>> # object that contains the required data and the style (color, marker, etc.).
+ >>> series: PlotSeries
+ >>> for series in project.get_plot_series(plot):
+ ... # Figure out if the series should be included in the figure legend.
+ ... label: Optional[str] = None
+ ... if series.has_legend():
+ ... label = series.get_label()
+ ...
+ ... # Figure out the color and marker.
+ ... color: Tuple[float, float, float, float] = series.get_color()
+ ... marker: Optional[str] = mpl.MPL_MARKERS.get(series.get_marker())
+ ...
+ ... # Determine whether or not the series should be plotted using markers,
+ ... # a line, or both.
+ ... # We will use the plotting functions provided by DearEIS in this example
+ ... # but you could use any plotting library that you wish. However, you
+ ... # would need to call, e.g., series.get_frequencies() and/or
+ ... # series.get_impedances() to get the relevant data.
+ ... if series.has_line():
+ ... _ = mpl.plot_nyquist(
+ ... series,
+ ... colors={"impedance": color},
+ ... markers={"impedance": marker},
+ ... line=True,
+ ... label=label if marker is None else "",
+ ... figure=figure,
+ ... axes=axes,
+ ... num_per_decade=50,
+ ... )
+ ... if marker is not None:
+ ... _ = mpl.plot_nyquist(
+ ... series,
+ ... colors={"impedance": color},
+ ... markers={"impedance": marker},
+ ... line=False,
+ ... label=label,
+ ... figure=figure,
+ ... axes=axes,
+ ... num_per_decade=-1,
+ ... )
+ ... elif marker is not None:
+ ... _ = mpl.plot_nyquist(
+ ... series,
+ ... colors={"impedance": color},
+ ... markers={"impedance": marker},
+ ... line=False,
+ ... label=label,
+ ... figure=figure,
+ ... axes=axes,
+ ... num_per_decade=-1,
+ ... )
+ >>>
+ >>> # Add the figure title and legend.
+ >>> _ = figure.suptitle(plot.get_label())
+ >>> _ = axis.legend()
+
+
+.. plot::
+
+ from deareis import (
+ PlotSeries,
+ PlotSettings,
+ PlotType,
+ Project,
+ mpl,
+ )
+ import matplotlib.pyplot as plt
+ from matplotlib.figure import Figure
+ from typing import (
+ Optional,
+ Tuple,
+ )
+ figure, axis = plt.subplots()
+ axes = [axis]
+ project: Project = Project.from_file("../../tests/example-project-v6.json")
+ plot: PlotSettings = [plot for plot in project.get_plots() if plot.get_label() == "Noisy"][0]
+ assert plot.get_type() == PlotType.NYQUIST_IMPEDANCE
+ series: PlotSeries
+ for series in project.get_plot_series(plot):
+ label: Optional[str] = None
+ if series.has_legend():
+ label = series.get_label()
+ color: Tuple[float, float, float, float] = series.get_color()
+ marker: Optional[str] = mpl.MPL_MARKERS.get(series.get_marker())
+ if series.has_line():
+ _ = mpl.plot_nyquist(
+ series,
+ colors={"impedance": color},
+ markers={"impedance": marker},
+ line=True,
+ label=label if marker is None else "",
+ figure=figure,
+ axes=axes,
+ num_per_decade=50,
+ )
+ if marker is not None:
+ _ = mpl.plot_nyquist(
+ series,
+ colors={"impedance": color},
+ markers={"impedance": marker},
+ line=False,
+ label=label,
+ figure=figure,
+ axes=axes,
+ num_per_decade=-1,
+ )
+ elif marker is not None:
+ _ = mpl.plot_nyquist(
+ series,
+ colors={"impedance": color},
+ markers={"impedance": marker},
+ line=False,
+ label=label,
+ figure=figure,
+ axes=axes,
+ num_per_decade=-1,
+ )
+ _ = figure.suptitle(plot.get_label())
+ _ = axis.legend()
+
+.. raw:: latex
+
+ \clearpage
+
+
+Generating tables
+-----------------
+
+Several of the various ``*Result`` classes have ``to_*_dataframe`` methods that return tables as ``pandas.DataFrame`` objects, which can be used to output, e.g., Markdown or LaTeX tables.
+
+.. doctest::
+
+ >>> from deareis import DataSet, FitResult, Project
+ >>> project: Project = Project.from_file("./tests/example-project-v6.json")
+ >>> data: DataSet = project.get_data_sets()[0]
+ >>> fit: FitResult = project.get_fits(data)[0]
+ >>> print(fit.to_parameters_dataframe().to_markdown(index=False))
+ | Element | Parameter | Value | Std. err. (%) | Unit | Fixed |
+ |:----------|:------------|--------------:|----------------:|:----------|:--------|
+ | R_1 | R | 99.9527 | 0.0270272 | ohm | No |
+ | R_2 | R | 200.295 | 0.0161674 | ohm | No |
+ | C_1 | C | 7.98618e-07 | 0.00251014 | F | No |
+ | R_3 | R | 499.93 | 0.0228817 | ohm | No |
+ | W_1 | Y | 0.000400664 | 0.0303242 | S*s^(1/2) | No |
+ >>> print(fit.to_parameters_dataframe(running=True).to_markdown(index=False))
+ | Element | Parameter | Value | Std. err. (%) | Unit | Fixed |
+ |:----------|:------------|--------------:|----------------:|:----------|:--------|
+ | R_0 | R | 99.9527 | 0.0270272 | ohm | No |
+ | R_1 | R | 200.295 | 0.0161674 | ohm | No |
+ | C_2 | C | 7.98618e-07 | 0.00251014 | F | No |
+ | R_3 | R | 499.93 | 0.0228817 | ohm | No |
+ | W_4 | Y | 0.000400664 | 0.0303242 | S*s^(1/2) | No |
+
+.. raw:: latex
+
+ \clearpage
+
+
+Generating circuit diagrams
+---------------------------
+
+``Circuit`` objects can be used to draw circuit diagrams.
+
+.. doctest::
+
+ >>> from deareis import DataSet, FitResult, Project
+ >>> project: Project = Project.from_file("./tests/example-project-v6.json")
+ >>> data: DataSet = project.get_data_sets()[0]
+ >>> fit: FitResult = project.get_fits(data)[0]
+ >>> print(fit.circuit.to_circuitikz())
+ \begin{circuitikz}
+ \draw (0,0) to[short, o-] (1,0);
+ \draw (1.0,0.0) to[R=$R_{\rm 1}$] (3.0,0.0);
+ \draw (3.0,-0.0) to[R=$R_{\rm 2}$] (5.0,-0.0);
+ \draw (3.0,-1.5) to[capacitor=$C_{\rm 1}$] (5.0,-1.5);
+ \draw (3.0,-0.0) to[short] (3.0,-1.5);
+ \draw (5.0,-0.0) to[short] (5.0,-1.5);
+ \draw (5.0,-0.0) to[R=$R_{\rm 3}$] (7.0,-0.0);
+ \draw (5.0,-1.5) to[generic=$W_{\rm 1}$] (7.0,-1.5);
+ \draw (5.0,-0.0) to[short] (5.0,-1.5);
+ \draw (7.0,-0.0) to[short] (7.0,-1.5);
+ \draw (7.0,0) to[short, -o] (8.0,0);
+ \end{circuitikz}
+ >>> print(fit.circuit.to_circuitikz(running=True))
+ \begin{circuitikz}
+ \draw (0,0) to[short, o-] (1,0);
+ \draw (1.0,0.0) to[R=$R_{\rm 0}$] (3.0,0.0);
+ \draw (3.0,-0.0) to[R=$R_{\rm 1}$] (5.0,-0.0);
+ \draw (3.0,-1.5) to[capacitor=$C_{\rm 2}$] (5.0,-1.5);
+ \draw (3.0,-0.0) to[short] (3.0,-1.5);
+ \draw (5.0,-0.0) to[short] (5.0,-1.5);
+ \draw (5.0,-0.0) to[R=$R_{\rm 3}$] (7.0,-0.0);
+ \draw (5.0,-1.5) to[generic=$W_{\rm 4}$] (7.0,-1.5);
+ \draw (5.0,-0.0) to[short] (5.0,-1.5);
+ \draw (7.0,-0.0) to[short] (7.0,-1.5);
+ \draw (7.0,0) to[short, -o] (8.0,0);
+ \end{circuitikz}
+ >>> figure = fit.circuit.to_drawing().draw()
+ >>> figure = fit.circuit.to_drawing(running=True).draw()
+
+.. plot::
+
+ from deareis import Project
+ project = Project.from_file("../../tests/example-project-v6.json")
+ data = project.get_data_sets()[0]
+ fit = project.get_fits(data)[0]
+ fit.circuit.to_drawing().draw()
+ fit.circuit.to_drawing(running=True).draw()
+
+.. raw:: latex
+
+ \clearpage
+
+.. _generating_equations:
+
+Generating equations
+--------------------
+
+Equations for the impedances of elements and circuits can be obtained in the form of SymPy_ expressions or LaTeX strings.
+
+.. note::
+
+ Equations **always** make use of a running count of the elements as the lower index in variables to avoid conflicting/duplicate variable names from different elements.
+ Circuit diagrams and tables can also make use of running counts as lower indices if explicitly told to (e.g., ``circuit.to_drawing(running=True)``, ``circuit.to_circuitikz(running=True)``, or ``fit.to_parameters_dataframe(running=True)``).
+
+.. doctest::
+
+ >>> from deareis import DataSet, FitResult, Project
+ >>> project: Project = Project.from_file("./tests/example-project-v6.json")
+ >>> data: DataSet = project.get_data_sets()[0]
+ >>> fit: FitResult = project.get_fits(data)[0]
+ >>> print(fit.circuit.to_sympy())
+ R_0 + 1/(2*I*pi*C_2*f + 1/R_1) + 1/(sqrt(2)*sqrt(pi)*Y_4*sqrt(I*f) + 1/R_3)
+ >>> print(fit.circuit.to_latex())
+ Z = R_{0} + \frac{1}{2 i \pi C_{2} f + \frac{1}{R_{1}}} + \frac{1}{\sqrt{2} \sqrt{\pi} Y_{4} \sqrt{i f} + \frac{1}{R_{3}}}
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/guide_batch.rst.txt b/_sources/guide_batch.rst.txt
new file mode 100644
index 0000000..1f9a657
--- /dev/null
+++ b/_sources/guide_batch.rst.txt
@@ -0,0 +1,29 @@
+.. include:: ./substitutions.rst
+
+Batch analysis
+==============
+
+The various tabs dedicated to performing some form of analysis also have a **Batch** button.
+These buttons bring up a window (:numref:`batch_window`)where multiple data sets can be selected for inclusion in a batch analysis.
+
+.. _batch_window:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/batch-analysis.png
+ :alt: The Batch analysis window
+
+ An example of the **Batch analysis** window where a few data sets have been selected.
+
+.. note::
+
+ If any errors are encountered while performing the analyses, then those errors are presented at the end.
+ There is no way to cancel a batch analysis once it has been started.
+
+
+.. note::
+
+ Performing Kramers-Kronig tests in **Exploratory** mode would usually bring up a window for inspection of the intermediate results.
+ This window is **NOT** shown when performing a batch analysis.
+
+.. raw:: latex
+
+ \clearpage
+
diff --git a/_sources/guide_data.rst.txt b/_sources/guide_data.rst.txt
new file mode 100644
index 0000000..1626ad6
--- /dev/null
+++ b/_sources/guide_data.rst.txt
@@ -0,0 +1,226 @@
+.. include:: ./substitutions.rst
+
+Processing data
+===============
+
+The **Data sets** tab
+---------------------
+
+Multiple impedance spectra (or *data sets*) can be loaded and processed in the **Data sets** tab (:numref:`data_tab`) that contains the following:
+
+- **Data set** combo for switching between data sets that have been loaded via the **Load** button.
+- **Label** input for modifying the label assigned to the current data set.
+- **Path** input for modifying the file path assigned to the current data set.
+- **Process** button for opening a popup window with buttons for accessing features that enable further processing of the current data set.
+- A table of data points with the ability to mask (i.e., hide/exclude) individual points (e.g., outliers).
+- **Toggle points** button for (un)masking multiple points at once.
+- **Copy mask** button for copying a mask from another data set and applying it to the current data set.
+- **Enlarge/show plot** button for viewing a larger version of the current plot type.
+- **Adjust limits** checkbox for enabling/disabling automatic adjustment of plot limits when switching between data sets.
+- Plot type combo for switching between plot types. This is primarily for use when the program window is so narrow that the plots are hidden in order to keep the table of data points from becoming to narrow.
+
+
+.. _data_tab:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/data-sets-tab.png
+ :alt: The Data sets tab of a project
+
+ The data point around 50 Hz has been omitted from this rather noisy data set as an outlier.
+
+.. raw:: latex
+
+ \clearpage
+
+
+Supported file formats
+----------------------
+
+Several different file formats are supported:
+
+- BioLogic: ``.mpt``
+- Eco Chemie: ``.dfr``
+- Gamry: ``.dta``
+- Ivium: ``.idf`` and ``.ids``
+- PalmSens: ``.pssession``
+- ZView: ``.z``
+- Spreadsheets: ``.xlsx`` and ``.ods``
+- Plain-text character-separated values (CSV): ``.csv`` and ``.txt``
+
+Additional file formats may be supported in the future.
+
+Not all CSV files and spreadsheets are necessarily supported as-is but the parsing of those types of files should be quite flexible in terms of, e.g., the characters that are used as separators.
+The parsers expect to find at least a column with frequencies (Hz) and columns for either the real and imaginary parts of the impedance (|ohm|), or the absolute magnitude (|ohm|) and the phase angle/shift (degrees).
+The supported column headers are:
+
+- frequency: ``frequency``, ``freq``, or ``f``
+- real: ``z'``, ``z re``, ``z_re``, ``zre``, ``real``, or ``re``
+- imaginary: ``z"``, ``z''``, ``z im``, ``z_im``, ``zim``, ``imaginary``, ``imag``, or ``im``
+- magnitude: ``|z|``, ``z``, ``magnitude``, ``modulus``, ``mag``, or ``mod``
+- phase: ``phase``, ``phz``, or ``phi``
+
+The identification of column headers is case insensitive (i.e., ``Zre`` and ``zre`` are considered to be the same).
+The sign of the imaginary part of the impedance and/or the phase angle/shift may be negative, but then that has to be indicated in the column header with a ``-`` prefix (e.g., ``-Zim`` or ``-phase``).
+
+.. raw:: latex
+
+ \clearpage
+
+
+Masking data points
+-------------------
+
+Masks can be applied to hide data points in several ways and masked data points are excluded from plots and analyses.
+This feature can be used to get rid of outliers or to analyze a fragment of a data set.
+Individual data points can be masked via the checkboxes along the left-hand side of the table of data points (:numref:`data_tab`).
+Ranges of data points can be toggled via the window that is accessible via the **Toggle points** button below the table of data points.
+This can be used to, e.g., quickly mask multiple points or to remove the mask from all points (:numref:`toggle_figure`).
+Middle-mouse clicking and dragging a region in a plot in that window can also be used to choose the points to toggle.
+
+
+.. _toggle_figure:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/data-sets-tab-toggle.png
+ :alt: Masking multiple points
+
+ The **Toggle points** can be used to (un)mask multiple data points in several ways.
+ A preview of what the current data set would look like with the new mask is also included.
+ Here a region has been highlighted in one of the plots by holding down the middle-mouse button and dragging.
+ All of the points are included, which means that the points within the highlighted region will be toggled (i.e., excluded) when the **Accept** button is clicked.
+
+.. raw:: latex
+
+ \clearpage
+
+If multiple data sets will need to have the same (or very similar) masks, then the **Copy mask** window can be used to copy the applied mask from another data set to the current data set (:numref:`mask_figure`).
+
+
+.. _mask_figure:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/data-sets-tab-copy.png
+ :alt: Copying a mask from another data set
+
+ The **Copy mask** includes a preview of what the current data set would look like with the mask that was applied to another data set in :numref:`toggle_figure`.
+
+.. raw:: latex
+
+ \clearpage
+
+
+Processing data sets
+--------------------
+
+DearEIS includes a few functions for processing data sets: averaging, interpolation, addition of parallel impedances, and subtraction of impedances.
+All of these functions are available via the **Process** button that can be found above the table of data points (:numref:`data_tab`).
+The results of these functions are added to the project as a new data set (i.e., without getting rid of the original data set).
+
+
+Averaging
+~~~~~~~~~
+
+The averaging feature can be used to obtain a less noisy spectrum by averaging multiple measurements (:numref:`averaging_figure`).
+This can be useful in cases where the noise cannot be reduced by adjusting some aspect of the experimental setup (e.g., by improving the shielding).
+Only data sets with the same frequencies can be averaged.
+
+.. note::
+
+ Make sure that the measurements differ due to random noise rather than, e.g., drift before using this feature.
+
+.. _averaging_figure:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/data-sets-tab-averaging.png
+ :alt: Averaging of multiple data sets
+
+ Two data sets have been chosen (markers) and an average data set has been generated (line).
+ The other data sets do not have the same frequencies as the two chosen data sets and thus cannot be selected while at least one of those two data sets is selected.
+
+.. raw:: latex
+
+ \clearpage
+
+
+Interpolation
+~~~~~~~~~~~~~
+
+The interpolation feature can be used to replace an outlier rather than simply omitting it (:numref:`interpolation_figure`).
+Some specific methods of analysis may be sensitive to the spacing of data points, which is why interpolation may be preferred over omission.
+The data set is smoothed using `LOWESS `_ and interpolated using an `Akima spline `_ while ignoring any masked points.
+Individual data points can then be replaced with a point on this spline by ticking the checkbox next to that data point.
+Alternatively, if the smoothing and interpolation cannot provide a reasonable result, then values for the real and/or imaginary part of the data point can be inputted directly.
+
+
+.. _interpolation_figure:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/data-sets-tab-interpolation.png
+ :alt: Interpolation of data points
+
+ The outlier (red marker), which was masked in :numref:`data_tab`, has been replaced with a value (orange marker) along the interpolated spline (green line).
+
+.. raw:: latex
+
+ \clearpage
+
+.. _parallel impedances:
+
+Adding parallel impedances
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Impedance data that include negative differential resistances may present some challenges.
+For example, such spectra cannot be validated directly using linear Kramers-Kronig tests if only the impedance representation is tested.
+However, they can be validated if the admittance representation is tested.
+Alternatively, one can add a suitable parallel resistance to the impedance data.
+The addition of a parallel resistance does not affect the Kramers-Kronig compliance of the data.
+
+.. plot::
+ :alt: A circuit where the a parallel resistance, R, has been added to the original impedance data, Z.
+
+ from pyimpspec import parse_cdc
+ # A Warburg impedance is used here just to have two different symbols
+ circuit = parse_cdc("(WR)")
+ elements = circuit.get_elements()
+ custom_labels = {
+ elements[0]: r"$Z_{\rm data}$",
+ elements[1]: r"$R_{\rm par}$",
+ }
+ circuit.to_drawing(custom_labels=custom_labels).draw()
+
+
+The magnitude of the parallel resistance to add depends on the original impedance data.
+In the example below (:numref:`parallel_figure`), a resistance of 50 |ohm| was chosen.
+
+
+.. note::
+
+ Equivalent circuits can be fitted to the original impedance data that include negative differential resistances provided that negative resistances are allowed (i.e., the lower limits of resistances are disabled or modified prior to fitting).
+
+.. _parallel_figure:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/data-sets-tab-parallel.png
+ :alt: Addition of parallel impedance to impedance data
+
+ An impedance spectrum that includes a negative differential resistance was generated for this example (marked here as **Before**).
+ Performing Kramers-Kronig tests on the impedance representation would fail despite the original data being compliant.
+ Adding a parallel resistance of 50 |ohm| produces impedance data (marked here as **After**) that can be validated.
+ The added parallel resistance is always Kramers-Kronig compliant, which means that the compliance of the resulting circuit and its impedance data depends on the compliance of the original data.
+
+
+.. raw:: latex
+
+ \clearpage
+
+
+Subtracting impedances
+~~~~~~~~~~~~~~~~~~~~~~
+
+The recorded impedances can also be corrected by subtracting one of the following (:numref:`subtraction_figure`):
+
+- a fixed impedance
+- a circuit
+- a fitted circuit
+- another data set
+
+This feature can be used to, e.g., correct for some aspect of a measurement setup that is independent of the sample itself.
+
+.. _subtraction_figure:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/data-sets-tab-subtraction.png
+ :alt: Subtraction of impedances from a recorded spectrum
+
+ A resistance of 50 |ohm| is subtracted from a data set.
+
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/guide_drt.rst.txt b/_sources/guide_drt.rst.txt
new file mode 100644
index 0000000..cf962ac
--- /dev/null
+++ b/_sources/guide_drt.rst.txt
@@ -0,0 +1,105 @@
+.. include:: ./substitutions.rst
+
+Distribution of relaxation times analysis
+=========================================
+
+Performing analyses
+-------------------
+
+The distribution of relaxation times (DRT) can be calculated using multiple different approaches (see the corresponding publications for details):
+
+- `Bayesian Hilbert transform (BHT) `_
+- `Tikhonov regularization and non-negative least squares fitting (TR-NNLS) `_
+- `Tikhonov regularization and radial basis function (or piecewise linear) discretization (TR-RBF) `_
+- `multi-(RQ) fit (m(RQ)fit) `_
+
+
+This type of analysis can be used, e.g., as an aid when developing equivalent circuits by revealing the number of time constants.
+The peak shapes (e.g., symmetry and sharpness) can also help with identifying circuit elements that could be suitable.
+
+DRT calculations can be performed in the **DRT analysis** tab (:numref:`drt_tab`):
+
+- the various settings that determine how the DRT calculations are performed
+- combo boxes that can be used to choose the active data set and the active result, and a button for deleting the active result
+- a table of statistics related to the active result
+- a table of the settings that were used to obtain the active result
+
+.. _drt_tab:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/drt-tab.png
+ :alt: The DRT analysis tab of a project
+
+ An example of a result obtained with the noisy data set and the TR-RBF method.
+
+The results are presented in the form of one or more tables (e.g., statistics, scores), a plot of gamma versus time constant, and other plots.
+Some results can be copied to the clipboard in different plain-text formats via the **Output** combo box and the **Copy** button.
+
+It was mentioned in the :doc:`/guide_data` subchapter that some forms of analysis can be sensitive to the omission of a data point.
+Below are some examples of this.
+The overlay plots shown below are created using the **Plotting** tab (more information about that can be found in the :doc:`/guide_plotting` subchapter).
+
+.. _drt_overlay:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/drt-overlaid.png
+ :alt: Three overlaid DRT spectra
+
+ Three overlaid DRT spectra that were obtained with the TR-RBF method using the same settings: with outlier (original), without outlier (omitted), and with the outlier replaced (interpolated).
+ The presence of the outlier clearly has a significant effect on peak positions in the range above 0.001 s.
+ However, omitting the outlier resulted in additional peaks appearing within the 0.01 to 0.1 s range.
+
+.. raw:: latex
+
+ \clearpage
+
+
+.. _drt_overlay_2:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/drt-overlaid-2.png
+ :alt: Six overlaid DRT spectra
+
+ Additional DRT spectra, which were obtained by fitting **R(RC)(RQ)** circuits and calculating the DRT using the m(RQ)fit method, overlaid on top of :numref:`drt_overlay`.
+ The presence of the outlier has shifted the peaks toward lower time constants (original).
+ The m(RQ)fit method is less sensitive to the omission of the outlier as can be seen from the two DRT spectra (omitted and interpolated) that are almost identical.
+ The two latter spectra also have, e.g., their left-most peaks in the correct position of approximately 0.00016 s which is the expected value based on the known resistance and capacitance values (200 |ohm| and 0.8 :math:`\mathrm{\mu F}`, respectively) of the circuit that was used to generate the data sets.
+
+.. raw:: latex
+
+ \clearpage
+
+
+One can see based on :numref:`drt_overlay_2` that different DRT methods can produce very different results, but the settings and amount of noise in the data also have a significant effect as can be seen in :numref:`drt_overlay_3`.
+
+.. _drt_overlay_3:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/drt-overlaid-3.png
+ :alt: Four overlaid DRT spectra
+
+ In this example two DRT spectra are shown for each of the data sets: ideal (no noise) and interpolated (noisy with the outlier replaced).
+ The DRT spectra have been obtained using the TR-RBF method with otherwise identical settings apart from the regularization parameters, |lambda|, that are indicated in the labels found in the plot legend.
+
+
+References:
+
+- `Boukamp, B.A., 2015, Electrochim. Acta, 154, 35-46 `_
+- `Boukamp, B.A. and Rolle, A, 2017, Solid State Ionics, 302, 12-18 `_
+- `Ciucci, F. and Chen, C., 2015, Electrochim. Acta, 167, 439-454 `_
+- `Effat, M. B. and Ciucci, F., 2017, Electrochim. Acta, 247, 1117-1129 `_
+- `Kulikovsky, A., 2021, J. Electrochem. Soc., 168, 044512 `_
+- `Liu, J., Wan, T. H., and Ciucci, F., 2020, Electrochim. Acta, 357, 136864 `_
+- `Wan, T. H., Saccoccio, M., Chen, C., and Ciucci, F., 2015, Electrochim. Acta, 184, 483-499 `_
+
+.. raw:: latex
+
+ \clearpage
+
+
+Applying old settings and masks
+-------------------------------
+
+The settings that were used to perform the active analysis result are also presented as a table and these settings can be applied by pressing the **Apply settings** button.
+
+The mask that was applied to the data set when the analysis was performed can be applied by pressing the **Apply mask** button.
+If the mask that is applied to the data set has changed since an earlier analysis was performed, then that will be indicated clearly above the statistics table.
+
+These features make it easy to restore old settings/masks in case, e.g., DearEIS has been closed and relaunched, or after trying out different settings.
+
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/guide_fitting.rst.txt b/_sources/guide_fitting.rst.txt
new file mode 100644
index 0000000..faa5f55
--- /dev/null
+++ b/_sources/guide_fitting.rst.txt
@@ -0,0 +1,185 @@
+.. include:: ./substitutions.rst
+
+Fitting
+=======
+
+The **Fitting** tab is where equivalent circuits can be fitted to data sets (:numref:`fitting_tab`):
+
+- the various settings that determine how the fitting is performed
+- combo boxes that can be used to choose the active data set, the active fit result, and the active output
+- a table of fitted parameter values and estimated errors (if possible to estimate)
+- a table of statistics related to the active fit result
+- a table of the settings that were used to obtain the active result
+
+
+.. _fitting_tab:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/fitting-tab.png
+ :alt: The Fitting tab of a project.
+
+ An example of an **R(RC)(RW)** circuit that has been fitted to a data set.
+ The obtained fitted parameters are close to the parameters that were used to generate the data set in the first place.
+
+Equivalent circuits can be constructed either by typing in a corresponding `circuit description code (CDC) `_ or by using the graphical circuit editor, which is accessible by pressing the **Edit** button.
+
+Different iterative methods and weights are available.
+If one or both of these settings are set to **Auto**, then combinations of iterative method(s) and weight(s) are used to perform multiple fits in parallel and the best fit is returned.
+
+The results are presented in the form of a table containing the fitted parameter values (and, if possible, error estimates for the fitted parameter values), a table containing statistics pertaining to the quality of the fit, three plots (Nyquist, Bode, and relative errors of the fit), and a preview of the circuit that was fitted to the data set.
+If you hover the mouse cursor over the cells in the tables, then you can get additional information (e.g., more precise values or explanations).
+
+.. note::
+
+ It may not always be possible to estimate errors for fitted parameters.
+ Common causes include:
+
+ - A parameter's fitted value is close to the parameter's lower or upper limit.
+ - An inappropriate equivalent circuit has been chosen.
+ - The maximum number of function evaluations is set too low.
+ - The data contains no noise and the equivalent circuit is very good at reproducing the data.
+
+
+Equivalent circuits
+-------------------
+
+The CDC syntax is quite simple:
+
+- Circuit elements are represented by one or more letter symbols such as ``R`` for a resistor, ``C`` for a capacitor, and ``Wo`` for a Warburg diffusion of finite-length with a reflective boundary.
+- Two or more circuit elements enclosed in parentheses, ``()``, are connected in parallel.
+- Two or more circuit elements enclosed in square brackets, ``[]``, are connected in series. This can be used to construct, e.g., a parallel connection that contains a nested series connection (``(C[RW])`` where ``R`` and ``W`` are connected together in series and that series connection is in parallel with ``C``).
+
+DearEIS also supports an extended CDC syntax.
+This extended syntax allows for defining circuit elements with, e.g., labels, initial values for parameters, and parameter limits.
+Circuit elements can be followed up by curly braces and the aforementioned things can be defined within these curly braces.
+For example, ``R{R=250f:ct}`` defines a resistor with:
+
+- an initial value of 250 ohms for the resistance ``R``
+- a fixed initial value (i.e., a constant value)
+- the label ``ct``, which stands for charge transfer
+
+E notation (e.g., ``1e-6`` or ``1E-6`` instead of ``0.000001``) is supported by the extended syntax.
+All parameters do not need to be defined if a circuit element has multiple parameters.
+If parameters are omitted, then the default values are used (e.g., the default initial value for the ``R`` parameter of a resistor is 1000 ohms).
+If parameter limits are completely omitted, then the default values are used (e.g., the default lower limit for the ``R`` parameter of a resistor i 0 and the upper limit is infinity).
+``Q{Y=1.3e-7//1e-5,n=0.95/0.9/1.0:dl}`` defines a constant phase element with:
+
+- an initial value of 1.3 \* 10^-7 F\*s^(n-1) for the ``Y`` parameter (other sources may use the notation ``A`` or ``Q0`` for this parameter) with no lower limit and an upper limit of 1 \* 10^-5 F\*s^(n-1)
+- an initial value of 0.95 for the ``n`` parameter (other sources may use the notation ``alpha`` or ``psi`` for this parameter) with a lower limit of 0.9 and an upper limit of 1.0
+- the label ``dl``, which stands for double-layer (i.e., double-layer capacitance)
+
+The valid symbols are listed in the **Elements** tab found within the **Diagram** tab of the **Circuit editor** window.
+
+Alternatively, nodes representing the circuit elements can be added to the node editor and connected together to form an equivalent circuit.
+Circuit elements can be added to the node editor by clicking on a type of element in the **Elements** tab or by dragging a type of element from the **Elements** tab and onto the node editor.
+The nodes can be linked together by clicking and dragging between the terminals of the nodes (i.e., the yellow dots on either side of a node).
+If two parallel circuits are connected in series like in :numref:`circuit_editor`, then it is necessary to place a node between them.
+This node could be an element (e.g., a resistor) that is also connected in series to the two parallel circuits or it could be a dummy node.
+This dummy node, which can be added with the **Add dummy/junction** button, does not affect the impedance of the system at all.
+Links between nodes can be deleted by either clicking on a link and then pressing the **Delete** button on the keyboard, or by holding down **Ctrl** when clicking on a link.
+Multiple nodes can be moved or deleted by clicking and dragging a selection box around them.
+
+.. raw:: latex
+
+ \clearpage
+
+
+.. note::
+
+ Click and hold on a terminal/pin (yellow dot) to start creating a link and then drag and release near another terminal/pin.
+ Hold down Ctrl while clicking on a link to remove the link.
+
+
+.. _circuit_editor:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/fitting-tab-editor.png
+ :alt: Example of the circuit editor window
+
+ The graphical circuit editor can be used to construct equivalent circuits and to define the initial values and limits of parameters.
+
+
+.. _node_selected:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/fitting-tab-editor-selected.png
+ :alt: After selecting a node
+
+ Selecting a node makes it possible to assign a label (e.g., ``ct`` for charge transfer).
+
+.. note::
+
+ Due to technical reasons, one must click on the upper part of a node (i.e., where the label is) that represents a circuit element in order to be able to define, e.g., custom initial values.
+ Also, any values typed into the input fields must be confirmed by pressing ``Enter`` or the value will not actually be set.
+ Click and hold on the lower part of the node to move it around.
+.. _container_elements:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/fitting-tab-editor-container.png
+ :alt: Example of the parameters and subcircuits of a container element
+
+ Container elements such as the general transmission line model have subcircuits that can also be modified.
+
+Press the **Accept circuit** button in the bottom right-hand corner once the equivalent circuit is complete.
+If there is an issue with the equivalent circuit (e.g., a missing or invalid connection), then the button will be labeled **Cancel** instead.
+The **Status** field at the bottom of the window should offer some help regarding the nature of the issue and the affected node should be highlighted with a red label (:numref:`invalid_circuit`).
+
+.. _invalid_circuit:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/fitting-tab-editor-invalid.png
+ :alt: Example of a status message for an invalid circuit (e.g., missing connection)
+
+ If the circuit is invalid because of, e.g., a missing connection, then that is indicated by highlighting the affected node and by showing a relevant error message in the status field near the bottom of the window.
+
+
+Adjusting parameters
+--------------------
+
+The initial values of the parameters of each circuit element can be adjusted via the circuit editor's **Parameters** tab.
+This tab provides a real-time preview of the impedance/admittance spectrum produced by the circuit.
+The lower and/or upper limits of the parameters can also be defined, and parameters can also be given fixed values.
+
+..
+ This figure must be updated
+
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/fitting-tab-editor-adjustment.png
+ :alt: The parameter adjustment tab of the Circuit editor window
+
+ The **Parameters** tab of the **Circuit editor** window provides a convenient way of dialing in the initial values before performing a fit.
+
+It is possible to apply the values, which were obtained by fitting a circuit, as the initial values for another iteration of circuit fitting.
+This is accomplished by clicking the **Apply fitted values as initial values** button that can be found below the table of fitted values in the **Fitting** tab of the project.
+
+
+Applying old settings and masks
+-------------------------------
+
+The settings that were used to perform the active fitting result are also presented as a table and these settings can be applied by pressing the **Apply settings** button.
+
+The mask that was applied to the data set when the fitting was performed can be applied by pressing the **Apply mask** button.
+If the mask that is applied to the data set has changed since an earlier fitting was performed, then that will be indicated clearly above the statistics table.
+
+These features make it easy to restore old settings/masks in case, e.g., DearEIS has been closed and relaunched, or after trying out different settings.
+
+
+Copying results to the clipboard
+--------------------------------
+
+Different aspects of the results can be copied to the clipboard in different plain-text formats via the **Output** combo box and the **Copy** button.
+For example, the following results can be copied:
+
+- the basic or extended CDC of the fitted circuit
+- a table of the impedance response of the fitted circuit as character-separated values
+- a table of the fitted parameters as, e.g., character-separated values.
+- a circuit diagram of the fitted circuit as, e.g., LaTeX or Scalable Vector Graphics (see example below)
+- the SymPy_ expression describing the impedance of the fitted circuit
+
+.. note::
+
+ Variables in SymPy expressions use a different set of lower indices to avoid conflicting variable names. See :ref:`generating_equations` for more information.
+
+
+.. plot::
+ :caption: Example of a circuit diagram as it would look if it was copied as Scalable Vector Graphics.
+
+ from pyimpspec import Circuit, parse_cdc
+ circuit: Circuit = parse_cdc("R(RC)(RW)")
+ drawing = circuit.to_drawing()
+ drawing.draw()
+
+
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/guide_installing.rst.txt b/_sources/guide_installing.rst.txt
new file mode 100644
index 0000000..1e9df75
--- /dev/null
+++ b/_sources/guide_installing.rst.txt
@@ -0,0 +1,127 @@
+.. include:: ./substitutions.rst
+
+Installing
+==========
+
+Supported platforms
+-------------------
+
+- Linux
+- Windows
+- MacOS
+
+The package **may** also work on other platforms depending on whether or not those platforms are supported by DearEIS' dependencies.
+
+
+Requirements
+------------
+
+- `Python `_ (3.10, 3.11, or 3.12)
+- The following Python packages
+
+ - `dearpygui `_
+ - `requests `_
+ - pyimpspec_
+
+These Python packages (and their dependencies) are installed automatically when DearEIS is installed using `pip `_.
+
+The following Python packages can be installed as optional dependencies for additional functionality:
+
+- DRT calculations using the `TR-RBF method `_ (at least one of the following is required):
+ - `cvxopt `_
+ - `kvxopt `_ (this fork of cvxopt may support additional platforms)
+
+
+Installing
+----------
+
+Make sure that Python and pip are installed first (see previous section for supported Python versions).
+For example, open a terminal and run the command:
+
+.. code:: bash
+
+ pip --version
+
+
+.. note::
+
+ Using a Python `virtual environment `_ is highly recommended in order to avoid possible issues related to conflicting versions of dependencies installed on a system.
+ Such a virtual environment needs to be activated before running a script that imports a package installed inside the virtual environment.
+ The system-wide Python environment may also be `externally managed `_ in order to prevent the user from accidentally breaking that environment since the operating system depends upon the packages in that environment.
+
+ A third-party tool called `pipx `_ can automatically manage such virtual environments, but it is primarily for installing programs that provide, e.g., a command-line interface (CLI) or a graphical user interface (GUI).
+ These programs can then be run without having to manually activate the virtual environment since pipx handles that.
+ The virtual environment would still need to be activated before running a script that imports DearEIS and makes use of DearEIS's application programming interface (API).
+
+If using pipx, then run the following command to make sure that pipx is available.
+If pipx is not available, then follow the `instructions to install pipx `_.
+
+.. code:: bash
+
+ pipx --version
+
+
+If there are no errors, then run the following command to install DearEIS and its dependencies:
+
+.. code:: bash
+
+ # If manually managing the virtual environment,
+ # follow the relevant pip documentation for creating
+ # and activating a virtual environment before running
+ # the following command.
+ pip install deareis
+
+ # If pipx is used to automatically manage the virtual environment.
+ pipx install deareis
+
+
+DearEIS should now be available as a command in the terminal and possibly also some application launchers.
+
+If you wish to install the optional dependencies, then they can be specified explicitly when installing DearEIS via pip:
+
+.. code:: bash
+
+ pip install deareis[cvxopt]
+
+
+Optional dependencies can also be install after the fact if pipx was used:
+
+.. code:: bash
+
+ pipx inject deareis cvxopt
+
+
+Newer versions of DearEIS can be installed in the following ways:
+
+.. code:: bash
+
+ pip install deareis --upgrade
+
+ pipx upgrade deareis --include-injected
+
+
+Running the GUI program
+-----------------------
+
+You should now be able to run DearEIS via, e.g., a terminal or the Windows start menu by typing in the command ``deareis``.
+There is also a ``deareis-debug`` command that can be used for troubleshooting purposes and prints a lot of potentially useful information to a terminal window.
+DearEIS can also be launched as a Python module:
+
+.. code:: bash
+
+ python -m deareis
+
+
+Using the API
+-------------
+
+The ``deareis`` package should now be accessible in Python:
+
+.. doctest::
+
+ >>> import deareis
+
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/guide_palettes.rst.txt b/_sources/guide_palettes.rst.txt
new file mode 100644
index 0000000..d967cb3
--- /dev/null
+++ b/_sources/guide_palettes.rst.txt
@@ -0,0 +1,38 @@
+.. include:: ./substitutions.rst
+
+Palettes
+========
+
+Command palette
+---------------
+
+DearEIS supports the use of keybindings to perform many but not all of the actions available in the various windows and tabs (e.g., switch to a specific tab, switch to a certain plot type, a Kramers-Kronig test, or perform a Kramers-Kronig test).
+These keybindings are in many cases similar from window to window and tab to tab, and the keybindings can be reassigned via the corresponding settings window.
+However, in some cases the keybindings are unique to the window (e.g., the file dialog).
+
+When a modal/popup window isn't open, then it is possible to perform actions via the **Command palette** (:numref:`command_palette`) that can be opened by default via ``Ctrl+P``.
+The contents of the list of actions depends upon the context (e.g., which tab is currently open).
+The list of actions can be navigated using, e.g., the arrow keys.
+Alternatively, the input field at the top can be used to search of a specific action.
+If the input field is empty, then the order of the options depends upon how recently an option was chosen.
+This should help with finding actions that are used frequently.
+
+.. _command_palette:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/command-palette.png
+ :alt: The Command palette window
+
+ Various actions can be performed via the **Command palette**, which only requires memorization of a single keybinding (``Ctrl+P`` by default).
+ Actions can be navigated with the ``Up/Down`` arrow keys, ``Page Up/Down`` keys, and ``Home/End`` keys.
+ The window also supports fuzzy matching for finding a specific action (e.g., ``saw`` should bring the ``Show the 'About' window`` action to the top).
+
+
+Data set and result palettes
+----------------------------
+
+The **Data set palette** and **Result palette** are similar to the **Command palette** but they instead facilitate switching between data sets or various results depending on the current tab (Kramers-Kronig test results, fit results, plots, etc.).
+The **Data set palette** and **Result palette** can be opened by default via ``Ctrl+Shift+P`` and ``Ctrl+Shift+Alt+P``, respectively.
+
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/guide_plotting.rst.txt b/_sources/guide_plotting.rst.txt
new file mode 100644
index 0000000..ba5e845
--- /dev/null
+++ b/_sources/guide_plotting.rst.txt
@@ -0,0 +1,120 @@
+.. include:: ./substitutions.rst
+
+Plotting
+========
+
+The **Plotting** tab (:numref:`plotting_tab`) can be used to compose plots with multiple data sets and/or analysis results.
+These plots can be used just within DearEIS to compare different results side-by-side.
+However, these plots can also be used to prepare relatively simple plots for sharing and/or publication.
+The plot settings can also be used via the API provided by DearEIS, which means that the basic layout can be prepared via the GUI and then the final plot can be generated programmatically.
+This approach would also mean that a plotting library other than `matplotlib`_, which is the default backend for exporting plots using DearEIS, could be used instead.
+
+.. _plotting_tab:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/plotting-tab.png
+ :alt: The Plotting tab of a project
+
+ The **Plotting** tab can be used to create plots containing multiple data sets and/or results.
+
+.. raw:: latex
+
+ \clearpage
+
+
+Selecting items to plot
+-----------------------
+
+The **Available** tab (:numref:`available`) contains entries for all of the data sets, analysis results, and simulations contained within a project.
+Individual items can be selected by ticking their corresponding checkboxes.
+
+.. _available:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/plotting-tab-available.png
+ :alt: The Available tab within the Plotting tab
+
+ Data sets and/or results can be selected from the **Available** tab.
+ In this example the substring ``randles`` has been used to filter items.
+
+The **Filter** input field can be used to search for specific items.
+The labels of analysis results are treated as if they also contain the label of the data set that they belong to, which means that filtering based on a data set's label will also include the analysis results belonging to that data set.
+Using a hyphen, "-", as a prefix is equal to a logical not (i.e., "-noisy" excludes items with "noisy" in their labels).
+Multiple filter terms can be used by separating them with commas.
+If one or more spaces, " ", are typed in this field, then all of the headings are expanded.
+Similarly, if the input field is cleared, then all of the headings are collapsed.
+
+Each heading contains buttons for (un)selecting all items within that heading and buttons for expanding/collapsing all subheadings.
+There are also buttons for (un)selecting all items regardless of the heading they fall under.
+Items that have been selected are added to the **Active** tab.
+
+.. raw:: latex
+
+ \clearpage
+
+
+Customizing selected items
+--------------------------
+
+Selected items are listed in a table in the **Active** tab and several aspects of those items can be edited.
+An item's label, which is used in the plot's legend, can be overridden by typing in a new label.
+If one or more spaces, " ", are given as the new label, then the item will not have an entry in the legend.
+
+.. _active:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/plotting-tab-active.png
+ :alt: The Active tab within the Plotting tab
+
+ The label and appearance of the selected items can be modified in the **Active** tab.
+ All three items have been given new labels that are used in the plot's legend.
+
+An item's appearance (color, marker shape, and whether or not it should have a line) can be edited from the popup window that appears when clicking the **Edit** button (:numref:`edit`).
+The **U** and **D** buttons can be used to adjust the order of an item when generating a plot, which affects the legend and whether or not an item will either be covered by or be covering some other item.
+
+.. _edit:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/plotting-tab-edit.png
+ :alt: The Edit appearance window within the Plotting tab
+
+ The **Edit appearance** window that can be used to define the color associated with a plottable item.
+ The type of marker (if any) can also be chosen.
+ Whether or not the item should (also) be plotted using a line can also be chosen.
+
+If specific items should have the same appearance across multiple plots, then there are two approaches for conveniently copying the relevant settings from one plot to another.
+The first approach is to have a main plot (e.g., labeled **Appearance template**) that is used simply to define the appearance of items.
+This main plot can then be duplicated, which also copies each item's settings, and modified.
+The second approach is to use the menu that is accessible via the **Copy appearance** button (:numref:`copy`) to copy item settings from another plot.
+One can choose which plot to copy from, which items to copy settings from, and which categories of settings to copy (label, colors, etc.).
+
+.. _copy:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/plotting-tab-copy.png
+ :alt: The Copy appearance settings window within the Plotting tab
+
+ The **Copy appearance settings** window is for copying the appearance settings for multiple items from one plot to another.
+ Alternatively, one can define the settings in one plot that is then duplicate the plot and make minor adjustments to the newly duplicated plot.
+
+.. raw:: latex
+
+ \clearpage
+
+
+Exporting plots
+---------------
+
+Plots can be exported (i.e., saved as files) using `matplotlib`_ (:numref:`export`).
+The plots (|PlotSettings|) and the items (|PlotSeries|) included in the plots are also accessible via the API.
+This means means that one can compose a plot using the GUI and generate the final plot using the API, which allows for batch exporting and also for greater control of a plot's appearance.
+
+.. _export:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/plotting-tab-export.png
+ :alt: The Export plot window within the Plotting tab
+
+ The **Export plot** window is for previewing and preparing to save a plot as a file.
+ Some amount of customization is available, but users who desire a greater degree of control are directed to use the API of DearEIS to extract the data (and possibly also the various plot settings) in order to programmatically generate the final plots.
+
+.. warning::
+
+ A subset of users may encounter crashes when attempting to export plots.
+ This issue appears to affect systems running Linux together with an nVidia GPU and proprietary drivers.
+
+ Unticking the ``Clear texture registry`` setting in ``Settings > Defaults > Plotting tab - Export plot > Miscellaneous`` may resolve the issue.
+ However, unticking this setting means that any memory allocated to previewing matplotlib plots is not freed until DearEIS is closed.
+
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/guide_projects.rst.txt b/_sources/guide_projects.rst.txt
new file mode 100644
index 0000000..64b5833
--- /dev/null
+++ b/_sources/guide_projects.rst.txt
@@ -0,0 +1,68 @@
+.. include:: ./substitutions.rst
+
+Projects
+========
+
+The workflow of DearEIS is based upon projects, which are stored as `JavaScript Object Notation (JSON) `_.
+These projects can contain multiple impedance spectra (or data sets) as well as multiple analysis results.
+
+Projects can be created from the **Home** tab (:numref:`home_tab`) or the **File** menu (top of the window).
+Recent projects are listed in this tab for quick access.
+The entire list can be cleared and individual entries can be also be removed.
+Two or more projects can also be merged to form a new project.
+
+.. _home_tab:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/home-tab.png
+ :alt: The Home tab of the program
+
+ Recent projects are easily accessible from the **Home** tab.
+
+
+DearEIS maintain a snapshot of a project while that project is open.
+The snapshot is updated every *N* actions (configurable in the settings) and this snapshot is recoverable in case DearEIS crashes or is closed while a project has unsaved changes.
+Any such snapshots are loaded automatically the next time that DearEIS is started.
+The snapshots are stored in ``XDG_STATE_HOME`` paths specified by the `XDG Base Directory Specification `_:
+
+
+.. list-table:: Default location of project snapshots files on different operating systems.
+ :widths: 33 67
+ :header-rows: 1
+
+ * - Operating system
+ - Location
+ * - Linux
+ - ``~/.local/state/DearEIS``
+ * - MacOS
+ - ``~/Library/Application Support/DearEIS``
+ * - Windows
+ - ``%LOCALAPPDATA%\DearEIS``
+
+.. raw:: latex
+
+ \clearpage
+
+
+Multiple projects can be open at the same time as separate tabs and each project is split into multiple tabs:
+
+- The **Overview** tab is where the project's label can be specified and notes can be kept.
+
+- The **Data sets** tab is for importing and processing experimental data before it is analyzed.
+
+- The **Kramers-Kronig** and **Z-HIT analysis** tabs provide the primary means of validating impedance spectra.
+
+- The **DRT analysis** and **Fitting** tabs are for extracting quantitative information.
+
+- The **Simulation** tab can be used to familiarize oneself with or to demonstrate the impedance spectra of different circuits and how parameter values affect the resulting spectra.
+
+- The **Plotting** tab is for composing figures where multiple results can be overlaid on top of each other.
+
+.. _overview_tab:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/overview-tab.png
+ :alt: The Overview tab of a project
+
+ Notes about a project can be kept in the **Overview** tab.
+
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/guide_settings.rst.txt b/_sources/guide_settings.rst.txt
new file mode 100644
index 0000000..d41476f
--- /dev/null
+++ b/_sources/guide_settings.rst.txt
@@ -0,0 +1,105 @@
+.. include:: ./substitutions.rst
+
+.. _settings_page:
+
+Settings
+========
+
+The configuration for DearEIS is stored as `JavaScript Object Notation (JSON) `_ that is stored in ``XDG_CONFIG_HOME`` paths specified by the `XDG Base Directory Specification `_:
+
+.. list-table:: Default location of the configuration file on different operating systems.
+ :widths: 33 67
+ :header-rows: 1
+
+ * - Operating system
+ - Location
+ * - Linux
+ - ``~/.config/DearEIS``
+ * - MacOS
+ - ``~/Library/Application Support/DearEIS``
+ * - Windows
+ - ``%LOCALAPPDATA%\DearEIS``
+
+
+Appearance
+----------
+
+Some aspects of the appearances of various plots can be defined (:numref:`appearance`).
+Some of these settings are also mixed and matched in some plots when there are more items to plot than shown in the plots in this window (e.g., see the plots in the window for interpolating data points in the **Data sets** tab).
+
+.. _appearance:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/settings-appearance.png
+ :alt: The Appearance settings window
+
+ Most changes made to plot appearances should take effect immediately.
+ Changing the number of points in simulated lines requires switching back and forth between data sets or results to update the plots.
+
+
+Defaults
+--------
+
+The default settings that are used in, e.g., the tabs for performing analyses can be defined here (:numref:`defaults`).
+
+.. _defaults:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/settings-defaults.png
+ :alt: The Default settings window
+
+ Changes made to defaults should take effect immediately.
+
+.. raw:: latex
+
+ \clearpage
+
+
+Keybindings
+-----------
+
+Many actions can be performed via keybindings.
+If an update to DearEIS changes or adds keybindings for actions, then those keybindings may not change or be assigned.
+In such cases it may be necessary to manually assign keybindings to those actions or to simply reset the keybindings.
+
+.. _keybindings:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/settings-keybindings.png
+ :alt: The Keybinding settings window
+
+ The keybindings defined in this window apply to a great extent also to modal/popup windows with similar functionality (e.g., for cycling results or plot types).
+
+.. raw:: latex
+
+ \clearpage
+
+
+User-defined elements
+---------------------
+
+Both pyimpspec and DearEIS include support for user-defined elements since version 4.0.0.
+The support has been implemented in DearEIS by providing a setting where the user can specify a Python script that defines one or more new elements.
+See `the source code (e.g., for the constant phase element) `_ and `the documentation `_ for pyimpspec for examples.
+The relevant functions and classes are available via the APIs of both DearEIS (:doc:`/apidocs_circuit`) and pyimpspec.
+
+.. warning::
+
+ User-defined elements are not stored in project files.
+ If a project is dependent on a user-defined element, then that project cannot be opened unless the user-defined element has been loaded.
+ A project is dependent on a user-defined element if it is used in, e.g., a circuit fit or a simulation.
+
+ The circuits used in these types of results are stored in a project file in the form of a circuit description code (CDC), which DearEIS needs to parse when a project is loaded.
+ User-defined elements are thus required at the moment of parsing and DearEIS/pyimpspec will expect to find elements that match the symbols encountered while parsing the CDC.
+ Changing the symbol of a user-defined element while it is in use can thus cause issues and symbols can conflict with, e.g., new elements that have been added to pyimpspec.
+ Changing the parameters/subcircuits of a user-defined element is also likely to cause issues if an older version is being used by a project.
+
+ So keep track of your script(s) that define user-defined elements and consider creating new elements when changes have to be made.
+
+.. _user_defined_elements:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/settings-user-defined-elements.png
+ :alt: The User-defined elements window
+
+ Specify the path to a Python script and then click the **Refresh** button.
+ The new circuit elements should show up in the table.
+ Hovering over a row in the table should show the automatically generated extended description for a circuit element.
+ If the path is left empty and then the **Refresh** button is clicked, then the user-defined elements are cleared.
+
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/guide_simulation.rst.txt b/_sources/guide_simulation.rst.txt
new file mode 100644
index 0000000..9c2579b
--- /dev/null
+++ b/_sources/guide_simulation.rst.txt
@@ -0,0 +1,26 @@
+.. include:: ./substitutions.rst
+
+Simulation
+==========
+
+The layout of the **Simulation** tab (:numref:`simulation_tab`) is similar to that of the **Fitting** tab:
+
+- the various settings that determine the simulation parameters
+- combo boxes that can be used to choose the active data set (or none), the active simulation result, and the active output
+- a table of the parameter values
+- a table of the settings that were used to obtain the active result
+
+However, the purpose of the **Simulation** tab is to provide a means to simulate impedance spectra of circuits within an arbitrary range of frequencies.
+The simulated impedance spectra can be loaded as data sets, which means that they can then be subjected to the various forms of analysis included in DearEIS.
+The **Simulation** tab can thus be very useful for teaching, demonstration, and development purposes.
+
+.. _simulation_tab:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/simulation-tab.png
+ :alt: The Simulation tab of a project.
+
+ An example of where a fitted circuit's impedance response has been extrapolated outside of the frequency range of the original experimental data.
+
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/guide_validation.rst.txt b/_sources/guide_validation.rst.txt
new file mode 100644
index 0000000..007fe4b
--- /dev/null
+++ b/_sources/guide_validation.rst.txt
@@ -0,0 +1,185 @@
+.. include:: ./substitutions.rst
+
+Validation
+==========
+
+The two primary approaches to validating experimental data included in DearEIS are linear Kramers-Kronig testing and Z-HIT analysis.
+The former is a widely adopted approach based on attempting to fit a specific type of equivalent circuit, which is known *a priori* to be Kramers-Kronig transformable.
+The latter approach reconstructs the modulus data from the (typically) more stable phase data, which can reveal issues such as drift at low frequencies due to time invariant behavior exhibited by the measured system.
+
+
+Kramers-Kronig testing
+----------------------
+
+Data validation based on linear Kramers-Kronig testing can be performed in the **Kramers-Kronig** tab (:numref:`kk_tab`) which contains the following:
+
+- various settings that determine how the Kramers-Kronig test is performed
+- combo boxes that can be used to choose the active data set and the active test result
+- a table of statistics related to the active test result
+- a table of settings that were used to obtain the active result
+- different plots
+
+.. _kk_tab:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/kramers-kronig-tab.png
+ :alt: The Kramers-Kronig tab of a project
+
+ A Kramers-Kronig test result for an impedance spectrum with a negative differential resistance.
+
+The three variants of the linear Kramers-Kronig test (complex, real, and imaginary) described by `Boukamp (1995) `_ have been included.
+These have been implemented using either least squares fitting or matrix inversion.
+There is also an implementation that uses complex non-linear least squares fitting.
+These tests can be performed with a fixed number of time constants (i.e., RC elements), |N_tau|, using the **Manual** mode.
+However, it is recommended that |N_tau| is determined automatically using one or more methods of the following methods by using either the **Auto** or the **Exploratory** mode.
+
+.. list-table:: Methods for suggesting the optimum number of time constants (i.e., the number of parallel/series RC elements).
+ :header-rows: 1
+
+ * - Method
+ - Reference
+ * - 1: |mu|-criterion
+ - `Schönleber et al. (2014) `_
+ * - 2: norm of fitted variables
+ - `Plank et al. (2022) `_
+ * - 3: norm of curvatures
+ - `Plank et al. (2022) `_
+ * - 4: number of sign changes among curvatures
+ - `Plank et al. (2022) `_
+ * - 5: mean distance between sign changes among curvatures
+ - `Yrjänä and Bobacka (2024) `_
+ * - 6: apex of |log sum abs tau R| (or |log sum abs tau C|) *versus* |N_tau|
+ - `Yrjänä and Bobacka (2024) `_
+
+The intermediate results of these methods can be inspected in the **Exploratory** mode as a means of detecting and dealing with issues such as false negatives.
+
+.. note::
+
+ A custom combination of methods 3, 4, and 5 is used by default. However, a specific method or combination of methods can be chosen via the window that shows up when using the **Exploratory** mode or via the **Settings > Defaults** window.
+
+In addition to |N_tau|, the range of time constants can and `should also be optimized `_.
+The range of time constants are by default defined by the reciprocals of the maximum and minimum frequencies of the impedance spectrum.
+However, the limits can be adjusted by an extension factor, |F_ext|, which is initially set to :math:`\log{F_{ext}} = 0` in terms of the settings provided in DearEIS.
+The optimal range of time constants may be wider (:math:`\log{F_{ext}} > 0`) or narrower (:math:`\log{F_{ext}} < 0`) than the default range.
+There are settings for the limits to use when optimizing |log F_ext| and the number of evaluations to perform.
+A specific |log F_ext| can also be used directly by setting the number of evaluations to zero.
+
+Some immittance spectra may need to be validated using based on their admittance representations rather than their impedance representations.
+It is therefore recommended that the **Representation** setting is set to **Auto**, which results in both the impedance and the admittance representation being tested.
+
+.. note::
+
+ If you only wish to validate the impedance representation of the immittance data, then see :ref:`parallel impedances` for information about how to process impedance data that include, e.g., negative differential resistances before attempting to validate the data.
+
+The test results are presented in the form of a table of statistics (e.g., |pseudo chi-squared| which indicates the quality of the fit) and different plots such as one of the relative residuals of the fit.
+
+
+Exploratory mode
+~~~~~~~~~~~~~~~~
+
+If the **Exploratory** mode is used, then the intermediate results of the linear Kramers-Kronig test and the various methods for suggesting the optimal number of RC elements are presented in a window that pops up.
+The main advantages of using the **Exploratory** mode over the **Auto** mode are that one can:
+
+- evaluate how |pseudo chi-squared| behaves as a function of |log F_ext| and |N_tau|, and how the values used by the different methods for suggesting the optimal |N_tau| behave
+- manually adjust, e.g., the representation, |log F_ext|, and/or |N_tau|
+
+.. _exploratory_window_log_fext:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/kramers-kronig-tab-exploratory-log-fext.png
+ :alt: 3D plot of pseudo chi-squared as a function of the number of RC elements and the extension factor of the range of time constants
+
+ The extension or contraction of the range of time constants can be evaluated using a 3D plot as shown here.
+ Rapid (i.e. partial) evaluations of different |log F_ext| values have been used here.
+ The full range of |N_tau| have only been evaluated with the initial :math:`\log{F_{ext}} = 0` and the optimal :math:`\log{F_{ext}} = -0.151`.
+
+.. _exploratory_window_num_rc:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/kramers-kronig-tab-exploratory-num-rc.png
+ :alt: Settings and results pertaining to suggesting the optimal number of RC elements
+
+ The settings for suggesting the optimal number of RC elements can be adjusted.
+ By default, the lower and upper limits are suggested automatically, and then a combination of methods 3, 4, and 5 are used to suggest the number of RC elements.
+ Various plots can be viewed to evaluate the results.
+
+
+References:
+
+- `Boukamp, B.A., 1995, J. Electrochem. Soc., 142, 1885-1894 `_
+- `Schönleber, M., Klotz, D., and Ivers-Tiffée, E., 2014, Electrochim. Acta, 131, 20-27 `_
+- `Plank, C., Rüther, T., and Danzer, M.A., 2022, 2022 International Workshop on Impedance Spectroscopy (IWIS), pp. 1–6 `_
+- `Yrjänä, V. and Bobacka, J., 2024, Electrochim. Acta, 504, 144951 `_
+
+
+.. raw:: latex
+
+ \clearpage
+
+
+Z-HIT analysis
+--------------
+
+Data validation using the `Z-HIT algorithm `_ can be performed in the **Z-HIT analysis** tab (:numref:`zhit_tab`) that contains the following:
+
+- the various settings that determine how the Z-HIT analysis is performed
+- combo boxes that can be used to choose the active data set and the active analysis result
+- a table of statistics related to the active analysis result
+- a table of the settings that were used to obtain the active result
+- different plots
+
+
+.. _zhit_tab:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/zhit-tab.png
+ :alt: The Z-HIT analysis tab of a project
+
+ The modulus data that is plotted in the upper plot has been reconstructed (red line) based on the phase data (orange markers and green line) of some example data that exhibits drift at low frequencies (blue markers).
+
+
+The Z-HIT algorithm was first described by Ehm et al. (2000) and provides a means of validating recorded impedance spectra using a modified logarithmic Hilbert transformation.
+The phase data is typically smoothed before it is interpolated using a spline, and then it is integrated and derivated to reconstruct the modulus data.
+The final step is an adjustment of the offset of the reconstructed modulus data by fitting to a subset of the experimental data that is unaffected by, e.g., drift.
+This subset of data points is typically in the range of 1 Hz to 1000 Hz.
+
+.. note::
+
+ The modulus data is not reconstructed perfectly.
+ There are often minor deviations even with ideal data.
+
+DearEIS offers a few options for smoothing algorithm and interpolation spline, and several different window functions for the weights to use during offset adjustment.
+The weights can also be previewed in a window (:numref:`weights_window`) that is accessible via the **Preview weights** button that is located below the section for settings.
+This window can help with selecting a window function and appropriate parameters for it.
+
+.. _weights_window:
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/zhit-tab-weights.png
+ :alt: A window for previewing weights
+
+ It is possible to preview the weights that could be applied when fitting the approximated modulus data to the experimental modulus data.
+ The shaded region shows the position of the window function while the orange markers show the weight (from 0.0 to 1.0) that could be applied.
+
+The results are presented in the form of a table of statistics and different plots.
+
+References:
+
+- Ehm, W., Göhr, H., Kaus, R., Röseler, B., and Schiller, C.A., 2000, Acta Chimica Hungarica, 137 (2-3), 145-157.
+- Ehm, W., Kaus, R., Schiller, C.A., and Strunz, W., 2001, in “New Trends in Electrochemical Impedance Spectroscopy and Electrochemical Noise Analysis”.
+- `Schiller, C.A., Richter, F., Gülzow, E., and Wagner, N., 2001, 3, 374-378 `_
+
+.. raw:: latex
+
+ \clearpage
+
+
+Applying old settings and masks
+-------------------------------
+
+The settings that were used to perform the active test result are also presented as a table and these settings can be applied by pressing the **Apply settings** button.
+
+The mask that was applied to the data set when the test was performed can be applied by pressing the **Apply mask** button.
+If the mask that is applied to the data set has changed since an earlier analysis was performed, then that will be indicated clearly above the statistics table.
+
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/kramers-kronig-tab-warning.png
+ :alt: Invalid result because the data set mask has changed
+
+ An example of the warning (red text on the left-hand side) that could be shown if, e.g., the mask applied to a data set has been changed after an analysis has been performed.
+ In this case, several points of the high-frequency semi-circle in the Nyquist plot have been omitted.
+
+These features make it easy to restore old settings/masks in case, e.g., DearEIS has been closed and relaunched, or after trying out different settings.
+
+.. raw:: latex
+
+ \clearpage
diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt
new file mode 100644
index 0000000..b1531ca
--- /dev/null
+++ b/_sources/index.rst.txt
@@ -0,0 +1,88 @@
+.. DearEIS documentation master file, created by
+ sphinx-quickstart on Wed Jan 11 19:11:26 2023.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+.. include:: ./substitutions.rst
+
+Welcome to DearEIS's documentation!
+===================================
+
+.. only:: html
+
+ .. image:: https://github.com/vyrjana/DearEIS/actions/workflows/test-package.yml/badge.svg
+ :alt: tests
+ :target: https://github.com/vyrjana/DearEIS/actions/workflows/test-package.yml
+
+ .. image:: https://github.com/vyrjana/DearEIS/actions/workflows/test-wheel.yml/badge.svg
+ :alt: build
+ :target: https://github.com/vyrjana/DearEIS/actions/workflows/test-wheel.yml
+
+ .. image:: https://img.shields.io/pypi/pyversions/DearEIS
+ :alt: Supported Python versions
+
+ .. image:: https://img.shields.io/github/license/vyrjana/DearEIS
+ :alt: GitHub
+ :target: https://www.gnu.org/licenses/gpl-3.0.html
+
+ .. image:: https://img.shields.io/pypi/v/DearEIS
+ :alt: PyPI
+ :target: https://pypi.org/project/deareis/
+
+ .. image:: https://joss.theoj.org/papers/10.21105/joss.04808/status.svg
+ :alt: DOI
+ :target: https://doi.org/10.21105/joss.04808
+
+DearEIS is a Python package for processing, analyzing, and visualizing impedance spectra.
+The primary interface for using DearEIS is a graphical user interface (GUI).
+
+.. figure:: https://raw.githubusercontent.com/wiki/vyrjana/DearEIS/images/fitting-tab.png
+ :alt: The graphical user interface of DearEIS
+
+
+.. only:: html
+
+ .. note::
+
+ PDF copies of the documentation are available in the `releases section `_.
+
+
+The GUI can be started via the following command:
+
+.. code:: bash
+
+ deareis
+
+
+The GUI can also be started by running DearEIS as a Python module:
+
+.. code:: bash
+
+ python -m deareis
+
+
+An application programming interface (API) is also included and it can be used to, e.g., batch process results into tables and plots.
+
+.. doctest::
+
+ >>> import deareis
+
+
+.. note::
+
+ If you would prefer to primarily use an API or are looking for a command-line interface (CLI), then check out `pyimpspec `_.
+
+The source code for DearEIS can be found `here `_.
+The changelog can be found `here `_.
+If you encounter bugs or wish to request a feature, then please open an `issue on GitHub `_.
+If you wish to contribute to the project, then please read the `readme `_ before submitting a `pull request via GitHub `_.
+
+DearEIS is licensed under GPLv3_ or later.
+
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Contents:
+
+ guide
+ apidocs
diff --git a/_sources/substitutions.rst.txt b/_sources/substitutions.rst.txt
new file mode 100644
index 0000000..5c44c61
--- /dev/null
+++ b/_sources/substitutions.rst.txt
@@ -0,0 +1,53 @@
+.. classes
+.. |PlotSettings| replace:: :class:`~deareis.PlotSettings`
+.. |PlotSeries| replace:: :class:`~deareis.PlotSeries`
+
+.. type hints
+.. |ComplexImpedance| replace:: :class:`~pyimpspec.ComplexImpedance`
+.. |ComplexImpedances| replace:: :class:`~pyimpspec.ComplexImpedances`
+.. |ComplexResidual| replace:: :class:`~pyimpspec.ComplexResidual`
+.. |ComplexResiduals| replace:: :class:`~pyimpspec.ComplexResiduals`
+.. |Frequencies| replace:: :class:`~pyimpspec.Frequencies`
+.. |Frequency| replace:: :class:`~pyimpspec.Frequency`
+.. |Gamma| replace:: :class:`~pyimpspec.Gamma`
+.. |Gammas| replace:: :class:`~pyimpspec.Gammas`
+.. |Impedance| replace:: :class:`~pyimpspec.Impedance`
+.. |Impedances| replace:: :class:`~pyimpspec.Impedances`
+.. |Indices| replace:: :class:`~pyimpspec.Indices`
+.. |Phase| replace:: :class:`~pyimpspec.Phase`
+.. |Phases| replace:: :class:`~pyimpspec.Phases`
+.. |Residual| replace:: :class:`~pyimpspec.Residual`
+.. |Residuals| replace:: :class:`~pyimpspec.Residuals`
+.. |TimeConstant| replace:: :class:`~pyimpspec.TimeConstant`
+.. |TimeConstants| replace:: :class:`~pyimpspec.TimeConstants`
+
+.. math
+.. |mu| replace:: :math:`{\rm \mu}`
+.. |lambda| replace:: :math:`\lambda`
+.. |chi-squared| replace:: :math:`\chi^2`
+.. |pseudo chi-squared| replace:: :math:`\chi^2_{ps.}`
+.. |ohm| replace:: :math:`\Omega`
+.. |degrees| replace:: :math:`^{\circ}`
+.. |log sum abs tau R| replace:: :math:`\log{\Sigma_{k=1}^{N_\tau} |\tau_k / R_k|}`
+.. |log sum abs tau C| replace:: :math:`\log{\Sigma_{k=1}^{N_\tau} |\tau_k / C_k|}`
+.. |N_tau| replace:: :math:`N_\tau`
+.. |N_tauopt| replace:: :math:`N_{\tau\rm,opt}`
+.. |N_taumin| replace:: :math:`N_{\tau\rm,min}`
+.. |N_taumax| replace:: :math:`N_{\tau\rm,max}`
+.. |F_ext| replace:: :math:`F_{\rm ext}`
+.. |log F_ext| replace:: :math:`\log{F_{\rm ext}}`
+
+.. functions
+.. |get_default_num_procs| replace:: :func:`~deareis.get_default_num_procs`
+.. |set_default_num_procs| replace:: :func:`~deareis.set_default_num_procs`
+.. |perform_kramers_kronig_test| replace:: :func:`~deareis.perform_kramers_kronig_test`
+.. |suggest_num_RC| replace:: :func:`~pyimpspec.analysis.kramers_kronig.suggest_num_RC`
+
+
+.. links
+.. _circuitikz: https://github.com/circuitikz/circuitikz
+.. _gplv3: https://www.gnu.org/licenses/gpl-3.0.en.html
+.. _matplotlib: https://matplotlib.org/
+.. _pyimpspec: https://vyrjana.github.io/pyimpspec/
+.. _sympify: https://docs.sympy.org/latest/modules/core.html#sympy.core.sympify.sympify
+.. _sympy: https://www.sympy.org/en/index.html
diff --git a/_static/_sphinx_javascript_frameworks_compat.js b/_static/_sphinx_javascript_frameworks_compat.js
new file mode 100644
index 0000000..8141580
--- /dev/null
+++ b/_static/_sphinx_javascript_frameworks_compat.js
@@ -0,0 +1,123 @@
+/* Compatability shim for jQuery and underscores.js.
+ *
+ * Copyright Sphinx contributors
+ * Released under the two clause BSD licence
+ */
+
+/**
+ * small helper function to urldecode strings
+ *
+ * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
+ */
+jQuery.urldecode = function(x) {
+ if (!x) {
+ return 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 rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+ var bbox = node.parentElement.getBBox();
+ 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);
+ 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;
+}
diff --git a/_static/basic.css b/_static/basic.css
new file mode 100644
index 0000000..f316efc
--- /dev/null
+++ b/_static/basic.css
@@ -0,0 +1,925 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+ clear: both;
+}
+
+div.section::after {
+ display: block;
+ content: '';
+ clear: left;
+}
+
+/* -- 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 p.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: 360px;
+ 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;
+}
+
+a:visited {
+ color: #551A8B;
+}
+
+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, .figure.align-left, object.align-left {
+ clear: left;
+ float: left;
+ margin-right: 1em;
+}
+
+img.align-right, figure.align-right, .figure.align-right, object.align-right {
+ clear: right;
+ float: right;
+ margin-left: 1em;
+}
+
+img.align-center, figure.align-center, .figure.align-center, object.align-center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+img.align-default, figure.align-default, .figure.align-default {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.align-left {
+ text-align: left;
+}
+
+.align-center {
+ text-align: center;
+}
+
+.align-default {
+ text-align: center;
+}
+
+.align-right {
+ text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar,
+aside.sidebar {
+ margin: 0 0 0.5em 1em;
+ border: 1px solid #ddb;
+ padding: 7px;
+ background-color: #ffe;
+ width: 40%;
+ float: right;
+ clear: right;
+ overflow-x: auto;
+}
+
+p.sidebar-title {
+ font-weight: bold;
+}
+
+nav.contents,
+aside.topic,
+div.admonition, div.topic, blockquote {
+ clear: left;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+nav.contents,
+aside.topic,
+div.topic {
+ border: 1px solid #ccc;
+ padding: 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;
+}
+
+p.admonition-title {
+ margin: 0px 10px 5px 0px;
+ font-weight: bold;
+}
+
+div.body p.centered {
+ text-align: center;
+ margin-top: 25px;
+}
+
+/* -- content of sidebars/topics/admonitions -------------------------------- */
+
+div.sidebar > :last-child,
+aside.sidebar > :last-child,
+nav.contents > :last-child,
+aside.topic > :last-child,
+div.topic > :last-child,
+div.admonition > :last-child {
+ margin-bottom: 0;
+}
+
+div.sidebar::after,
+aside.sidebar::after,
+nav.contents::after,
+aside.topic::after,
+div.topic::after,
+div.admonition::after,
+blockquote::after {
+ display: block;
+ content: '';
+ clear: both;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ border: 0;
+ border-collapse: collapse;
+}
+
+table.align-center {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table.align-default {
+ 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;
+}
+
+th {
+ text-align: left;
+ padding-right: 5px;
+}
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px;
+}
+
+table.citation td {
+ border-bottom: none;
+}
+
+th > :first-child,
+td > :first-child {
+ margin-top: 0px;
+}
+
+th > :last-child,
+td > :last-child {
+ margin-bottom: 0px;
+}
+
+/* -- figures --------------------------------------------------------------- */
+
+div.figure, figure {
+ margin: 0.5em;
+ padding: 0.5em;
+}
+
+div.figure p.caption, figcaption {
+ padding: 0.3em;
+}
+
+div.figure p.caption span.caption-number,
+figcaption span.caption-number {
+ font-style: italic;
+}
+
+div.figure p.caption span.caption-text,
+figcaption 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 {
+ margin: 1em 0;
+}
+
+table.hlist td {
+ vertical-align: top;
+}
+
+/* -- object description styles --------------------------------------------- */
+
+.sig {
+ font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+}
+
+.sig-name, code.descname {
+ background-color: transparent;
+ font-weight: bold;
+}
+
+.sig-name {
+ font-size: 1.1em;
+}
+
+code.descname {
+ font-size: 1.2em;
+}
+
+.sig-prename, code.descclassname {
+ background-color: transparent;
+}
+
+.optional {
+ font-size: 1.3em;
+}
+
+.sig-paren {
+ font-size: larger;
+}
+
+.sig-param.n {
+ font-style: italic;
+}
+
+/* C++ specific styling */
+
+.sig-inline.c-texpr,
+.sig-inline.cpp-texpr {
+ font-family: unset;
+}
+
+.sig.c .k, .sig.c .kt,
+.sig.cpp .k, .sig.cpp .kt {
+ color: #0033B3;
+}
+
+.sig.c .m,
+.sig.cpp .m {
+ color: #1750EB;
+}
+
+.sig.c .s, .sig.c .sc,
+.sig.cpp .s, .sig.cpp .sc {
+ color: #067D17;
+}
+
+
+/* -- 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;
+}
+
+:not(li) > ol > li:first-child > :first-child,
+:not(li) > ul > li:first-child > :first-child {
+ margin-top: 0px;
+}
+
+:not(li) > ol > li:last-child > :last-child,
+:not(li) > ul > li:last-child > :last-child {
+ margin-bottom: 0px;
+}
+
+ol.simple ol p,
+ol.simple ul p,
+ul.simple ol p,
+ul.simple ul p {
+ margin-top: 0;
+}
+
+ol.simple > li:not(:first-child) > p,
+ul.simple > li:not(:first-child) > p {
+ margin-top: 0;
+}
+
+ol.simple p,
+ul.simple p {
+ margin-bottom: 0;
+}
+
+aside.footnote > span,
+div.citation > span {
+ float: left;
+}
+aside.footnote > span:last-of-type,
+div.citation > span:last-of-type {
+ padding-right: 0.5em;
+}
+aside.footnote > p {
+ margin-left: 2em;
+}
+div.citation > p {
+ margin-left: 4em;
+}
+aside.footnote > p:last-of-type,
+div.citation > p:last-of-type {
+ margin-bottom: 0em;
+}
+aside.footnote > p:last-of-type:after,
+div.citation > p:last-of-type:after {
+ content: "";
+ clear: both;
+}
+
+dl.field-list {
+ display: grid;
+ grid-template-columns: fit-content(30%) auto;
+}
+
+dl.field-list > dt {
+ font-weight: bold;
+ word-break: break-word;
+ padding-left: 0.5em;
+ padding-right: 5px;
+}
+
+dl.field-list > dd {
+ padding-left: 0.5em;
+ margin-top: 0em;
+ margin-left: 0em;
+ margin-bottom: 0em;
+}
+
+dl {
+ margin-bottom: 15px;
+}
+
+dd > :first-child {
+ margin-top: 0px;
+}
+
+dd ul, dd table {
+ margin-bottom: 10px;
+}
+
+dd {
+ margin-top: 3px;
+ margin-bottom: 10px;
+ margin-left: 30px;
+}
+
+.sig dd {
+ margin-top: 0px;
+ margin-bottom: 0px;
+}
+
+.sig dl {
+ margin-top: 0px;
+ margin-bottom: 0px;
+}
+
+dl > dd:last-child,
+dl > dd:last-child > :last-child {
+ margin-bottom: 0;
+}
+
+dt:target, span.highlighted {
+ background-color: #fbe54e;
+}
+
+rect.highlighted {
+ fill: #fbe54e;
+}
+
+dl.glossary dt {
+ font-weight: bold;
+ font-size: 1.1em;
+}
+
+.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;
+}
+
+.classifier:before {
+ font-style: normal;
+ margin: 0 0.5em;
+ content: ":";
+ display: inline-block;
+}
+
+abbr, acronym {
+ border-bottom: dotted 1px;
+ cursor: help;
+}
+
+.translated {
+ background-color: rgba(207, 255, 207, 0.2)
+}
+
+.untranslated {
+ background-color: rgba(255, 207, 207, 0.2)
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+ overflow: auto;
+ overflow-y: hidden; /* fixes display issues on Chrome browsers */
+}
+
+pre, div[class*="highlight-"] {
+ clear: both;
+}
+
+span.pre {
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ -webkit-hyphens: none;
+ hyphens: none;
+ white-space: nowrap;
+}
+
+div[class*="highlight-"] {
+ margin: 1em 0;
+}
+
+td.linenos pre {
+ border: 0;
+ background-color: transparent;
+ color: #aaa;
+}
+
+table.highlighttable {
+ display: block;
+}
+
+table.highlighttable tbody {
+ display: block;
+}
+
+table.highlighttable tr {
+ display: flex;
+}
+
+table.highlighttable td {
+ margin: 0;
+ padding: 0;
+}
+
+table.highlighttable td.linenos {
+ padding-right: 0.5em;
+}
+
+table.highlighttable td.code {
+ flex: 1;
+ overflow: hidden;
+}
+
+.highlight .hll {
+ display: block;
+}
+
+div.highlight pre,
+table.highlighttable pre {
+ margin: 0;
+}
+
+div.code-block-caption + div {
+ margin-top: 0;
+}
+
+div.code-block-caption {
+ margin-top: 1em;
+ padding: 2px 5px;
+ font-size: small;
+}
+
+div.code-block-caption code {
+ background-color: transparent;
+}
+
+table.highlighttable td.linenos,
+span.linenos,
+div.highlight span.gp { /* gp: Generic.Prompt */
+ user-select: none;
+ -webkit-user-select: text; /* Safari fallback only */
+ -webkit-user-select: none; /* Chrome/Safari */
+ -moz-user-select: none; /* Firefox */
+ -ms-user-select: none; /* IE10+ */
+}
+
+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 {
+ margin: 1em 0;
+}
+
+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: absolute;
+ 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/_static/css/badge_only.css b/_static/css/badge_only.css
new file mode 100644
index 0000000..c718cee
--- /dev/null
+++ b/_static/css/badge_only.css
@@ -0,0 +1 @@
+.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}
\ No newline at end of file
diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff b/_static/css/fonts/Roboto-Slab-Bold.woff
new file mode 100644
index 0000000..6cb6000
Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff differ
diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff2 b/_static/css/fonts/Roboto-Slab-Bold.woff2
new file mode 100644
index 0000000..7059e23
Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff2 differ
diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff b/_static/css/fonts/Roboto-Slab-Regular.woff
new file mode 100644
index 0000000..f815f63
Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff differ
diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff2 b/_static/css/fonts/Roboto-Slab-Regular.woff2
new file mode 100644
index 0000000..f2c76e5
Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff2 differ
diff --git a/_static/css/fonts/fontawesome-webfont.eot b/_static/css/fonts/fontawesome-webfont.eot
new file mode 100644
index 0000000..e9f60ca
Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.eot differ
diff --git a/_static/css/fonts/fontawesome-webfont.svg b/_static/css/fonts/fontawesome-webfont.svg
new file mode 100644
index 0000000..855c845
--- /dev/null
+++ b/_static/css/fonts/fontawesome-webfont.svg
@@ -0,0 +1,2671 @@
+
+
+
diff --git a/_static/css/fonts/fontawesome-webfont.ttf b/_static/css/fonts/fontawesome-webfont.ttf
new file mode 100644
index 0000000..35acda2
Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.ttf differ
diff --git a/_static/css/fonts/fontawesome-webfont.woff b/_static/css/fonts/fontawesome-webfont.woff
new file mode 100644
index 0000000..400014a
Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff differ
diff --git a/_static/css/fonts/fontawesome-webfont.woff2 b/_static/css/fonts/fontawesome-webfont.woff2
new file mode 100644
index 0000000..4d13fc6
Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff2 differ
diff --git a/_static/css/fonts/lato-bold-italic.woff b/_static/css/fonts/lato-bold-italic.woff
new file mode 100644
index 0000000..88ad05b
Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff differ
diff --git a/_static/css/fonts/lato-bold-italic.woff2 b/_static/css/fonts/lato-bold-italic.woff2
new file mode 100644
index 0000000..c4e3d80
Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff2 differ
diff --git a/_static/css/fonts/lato-bold.woff b/_static/css/fonts/lato-bold.woff
new file mode 100644
index 0000000..c6dff51
Binary files /dev/null and b/_static/css/fonts/lato-bold.woff differ
diff --git a/_static/css/fonts/lato-bold.woff2 b/_static/css/fonts/lato-bold.woff2
new file mode 100644
index 0000000..bb19504
Binary files /dev/null and b/_static/css/fonts/lato-bold.woff2 differ
diff --git a/_static/css/fonts/lato-normal-italic.woff b/_static/css/fonts/lato-normal-italic.woff
new file mode 100644
index 0000000..76114bc
Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff differ
diff --git a/_static/css/fonts/lato-normal-italic.woff2 b/_static/css/fonts/lato-normal-italic.woff2
new file mode 100644
index 0000000..3404f37
Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff2 differ
diff --git a/_static/css/fonts/lato-normal.woff b/_static/css/fonts/lato-normal.woff
new file mode 100644
index 0000000..ae1307f
Binary files /dev/null and b/_static/css/fonts/lato-normal.woff differ
diff --git a/_static/css/fonts/lato-normal.woff2 b/_static/css/fonts/lato-normal.woff2
new file mode 100644
index 0000000..3bf9843
Binary files /dev/null and b/_static/css/fonts/lato-normal.woff2 differ
diff --git a/_static/css/theme.css b/_static/css/theme.css
new file mode 100644
index 0000000..19a446a
--- /dev/null
+++ b/_static/css/theme.css
@@ -0,0 +1,4 @@
+html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*!
+ * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block}
\ No newline at end of file
diff --git a/_static/doctools.js b/_static/doctools.js
new file mode 100644
index 0000000..4d67807
--- /dev/null
+++ b/_static/doctools.js
@@ -0,0 +1,156 @@
+/*
+ * doctools.js
+ * ~~~~~~~~~~~
+ *
+ * Base JavaScript utilities for all Sphinx HTML documentation.
+ *
+ * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+"use strict";
+
+const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([
+ "TEXTAREA",
+ "INPUT",
+ "SELECT",
+ "BUTTON",
+]);
+
+const _ready = (callback) => {
+ if (document.readyState !== "loading") {
+ callback();
+ } else {
+ document.addEventListener("DOMContentLoaded", callback);
+ }
+};
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+const Documentation = {
+ init: () => {
+ Documentation.initDomainIndexTable();
+ Documentation.initOnKeyListeners();
+ },
+
+ /**
+ * i18n support
+ */
+ TRANSLATIONS: {},
+ PLURAL_EXPR: (n) => (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: (string) => {
+ const translated = Documentation.TRANSLATIONS[string];
+ switch (typeof translated) {
+ case "undefined":
+ return string; // no translation
+ case "string":
+ return translated; // translation exists
+ default:
+ return translated[0]; // (singular, plural) translation tuple exists
+ }
+ },
+
+ ngettext: (singular, plural, n) => {
+ const translated = Documentation.TRANSLATIONS[singular];
+ if (typeof translated !== "undefined")
+ return translated[Documentation.PLURAL_EXPR(n)];
+ return n === 1 ? singular : plural;
+ },
+
+ addTranslations: (catalog) => {
+ Object.assign(Documentation.TRANSLATIONS, catalog.messages);
+ Documentation.PLURAL_EXPR = new Function(
+ "n",
+ `return (${catalog.plural_expr})`
+ );
+ Documentation.LOCALE = catalog.locale;
+ },
+
+ /**
+ * helper function to focus on search bar
+ */
+ focusSearchBar: () => {
+ document.querySelectorAll("input[name=q]")[0]?.focus();
+ },
+
+ /**
+ * Initialise the domain index toggle buttons
+ */
+ initDomainIndexTable: () => {
+ const toggler = (el) => {
+ const idNumber = el.id.substr(7);
+ const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);
+ if (el.src.substr(-9) === "minus.png") {
+ el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;
+ toggledRows.forEach((el) => (el.style.display = "none"));
+ } else {
+ el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;
+ toggledRows.forEach((el) => (el.style.display = ""));
+ }
+ };
+
+ const togglerElements = document.querySelectorAll("img.toggler");
+ togglerElements.forEach((el) =>
+ el.addEventListener("click", (event) => toggler(event.currentTarget))
+ );
+ togglerElements.forEach((el) => (el.style.display = ""));
+ if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);
+ },
+
+ initOnKeyListeners: () => {
+ // only install a listener if it is really needed
+ if (
+ !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&
+ !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
+ )
+ return;
+
+ document.addEventListener("keydown", (event) => {
+ // bail for input elements
+ if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
+ // bail with special keys
+ if (event.altKey || event.ctrlKey || event.metaKey) return;
+
+ if (!event.shiftKey) {
+ switch (event.key) {
+ case "ArrowLeft":
+ if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
+
+ const prevLink = document.querySelector('link[rel="prev"]');
+ if (prevLink && prevLink.href) {
+ window.location.href = prevLink.href;
+ event.preventDefault();
+ }
+ break;
+ case "ArrowRight":
+ if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
+
+ const nextLink = document.querySelector('link[rel="next"]');
+ if (nextLink && nextLink.href) {
+ window.location.href = nextLink.href;
+ event.preventDefault();
+ }
+ break;
+ }
+ }
+
+ // some keyboard layouts may need Shift to get /
+ switch (event.key) {
+ case "/":
+ if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
+ Documentation.focusSearchBar();
+ event.preventDefault();
+ }
+ });
+ },
+};
+
+// quick alias for translations
+const _ = Documentation.gettext;
+
+_ready(Documentation.init);
diff --git a/_static/documentation_options.js b/_static/documentation_options.js
new file mode 100644
index 0000000..f6796e9
--- /dev/null
+++ b/_static/documentation_options.js
@@ -0,0 +1,13 @@
+const DOCUMENTATION_OPTIONS = {
+ VERSION: '5.0.1',
+ LANGUAGE: 'en',
+ COLLAPSE_INDEX: false,
+ BUILDER: 'html',
+ FILE_SUFFIX: '.html',
+ LINK_SUFFIX: '.html',
+ HAS_SOURCE: true,
+ SOURCELINK_SUFFIX: '.txt',
+ NAVIGATION_WITH_KEYS: false,
+ SHOW_SEARCH_SUMMARY: true,
+ ENABLE_SEARCH_SHORTCUTS: true,
+};
\ No newline at end of file
diff --git a/_static/file.png b/_static/file.png
new file mode 100644
index 0000000..a858a41
Binary files /dev/null and b/_static/file.png differ
diff --git a/_static/jquery.js b/_static/jquery.js
new file mode 100644
index 0000000..c4c6022
--- /dev/null
+++ b/_static/jquery.js
@@ -0,0 +1,2 @@
+/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */
+!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"
","
"],col:[2,"
","
"],tr:[2,"
","
"],td:[3,"
","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.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(e,n){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document);
\ No newline at end of file
diff --git a/_static/js/html5shiv.min.js b/_static/js/html5shiv.min.js
new file mode 100644
index 0000000..cd1c674
--- /dev/null
+++ b/_static/js/html5shiv.min.js
@@ -0,0 +1,4 @@
+/**
+* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
+*/
+!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);
\ No newline at end of file
diff --git a/_static/js/theme.js b/_static/js/theme.js
new file mode 100644
index 0000000..1fddb6e
--- /dev/null
+++ b/_static/js/theme.js
@@ -0,0 +1 @@
+!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap(""),n("table.docutils.footnote").wrap(""),n("table.docutils.citation").wrap(""),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0
+ 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;
+ }
+}
+
diff --git a/_static/minus.png b/_static/minus.png
new file mode 100644
index 0000000..d96755f
Binary files /dev/null and b/_static/minus.png differ
diff --git a/_static/plot_directive.css b/_static/plot_directive.css
new file mode 100644
index 0000000..d45593c
--- /dev/null
+++ b/_static/plot_directive.css
@@ -0,0 +1,16 @@
+/*
+ * plot_directive.css
+ * ~~~~~~~~~~~~
+ *
+ * Stylesheet controlling images created using the `plot` directive within
+ * Sphinx.
+ *
+ * :copyright: Copyright 2020-* by the Matplotlib development team.
+ * :license: Matplotlib, see LICENSE for details.
+ *
+ */
+
+img.plot-directive {
+ border: 0;
+ max-width: 100%;
+}
diff --git a/_static/plus.png b/_static/plus.png
new file mode 100644
index 0000000..7107cec
Binary files /dev/null and b/_static/plus.png differ
diff --git a/_static/pygments.css b/_static/pygments.css
new file mode 100644
index 0000000..84ab303
--- /dev/null
+++ b/_static/pygments.css
@@ -0,0 +1,75 @@
+pre { line-height: 125%; }
+td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+.highlight .hll { background-color: #ffffcc }
+.highlight { background: #f8f8f8; }
+.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */
+.highlight .err { border: 1px solid #FF0000 } /* Error */
+.highlight .k { color: #008000; font-weight: bold } /* Keyword */
+.highlight .o { color: #666666 } /* Operator */
+.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
+.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #9C6500 } /* Comment.Preproc */
+.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
+.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
+.highlight .gr { color: #E40000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #008400 } /* Generic.Inserted */
+.highlight .go { color: #717171 } /* Generic.Output */
+.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #0044DD } /* Generic.Traceback */
+.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #008000 } /* Keyword.Pseudo */
+.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #B00040 } /* Keyword.Type */
+.highlight .m { color: #666666 } /* Literal.Number */
+.highlight .s { color: #BA2121 } /* Literal.String */
+.highlight .na { color: #687822 } /* Name.Attribute */
+.highlight .nb { color: #008000 } /* Name.Builtin */
+.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.highlight .no { color: #880000 } /* Name.Constant */
+.highlight .nd { color: #AA22FF } /* Name.Decorator */
+.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
+.highlight .nf { color: #0000FF } /* Name.Function */
+.highlight .nl { color: #767600 } /* Name.Label */
+.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #19177C } /* Name.Variable */
+.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mb { color: #666666 } /* Literal.Number.Bin */
+.highlight .mf { color: #666666 } /* Literal.Number.Float */
+.highlight .mh { color: #666666 } /* Literal.Number.Hex */
+.highlight .mi { color: #666666 } /* Literal.Number.Integer */
+.highlight .mo { color: #666666 } /* Literal.Number.Oct */
+.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
+.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
+.highlight .sc { color: #BA2121 } /* Literal.String.Char */
+.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
+.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
+.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
+.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
+.highlight .sx { color: #008000 } /* Literal.String.Other */
+.highlight .sr { color: #A45A77 } /* Literal.String.Regex */
+.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
+.highlight .ss { color: #19177C } /* Literal.String.Symbol */
+.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
+.highlight .fm { color: #0000FF } /* Name.Function.Magic */
+.highlight .vc { color: #19177C } /* Name.Variable.Class */
+.highlight .vg { color: #19177C } /* Name.Variable.Global */
+.highlight .vi { color: #19177C } /* Name.Variable.Instance */
+.highlight .vm { color: #19177C } /* Name.Variable.Magic */
+.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/_static/searchtools.js b/_static/searchtools.js
new file mode 100644
index 0000000..b08d58c
--- /dev/null
+++ b/_static/searchtools.js
@@ -0,0 +1,620 @@
+/*
+ * searchtools.js
+ * ~~~~~~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilities for the full-text search.
+ *
+ * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+"use strict";
+
+/**
+ * Simple result scoring code.
+ */
+if (typeof Scorer === "undefined") {
+ var Scorer = {
+ // Implement the following function to further tweak the score for each result
+ // The function takes a result array [docname, title, anchor, descr, score, filename]
+ // and returns the new score.
+ /*
+ score: result => {
+ const [docname, title, anchor, descr, score, filename] = result
+ return score
+ },
+ */
+
+ // 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,
+ partialTitle: 7,
+ // query found in terms
+ term: 5,
+ partialTerm: 2,
+ };
+}
+
+const _removeChildren = (element) => {
+ while (element && element.lastChild) element.removeChild(element.lastChild);
+};
+
+/**
+ * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
+ */
+const _escapeRegExp = (string) =>
+ string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
+
+const _displayItem = (item, searchTerms, highlightTerms) => {
+ const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
+ const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
+ const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
+ const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
+ const contentRoot = document.documentElement.dataset.content_root;
+
+ const [docName, title, anchor, descr, score, _filename] = item;
+
+ let listItem = document.createElement("li");
+ let requestUrl;
+ let linkUrl;
+ if (docBuilder === "dirhtml") {
+ // dirhtml builder
+ let dirname = docName + "/";
+ if (dirname.match(/\/index\/$/))
+ dirname = dirname.substring(0, dirname.length - 6);
+ else if (dirname === "index/") dirname = "";
+ requestUrl = contentRoot + dirname;
+ linkUrl = requestUrl;
+ } else {
+ // normal html builders
+ requestUrl = contentRoot + docName + docFileSuffix;
+ linkUrl = docName + docLinkSuffix;
+ }
+ let linkEl = listItem.appendChild(document.createElement("a"));
+ linkEl.href = linkUrl + anchor;
+ linkEl.dataset.score = score;
+ linkEl.innerHTML = title;
+ if (descr) {
+ listItem.appendChild(document.createElement("span")).innerHTML =
+ " (" + descr + ")";
+ // highlight search terms in the description
+ if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
+ highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
+ }
+ else if (showSearchSummary)
+ fetch(requestUrl)
+ .then((responseData) => responseData.text())
+ .then((data) => {
+ if (data)
+ listItem.appendChild(
+ Search.makeSearchSummary(data, searchTerms, anchor)
+ );
+ // highlight search terms in the summary
+ if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
+ highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
+ });
+ Search.output.appendChild(listItem);
+};
+const _finishSearch = (resultCount) => {
+ Search.stopPulse();
+ Search.title.innerText = _("Search Results");
+ if (!resultCount)
+ Search.status.innerText = Documentation.gettext(
+ "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.innerText = _(
+ "Search finished, found ${resultCount} page(s) matching the search query."
+ ).replace('${resultCount}', resultCount);
+};
+const _displayNextItem = (
+ results,
+ resultCount,
+ searchTerms,
+ highlightTerms,
+) => {
+ // results left, load the summary and display it
+ // this is intended to be dynamic (don't sub resultsCount)
+ if (results.length) {
+ _displayItem(results.pop(), searchTerms, highlightTerms);
+ setTimeout(
+ () => _displayNextItem(results, resultCount, searchTerms, highlightTerms),
+ 5
+ );
+ }
+ // search finished, update title and status message
+ else _finishSearch(resultCount);
+};
+// Helper function used by query() to order search results.
+// Each input is an array of [docname, title, anchor, descr, score, filename].
+// Order the results by score (in opposite order of appearance, since the
+// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically.
+const _orderResultsByScoreThenName = (a, b) => {
+ const leftScore = a[4];
+ const rightScore = b[4];
+ if (leftScore === rightScore) {
+ // same score: sort alphabetically
+ const leftTitle = a[1].toLowerCase();
+ const rightTitle = b[1].toLowerCase();
+ if (leftTitle === rightTitle) return 0;
+ return leftTitle > rightTitle ? -1 : 1; // inverted is intentional
+ }
+ return leftScore > rightScore ? 1 : -1;
+};
+
+/**
+ * Default splitQuery function. Can be overridden in ``sphinx.search`` with a
+ * custom function per language.
+ *
+ * The regular expression works by splitting the string on consecutive characters
+ * that are not Unicode letters, numbers, underscores, or emoji characters.
+ * This is the same as ``\W+`` in Python, preserving the surrogate pair area.
+ */
+if (typeof splitQuery === "undefined") {
+ var splitQuery = (query) => query
+ .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu)
+ .filter(term => term) // remove remaining empty strings
+}
+
+/**
+ * Search Module
+ */
+const Search = {
+ _index: null,
+ _queued_query: null,
+ _pulse_status: -1,
+
+ htmlToText: (htmlString, anchor) => {
+ const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
+ for (const removalQuery of [".headerlink", "script", "style"]) {
+ htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() });
+ }
+ if (anchor) {
+ const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`);
+ if (anchorContent) return anchorContent.textContent;
+
+ console.warn(
+ `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.`
+ );
+ }
+
+ // if anchor not specified or not found, fall back to main content
+ const docContent = htmlElement.querySelector('[role="main"]');
+ if (docContent) return docContent.textContent;
+
+ console.warn(
+ "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template."
+ );
+ return "";
+ },
+
+ init: () => {
+ const query = new URLSearchParams(window.location.search).get("q");
+ document
+ .querySelectorAll('input[name="q"]')
+ .forEach((el) => (el.value = query));
+ if (query) Search.performSearch(query);
+ },
+
+ loadIndex: (url) =>
+ (document.body.appendChild(document.createElement("script")).src = url),
+
+ setIndex: (index) => {
+ Search._index = index;
+ if (Search._queued_query !== null) {
+ const query = Search._queued_query;
+ Search._queued_query = null;
+ Search.query(query);
+ }
+ },
+
+ hasIndex: () => Search._index !== null,
+
+ deferQuery: (query) => (Search._queued_query = query),
+
+ stopPulse: () => (Search._pulse_status = -1),
+
+ startPulse: () => {
+ if (Search._pulse_status >= 0) return;
+
+ const pulse = () => {
+ Search._pulse_status = (Search._pulse_status + 1) % 4;
+ Search.dots.innerText = ".".repeat(Search._pulse_status);
+ if (Search._pulse_status >= 0) window.setTimeout(pulse, 500);
+ };
+ pulse();
+ },
+
+ /**
+ * perform a search for something (or wait until index is loaded)
+ */
+ performSearch: (query) => {
+ // create the required interface elements
+ const searchText = document.createElement("h2");
+ searchText.textContent = _("Searching");
+ const searchSummary = document.createElement("p");
+ searchSummary.classList.add("search-summary");
+ searchSummary.innerText = "";
+ const searchList = document.createElement("ul");
+ searchList.classList.add("search");
+
+ const out = document.getElementById("search-results");
+ Search.title = out.appendChild(searchText);
+ Search.dots = Search.title.appendChild(document.createElement("span"));
+ Search.status = out.appendChild(searchSummary);
+ Search.output = out.appendChild(searchList);
+
+ const searchProgress = document.getElementById("search-progress");
+ // Some themes don't use the search progress node
+ if (searchProgress) {
+ searchProgress.innerText = _("Preparing search...");
+ }
+ Search.startPulse();
+
+ // index already loaded, the browser was quick!
+ if (Search.hasIndex()) Search.query(query);
+ else Search.deferQuery(query);
+ },
+
+ _parseQuery: (query) => {
+ // stem the search terms and add them to the correct list
+ const stemmer = new Stemmer();
+ const searchTerms = new Set();
+ const excludedTerms = new Set();
+ const highlightTerms = new Set();
+ const objectTerms = new Set(splitQuery(query.toLowerCase().trim()));
+ splitQuery(query.trim()).forEach((queryTerm) => {
+ const queryTermLower = queryTerm.toLowerCase();
+
+ // maybe skip this "word"
+ // stopwords array is from language_data.js
+ if (
+ stopwords.indexOf(queryTermLower) !== -1 ||
+ queryTerm.match(/^\d+$/)
+ )
+ return;
+
+ // stem the word
+ let word = stemmer.stemWord(queryTermLower);
+ // select the correct list
+ if (word[0] === "-") excludedTerms.add(word.substr(1));
+ else {
+ searchTerms.add(word);
+ highlightTerms.add(queryTermLower);
+ }
+ });
+
+ if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js
+ localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" "))
+ }
+
+ // console.debug("SEARCH: searching for:");
+ // console.info("required: ", [...searchTerms]);
+ // console.info("excluded: ", [...excludedTerms]);
+
+ return [query, searchTerms, excludedTerms, highlightTerms, objectTerms];
+ },
+
+ /**
+ * execute search (requires search index to be loaded)
+ */
+ _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => {
+ const filenames = Search._index.filenames;
+ const docNames = Search._index.docnames;
+ const titles = Search._index.titles;
+ const allTitles = Search._index.alltitles;
+ const indexEntries = Search._index.indexentries;
+
+ // Collect multiple result groups to be sorted separately and then ordered.
+ // Each is an array of [docname, title, anchor, descr, score, filename].
+ const normalResults = [];
+ const nonMainIndexResults = [];
+
+ _removeChildren(document.getElementById("search-progress"));
+
+ const queryLower = query.toLowerCase().trim();
+ for (const [title, foundTitles] of Object.entries(allTitles)) {
+ if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) {
+ for (const [file, id] of foundTitles) {
+ const score = Math.round(Scorer.title * queryLower.length / title.length);
+ const boost = titles[file] === title ? 1 : 0; // add a boost for document titles
+ normalResults.push([
+ docNames[file],
+ titles[file] !== title ? `${titles[file]} > ${title}` : title,
+ id !== null ? "#" + id : "",
+ null,
+ score + boost,
+ filenames[file],
+ ]);
+ }
+ }
+ }
+
+ // search for explicit entries in index directives
+ for (const [entry, foundEntries] of Object.entries(indexEntries)) {
+ if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) {
+ for (const [file, id, isMain] of foundEntries) {
+ const score = Math.round(100 * queryLower.length / entry.length);
+ const result = [
+ docNames[file],
+ titles[file],
+ id ? "#" + id : "",
+ null,
+ score,
+ filenames[file],
+ ];
+ if (isMain) {
+ normalResults.push(result);
+ } else {
+ nonMainIndexResults.push(result);
+ }
+ }
+ }
+ }
+
+ // lookup as object
+ objectTerms.forEach((term) =>
+ normalResults.push(...Search.performObjectSearch(term, objectTerms))
+ );
+
+ // lookup as search terms in fulltext
+ normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms));
+
+ // let the scorer override scores with a custom scoring function
+ if (Scorer.score) {
+ normalResults.forEach((item) => (item[4] = Scorer.score(item)));
+ nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item)));
+ }
+
+ // Sort each group of results by score and then alphabetically by name.
+ normalResults.sort(_orderResultsByScoreThenName);
+ nonMainIndexResults.sort(_orderResultsByScoreThenName);
+
+ // Combine the result groups in (reverse) order.
+ // Non-main index entries are typically arbitrary cross-references,
+ // so display them after other results.
+ let results = [...nonMainIndexResults, ...normalResults];
+
+ // remove duplicate search results
+ // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept
+ let seen = new Set();
+ results = results.reverse().reduce((acc, result) => {
+ let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(',');
+ if (!seen.has(resultStr)) {
+ acc.push(result);
+ seen.add(resultStr);
+ }
+ return acc;
+ }, []);
+
+ return results.reverse();
+ },
+
+ query: (query) => {
+ const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query);
+ const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms);
+
+ // for debugging
+ //Search.lastresults = results.slice(); // a copy
+ // console.info("search results:", Search.lastresults);
+
+ // print the results
+ _displayNextItem(results, results.length, searchTerms, highlightTerms);
+ },
+
+ /**
+ * search for object names
+ */
+ performObjectSearch: (object, objectTerms) => {
+ const filenames = Search._index.filenames;
+ const docNames = Search._index.docnames;
+ const objects = Search._index.objects;
+ const objNames = Search._index.objnames;
+ const titles = Search._index.titles;
+
+ const results = [];
+
+ const objectSearchCallback = (prefix, match) => {
+ const name = match[4]
+ const fullname = (prefix ? prefix + "." : "") + name;
+ const fullnameLower = fullname.toLowerCase();
+ if (fullnameLower.indexOf(object) < 0) return;
+
+ let score = 0;
+ const parts = fullnameLower.split(".");
+
+ // check for different match types: exact matches of full name or
+ // "last name" (i.e. last dotted part)
+ if (fullnameLower === object || parts.slice(-1)[0] === object)
+ score += Scorer.objNameMatch;
+ else if (parts.slice(-1)[0].indexOf(object) > -1)
+ score += Scorer.objPartialMatch; // matches in last name
+
+ const objName = objNames[match[1]][2];
+ const title = titles[match[0]];
+
+ // If more than one term searched for, we require other words to be
+ // found in the name/title/description
+ const otherTerms = new Set(objectTerms);
+ otherTerms.delete(object);
+ if (otherTerms.size > 0) {
+ const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase();
+ if (
+ [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0)
+ )
+ return;
+ }
+
+ let anchor = match[3];
+ if (anchor === "") anchor = fullname;
+ else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname;
+
+ const descr = objName + _(", in ") + title;
+
+ // 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]],
+ ]);
+ };
+ Object.keys(objects).forEach((prefix) =>
+ objects[prefix].forEach((array) =>
+ objectSearchCallback(prefix, array)
+ )
+ );
+ return results;
+ },
+
+ /**
+ * search for full-text terms in the index
+ */
+ performTermsSearch: (searchTerms, excludedTerms) => {
+ // prepare search
+ const terms = Search._index.terms;
+ const titleTerms = Search._index.titleterms;
+ const filenames = Search._index.filenames;
+ const docNames = Search._index.docnames;
+ const titles = Search._index.titles;
+
+ const scoreMap = new Map();
+ const fileMap = new Map();
+
+ // perform the search on the required terms
+ searchTerms.forEach((word) => {
+ const files = [];
+ const arr = [
+ { files: terms[word], score: Scorer.term },
+ { files: titleTerms[word], score: Scorer.title },
+ ];
+ // add support for partial matches
+ if (word.length > 2) {
+ const escapedWord = _escapeRegExp(word);
+ if (!terms.hasOwnProperty(word)) {
+ Object.keys(terms).forEach((term) => {
+ if (term.match(escapedWord))
+ arr.push({ files: terms[term], score: Scorer.partialTerm });
+ });
+ }
+ if (!titleTerms.hasOwnProperty(word)) {
+ Object.keys(titleTerms).forEach((term) => {
+ if (term.match(escapedWord))
+ arr.push({ files: titleTerms[term], score: Scorer.partialTitle });
+ });
+ }
+ }
+
+ // no match but word was a required one
+ if (arr.every((record) => record.files === undefined)) return;
+
+ // found search word in contents
+ arr.forEach((record) => {
+ if (record.files === undefined) return;
+
+ let recordFiles = record.files;
+ if (recordFiles.length === undefined) recordFiles = [recordFiles];
+ files.push(...recordFiles);
+
+ // set score for the word in each file
+ recordFiles.forEach((file) => {
+ if (!scoreMap.has(file)) scoreMap.set(file, {});
+ scoreMap.get(file)[word] = record.score;
+ });
+ });
+
+ // create the mapping
+ files.forEach((file) => {
+ if (!fileMap.has(file)) fileMap.set(file, [word]);
+ else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word);
+ });
+ });
+
+ // now check if the files don't contain excluded terms
+ const results = [];
+ for (const [file, wordList] of fileMap) {
+ // check if all requirements are matched
+
+ // as search terms with length < 3 are discarded
+ const filteredTermCount = [...searchTerms].filter(
+ (term) => term.length > 2
+ ).length;
+ if (
+ wordList.length !== searchTerms.size &&
+ wordList.length !== filteredTermCount
+ )
+ continue;
+
+ // ensure that none of the excluded terms is in the search result
+ if (
+ [...excludedTerms].some(
+ (term) =>
+ terms[term] === file ||
+ titleTerms[term] === file ||
+ (terms[term] || []).includes(file) ||
+ (titleTerms[term] || []).includes(file)
+ )
+ )
+ break;
+
+ // select one (max) score for the file.
+ const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w]));
+ // add result to the result list
+ 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.
+ */
+ makeSearchSummary: (htmlText, keywords, anchor) => {
+ const text = Search.htmlToText(htmlText, anchor);
+ if (text === "") return null;
+
+ const textLower = text.toLowerCase();
+ const actualStartPosition = [...keywords]
+ .map((k) => textLower.indexOf(k.toLowerCase()))
+ .filter((i) => i > -1)
+ .slice(-1)[0];
+ const startWithContext = Math.max(actualStartPosition - 120, 0);
+
+ const top = startWithContext === 0 ? "" : "...";
+ const tail = startWithContext + 240 < text.length ? "..." : "";
+
+ let summary = document.createElement("p");
+ summary.classList.add("context");
+ summary.textContent = top + text.substr(startWithContext, 240).trim() + tail;
+
+ return summary;
+ },
+};
+
+_ready(Search.init);
diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js
new file mode 100644
index 0000000..8a96c69
--- /dev/null
+++ b/_static/sphinx_highlight.js
@@ -0,0 +1,154 @@
+/* Highlighting utilities for Sphinx HTML documentation. */
+"use strict";
+
+const SPHINX_HIGHLIGHT_ENABLED = true
+
+/**
+ * highlight a given string on a node by wrapping it in
+ * span elements with the given class name.
+ */
+const _highlight = (node, addItems, text, className) => {
+ if (node.nodeType === Node.TEXT_NODE) {
+ const val = node.nodeValue;
+ const parent = node.parentNode;
+ const pos = val.toLowerCase().indexOf(text);
+ if (
+ pos >= 0 &&
+ !parent.classList.contains(className) &&
+ !parent.classList.contains("nohighlight")
+ ) {
+ let span;
+
+ const closestNode = parent.closest("body, svg, foreignObject");
+ const isInSVG = closestNode && closestNode.matches("svg");
+ if (isInSVG) {
+ span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
+ } else {
+ span = document.createElement("span");
+ span.classList.add(className);
+ }
+
+ span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+ const rest = document.createTextNode(val.substr(pos + text.length));
+ parent.insertBefore(
+ span,
+ parent.insertBefore(
+ rest,
+ node.nextSibling
+ )
+ );
+ node.nodeValue = val.substr(0, pos);
+ /* There may be more occurrences of search term in this node. So call this
+ * function recursively on the remaining fragment.
+ */
+ _highlight(rest, addItems, text, className);
+
+ if (isInSVG) {
+ const rect = document.createElementNS(
+ "http://www.w3.org/2000/svg",
+ "rect"
+ );
+ const bbox = parent.getBBox();
+ 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);
+ addItems.push({ parent: parent, target: rect });
+ }
+ }
+ } else if (node.matches && !node.matches("button, select, textarea")) {
+ node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
+ }
+};
+const _highlightText = (thisNode, text, className) => {
+ let addItems = [];
+ _highlight(thisNode, addItems, text, className);
+ addItems.forEach((obj) =>
+ obj.parent.insertAdjacentElement("beforebegin", obj.target)
+ );
+};
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+const SphinxHighlight = {
+
+ /**
+ * highlight the search words provided in localstorage in the text
+ */
+ highlightSearchWords: () => {
+ if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight
+
+ // get and clear terms from localstorage
+ const url = new URL(window.location);
+ const highlight =
+ localStorage.getItem("sphinx_highlight_terms")
+ || url.searchParams.get("highlight")
+ || "";
+ localStorage.removeItem("sphinx_highlight_terms")
+ url.searchParams.delete("highlight");
+ window.history.replaceState({}, "", url);
+
+ // get individual terms from highlight string
+ const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
+ if (terms.length === 0) return; // nothing to do
+
+ // There should never be more than one element matching "div.body"
+ const divBody = document.querySelectorAll("div.body");
+ const body = divBody.length ? divBody[0] : document.querySelector("body");
+ window.setTimeout(() => {
+ terms.forEach((term) => _highlightText(body, term, "highlighted"));
+ }, 10);
+
+ const searchBox = document.getElementById("searchbox");
+ if (searchBox === null) return;
+ searchBox.appendChild(
+ document
+ .createRange()
+ .createContextualFragment(
+ '
DearEIS includes an API that is primarily intended for batch processing (e.g., importing data into a project or exporting results/plots/tables).
+
>>> importdeareis# The main functions, classes, etc.
+>>> fromdeareisimportmpl# Plotting functions based on matplotlib.
+
+
+
+
Warning
+
DearEIS provides wrapper functions for some of pyimpspec’s functions since DearEIS uses classes that store the relevant arguments/settings in a way that can be serialized and deserialized as part of project files.
+Consequently, the API might feel somewhat cumbersome to use for some tasks where these settings classes must be instantiated and using pyimpspec directly might be more convenient.
+
DearEIS also implements subclasses or entirely new classes to contain some of the information that pyimpspec’s various result classes would contain.
+This has been done so that various results can be serialized and deserialized as part of project files.
+
However, DearEIS’ classes can in several cases be used directly with functions from pyimpspec (e.g., the various plotting functions) since pyimpspec checks for the presence of attributes and/or methods with specific names rather than whether or not an object is an instance of some class.
+
+
+
Note
+
The API makes use of multiple processes where possible to perform tasks in parallel.
+Functions that implement this parallelization have a num_procs keyword argument that can be used to override the maximum number of processes allowed.
+Using this keyword argument should not be necessary for most users under most circumstances.
+Call the get_default_num_procs() function to get the automatically determined value for your system.
+There is also a set_default_num_procs() function that can be used to set a global override rather than using the num_procs keyword argument when calling various functions.
+
If NumPy is linked against a multithreaded linear algebra library like OpenBLAS or MKL, then this may in some circumstances result in unusually poor performance despite heavy CPU utilization.
+It may be possible to remedy the issue by specifying a lower number of processes via the num_procs keyword argument and/or limiting the number of threads that, e.g., OpenBLAS should use by setting the appropriate environment variable (e.g., OPENBLAS_NUM_THREADS).
+Again, this should not be necessary for most users and reporting this as an issue to the DearEIS or pyimpspec repository on GitHub would be preferred.
Get the default number of parallel processes that pyimpspec would try to use.
+NumPy may be using libraries that are multithreaded, which can lead to poor performance or system responsiveness when combined with pyimpspec’s use of multiple processes.
+This function attempts to return a reasonable number of processes depending on the detected libraries (and relevant environment variables):
+
+
OpenBLAS (OPENBLAS_NUM_THREADS)
+
MKL (MKL_NUM_THREADS)
+
+
If none of the libraries listed above are detected because some other library is used, then the value returned by multiprocessing.cpu_count() is used.
Override the default number of parallel process that pyimpspec should use.
+Setting the value to less than one disables any previous override.
+
+
Parameters:
+
num_procs (int) – If the value is greater than zero, then the value is used as the number of processes to use.
+Otherwise, any previous override is disabled.
Register a circuit element so that it is supported by the parse_cdc and get_elements functions. The class definition (symbol, name, etc.) must be provided as keyword arguments.
+
+
Parameters:
+
+
definition (ElementDefinition) – An ElementDefinition instance that defines a class, which inherits from the Element class and implements a method called _impedance that takes a float value (i.e., the excitation frequency in hertz) and returns a complex value.
Generate a mapping of elements to their corresponding integer identifiers.
+
+
Parameters:
+
running (bool) – If true, then the identifiers are simply a running count from 0 to N. Primarily intended for use within pyimpspec.
+If false, then the identifiers represent what number instance of a particular element type an element is (e.g., the second resistor of three resistors would have 2 as its identifier). Primarily intended for use in anything that most users would see (e.g., circuit diagrams and parameter tables).
recursive (bool, optional) – If True and this Connection contains other Connection instances, then all nested Connect instances are returned.
+If False, then only the Connection instances within the top level of this Connection are returned.
Get the name of the element with consideration for any overriding label assigned to the element or the type-specific count in the context of this connection.
+
+
Parameters:
+
+
element (Element) – The element whose name should be returned.
+
identifiers (Optional[Dict[Element, int]], optional) – The identifiers to use when determining the name of the provided element.
recursive (bool, optional) – If True and this Connection contains other Connection instances, then all nested elements are returned.
+If False, then only the Element instances within the top level of this Connection are returned.
Get the LaTeX source needed to draw a circuit diagram for this circuit using the CircuiTikZ package.
+
+
Parameters:
+
+
node_width (float, optional) – The width of each node.
+
node_height (float, optional) – The height of each node.
+
left_terminal_label (str, optional) – The label assigned to the terminal representing the working and working sense electrodes.
+
right_terminal_label (str, optional) – The label assigned to the terminal representing the counter and reference electrodes.
+
hide_labels (bool, optional) – Whether or not to hide element and terminal labels.
+
running (bool, optional) – Whether or not to use running counts as the lower indices of elements.
+
custom_labels (Optional[Dict[Element, str]], optional) – A mapping of elements to their custom labels that are used instead of the automatically generated labels.
+The labels can make use of LaTeX’s math mode.
node_height (float, optional) – The height of each node.
+
left_terminal_label (str, optional) – The label assigned to the terminal representing the working and working sense electrodes.
+
right_terminal_label (str, optional) – The label assigned to the terminal representing the counter and reference electrodes.
+
hide_labels (bool, optional) – Whether or not to hide element and terminal labels.
+
running (bool, optional) – Whether or not to use running counts as the lower indices of elements.
+
custom_labels (Optional[Dict[Element, str]], optional) – A mapping of elements to their custom labels that are used instead of the automatically generated labels.
+The labels can make use of LaTeX’s math mode.
+
canvas (Optional[Union[str, Axes]], optional) – The canvas that the _schemdraw.Drawing class should use.
Generate a mapping of elements to their corresponding integer identifiers.
+
+
Parameters:
+
running (bool) – If true, then the identifiers are simply a running count from 0 to N. Primarily intended for use within pyimpspec.
+If false, then the identifiers represent what number instance of a particular element type an element is (e.g., the second resistor of three resistors would have 2 as its identifier). Primarily intended for use in anything that most users would see (e.g., circuit diagrams and parameter tables).
decimals (int, optional) – The number of decimals used when formatting the current value and the limits for the element’s parameters.
+-1 corresponds to no values being included in the output.
The base class for circuit elements.
+Classes implementing circuit elements should extend this base class and implement the _impedance method (note the underscore).
+The docstring for the class is generated when the class is registered via the register_element() function.
decimals (int, optional) – The number of decimals used when formatting the current value and the limits for the element’s parameters.
+-1 corresponds to no values being included in the output.
Generate a mapping of elements to their corresponding integer identifiers.
+
+
Parameters:
+
running (bool) – If true, then the identifiers are simply a running count from 0 to N. Primarily intended for use within pyimpspec.
+If false, then the identifiers represent what number instance of a particular element type an element is (e.g., the second resistor of three resistors would have 2 as its identifier). Primarily intended for use in anything that most users would see (e.g., circuit diagrams and parameter tables).
recursive (bool, optional) – If True and this Circuit contains nested Connection instances, then all of them are returned.
+If False, then only the top-level Connection is returned.
Get the name of the element with consideration for any overriding label assigned to the element or the type-specific count in the context of this circuit.
+
+
Parameters:
+
+
element (Element) – The element whose name should be returned.
+
identifiers (Optional[Dict[Element, int]], optional) – The identifiers to use when determining the name of the provided element.
recursive (bool, optional) – If True and there are Element instances nested within Connection instances, then all Element instances are returned.
+If False, then only the Element instances within the top-level Connection are returned.
Get the LaTeX source needed to draw a circuit diagram for this circuit using the CircuiTikZ package.
+
+
Parameters:
+
+
node_width (float, optional) – The width of each node.
+
node_height (float, optional) – The height of each node.
+
left_terminal_label (str, optional) – The label assigned to the terminal representing the working and working sense electrodes.
+
right_terminal_label (str, optional) – The label assigned to the terminal representing the counter and reference electrodes.
+
hide_labels (bool, optional) – Whether or not to hide element and terminal labels.
+
running (bool, optional) – Whether or not to use running counts as the lower indices of elements.
+
custom_labels (Optional[Dict[Element, str]], optional) – A mapping of elements to their custom labels that are used instead of the automatically generated labels.
+The labels can make use of LaTeX’s math mode.
node_height (float, optional) – The height of each node.
+
left_terminal_label (str, optional) – The label assigned to the terminal representing the working and working sense electrodes.
+
right_terminal_label (str, optional) – The label assigned to the terminal representing the counter and reference electrodes.
+
hide_labels (bool, optional) – Whether or not to hide element and terminal labels.
+
running (bool, optional) – Whether or not to use running counts as the lower indices of elements.
+
custom_labels (Optional[Dict[Element, str]], optional) – A mapping of elements to their custom labels that are used instead of the automatically generated labels.
+The labels can make use of LaTeX’s math mode.
+
canvas (Optional[Union[str, Axes]], optional) – The canvas that the _schemdraw.Drawing class should use.
Generate the circuit description code (CDC) that represents this circuit.
+
+
Parameters:
+
decimals (int, optional) – The number of decimals to include for the current element parameter values and limits.
+-1 means that the CDC is generated using the basic syntax, which omits element labels, parameter values, and parameter limits.
decimals (int = -1) – The number of decimals to include for the current element parameter values and limits.
+-1 means that the CDC is generated using the basic syntax, which omits element labels, parameter values, and parameter limits.
A general model for a transmission line. The units of the subcircuits’ parameters vary depending on the connections. Note the pore length parameter, L, for this element and how it may affect the aforementioned units. The equation that is used depends on the configuration of subcircuits that have been chosen. See DOI:10.1039/B001708F for more information about this element.
+
+
Parameters:
+
+
L (float = 1 m, fixed) – Pore length
+
X_1 (Optional[Connection] = [R]) – The impedance of the liquid phase (i.e., ionic conductivity in the pore)
+
X_2 (Optional[Connection] = []) – The impedance of the solid phase (i.e., electronic conductivity of the film)
+
Z_A (Optional[Connection] = None) – The impedance at the outer boundary of the porous electrode (i.e., at the electrolyte-film interface outside of the pore)
+
Z_B (Optional[Connection] = None) – The impedance at the inner boundary of the porous electrode (i.e., at the electrolyte-substrate interface in the pore)
+
Zeta (Optional[Connection] = [Q]) – The interfacial impedance (i.e., at the electrolyte-film interface of the pore wall)
Transmission line, non-blocking porous electrode with perfectly reflective inner boundary. Also known as ‘Bisquert, open’. Model (f) in DOI:10.1039/B001708F with corrected form from DOI:10.1021/jp993148h.
Transmission line, non-blocking porous electrode with absorbing inner boundary. Also known as ‘Bisquert, short’. Model (g) in DOI:10.1039/B001708F with a shorted Z_B (i.e., Z_B == 0).
A class that defines a new circuit element and its parameters.
+The information contained in this object is also used to automatically generate a docstring for the circuit element’s class.
+
+
Parameters:
+
+
Class (Type[Element]) – The class representing the circuit element.
+
symbol (str) – The symbol that can be used to represent the circuit element in a circuit description code (CDC).
+
name (str) – The name of the circuit element.
+
description (str) – The description of the element.
+A placeholder, |equation|, for the automatically formatted equation can be included in the description in case the intention is to have more text below the equation.
+Otherwise the formatted equation will be added to the end of the description.
+Another placeholder, |no-equation|, can be included (e.g., at the end) in case the automatically formatted equation should be excluded for some reason (e.g., it would be too large to be properly displayed).
+
equation (str) – The equation (assume an implicit “Z = “ on the left-hand side) for the circuit element’s impedance.
+The string must be compatible with SymPy’s sympify function.
+For example, “(2*pi*f*C*I)^-1” for a capacitor is valid and will show up in the generated docstring as \(Z = \frac{1}{j 2 \pi f C}\).
+This is also used to verify that the circuit element’s _impedance method outputs the same answer as the circuit element’s impedance equation.
+
parameters (List[ParameterDefinition]) – A list of objects that define the circuit element’s parameter(s).
A class that defines a new circuit element and its parameters.
+The information contained in this object is also used to automatically generate a docstring for the circuit element’s class.
+
+
Parameters:
+
+
Class (Type[Element]) – The class representing the circuit element.
+
symbol (str) – The symbol that can be used to represent the circuit element in a circuit description code (CDC).
+
name (str) – The name of the circuit element.
+
description (str) – The description of the element.
+A placeholder, |equation|, for the automatically formatted equation can be included in the description in case the intention is to have more text below the equation.
+Otherwise the formatted equation will be added to the end of the description.
+Another placeholder, |no-equation|, can be included (e.g., at the end) in case the automatically formatted equation should be excluded for some reason (e.g., it would be too large to be properly displayed).
+
equation (str) – The equation (assume an implicit “Z = “ on the left-hand side) for the circuit element’s impedance.
+The string must be compatible with SymPy’s sympify function.
+For example, “(2*pi*f*C*I)^-1” for a capacitor is valid and will show up in the generated docstring as \(Z = \frac{1}{j 2 \pi f C}\).
+This is also used to verify that the circuit element’s _impedance method outputs the same answer as the circuit element’s impedance equation.
+
parameters (List[ParameterDefinition]) – A list of objects that define the circuit element’s parameter(s).
+
+
+
+
+
+
+
+classdeareis.ParameterDefinition(symbol, unit, description, value, lower_limit, upper_limit, fixed)
+
A circuit element’s parameter.
+
+
Parameters:
+
+
symbol (str) – The symbol/name of the parameter that can be used when, e.g., obtaining the value for a specific parameter via Element.get_value(symbol). Required to be a non-empty string.
+
unit (str) – The parameter’s unit (ohm*cm, F/cm, H, etc.). Can be an empty string.
+
description (str) – A description of the parameter. Can be an empty string.
+
value (float) – The default value for the parameter.
+
lower_limit (float) – The lower limit of what this parameter’s value can be during circuit fitting. A value of -numpy.inf means that there is no lower limit.
+
upper_limit (float) – The upper limit of what this parameter’s value can be during circuit fitting. A value of numpy.inf means that there is no upper limit.
+
fixed (bool) – If true, then this parameter’s value will not change during circuit fitting.
+
+
+
+
+
+
+
+classdeareis.SubcircuitDefinition(symbol, unit, description, value)
+
A container element’s subcircuit.
+
+
Parameters:
+
+
symbol (str) – The symbol/name of the subcircuit that can be used when, e.g., obtaining a specific subcircuit belonging to a container element. Required to be a non-empty string.
+
unit (str) – The unit of the subcircuit’s impedance.
+
description (str) – A description of the subcircuit. Can be an empty string.
+
value (Optional[Connection]) – The default value for the parameter. Can be a connection such as Series or Parallel, or None.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apidocs_data.html b/apidocs_data.html
new file mode 100644
index 0000000..e1d7250
--- /dev/null
+++ b/apidocs_data.html
@@ -0,0 +1,500 @@
+
+
+
+
+
+
+ Data parsing — DearEIS 5.0.1 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Parse experimental data and return a list of DataSet instances.
+One or more specific sheets can be specified by name when parsing spreadsheets (e.g., .xlsx or .ods) to only return DataSet instances for those sheets.
+If no sheets are specified, then all sheets will be processed and the data from successfully parsed sheets will be returned as DataSet instances.
+
+
Parameters:
+
+
path (Union[str, pathlib.Path]) – The path to a file containing experimental data that is to be parsed.
+
file_format (str, optional) – The file format (or extension) that should be assumed when parsing the data.
+If no file format is specified, then the file format will be determined based on the file extension.
+If there is no file extension, then attempts will be made to parse the file as if it was one of the supported file formats.
+
**kwargs – Keyword arguments are passed to the parser.
Extends pyimpspec.DataSet to implement data minimization when writing to disk and to recreate the data when loading from disk.
+Equality checks between DataSet instances is also modified.
+
+
Parameters:
+
+
frequencies (Frequencies) – A 1-dimensional array of frequencies in hertz.
+
impedances (ComplexImpedances) – A 1-dimensional array of complex impedances in ohms.
+
mask (Dict[int, bool], optional) – A mapping of integer indices to boolean values where a value of True means that the data point is to be omitted.
+
path (str, optional) – The path to the file that has been parsed to generate this DataSet instance.
+
label (str, optional) – The label assigned to this DataSet instance.
+
uuid (str, optional) – The universivally unique identifier assigned to this DataSet instance.
+If empty, then one will be automatically assigned.
Get the data necessary to plot this DataSet as a Bode plot: the frequencies, the absolute magnitudes of the impedances, and the negative phase angles/shifts of the impedances in degrees.
+
+
Parameters:
+
masked (Optional[bool], optional) – None means that all impedances are returned.
+True means that only impedances that are to be omitted are returned.
+False means that only impedances that are to be included are returned.
masked (Optional[bool], optional) – None means that all frequencies are returned.
+True means that only frequencies that are to be omitted are returned.
+False means that only frequencies that are to be included are returned.
masked (Optional[bool], optional) – None means that all impedances are returned.
+True means that only impedances that are to be omitted are returned.
+False means that only impedances that are to be included are returned.
Get the absolute magnitudes of the impedances in this DataSet.
+
+
Parameters:
+
masked (Optional[bool], optional) – None means that all impedances are returned.
+True means that only impedances that are to be omitted are returned.
+False means that only impedances that are to be included are returned.
Get the mask for this DataSet.
+True means that the data point is to be omitted and False means that the data point is to be included.
+The keys are zero-based integer indices and the values are booleans.
masked (Optional[bool], optional) – None means that all impedances are returned.
+True means that only impedances that are to be omitted are returned.
+False means that only impedances that are to be included are returned.
Get the data necessary to plot this DataSet as a Nyquist plot: the real and the negative imaginary parts of the impedances.
+
+
Parameters:
+
masked (Optional[bool], optional) – None means that all impedances are returned.
+True means that only impedances that are to be omitted are returned.
+False means that only impedances that are to be included are returned.
Get the phase angles/shifts of the impedances in this DataSet in degrees.
+
+
Parameters:
+
masked (Optional[bool], optional) – None means that all impedances are returned.
+True means that only impedances that are to be omitted are returned.
+False means that only impedances that are to be included are returned.
mask (Dict[int, bool]) – The new mask that determines which data points are omitted.
+True means that the data point is to be omitted and False means that the data point is to be included.
+The keys must be zero-based integer indices and the values must be boolean values.
masked (Optional[bool], optional) – None means that all impedances are returned.
+True means that only impedances that are to be omitted are returned.
+False means that only impedances that are to be included are returned.
+
columns (Optional[List[str]], optional) – The column headers to use.
+
negative_imaginary (bool, optional) – Whether or not the sign of the imaginary part of the impedance data should be inverted.
+Note that this does not automatically add a minus sign in front of the column label.
+
negative_phase (bool, optional) – Whether or not the sign of the phase of the impedance data should be inverted.
+Note that this does not automatically add a minus sign in front of the column label.
num_procs (int, optional) – The maximum number of processes to use.
+A value less than 1 will result in an attempt to automatically figure out a suitable value.
+Negative values are used as offsets relative to the number of cores detected.
An object representing the results of calculating the distribution of relaxation times in a data set.
+
+
Parameters:
+
+
uuid (str) – The universally unique identifier assigned to this result.
+
timestamp (float) – The Unix time (in seconds) for when the test was performed.
+
time_constants (TimeConstants) – The time constants (in seconds).
+
real_gammas (Gammas) – The corresponding gamma values (in ohms).
+
imaginary_gammas (Gammas) – The gamma values calculated based the imaginary part of the impedance data.
+Only non-empty when the BHT method has been used.
+
frequencies (Frequencies) – The frequencies of the analyzed data set.
+
impedances (ComplexImpedances) – The modeled impedances.
+
residuals (ComplexResiduals) – The residuals for the real and imaginary parts of the modeled impedances.
+
mean_gammas (Gammas) – The mean values for gamma(tau).
+Only non-empty when the TR-RBF method has been used and the Bayesian credible intervals have been calculated.
+
lower_bounds (Gammas) – The lower bound for the gamma(tau) values.
+Only non-empty when the TR-RBF method has been used and the Bayesian credible intervals have been calculated.
+
upper_bounds (Gammas) – The upper bound for the gamma(tau) values.
+Only non-empty when the TR-RBF method has been used and the Bayesian credible intervals have been calculated.
+
scores (Dict[str, complex]) – The scores calculated for the analyzed data set.
+Only non-empty when the BHT method has been used.
+
pseudo_chisqr (float) – The calculated \(\chi^2_{ps.}\) (eq. 14 in Boukamp, 1995).
+
lambda_value (float) – The regularization parameter used as part of the Tikhonov regularization.
+Only valid (i.e., positive) when the TR-NNLS or TR-RBF methods have been used.
+
mask (Dict[int, bool]) – The mask that was applied to the analyzed data set.
+
settings (DRTSettings) – The settings used to perform this analysis.
Get the data necessary to plot this DataSet as a Bode plot: the frequencies, the absolute magnitudes of the impedances, and the negative phase angles/shifts of the impedances in degrees.
Get the data necessary to plot the Bayesian credible intervals for this DRTResult: the time constants, the mean gamma values, the lower bound gamma values, and the upper bound gamma values.
Get the time constants (in seconds) and gamma (in ohms) of peaks with magnitudes greater than the threshold.
+The threshold and the magnitudes are all relative to the magnitude of the highest peak.
+
+
Parameters:
+
threshold (float, optional) – The threshold for the relative magnitude (0.0 to 1.0).
Get the data necessary to plot the relative residuals for this DRTResult: the frequencies and the relative residuals for the real and imaginary parts of the impedances in percents.
Get the scores for the data set.
+The scores are represented as complex values where the real and imaginary parts have magnitudes ranging from 0.0 to 1.0.
+A consistent impedance spectrum should score high.
+BHT method only.
Get the peaks as a pandas.DataFrame object that can be used to generate, e.g., a Markdown table.
+
+
Parameters:
+
+
threshold (float, optional) – The minimum peak height threshold (relative to the height of the tallest peak) for a peak to be included.
+
columns (Optional[List[str]], optional) – The labels to use as the column headers for real time constants, real gammas, imaginary time constants, and imaginary gammas.
The settings to use when performing a DRT analysis.
+
+
Parameters:
+
+
method (DRTMethod) – The method to use to perform the analysis.
+
mode (DRTMode) – The mode or type of data (i.e., complex, real, or imaginary) to use.
+TR-NNLS and TR-RBF methods only.
+
lambda_value (float) – The Tikhonov regularization parameter to use.
+TR-NNLS and TR-RBF methods only.
+
rbf_type (RBFType) – The radial basis function to use for discretization.
+BHT and TR-RBF methods only.
+
derivative_order (int) – The derivative order to use when calculating the penalty in the Tikhonov regularization.
+BHT and TR-RBF methods only.
+
rbf_shape (RBFShape) – The shape to use with the radial basis function discretization.
+BHT and TR-RBF methods only.
+
shape_coeff (float) – The shape coefficient.
+BHT and TR-RBF methods only.
+
inductance (bool) – Whether or not to include an inductive term in the calculations.
+TR-RBF method only.
+
credible_intervals (bool) – Whether or not to calculate Bayesian credible intervals.
+TR-RBF method only.
+
timeout (int) – The number of seconds to wait for the calculation of credible intervals to complete.
+TR-RBF method only.
+
num_samples (int) – The number of samples to use when calculating:
+- the Bayesian credible intervals (TR-RBF method)
+- the Jensen-Shannon distance (BHT method)
+
num_attempts (int) – The number of attempts to make to find a solution.
+BHT method only.
+
maximum_symmetry (float) – The maximum vertical peak-to-peak symmetry allowed.
+Used to discard results with strong oscillations.
+Smaller values provide stricter conditions.
+BHT method only.
+
fit (Optional[FitResult]) – The FitResult for a circuit that contains one or more “(RQ)” or “(RC)” elements connected in series.
+An optional series resistance may also be included.
+For example, a circuit with a CDC representation of “R(RQ)(RQ)(RC)” would be a valid circuit.
+m(RQ)fit method only.
+
gaussian_width (float) – The width of the Gaussian curve that is used to approximate the DRT of an “(RC)” element.
+m(RQ)fit method only.
+
num_per_decade (int) – The number of points per decade to use when calculating a DRT.
+m(RQ)fit method only.
+
cross_validation_method (CrossValidationMethod) – The cross-validation method used by the TR-RBF method to automatically determine a suitable value for lambda.
+
tr_nnls_lambda_method (TRNNLSLambdaMethod) – The method used by the TR-NNLS method to automatically pick a lambda value
data (DataSet) – The data set that the circuit will be fitted to.
+
settings (FitSettings) – The settings that determine the circuit and how the fit is performed.
+
num_procs (int, optional) – The maximum number of parallel processes to use when method is CNLSMethod.AUTO and/or weight is Weight.AUTO.
+A value less than 1 will result in an attempt to automatically figure out a suitable value.
+Negative values are used as offsets relative to the number of cores detected.
Get the data required to plot the results as a Bode plot (Mod(Z) and -Phase(Z) vs f).
+
+
Parameters:
+
num_per_decade (int, optional) – If the value is greater than zero, then logarithmically distributed frequencies will be generated within the range of frequencies in the data set and used to calculate the impedance produced by the fitted circuit.
Get an array of frequencies within the range of frequencies in the data set.
+
+
Parameters:
+
num_per_decade (int, optional) – If the value is greater than zero, then logarithmically distributed frequencies will be generated within the range of fitted frequencies.
Get the complex impedances produced by the fitted circuit within the range of frequencies in the data set.
+
+
Parameters:
+
num_per_decade (int, optional) – If the value is greater than zero, then logarithmically distributed frequencies will be generated within the range of fitted frequencies and used to calculate the impedance produced by the fitted circuit.
Get the data required to plot the results as a Nyquist plot (-Im(Z) vs Re(Z)).
+
+
Parameters:
+
num_per_decade (int, optional) – If the value is greater than zero, then logarithmically distributed frequencies will be generated within the range of frequencies in the data set and used to calculate the impedance produced by the fitted circuit.
A class to store the settings used to perform a circuit fit.
+
+
Parameters:
+
+
cdc (str) – The circuit description code (CDC) for the circuit to fit.
+
method (CNLSMethod) – The iterative method to use when performing the fit.
+
weight (Weight) – The weight function to use when performing the fit.
+
max_nfev (int) – The maximum number of function evaluations to use when performing the fit.
+
timeout (int) – The amount of time in seconds that a single fit is allowed to take before being timed out.
+If this values is less than one, then no time limit is imposed.
Get the data required to plot the results as a Bode plot (Mode(Z) and -Phase(Z) vs f).
+
+
Parameters:
+
num_per_decade (int, optional) – If the value is greater than zero, then logarithmically distributed frequencies will be generated within the range of tested frequencies and used to calculate the impedance produced by the fitted circuit.
Estimate the standard deviation of the noise (as a percentage of \(|Z|\)) using the approximation \({\rm SD}_{\rm est} \approx \sqrt{\chi^2_{\rm ps} \times 5000 / N_\omega}\) where \(\chi^2_{\rm ps}\) is the pseudo chi-squared value of the fit and \(N_\omega\) is the number of excitation frequencies. This approximation assumes that the error is spread evenly across the real and imaginary parts of the immittance spectrum.
Get an array of frequencies within the range of tested frequencies.
+
+
Parameters:
+
num_per_decade (int, optional) – If the value is greater than zero, then logarithmically distributed frequencies will be generated within the range of tested frequencies.
Get the complex impedances produced by the fitted circuit within the range of tested frequencies.
+
+
Parameters:
+
num_per_decade (int, optional) – If the value is greater than zero, then logarithmically distributed frequencies will be generated within the range of tested frequencies and used to calculate the impedance produced by the fitted circuit.
Get the data required to plot the results as a Nyquist plot (-Im(Z) vs Re(Z)).
+
+
Parameters:
+
num_per_decade (int, optional) – If the value is greater than zero, then logarithmically distributed frequencies will be generated within the range of tested frequencies and used to calculate the impedance produced by the fitted circuit.
Get the data necessary to plot the relative residuals for this result: the frequencies, the relative residuals for the real parts of the impedances in percents, and the relative residuals for the imaginary parts of the impedances in percents.
Perform one-sample Kolmogorov-Smirnov test on the residuals of the real and imaginary parts.
+The residuals are tested against a normal distribution with a mean that is assumed to be zero and a standard deviation that can either be provided or estimated automatically.
+
+
Parameters:
+
standard_deviation (float, optional) – If greater than zero, then the provided value is used.
+Otherwise, the standard deviation estimated based on the pseudo chi-squared and the number of frequencies is used.
+
+
Returns:
+
The p-values for the tests performed on the residuals of the real and imaginary parts.
+The null hypothesis is that the distributions of the residuals are identical to the normal distribution with a mean of zero and the provided (or estimated) standard deviation.
Perform the Lilliefors test for normality on the residuals of the real and imaginary parts.
+
+
Returns:
+
The p-values for the tests performed on the residuals of the real and imaginary parts.
+The null hypothesis is that the residuals come from a normal distribution.
Perform the Shapiro-Wilk test for normality on the residuals of the real and imaginary parts.
+
+
Returns:
+
The p-values for the tests performed on the residuals of the real and imaginary parts.
+The null hypothesis is that the residuals come from a normal distribution.
Get the statistics related to the test as a pandas.DataFrame object.
+
+
Parameters:
+
extended_statistics (int, optional) –
Include different amounts of additional statistics depending on the chosen level.
+Level 1 includes:
+
+
The estimated equivalent standard deviation of a Gaussian noise calculated based on the pseudo chi-squared value assuming that the noise in the real and imaginary parts of the impedance are independent, have a Gaussian distribution, a mean of zero, and the same standard deviation.
+
The means of the real and imaginary residuals.
+
The sample standard deviations of the real and imaginary residuals.
+
The percentage of points found within 1, 2, or 3 standard deviations.
+
+
Level 2 includes:
+
+
The p-values of normality tests performed on the real or imaginary residuals. These tests include: Lilliefors and Shapiro-Wilk.
+
+
Level 3 includes:
+
+
The p-values for one-sample Kolmogorov-Smirnov tests comparing the real or imaginary residuals against a normal distribution with a mean of zero and a standard deviation (as a percentage of \(|Z|\)) equal to the approximation obtained with \({\rm SD}_{\rm est} \approx \sqrt{\chi^2_{\rm ps} \times 5000 / N_\omega}\) where \(\chi^2_{\rm ps}\) is the pseudo chi-squared value of the fit and \(N_\omega\) is the number of excitation frequencies. This approximation assumes that the error is spread evenly across the real and imaginary parts of the immittance spectrum.
A class to store the settings used to perform a Kramers-Kronig test.
+
+
Parameters:
+
+
test (KramersKronigTest) – The type of test to perform: complex, real, imaginary, or CNLS.
+See pyimpspec and its documentation for details about the different types of tests.
+
mode (KramersKronigMode) – How to perform the test: automatic, exploratory, or manual.
+The automatic mode uses one or more methods to determine a suitable number of RC circuits.
+The exploratory mode is similar to the automatic mode except the user is allowed to choose which of the results to accept, which can help with avoiding false positives or false negatives.
+The manual mode requires the user to pick the number of RC circuits.
+
representation (KramersKronigRepresentation) – Use a specific representation of the immittance data for validation or automatically select one.
+
add_capacitance (bool) – Add a capacitance in series or in parallel when validating impedance or admittance data, respectively.
+
add_inductance (bool) – Add an inductance in series or in parallel when validating impedance or admittance data, respectively.
+
num_RC (int) – The (maximum) number of RC circuits.
+
min_log_F_ext (float) – The lower limit for log Fext values to evaluate during optimization.
+
max_log_F_ext (float) – The upper limit for log Fext values to evaluate during optimization.
+
log_F_ext (float) – The log Fext value to use if the number of Fext evluations is set to zero.
+
num_F_ext_evaluations (int) – The number of evaluations to perform when automatically determining the number of decades to extend the range of time constants in both directions.
+
rapid_F_ext_evaluations (bool) – Reduce the time spent optimizing Fext by evaluating a narrower range of RC elements.
+
cnls_method (CNLSMethod) – The iterative method to use if the CNLS test is chosen.
+
max_nfev (int) – The maximum number of function evaluations to use if the CNLS test is chosen.
+
timeout (int) – The number of seconds to wait for a single fit to be performed.
+
suggestion_settings (KramersKronigSuggestionSettings) – The settings used to define how to suggest the optimum number of RC elements.
Singleton that is used to maintain the exploratory window’s settings while
+DearEIS is running.
+
+
methods: List[int]
The 1-based identifiers of suggestion methods:
+- 1: mu-criterion (modified)
+- 2: norm of fitted variables
+- 3: norm of curvatures
+- 4: number of sign changes in curvatures
+- 5: mean distance between sign changes in curvatures
+- 6: log(sum(tau_k/var_k)) inflection point
+
+
use_mean: bool
Use the mean of the number of RC elements suggested by different methods.
+
+
use_ranking: bool
Let the different methods rank the number of RC elements, assign scores, and pick the highest-scoring number of RC elements.
+
+
use_sum: bool
Add the score from each method together and pick the highest-scoring number of RC elements.
+
+
lower_limit: int
If greater than zero, then this value is used as the lower limit instead of trying to estimate the lower limit algorithmically.
+
+
upper_limit: int
If greater than zero, then this value is used as the upper limit instead of trying to estimate the upper limit algorithmically.
+
+
limit_delta: int
The upper limit can also be defined as the lower limit plus some delta.
+
+
m1_mu_criterion: float
The threshold value used in the method described by Schönleber et al. (2014).
+
+
m1_beta: float
The exponent that affects the penalty imposed based on the distance between \({\rm \mu}\)-criterion and \({\rm \mu}\) in the score calculated as part of the modified \({\rm \mu}\)-criterion method.
These functions provide a high-level API for visualizing various objects/results (e.g., DataSet).
+Most of them are the same functions included in pyimpspec with the notable exception of plot().
Plot a complex plot containing one or more items from a project based on the provided settings.
+
+
Parameters:
+
+
settings (PlotSettings) – The settings for the plot.
+
project (Project) – The project that the plot is a part of.
+
x_limits (Optional[Tuple[Optional[float], Optional[float]]], optional) – The lower and upper limits of the x-axis.
+
y_limits (Optional[Tuple[Optional[float], Optional[float]]], optional) – The lower and upper limits of the y-axis.
+
title (bool, optional) – Whether or not to include the title in the figure.
+
legend (Optional[bool], optional) – Whether or not to include a legend in the figure.
+
legend_loc (Union[int, str], optional) – The position of the legend in the figure. See matplotlib’s documentation for valid values.
+
grid (bool, optional) – Whether or not to include a grid in the figure.
+
tight_layout (bool, optional) – Whether or not to apply a tight layout that the sizes of the reduces margins.
+
figure (Optional[matplotlib.Figure], optional) – The matplotlib.figure.Figure instance to use when plotting the data.
+
axes (List[Axes], optional) – The matplotlib.axes.Axes instance to use when plotting the data.
+
num_per_decade (int, optional) – If any circuit fits, circuit simulations, or Kramers-Kronig test results are included in the plot, then this parameter can be used to change how many points are used to draw the line (i.e. how smooth or angular the line looks).
Plot the simulated impedance response of a circuit as both a Nyquist and a Bode plot.
+
+
Parameters:
+
+
circuit (Circuit) – The circuit to use when simulating the impedance response.
+
frequencies (Frequencies) – The frequencies (in hertz) to use when simulating the impedance response.
+
label (Optional[str], optional) – The optional label to use in the legend.
+
colors (Optional[Dict[str, str]], optional) – The colors of the markers or lines. Valid keys: ‘impedance’, ‘magnitude’, ‘phase’.
+
markers (Optional[Dict[str, str]], optional) – The markers to use when not plotting lines. Valid keys: ‘impedance’, ‘magnitude’, ‘phase’.
+
figure – The matplotlib.figure.Figure instance to use when plotting the data.
+
title (Optional[str], optional) – The title of the figure.
+If not title is provided, then the circuit description code of the circuit is used instead.
+
legend (bool, optional) – Whether or not to add a legend.
+
axes – A list of matplotlib.axes.Axes instances to use when plotting the data.
+
adjust_axes (bool, optional) – Whether or not to adjust the axes (label, scale, limits, etc.).
data (DataSet) – The DataSet instance that was used in the DRT calculations.
+
peak_threshold (float, optional) – The threshold to use for identifying and marking peaks (0.0 to 1.0, relative to the highest peak).
+Negative values disable marking peaks.
+
label (Optional[str], optional) – The optional label to use in the legend.
+
admittance (bool, optional) – Plot the admittance representation of the immittance data.
+
colors (Optional[Dict[str, str]], optional) – The colors of the markers or lines. Valid keys: ‘gamma’, ‘real’, ‘imaginary’, ‘data_real’, ‘data_imaginary’.
+
markers (Optional[Dict[str, str]], optional) – The markers to use when not plotting lines. Valid keys: ‘real’, ‘imaginary’, ‘data_real’, ‘data_imaginary’.
+
figure – The matplotlib.figure.Figure instance to use when plotting the data.
+
title (Optional[str], optional) – The title of the figure.
+If no title is provided, then the circuit description code (and label of the DataSet) is used instead.
+
legend (bool, optional) – Whether or not to add a legend.
+
axes – A list of matplotlib.axes.Axes instances to use when plotting the data.
+
adjust_axes (bool, optional) – Whether or not to adjust the axes (label, scale, limits, etc.).
data (DataSet) – The DataSet instance that a circuit was fitted to.
+
label (Optional[str], optional) – The optional label to use in the legend.
+
admittance (bool, optional) – Plot the admittance representation of the immittance data.
+
colors (Optional[Dict[str, str]], optional) – The colors of the markers or lines. Valid keys: ‘real’, ‘imaginary’, ‘data_impedance’, ‘impedance’, ‘data_magnitude’, ‘data_phase’, ‘magnitude’, ‘phase’.
+
markers (Optional[Dict[str, str]], optional) – The markers to use when not plotting lines. Valid keys: ‘real’, ‘imaginary’, ‘data_impedance’, ‘data_magnitude’, ‘data_phase’.
+
num_per_decade (int, optional) – If the data being plotted is not a DataSet instance (e.g. a KramersKronigResult instance), then this parameter can be used to change how many points are used to draw the line (i.e. how smooth or angular the line looks).
+
figure – The matplotlib.figure.Figure instance to use when plotting the data.
+
title (Optional[str], optional) – The title of the figure.
+If no title is provided, then the circuit description code (and label of the DataSet) is used instead.
+
legend (bool, optional) – Whether or not to add a legend.
+
axes – A list of matplotlib.axes.Axes instances to use when plotting the data.
+
adjust_axes (bool, optional) – Whether or not to adjust the axes (label, scale, limits, etc.).
Plot the results of exploratory Kramers-Kronig tests as a Nyquist plot, a Bode plot, a plot of the residuals, and a plot of the \(\chi^2_{ps.}\) values and the scores used to suggest the number of RC elements.
suggestion (Tuple[KramersKronigResult, List[int], int, int]) – The return value of suggest_num_RC().
+
data (DataSet) – The DataSet instance that was tested.
+
admittance (bool, optional) – Whether or not to plot the admittance representation of the data instead of the impedance representation.
+
estimate_noise (bool, optional) – Whether or not to plot the estimated standard deviation of the noise based on the pseudo chi-squared value and the number of measured frequencies. The 3-sigma standard deviations are indicated in the plots. The noise is assumed to be Gaussian and the noise in each part (real and imaginary) is assumed to be independent of the other. See equation 16 in Yrjänä and Bobacka (2024) for details.
+
colors (Optional[Dict[str, str]], optional) – The colors of the markers or lines. Valid keys: ‘chisqr’, ‘num_RC’, ‘real’, ‘imaginary’, ‘data_impedance’, ‘impedance’, ‘data_magnitude’, ‘data_phase’, ‘magnitude’, ‘phase’.
+
markers (Optional[Dict[str, str]], optional) – The markers to use when not plotting lines. Valid keys: ‘chisqr’, ‘num_RC’, ‘real’, ‘imaginary’, ‘data_impedance’, ‘data_magnitude’, ‘data_phase’.
+
figure – The matplotlib.figure.Figure instance to use when plotting the data.
+
title (Optional[str], optional) – The title of the figure.
+If no title is provided, then the label of the DataSet is used instead.
+
legend (bool, optional) – Whether or not to add a legend.
+
axes – A list of matplotlib.axes.Axes instances to use when plotting the data.
+
adjust_axes (bool, optional) – Whether or not to adjust the axes (label, scale, limits, etc.).
+
colored_axes (bool, optional) – Color the y-axes.
+
moving_average_width (int, optional) – The width of the moving average to use when plotting the residuals. Must be an odd integer number greater than or equal to three. Otherwise, the moving averages are not plotted.
These functions are used by the wrapper functions to make a more complex figure with multiple subplots.
+These are all the same as those included in pyimpspec.
label (Optional[str], optional) – The optional label to use in the legend.
+
admittance (bool, optional) – Plot the admittance representation of the immittance data.
+
colors (Optional[Dict[str, str]], optional) – The colors of the markers or lines. Valid keys: ‘magnitude’, ‘phase’.
+
markers (Optional[Dict[str, str]], optional) – The markers to use when not plotting lines. Valid keys: ‘magnitude’, ‘phase’.
+
line (bool, optional) – Whether or not lines should be used instead of markers.
+
num_per_decade (int, optional) – If the data being plotted is not a DataSet instance (e.g. a KramersKronigResult instance), then this parameter can be used to change how many points are used to draw the line (i.e. how smooth or angular the line looks).
+
figure – The matplotlib.figure.Figure instance to use when plotting the data.
+
legend (bool, optional) – Whether or not to add a legend.
+
axes – A list of matplotlib.axes.Axes instances to use when plotting the data.
+
adjust_axes (bool, optional) – Whether or not to adjust the axes (label, scale, limits, etc.).
peak_threshold (float, optional) – The threshold to use for identifying and marking peaks (0.0 to 1.0, relative to the highest peak).
+Negative values disable marking peaks.
+
label (Optional[str], optional) – The optional label to use in the legend.
+
bounds_alpha (float, optional) – The alpha to use when plotting the bounds of the Bayesian credible intervals (if they are included in the data).
+
colors (Optional[Dict[str, str]], optional) – The colors of the lines. Valid keys: ‘gamma’.
+
figure – The matplotlib.figure.Figure instance to use when plotting the data.
+
legend (bool, optional) – Whether or not to add a legend.
+
axes – The matplotlib.axes.Axes instance to use when plotting the data.
+
adjust_axes (bool, optional) – Whether or not to adjust the axes (label, scale, limits, etc.).
label (Optional[str], optional) – The optional label to use in the legend.
+
admittance (bool, optional) – Plot the admittance representation of the immittance data.
+
colors (Optional[Dict[str, str]], optional) – The colors of the markers or lines. Valid keys: ‘imaginary’.
+
markers (Optional[Dict[str, str]], optional) – The markers to use when not plotting lines. Valid keys: ‘imaginary’.
+
line (bool, optional) – Whether or not a line should be used instead of markers.
+
num_per_decade (int, optional) – If the data being plotted is not a DataSet instance (e.g. a KramersKronigResult instance), then this parameter can be used to change how many points are used to draw the line (i.e. how smooth or angular the line looks).
+
figure – The matplotlib.figure.Figure instance to use when plotting the data.
+
legend (bool, optional) – Whether or not to add a legend.
+
axes – A list of matplotlib.axes.Axes instances to use when plotting the data.
+
adjust_axes (bool, optional) – Whether or not to adjust the axes (label, scale, limits, etc.).
label (Optional[str], optional) – The optional label to use in the legend.
+
admittance (bool, optional) – Plot the admittance representation of the immittance data.
+
colors (Optional[Dict[str, str]], optional) – The colors of the markers or lines. Valid keys: ‘magnitude’.
+
markers (Optional[Dict[str, str]], optional) – The markers to use when not plotting lines. Valid keys: ‘magnitude’.
+
line (bool, optional) – Whether or not a line should be used instead of markers.
+
num_per_decade (int, optional) – If the data being plotted is not a DataSet instance (e.g. a KramersKronigResult instance), then this parameter can be used to change how many points are used to draw the line (i.e. how smooth or angular the line looks).
+
figure – The matplotlib.figure.Figure instance to use when plotting the data.
+
legend (bool, optional) – Whether or not to add a legend.
+
axes – A list of matplotlib.axes.Axes instances to use when plotting the data.
+
adjust_axes (bool, optional) – Whether or not to adjust the axes (label, scale, limits, etc.).
label (Optional[str], optional) – The optional label to use in the legend.
+
admittance (bool, optional) – Plot the admittance representation of the immittance data.
+
colors (Optional[Dict[str, str]], optional) – The colors of the markers or lines. Valid keys: ‘impedance’.
+
markers (Optional[Dict[str, str]], optional) – The markers to use when not plotting lines. Valid keys: ‘impedance’.
+
line (bool, optional) – Whether or not a line should be used instead of markers.
+
num_per_decade (int, optional) – If the data being plotted is not a DataSet instance (e.g. a KramersKronigResult instance), then this parameter can be used to change how many points are used to draw the line (i.e. how smooth or angular the line looks).
+
figure – The matplotlib.figure.Figure instance to use when plotting the data.
+
legend (bool, optional) – Whether or not to add a legend.
+
axes – A list of matplotlib.axes.Axes instances to use when plotting the data.
+
adjust_axes (bool, optional) – Whether or not to adjust the axes (label, scale, limits, etc.).
label (Optional[str], optional) – The optional label to use in the legend.
+
admittance (bool, optional) – Plot the admittance representation of the immittance data.
+
colors (Optional[Dict[str, str]], optional) – The colors of the markers or lines. Valid keys: ‘phase’.
+
markers (Optional[Dict[str, str]], optional) – The markers to use when not plotting lines. Valid keys: ‘phase’.
+
line (bool, optional) – Whether or not a line should be used instead of markers.
+
num_per_decade (int, optional) – If the data being plotted is not a DataSet instance (e.g. a KramersKronigResult instance), then this parameter can be used to change how many points are used to draw the line (i.e. how smooth or angular the line looks).
+
figure – The matplotlib.figure.Figure instance to use when plotting the data.
+
legend (bool, optional) – Whether or not to add a legend.
+
axes – A list of matplotlib.axes.Axes instances to use when plotting the data.
+
adjust_axes (bool, optional) – Whether or not to adjust the axes (label, scale, limits, etc.).
label (Optional[str], optional) – The optional label to use in the legend.
+
admittance (bool, optional) – Plot the admittance representation of the immittance data.
+
colors (Optional[Dict[str, str]], optional) – The colors of the markers or lines. Valid keys: ‘real’.
+
markers (Optional[Dict[str, str]], optional) – The markers to use when not plotting lines. Valid keys: ‘real’.
+
line (bool, optional) – Whether or not a line should be used instead of markers.
+
num_per_decade (int, optional) – If the data being plotted is not a DataSet instance (e.g. a KramersKronigResult instance), then this parameter can be used to change how many points are used to draw the line (i.e. how smooth or angular the line looks).
+
figure – The matplotlib.figure.Figure instance to use when plotting the data.
+
legend (bool, optional) – Whether or not to add a legend.
+
axes – A list of matplotlib.axes.Axes instances to use when plotting the data.
+
adjust_axes (bool, optional) – Whether or not to adjust the axes (label, scale, limits, etc.).
label (Optional[str], optional) – The optional label to use in the legend.
+
admittance (bool, optional) – Plot the admittance representation of the immittance data.
+
colors (Optional[Dict[str, str]], optional) – The colors of the markers or lines. Valid keys: ‘real’, ‘imaginary’.
+
markers (Optional[Dict[str, str]], optional) – The markers to use when not plotting lines. Valid keys: ‘real’, ‘imaginary’.
+
line (bool, optional) – Whether or not lines should be used instead of markers.
+
num_per_decade (int, optional) – If the data being plotted is not a DataSet instance (e.g. a KramersKronigResult instance), then this parameter can be used to change how many points are used to draw the line (i.e. how smooth or angular the line looks).
+
figure – The matplotlib.figure.Figure instance to use when plotting the data.
+
legend (bool, optional) – Whether or not to add a legend.
+
axes – A list of matplotlib.axes.Axes instances to use when plotting the data.
+
adjust_axes (bool, optional) – Whether or not to adjust the axes (label, scale, limits, etc.).
colors (Optional[Dict[str, str]], optional) – The colors of the markers or lines. Valid keys: ‘real’, ‘imaginary’.
+
markers (Optional[Dict[str, str]], optional) – The markers to use when not plotting lines. Valid keys: ‘real’, ‘imaginary’.
+
figure – The matplotlib.figure.Figure instance to use when plotting the data.
+
legend (bool, optional) – Whether or not to add a legend.
+
axes – A list of matplotlib.axes.Axes instances to use when plotting the data.
+
adjust_axes (bool, optional) – Whether or not to adjust the axes (label, scale, limits, etc.).
+
colored_axes (bool, optional) – Color the y-axes.
+
limit (float, optional) – The absolute value of the positive and negative limits to apply to each y-axis.
+If equal to or less than zero, then the limits are adjusted automatically.
+
moving_average_width (int, optional) – The width of the moving average. Must be an odd integer number greater than or equal to three. Otherwise, the moving averages are not plotted.
Below are some examples of plots created using the plotting functions listed above.
+The circuit and the data set are based on test circuit 1 (TC-1) from this 1995 article by Bernard Boukamp.
+
Legends are disabled and colored axes are used instead in the figures generated by the wrapper functions (i.e., the first figure in each series).
+This has been done due to the small size of the figures in this documentation.
+However, the figures generated by the individual primitive functions are also included with the legends enabled and without colored axes.
+
The default color scheme is based on the Vibrant qualitative color scheme presented in Paul Tol’s blog.
+Colors and markers can be defined when calling any of the functions.
Create an instance by merging multiple Project instances.
+All UUIDs are replaced to avoid collisions.
+The labels of some objects are also replaced to avoid collisions.
+
+
Parameters:
+
projects (List[Project]) – A list of the Project instances to merge.
Performs a reconstruction of the modulus data of an impedance spectrum based on the phase data of that impedance spectrum using the Z-HIT algorithm described by Ehm et al. (2000).
+The results can be used to, e.g., check the validity of an impedance spectrum by detecting non-steady state issues like drift at low frequencies.
+See the references below for more information about the algorithm and its applications.
+The algorithm involves an offset adjustment of the reconstructed modulus data, which is done by fitting the reconstructed modulus data to the experimental modulus data in a frequency range that is unaffected (or minimally affected) by artifacts.
+This frequency range is typically around 1 Hz to 1000 Hz, which is why the default window function is a “boxcar” window that is centered around \(\log{f} = 1.5\) and has a width of 3.0.
+Multiple window functions are supported and a custom array of weights can also be used.
+
References:
+
+
+
Ehm, H. Göhr, R. Kaus, B. Röseler, and C.A. Schiller, 2000, Acta Chimica Hungarica, 137 (2-3), 145-157.
+
+
+
+
Ehm, R. Kaus, C.A. Schiller, and W. Strunz, 2001, in “New Trends in Electrochemical Impedance Spectroscopy and Electrochemical Noise Analysis”.
settings (ZHITSettings) – The settings that determine how the Z-HIT computation is performed.
+
num_procs (int, optional) – The maximum number of parallel processes to use when performing the computations.
+A value less than 1 will result in an attempt to automatically figure out a suitable value.
+Negative values are used as offsets relative to the number of cores detected.
+Applies only when there are multiple possible options for smoothing, interpolation, or window function.
A class to store the settings used to perform a Z-HIT analysis.
+
+
Parameters:
+
+
smoothing (ZHITSmoothing) – The smoothing algorithm to use.
+
num_points (int) – The number of points to consider when smoothing a point.
+
polynomial_order (int) – The order of the polynomial to use in the Savitzky-Golay algorithm.
+
num_iterations (int) – The number of iterations to use in the LOWESS algorithm.
+
interpolation (ZHITInterpolation) – The spline to use when interpolating the phase data.
+
window (ZHITWindow) – The window function to use when generating weights for the offset adjustment.
+
window_center (float) – The center of the window function on the logarithmic frequency scale (e.g., 100 Hz -> 2.0).
+
window_width (float) – The width of the window function on the logarithmic frequency scale (e.g., 2.0 means 1 decade on each side of the window center).
+
representation (ZHITRepresentation) – Which immittance representation to operate on.
The GUI is the primary interface of DearEIS but an API is also included for some batch processing capabilities.
+However, if an API is the desired interface for performing various tasks, then using pyimpspec directly may be preferable.
In the following example we will load a project, iterate over data sets, various results, simulations, and plots.
+A single example of each of these will be plotted.
The approach used in the previous example could be used as the basis for creating more complicated plots (i.e., select the data sets and results programmatically).
+However, it may be more convenient to use DearEIS’ GUI to select the data sets, results, etc. and assign colors, markers, etc.
+The resulting PlotSettings and PlotSeries objects can then be used as the foundation for generating the final plot using either the plotting functions included with DearEIS or another plotting library.
+
>>> fromdeareisimport(
+... PlotSeries,# Wrapper class for DataSet, KramersKronigResult, etc.
+... PlotSettings,# The settings class for plots created via DearEIS' GUI
+... PlotType,# Enum for different types of plots (e.g., Nyquist)
+... Project,
+... mpl,
+... )
+>>> importmatplotlib.pyplotasplt
+>>> frommatplotlib.figureimportFigure
+>>> fromtypingimport(
+... Optional,
+... Tuple,
+... )
+>>>
+>>> # Prepare the figure that will be used to create a custom Nyquist plot.
+>>> figure,axis=plt.subplots()
+>>> axes=[axis]
+>>>
+>>> # Load the project of interest.
+>>> project:Project=Project.from_file("./tests/example-project-v6.json")
+>>>
+>>> # Get the settings for the plot that contains the series (data sets,
+>>> # fit results, etc.) that we wish to plot.
+>>> plot:PlotSettings=[
+... plotforplotinproject.get_plots()
+... ifplot.get_label()=="Noisy"
+... ][0]
+>>>
+>>> # Each data set, fit result, etc. can be represented as a PlotSeries
+>>> # object that contains the required data and the style (color, marker, etc.).
+>>> series:PlotSeries
+>>> forseriesinproject.get_plot_series(plot):
+... # Figure out if the series should be included in the figure legend.
+... label:Optional[str]=None
+... ifseries.has_legend():
+... label=series.get_label()
+...
+... # Figure out the color and marker.
+... color:Tuple[float,float,float,float]=series.get_color()
+... marker:Optional[str]=mpl.MPL_MARKERS.get(series.get_marker())
+...
+... # Determine whether or not the series should be plotted using markers,
+... # a line, or both.
+... # We will use the plotting functions provided by DearEIS in this example
+... # but you could use any plotting library that you wish. However, you
+... # would need to call, e.g., series.get_frequencies() and/or
+... # series.get_impedances() to get the relevant data.
+... ifseries.has_line():
+... _=mpl.plot_nyquist(
+... series,
+... colors={"impedance":color},
+... markers={"impedance":marker},
+... line=True,
+... label=labelifmarkerisNoneelse"",
+... figure=figure,
+... axes=axes,
+... num_per_decade=50,
+... )
+... ifmarkerisnotNone:
+... _=mpl.plot_nyquist(
+... series,
+... colors={"impedance":color},
+... markers={"impedance":marker},
+... line=False,
+... label=label,
+... figure=figure,
+... axes=axes,
+... num_per_decade=-1,
+... )
+... elifmarkerisnotNone:
+... _=mpl.plot_nyquist(
+... series,
+... colors={"impedance":color},
+... markers={"impedance":marker},
+... line=False,
+... label=label,
+... figure=figure,
+... axes=axes,
+... num_per_decade=-1,
+... )
+>>>
+>>> # Add the figure title and legend.
+>>> _=figure.suptitle(plot.get_label())
+>>> _=axis.legend()
+
Several of the various *Result classes have to_*_dataframe methods that return tables as pandas.DataFrame objects, which can be used to output, e.g., Markdown or LaTeX tables.
+
>>> fromdeareisimportDataSet,FitResult,Project
+>>> project:Project=Project.from_file("./tests/example-project-v6.json")
+>>> data:DataSet=project.get_data_sets()[0]
+>>> fit:FitResult=project.get_fits(data)[0]
+>>> print(fit.to_parameters_dataframe().to_markdown(index=False))
+| Element | Parameter | Value | Std. err. (%) | Unit | Fixed |
+|:----------|:------------|--------------:|----------------:|:----------|:--------|
+| R_1 | R | 99.9527 | 0.0270272 | ohm | No |
+| R_2 | R | 200.295 | 0.0161674 | ohm | No |
+| C_1 | C | 7.98618e-07 | 0.00251014 | F | No |
+| R_3 | R | 499.93 | 0.0228817 | ohm | No |
+| W_1 | Y | 0.000400664 | 0.0303242 | S*s^(1/2) | No |
+>>> print(fit.to_parameters_dataframe(running=True).to_markdown(index=False))
+| Element | Parameter | Value | Std. err. (%) | Unit | Fixed |
+|:----------|:------------|--------------:|----------------:|:----------|:--------|
+| R_0 | R | 99.9527 | 0.0270272 | ohm | No |
+| R_1 | R | 200.295 | 0.0161674 | ohm | No |
+| C_2 | C | 7.98618e-07 | 0.00251014 | F | No |
+| R_3 | R | 499.93 | 0.0228817 | ohm | No |
+| W_4 | Y | 0.000400664 | 0.0303242 | S*s^(1/2) | No |
+
Equations for the impedances of elements and circuits can be obtained in the form of SymPy expressions or LaTeX strings.
+
+
Note
+
Equations always make use of a running count of the elements as the lower index in variables to avoid conflicting/duplicate variable names from different elements.
+Circuit diagrams and tables can also make use of running counts as lower indices if explicitly told to (e.g., circuit.to_drawing(running=True), circuit.to_circuitikz(running=True), or fit.to_parameters_dataframe(running=True)).
The various tabs dedicated to performing some form of analysis also have a Batch button.
+These buttons bring up a window (Fig. 35)where multiple data sets can be selected for inclusion in a batch analysis.
+
+
+
+
Fig. 35 An example of the Batch analysis window where a few data sets have been selected.
+
+
+
+
Note
+
If any errors are encountered while performing the analyses, then those errors are presented at the end.
+There is no way to cancel a batch analysis once it has been started.
+
+
+
Note
+
Performing Kramers-Kronig tests in Exploratory mode would usually bring up a window for inspection of the intermediate results.
+This window is NOT shown when performing a batch analysis.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/guide_data.html b/guide_data.html
new file mode 100644
index 0000000..13f1047
--- /dev/null
+++ b/guide_data.html
@@ -0,0 +1,296 @@
+
+
+
+
+
+
+ Processing data — DearEIS 5.0.1 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Multiple impedance spectra (or data sets) can be loaded and processed in the Data sets tab (Fig. 3) that contains the following:
+
+
Data set combo for switching between data sets that have been loaded via the Load button.
+
Label input for modifying the label assigned to the current data set.
+
Path input for modifying the file path assigned to the current data set.
+
Process button for opening a popup window with buttons for accessing features that enable further processing of the current data set.
+
A table of data points with the ability to mask (i.e., hide/exclude) individual points (e.g., outliers).
+
Toggle points button for (un)masking multiple points at once.
+
Copy mask button for copying a mask from another data set and applying it to the current data set.
+
Enlarge/show plot button for viewing a larger version of the current plot type.
+
Adjust limits checkbox for enabling/disabling automatic adjustment of plot limits when switching between data sets.
+
Plot type combo for switching between plot types. This is primarily for use when the program window is so narrow that the plots are hidden in order to keep the table of data points from becoming to narrow.
+
+
+
+
+
Fig. 3 The data point around 50 Hz has been omitted from this rather noisy data set as an outlier.
Plain-text character-separated values (CSV): .csv and .txt
+
+
Additional file formats may be supported in the future.
+
Not all CSV files and spreadsheets are necessarily supported as-is but the parsing of those types of files should be quite flexible in terms of, e.g., the characters that are used as separators.
+The parsers expect to find at least a column with frequencies (Hz) and columns for either the real and imaginary parts of the impedance (\(\Omega\)), or the absolute magnitude (\(\Omega\)) and the phase angle/shift (degrees).
+The supported column headers are:
+
+
frequency: frequency, freq, or f
+
real: z', zre, z_re, zre, real, or re
+
imaginary: z", z'', zim, z_im, zim, imaginary, imag, or im
+
magnitude: |z|, z, magnitude, modulus, mag, or mod
+
phase: phase, phz, or phi
+
+
The identification of column headers is case insensitive (i.e., Zre and zre are considered to be the same).
+The sign of the imaginary part of the impedance and/or the phase angle/shift may be negative, but then that has to be indicated in the column header with a - prefix (e.g., -Zim or -phase).
Masks can be applied to hide data points in several ways and masked data points are excluded from plots and analyses.
+This feature can be used to get rid of outliers or to analyze a fragment of a data set.
+Individual data points can be masked via the checkboxes along the left-hand side of the table of data points (Fig. 3).
+Ranges of data points can be toggled via the window that is accessible via the Toggle points button below the table of data points.
+This can be used to, e.g., quickly mask multiple points or to remove the mask from all points (Fig. 4).
+Middle-mouse clicking and dragging a region in a plot in that window can also be used to choose the points to toggle.
+
+
+
+
Fig. 4 The Toggle points can be used to (un)mask multiple data points in several ways.
+A preview of what the current data set would look like with the new mask is also included.
+Here a region has been highlighted in one of the plots by holding down the middle-mouse button and dragging.
+All of the points are included, which means that the points within the highlighted region will be toggled (i.e., excluded) when the Accept button is clicked.
+
+
+
If multiple data sets will need to have the same (or very similar) masks, then the Copy mask window can be used to copy the applied mask from another data set to the current data set (Fig. 5).
+
+
+
+
Fig. 5 The Copy mask includes a preview of what the current data set would look like with the mask that was applied to another data set in Fig. 4.
DearEIS includes a few functions for processing data sets: averaging, interpolation, addition of parallel impedances, and subtraction of impedances.
+All of these functions are available via the Process button that can be found above the table of data points (Fig. 3).
+The results of these functions are added to the project as a new data set (i.e., without getting rid of the original data set).
The averaging feature can be used to obtain a less noisy spectrum by averaging multiple measurements (Fig. 6).
+This can be useful in cases where the noise cannot be reduced by adjusting some aspect of the experimental setup (e.g., by improving the shielding).
+Only data sets with the same frequencies can be averaged.
+
+
Note
+
Make sure that the measurements differ due to random noise rather than, e.g., drift before using this feature.
+
+
+
+
+
Fig. 6 Two data sets have been chosen (markers) and an average data set has been generated (line).
+The other data sets do not have the same frequencies as the two chosen data sets and thus cannot be selected while at least one of those two data sets is selected.
The interpolation feature can be used to replace an outlier rather than simply omitting it (Fig. 7).
+Some specific methods of analysis may be sensitive to the spacing of data points, which is why interpolation may be preferred over omission.
+The data set is smoothed using LOWESS and interpolated using an Akima spline while ignoring any masked points.
+Individual data points can then be replaced with a point on this spline by ticking the checkbox next to that data point.
+Alternatively, if the smoothing and interpolation cannot provide a reasonable result, then values for the real and/or imaginary part of the data point can be inputted directly.
+
+
+
+
Fig. 7 The outlier (red marker), which was masked in Fig. 3, has been replaced with a value (orange marker) along the interpolated spline (green line).
Impedance data that include negative differential resistances may present some challenges.
+For example, such spectra cannot be validated directly using linear Kramers-Kronig tests if only the impedance representation is tested.
+However, they can be validated if the admittance representation is tested.
+Alternatively, one can add a suitable parallel resistance to the impedance data.
+The addition of a parallel resistance does not affect the Kramers-Kronig compliance of the data.
The magnitude of the parallel resistance to add depends on the original impedance data.
+In the example below (Fig. 8), a resistance of 50 \(\Omega\) was chosen.
+
+
Note
+
Equivalent circuits can be fitted to the original impedance data that include negative differential resistances provided that negative resistances are allowed (i.e., the lower limits of resistances are disabled or modified prior to fitting).
+
+
+
+
+
Fig. 8 An impedance spectrum that includes a negative differential resistance was generated for this example (marked here as Before).
+Performing Kramers-Kronig tests on the impedance representation would fail despite the original data being compliant.
+Adding a parallel resistance of 50 \(\Omega\) produces impedance data (marked here as After) that can be validated.
+The added parallel resistance is always Kramers-Kronig compliant, which means that the compliance of the resulting circuit and its impedance data depends on the compliance of the original data.
This type of analysis can be used, e.g., as an aid when developing equivalent circuits by revealing the number of time constants.
+The peak shapes (e.g., symmetry and sharpness) can also help with identifying circuit elements that could be suitable.
+
DRT calculations can be performed in the DRT analysis tab (Fig. 16):
+
+
the various settings that determine how the DRT calculations are performed
+
combo boxes that can be used to choose the active data set and the active result, and a button for deleting the active result
+
a table of statistics related to the active result
+
a table of the settings that were used to obtain the active result
+
+
+
+
+
Fig. 16 An example of a result obtained with the noisy data set and the TR-RBF method.
+
+
+
The results are presented in the form of one or more tables (e.g., statistics, scores), a plot of gamma versus time constant, and other plots.
+Some results can be copied to the clipboard in different plain-text formats via the Output combo box and the Copy button.
+
It was mentioned in the Processing data subchapter that some forms of analysis can be sensitive to the omission of a data point.
+Below are some examples of this.
+The overlay plots shown below are created using the Plotting tab (more information about that can be found in the Plotting subchapter).
+
+
+
+
Fig. 17 Three overlaid DRT spectra that were obtained with the TR-RBF method using the same settings: with outlier (original), without outlier (omitted), and with the outlier replaced (interpolated).
+The presence of the outlier clearly has a significant effect on peak positions in the range above 0.001 s.
+However, omitting the outlier resulted in additional peaks appearing within the 0.01 to 0.1 s range.
+
+
+
+
+
+
Fig. 18 Additional DRT spectra, which were obtained by fitting R(RC)(RQ) circuits and calculating the DRT using the m(RQ)fit method, overlaid on top of Fig. 17.
+The presence of the outlier has shifted the peaks toward lower time constants (original).
+The m(RQ)fit method is less sensitive to the omission of the outlier as can be seen from the two DRT spectra (omitted and interpolated) that are almost identical.
+The two latter spectra also have, e.g., their left-most peaks in the correct position of approximately 0.00016 s which is the expected value based on the known resistance and capacitance values (200 \(\Omega\) and 0.8 \(\mathrm{\mu F}\), respectively) of the circuit that was used to generate the data sets.
+
+
+
One can see based on Fig. 18 that different DRT methods can produce very different results, but the settings and amount of noise in the data also have a significant effect as can be seen in Fig. 19.
+
+
+
+
Fig. 19 In this example two DRT spectra are shown for each of the data sets: ideal (no noise) and interpolated (noisy with the outlier replaced).
+The DRT spectra have been obtained using the TR-RBF method with otherwise identical settings apart from the regularization parameters, \(\lambda\), that are indicated in the labels found in the plot legend.
The settings that were used to perform the active analysis result are also presented as a table and these settings can be applied by pressing the Apply settings button.
+
The mask that was applied to the data set when the analysis was performed can be applied by pressing the Apply mask button.
+If the mask that is applied to the data set has changed since an earlier analysis was performed, then that will be indicated clearly above the statistics table.
+
These features make it easy to restore old settings/masks in case, e.g., DearEIS has been closed and relaunched, or after trying out different settings.
The Fitting tab is where equivalent circuits can be fitted to data sets (Fig. 20):
+
+
the various settings that determine how the fitting is performed
+
combo boxes that can be used to choose the active data set, the active fit result, and the active output
+
a table of fitted parameter values and estimated errors (if possible to estimate)
+
a table of statistics related to the active fit result
+
a table of the settings that were used to obtain the active result
+
+
+
+
+
Fig. 20 An example of an R(RC)(RW) circuit that has been fitted to a data set.
+The obtained fitted parameters are close to the parameters that were used to generate the data set in the first place.
+
+
+
Equivalent circuits can be constructed either by typing in a corresponding circuit description code (CDC) or by using the graphical circuit editor, which is accessible by pressing the Edit button.
+
Different iterative methods and weights are available.
+If one or both of these settings are set to Auto, then combinations of iterative method(s) and weight(s) are used to perform multiple fits in parallel and the best fit is returned.
+
The results are presented in the form of a table containing the fitted parameter values (and, if possible, error estimates for the fitted parameter values), a table containing statistics pertaining to the quality of the fit, three plots (Nyquist, Bode, and relative errors of the fit), and a preview of the circuit that was fitted to the data set.
+If you hover the mouse cursor over the cells in the tables, then you can get additional information (e.g., more precise values or explanations).
+
+
Note
+
It may not always be possible to estimate errors for fitted parameters.
+Common causes include:
+
+
A parameter’s fitted value is close to the parameter’s lower or upper limit.
+
An inappropriate equivalent circuit has been chosen.
+
The maximum number of function evaluations is set too low.
+
The data contains no noise and the equivalent circuit is very good at reproducing the data.
Circuit elements are represented by one or more letter symbols such as R for a resistor, C for a capacitor, and Wo for a Warburg diffusion of finite-length with a reflective boundary.
+
Two or more circuit elements enclosed in parentheses, (), are connected in parallel.
+
Two or more circuit elements enclosed in square brackets, [], are connected in series. This can be used to construct, e.g., a parallel connection that contains a nested series connection ((C[RW]) where R and W are connected together in series and that series connection is in parallel with C).
+
+
DearEIS also supports an extended CDC syntax.
+This extended syntax allows for defining circuit elements with, e.g., labels, initial values for parameters, and parameter limits.
+Circuit elements can be followed up by curly braces and the aforementioned things can be defined within these curly braces.
+For example, R{R=250f:ct} defines a resistor with:
+
+
an initial value of 250 ohms for the resistance R
+
a fixed initial value (i.e., a constant value)
+
the label ct, which stands for charge transfer
+
+
E notation (e.g., 1e-6 or 1E-6 instead of 0.000001) is supported by the extended syntax.
+All parameters do not need to be defined if a circuit element has multiple parameters.
+If parameters are omitted, then the default values are used (e.g., the default initial value for the R parameter of a resistor is 1000 ohms).
+If parameter limits are completely omitted, then the default values are used (e.g., the default lower limit for the R parameter of a resistor i 0 and the upper limit is infinity).
+Q{Y=1.3e-7//1e-5,n=0.95/0.9/1.0:dl} defines a constant phase element with:
+
+
an initial value of 1.3 * 10^-7 F*s^(n-1) for the Y parameter (other sources may use the notation A or Q0 for this parameter) with no lower limit and an upper limit of 1 * 10^-5 F*s^(n-1)
+
an initial value of 0.95 for the n parameter (other sources may use the notation alpha or psi for this parameter) with a lower limit of 0.9 and an upper limit of 1.0
+
the label dl, which stands for double-layer (i.e., double-layer capacitance)
+
+
The valid symbols are listed in the Elements tab found within the Diagram tab of the Circuit editor window.
+
Alternatively, nodes representing the circuit elements can be added to the node editor and connected together to form an equivalent circuit.
+Circuit elements can be added to the node editor by clicking on a type of element in the Elements tab or by dragging a type of element from the Elements tab and onto the node editor.
+The nodes can be linked together by clicking and dragging between the terminals of the nodes (i.e., the yellow dots on either side of a node).
+If two parallel circuits are connected in series like in Fig. 21, then it is necessary to place a node between them.
+This node could be an element (e.g., a resistor) that is also connected in series to the two parallel circuits or it could be a dummy node.
+This dummy node, which can be added with the Add dummy/junction button, does not affect the impedance of the system at all.
+Links between nodes can be deleted by either clicking on a link and then pressing the Delete button on the keyboard, or by holding down Ctrl when clicking on a link.
+Multiple nodes can be moved or deleted by clicking and dragging a selection box around them.
+
+
Note
+
Click and hold on a terminal/pin (yellow dot) to start creating a link and then drag and release near another terminal/pin.
+Hold down Ctrl while clicking on a link to remove the link.
+
+
+
+
+
Fig. 21 The graphical circuit editor can be used to construct equivalent circuits and to define the initial values and limits of parameters.
+
+
+
+
+
+
Fig. 22 Selecting a node makes it possible to assign a label (e.g., ct for charge transfer).
+
+
+
+
Note
+
Due to technical reasons, one must click on the upper part of a node (i.e., where the label is) that represents a circuit element in order to be able to define, e.g., custom initial values.
+Also, any values typed into the input fields must be confirmed by pressing Enter or the value will not actually be set.
+Click and hold on the lower part of the node to move it around.
+
+
+
+
+
Fig. 23 Container elements such as the general transmission line model have subcircuits that can also be modified.
+
+
+
Press the Accept circuit button in the bottom right-hand corner once the equivalent circuit is complete.
+If there is an issue with the equivalent circuit (e.g., a missing or invalid connection), then the button will be labeled Cancel instead.
+The Status field at the bottom of the window should offer some help regarding the nature of the issue and the affected node should be highlighted with a red label (Fig. 24).
+
+
+
+
Fig. 24 If the circuit is invalid because of, e.g., a missing connection, then that is indicated by highlighting the affected node and by showing a relevant error message in the status field near the bottom of the window.
The initial values of the parameters of each circuit element can be adjusted via the circuit editor’s Parameters tab.
+This tab provides a real-time preview of the impedance/admittance spectrum produced by the circuit.
+The lower and/or upper limits of the parameters can also be defined, and parameters can also be given fixed values.
+
+
+
+
Fig. 25 The Parameters tab of the Circuit editor window provides a convenient way of dialing in the initial values before performing a fit.
+
+
+
It is possible to apply the values, which were obtained by fitting a circuit, as the initial values for another iteration of circuit fitting.
+This is accomplished by clicking the Apply fitted values as initial values button that can be found below the table of fitted values in the Fitting tab of the project.
The settings that were used to perform the active fitting result are also presented as a table and these settings can be applied by pressing the Apply settings button.
+
The mask that was applied to the data set when the fitting was performed can be applied by pressing the Apply mask button.
+If the mask that is applied to the data set has changed since an earlier fitting was performed, then that will be indicated clearly above the statistics table.
+
These features make it easy to restore old settings/masks in case, e.g., DearEIS has been closed and relaunched, or after trying out different settings.
Different aspects of the results can be copied to the clipboard in different plain-text formats via the Output combo box and the Copy button.
+For example, the following results can be copied:
+
+
the basic or extended CDC of the fitted circuit
+
a table of the impedance response of the fitted circuit as character-separated values
+
a table of the fitted parameters as, e.g., character-separated values.
+
a circuit diagram of the fitted circuit as, e.g., LaTeX or Scalable Vector Graphics (see example below)
+
the SymPy expression describing the impedance of the fitted circuit
+
+
+
Note
+
Variables in SymPy expressions use a different set of lower indices to avoid conflicting variable names. See Generating equations for more information.
Make sure that Python and pip are installed first (see previous section for supported Python versions).
+For example, open a terminal and run the command:
+
pip--version
+
+
+
+
Note
+
Using a Python virtual environment is highly recommended in order to avoid possible issues related to conflicting versions of dependencies installed on a system.
+Such a virtual environment needs to be activated before running a script that imports a package installed inside the virtual environment.
+The system-wide Python environment may also be externally managed in order to prevent the user from accidentally breaking that environment since the operating system depends upon the packages in that environment.
+
A third-party tool called pipx can automatically manage such virtual environments, but it is primarily for installing programs that provide, e.g., a command-line interface (CLI) or a graphical user interface (GUI).
+These programs can then be run without having to manually activate the virtual environment since pipx handles that.
+The virtual environment would still need to be activated before running a script that imports DearEIS and makes use of DearEIS’s application programming interface (API).
+
+
If using pipx, then run the following command to make sure that pipx is available.
+If pipx is not available, then follow the instructions to install pipx.
+
pipx--version
+
+
+
If there are no errors, then run the following command to install DearEIS and its dependencies:
+
# If manually managing the virtual environment,
+# follow the relevant pip documentation for creating
+# and activating a virtual environment before running
+# the following command.
+pipinstalldeareis
+
+# If pipx is used to automatically manage the virtual environment.
+pipxinstalldeareis
+
+
+
DearEIS should now be available as a command in the terminal and possibly also some application launchers.
+
If you wish to install the optional dependencies, then they can be specified explicitly when installing DearEIS via pip:
+
pipinstalldeareis[cvxopt]
+
+
+
Optional dependencies can also be install after the fact if pipx was used:
+
pipxinjectdeareiscvxopt
+
+
+
Newer versions of DearEIS can be installed in the following ways:
You should now be able to run DearEIS via, e.g., a terminal or the Windows start menu by typing in the command deareis.
+There is also a deareis-debug command that can be used for troubleshooting purposes and prints a lot of potentially useful information to a terminal window.
+DearEIS can also be launched as a Python module:
DearEIS supports the use of keybindings to perform many but not all of the actions available in the various windows and tabs (e.g., switch to a specific tab, switch to a certain plot type, a Kramers-Kronig test, or perform a Kramers-Kronig test).
+These keybindings are in many cases similar from window to window and tab to tab, and the keybindings can be reassigned via the corresponding settings window.
+However, in some cases the keybindings are unique to the window (e.g., the file dialog).
+
When a modal/popup window isn’t open, then it is possible to perform actions via the Command palette (Fig. 40) that can be opened by default via Ctrl+P.
+The contents of the list of actions depends upon the context (e.g., which tab is currently open).
+The list of actions can be navigated using, e.g., the arrow keys.
+Alternatively, the input field at the top can be used to search of a specific action.
+If the input field is empty, then the order of the options depends upon how recently an option was chosen.
+This should help with finding actions that are used frequently.
+
+
+
+
Fig. 40 Various actions can be performed via the Command palette, which only requires memorization of a single keybinding (Ctrl+P by default).
+Actions can be navigated with the Up/Down arrow keys, PageUp/Down keys, and Home/End keys.
+The window also supports fuzzy matching for finding a specific action (e.g., saw should bring the Showthe'About'window action to the top).
The Data set palette and Result palette are similar to the Command palette but they instead facilitate switching between data sets or various results depending on the current tab (Kramers-Kronig test results, fit results, plots, etc.).
+The Data set palette and Result palette can be opened by default via Ctrl+Shift+P and Ctrl+Shift+Alt+P, respectively.
The Plotting tab (Fig. 29) can be used to compose plots with multiple data sets and/or analysis results.
+These plots can be used just within DearEIS to compare different results side-by-side.
+However, these plots can also be used to prepare relatively simple plots for sharing and/or publication.
+The plot settings can also be used via the API provided by DearEIS, which means that the basic layout can be prepared via the GUI and then the final plot can be generated programmatically.
+This approach would also mean that a plotting library other than matplotlib, which is the default backend for exporting plots using DearEIS, could be used instead.
+
+
+
+
Fig. 29 The Plotting tab can be used to create plots containing multiple data sets and/or results.
The Available tab (Fig. 30) contains entries for all of the data sets, analysis results, and simulations contained within a project.
+Individual items can be selected by ticking their corresponding checkboxes.
+
+
+
+
Fig. 30 Data sets and/or results can be selected from the Available tab.
+In this example the substring randles has been used to filter items.
+
+
+
The Filter input field can be used to search for specific items.
+The labels of analysis results are treated as if they also contain the label of the data set that they belong to, which means that filtering based on a data set’s label will also include the analysis results belonging to that data set.
+Using a hyphen, “-”, as a prefix is equal to a logical not (i.e., “-noisy” excludes items with “noisy” in their labels).
+Multiple filter terms can be used by separating them with commas.
+If one or more spaces, “ “, are typed in this field, then all of the headings are expanded.
+Similarly, if the input field is cleared, then all of the headings are collapsed.
+
Each heading contains buttons for (un)selecting all items within that heading and buttons for expanding/collapsing all subheadings.
+There are also buttons for (un)selecting all items regardless of the heading they fall under.
+Items that have been selected are added to the Active tab.
Selected items are listed in a table in the Active tab and several aspects of those items can be edited.
+An item’s label, which is used in the plot’s legend, can be overridden by typing in a new label.
+If one or more spaces, “ “, are given as the new label, then the item will not have an entry in the legend.
+
+
+
+
Fig. 31 The label and appearance of the selected items can be modified in the Active tab.
+All three items have been given new labels that are used in the plot’s legend.
+
+
+
An item’s appearance (color, marker shape, and whether or not it should have a line) can be edited from the popup window that appears when clicking the Edit button (Fig. 32).
+The U and D buttons can be used to adjust the order of an item when generating a plot, which affects the legend and whether or not an item will either be covered by or be covering some other item.
+
+
+
+
Fig. 32 The Edit appearance window that can be used to define the color associated with a plottable item.
+The type of marker (if any) can also be chosen.
+Whether or not the item should (also) be plotted using a line can also be chosen.
+
+
+
If specific items should have the same appearance across multiple plots, then there are two approaches for conveniently copying the relevant settings from one plot to another.
+The first approach is to have a main plot (e.g., labeled Appearance template) that is used simply to define the appearance of items.
+This main plot can then be duplicated, which also copies each item’s settings, and modified.
+The second approach is to use the menu that is accessible via the Copy appearance button (Fig. 33) to copy item settings from another plot.
+One can choose which plot to copy from, which items to copy settings from, and which categories of settings to copy (label, colors, etc.).
+
+
+
+
Fig. 33 The Copy appearance settings window is for copying the appearance settings for multiple items from one plot to another.
+Alternatively, one can define the settings in one plot that is then duplicate the plot and make minor adjustments to the newly duplicated plot.
Plots can be exported (i.e., saved as files) using matplotlib (Fig. 34).
+The plots (PlotSettings) and the items (PlotSeries) included in the plots are also accessible via the API.
+This means means that one can compose a plot using the GUI and generate the final plot using the API, which allows for batch exporting and also for greater control of a plot’s appearance.
+
+
+
+
Fig. 34 The Export plot window is for previewing and preparing to save a plot as a file.
+Some amount of customization is available, but users who desire a greater degree of control are directed to use the API of DearEIS to extract the data (and possibly also the various plot settings) in order to programmatically generate the final plots.
+
+
+
+
Warning
+
A subset of users may encounter crashes when attempting to export plots.
+This issue appears to affect systems running Linux together with an nVidia GPU and proprietary drivers.
+
Unticking the Cleartextureregistry setting in Settings>Defaults>Plottingtab-Exportplot>Miscellaneous may resolve the issue.
+However, unticking this setting means that any memory allocated to previewing matplotlib plots is not freed until DearEIS is closed.
The workflow of DearEIS is based upon projects, which are stored as JavaScript Object Notation (JSON).
+These projects can contain multiple impedance spectra (or data sets) as well as multiple analysis results.
+
Projects can be created from the Home tab (Fig. 1) or the File menu (top of the window).
+Recent projects are listed in this tab for quick access.
+The entire list can be cleared and individual entries can be also be removed.
+Two or more projects can also be merged to form a new project.
+
+
+
+
Fig. 1 Recent projects are easily accessible from the Home tab.
+
+
+
DearEIS maintain a snapshot of a project while that project is open.
+The snapshot is updated every N actions (configurable in the settings) and this snapshot is recoverable in case DearEIS crashes or is closed while a project has unsaved changes.
+Any such snapshots are loaded automatically the next time that DearEIS is started.
+The snapshots are stored in XDG_STATE_HOME paths specified by the XDG Base Directory Specification:
+
+
Table 1 Default location of project snapshots files on different operating systems.
+
+
+
+
+
+
Operating system
+
Location
+
+
+
+
Linux
+
~/.local/state/DearEIS
+
+
MacOS
+
~/Library/ApplicationSupport/DearEIS
+
+
Windows
+
%LOCALAPPDATA%\DearEIS
+
+
+
+
Multiple projects can be open at the same time as separate tabs and each project is split into multiple tabs:
+
+
The Overview tab is where the project’s label can be specified and notes can be kept.
+
The Data sets tab is for importing and processing experimental data before it is analyzed.
+
The Kramers-Kronig and Z-HIT analysis tabs provide the primary means of validating impedance spectra.
+
The DRT analysis and Fitting tabs are for extracting quantitative information.
+
The Simulation tab can be used to familiarize oneself with or to demonstrate the impedance spectra of different circuits and how parameter values affect the resulting spectra.
+
The Plotting tab is for composing figures where multiple results can be overlaid on top of each other.
+
+
+
+
+
Fig. 2 Notes about a project can be kept in the Overview tab.
Some aspects of the appearances of various plots can be defined (Fig. 36).
+Some of these settings are also mixed and matched in some plots when there are more items to plot than shown in the plots in this window (e.g., see the plots in the window for interpolating data points in the Data sets tab).
+
+
+
+
Fig. 36 Most changes made to plot appearances should take effect immediately.
+Changing the number of points in simulated lines requires switching back and forth between data sets or results to update the plots.
Many actions can be performed via keybindings.
+If an update to DearEIS changes or adds keybindings for actions, then those keybindings may not change or be assigned.
+In such cases it may be necessary to manually assign keybindings to those actions or to simply reset the keybindings.
+
+
+
+
Fig. 38 The keybindings defined in this window apply to a great extent also to modal/popup windows with similar functionality (e.g., for cycling results or plot types).
Both pyimpspec and DearEIS include support for user-defined elements since version 4.0.0.
+The support has been implemented in DearEIS by providing a setting where the user can specify a Python script that defines one or more new elements.
+See the source code (e.g., for the constant phase element) and the documentation for pyimpspec for examples.
+The relevant functions and classes are available via the APIs of both DearEIS (Equivalent circuits) and pyimpspec.
+
+
Warning
+
User-defined elements are not stored in project files.
+If a project is dependent on a user-defined element, then that project cannot be opened unless the user-defined element has been loaded.
+A project is dependent on a user-defined element if it is used in, e.g., a circuit fit or a simulation.
+
The circuits used in these types of results are stored in a project file in the form of a circuit description code (CDC), which DearEIS needs to parse when a project is loaded.
+User-defined elements are thus required at the moment of parsing and DearEIS/pyimpspec will expect to find elements that match the symbols encountered while parsing the CDC.
+Changing the symbol of a user-defined element while it is in use can thus cause issues and symbols can conflict with, e.g., new elements that have been added to pyimpspec.
+Changing the parameters/subcircuits of a user-defined element is also likely to cause issues if an older version is being used by a project.
+
So keep track of your script(s) that define user-defined elements and consider creating new elements when changes have to be made.
+
+
+
+
+
Fig. 39 Specify the path to a Python script and then click the Refresh button.
+The new circuit elements should show up in the table.
+Hovering over a row in the table should show the automatically generated extended description for a circuit element.
+If the path is left empty and then the Refresh button is clicked, then the user-defined elements are cleared.
The layout of the Simulation tab (Fig. 28) is similar to that of the Fitting tab:
+
+
the various settings that determine the simulation parameters
+
combo boxes that can be used to choose the active data set (or none), the active simulation result, and the active output
+
a table of the parameter values
+
a table of the settings that were used to obtain the active result
+
+
However, the purpose of the Simulation tab is to provide a means to simulate impedance spectra of circuits within an arbitrary range of frequencies.
+The simulated impedance spectra can be loaded as data sets, which means that they can then be subjected to the various forms of analysis included in DearEIS.
+The Simulation tab can thus be very useful for teaching, demonstration, and development purposes.
+
+
+
+
Fig. 28 An example of where a fitted circuit’s impedance response has been extrapolated outside of the frequency range of the original experimental data.
The two primary approaches to validating experimental data included in DearEIS are linear Kramers-Kronig testing and Z-HIT analysis.
+The former is a widely adopted approach based on attempting to fit a specific type of equivalent circuit, which is known a priori to be Kramers-Kronig transformable.
+The latter approach reconstructs the modulus data from the (typically) more stable phase data, which can reveal issues such as drift at low frequencies due to time invariant behavior exhibited by the measured system.
Data validation based on linear Kramers-Kronig testing can be performed in the Kramers-Kronig tab (Fig. 10) which contains the following:
+
+
various settings that determine how the Kramers-Kronig test is performed
+
combo boxes that can be used to choose the active data set and the active test result
+
a table of statistics related to the active test result
+
a table of settings that were used to obtain the active result
+
different plots
+
+
+
+
+
Fig. 10 A Kramers-Kronig test result for an impedance spectrum with a negative differential resistance.
+
+
+
The three variants of the linear Kramers-Kronig test (complex, real, and imaginary) described by Boukamp (1995) have been included.
+These have been implemented using either least squares fitting or matrix inversion.
+There is also an implementation that uses complex non-linear least squares fitting.
+These tests can be performed with a fixed number of time constants (i.e., RC elements), \(N_\tau\), using the Manual mode.
+However, it is recommended that \(N_\tau\) is determined automatically using one or more methods of the following methods by using either the Auto or the Exploratory mode.
+
+
Table 2 Methods for suggesting the optimum number of time constants (i.e., the number of parallel/series RC elements).
The intermediate results of these methods can be inspected in the Exploratory mode as a means of detecting and dealing with issues such as false negatives.
+
+
Note
+
A custom combination of methods 3, 4, and 5 is used by default. However, a specific method or combination of methods can be chosen via the window that shows up when using the Exploratory mode or via the Settings > Defaults window.
+
+
In addition to \(N_\tau\), the range of time constants can and should also be optimized.
+The range of time constants are by default defined by the reciprocals of the maximum and minimum frequencies of the impedance spectrum.
+However, the limits can be adjusted by an extension factor, \(F_{\rm ext}\), which is initially set to \(\log{F_{ext}} = 0\) in terms of the settings provided in DearEIS.
+The optimal range of time constants may be wider (\(\log{F_{ext}} > 0\)) or narrower (\(\log{F_{ext}} < 0\)) than the default range.
+There are settings for the limits to use when optimizing \(\log{F_{\rm ext}}\) and the number of evaluations to perform.
+A specific \(\log{F_{\rm ext}}\) can also be used directly by setting the number of evaluations to zero.
+
Some immittance spectra may need to be validated using based on their admittance representations rather than their impedance representations.
+It is therefore recommended that the Representation setting is set to Auto, which results in both the impedance and the admittance representation being tested.
+
+
Note
+
If you only wish to validate the impedance representation of the immittance data, then see Adding parallel impedances for information about how to process impedance data that include, e.g., negative differential resistances before attempting to validate the data.
+
+
The test results are presented in the form of a table of statistics (e.g., \(\chi^2_{ps.}\) which indicates the quality of the fit) and different plots such as one of the relative residuals of the fit.
If the Exploratory mode is used, then the intermediate results of the linear Kramers-Kronig test and the various methods for suggesting the optimal number of RC elements are presented in a window that pops up.
+The main advantages of using the Exploratory mode over the Auto mode are that one can:
+
+
evaluate how \(\chi^2_{ps.}\) behaves as a function of \(\log{F_{\rm ext}}\) and \(N_\tau\), and how the values used by the different methods for suggesting the optimal \(N_\tau\) behave
+
manually adjust, e.g., the representation, \(\log{F_{\rm ext}}\), and/or \(N_\tau\)
+
+
+
+
+
Fig. 11 The extension or contraction of the range of time constants can be evaluated using a 3D plot as shown here.
+Rapid (i.e. partial) evaluations of different \(\log{F_{\rm ext}}\) values have been used here.
+The full range of \(N_\tau\) have only been evaluated with the initial \(\log{F_{ext}} = 0\) and the optimal \(\log{F_{ext}} = -0.151\).
+
+
+
+
+
+
Fig. 12 The settings for suggesting the optimal number of RC elements can be adjusted.
+By default, the lower and upper limits are suggested automatically, and then a combination of methods 3, 4, and 5 are used to suggest the number of RC elements.
+Various plots can be viewed to evaluate the results.
Data validation using the Z-HIT algorithm can be performed in the Z-HIT analysis tab (Fig. 13) that contains the following:
+
+
the various settings that determine how the Z-HIT analysis is performed
+
combo boxes that can be used to choose the active data set and the active analysis result
+
a table of statistics related to the active analysis result
+
a table of the settings that were used to obtain the active result
+
different plots
+
+
+
+
+
Fig. 13 The modulus data that is plotted in the upper plot has been reconstructed (red line) based on the phase data (orange markers and green line) of some example data that exhibits drift at low frequencies (blue markers).
+
+
+
The Z-HIT algorithm was first described by Ehm et al. (2000) and provides a means of validating recorded impedance spectra using a modified logarithmic Hilbert transformation.
+The phase data is typically smoothed before it is interpolated using a spline, and then it is integrated and derivated to reconstruct the modulus data.
+The final step is an adjustment of the offset of the reconstructed modulus data by fitting to a subset of the experimental data that is unaffected by, e.g., drift.
+This subset of data points is typically in the range of 1 Hz to 1000 Hz.
+
+
Note
+
The modulus data is not reconstructed perfectly.
+There are often minor deviations even with ideal data.
+
+
DearEIS offers a few options for smoothing algorithm and interpolation spline, and several different window functions for the weights to use during offset adjustment.
+The weights can also be previewed in a window (Fig. 14) that is accessible via the Preview weights button that is located below the section for settings.
+This window can help with selecting a window function and appropriate parameters for it.
+
+
+
+
Fig. 14 It is possible to preview the weights that could be applied when fitting the approximated modulus data to the experimental modulus data.
+The shaded region shows the position of the window function while the orange markers show the weight (from 0.0 to 1.0) that could be applied.
+
+
+
The results are presented in the form of a table of statistics and different plots.
+
References:
+
+
Ehm, W., Göhr, H., Kaus, R., Röseler, B., and Schiller, C.A., 2000, Acta Chimica Hungarica, 137 (2-3), 145-157.
+
Ehm, W., Kaus, R., Schiller, C.A., and Strunz, W., 2001, in “New Trends in Electrochemical Impedance Spectroscopy and Electrochemical Noise Analysis”.
The settings that were used to perform the active test result are also presented as a table and these settings can be applied by pressing the Apply settings button.
+
The mask that was applied to the data set when the test was performed can be applied by pressing the Apply mask button.
+If the mask that is applied to the data set has changed since an earlier analysis was performed, then that will be indicated clearly above the statistics table.
+
+
+
+
Fig. 15 An example of the warning (red text on the left-hand side) that could be shown if, e.g., the mask applied to a data set has been changed after an analysis has been performed.
+In this case, several points of the high-frequency semi-circle in the Nyquist plot have been omitted.
+
+
+
These features make it easy to restore old settings/masks in case, e.g., DearEIS has been closed and relaunched, or after trying out different settings.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..f357872
--- /dev/null
+++ b/index.html
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+ Welcome to DearEIS’s documentation! — DearEIS 5.0.1 documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
DearEIS is a Python package for processing, analyzing, and visualizing impedance spectra.
+The primary interface for using DearEIS is a graphical user interface (GUI).
+
+
+
+
+
Note
+
PDF copies of the documentation are available in the releases section.
+
+
The GUI can be started via the following command:
+
deareis
+
+
+
The GUI can also be started by running DearEIS as a Python module:
+
python-mdeareis
+
+
+
An application programming interface (API) is also included and it can be used to, e.g., batch process results into tables and plots.
+
>>> importdeareis
+
+
+
+
Note
+
If you would prefer to primarily use an API or are looking for a command-line interface (CLI), then check out pyimpspec.
+
+
The source code for DearEIS can be found here.
+The changelog can be found here.
+If you encounter bugs or wish to request a feature, then please open an issue on GitHub.
+If you wish to contribute to the project, then please read the readme before submitting a pull request via GitHub.