diff --git a/.github/workflows/tutorial.yml b/.github/workflows/tutorial.yml new file mode 100644 index 0000000..4da85ec --- /dev/null +++ b/.github/workflows/tutorial.yml @@ -0,0 +1,60 @@ +name: deploy-book + +# Run this when the master or main branch changes +on: + push: + branches: + - main + # If your git repository has the Jupyter Book within some-subfolder next to + # unrelated files, you can make this run only if a file within that specific + # folder has been modified. + # + # paths: + # - some-subfolder/** + +# This job installs dependencies, builds the book, and pushes it to `gh-pages` +jobs: + deploy-book: + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + steps: + - uses: actions/checkout@v3 + + # Install dependencies + - name: Set up Python 3.11 + uses: actions/setup-python@v4 + with: + python-version: 3.11 + + - name: Install dependencies + run: | + pip install -r requirements.txt + + # (optional) Cache your executed notebooks between runs + # if you have config: + # execute: + # execute_notebooks: cache + - name: cache executed notebooks + uses: actions/cache@v3 + with: + path: _build/.jupyter_cache + key: jupyter-book-cache-${{ hashFiles('requirements.txt') }} + + # Build the book + - name: Build the book + run: | + jupyter-book build . + + # Upload the book's HTML as an artifact + - name: Upload artifact + uses: actions/upload-pages-artifact@v2 + with: + path: "_build/html" + + # Deploy the book's HTML to GitHub Pages + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 + diff --git a/_build/.doctrees/environment.pickle b/_build/.doctrees/environment.pickle deleted file mode 100644 index 43e8cd7..0000000 Binary files a/_build/.doctrees/environment.pickle and /dev/null differ diff --git a/_build/.doctrees/genindex.doctree b/_build/.doctrees/genindex.doctree deleted file mode 100644 index 0eccca5..0000000 Binary files a/_build/.doctrees/genindex.doctree and /dev/null differ diff --git a/_build/.doctrees/intro.doctree b/_build/.doctrees/intro.doctree deleted file mode 100644 index b4e81a4..0000000 Binary files a/_build/.doctrees/intro.doctree and /dev/null differ diff --git a/_build/.doctrees/notebooks/PyomoFundamentals/Fundamentals.doctree b/_build/.doctrees/notebooks/PyomoFundamentals/Fundamentals.doctree deleted file mode 100644 index c853f6e..0000000 Binary files a/_build/.doctrees/notebooks/PyomoFundamentals/Fundamentals.doctree and /dev/null differ diff --git a/_build/.doctrees/notebooks/PyomoNonlinear/PyomoNonlinear.doctree b/_build/.doctrees/notebooks/PyomoNonlinear/PyomoNonlinear.doctree deleted file mode 100644 index 1f7fe3c..0000000 Binary files a/_build/.doctrees/notebooks/PyomoNonlinear/PyomoNonlinear.doctree and /dev/null differ diff --git a/_build/.doctrees/notebooks/python-dictionary.doctree b/_build/.doctrees/notebooks/python-dictionary.doctree deleted file mode 100644 index 49aa4be..0000000 Binary files a/_build/.doctrees/notebooks/python-dictionary.doctree and /dev/null differ diff --git a/_build/.doctrees/notebooks/python/python-dictionary.doctree b/_build/.doctrees/notebooks/python/python-dictionary.doctree deleted file mode 100644 index cfd1228..0000000 Binary files a/_build/.doctrees/notebooks/python/python-dictionary.doctree and /dev/null differ diff --git a/_build/.doctrees/notebooks/python/python-exercises.doctree b/_build/.doctrees/notebooks/python/python-exercises.doctree deleted file mode 100644 index 999d350..0000000 Binary files a/_build/.doctrees/notebooks/python/python-exercises.doctree and /dev/null differ diff --git a/_build/.doctrees/notebooks/python/python-forloop.doctree b/_build/.doctrees/notebooks/python/python-forloop.doctree deleted file mode 100644 index ee88b22..0000000 Binary files a/_build/.doctrees/notebooks/python/python-forloop.doctree and /dev/null differ diff --git a/_build/.doctrees/notebooks/python/python-function.doctree b/_build/.doctrees/notebooks/python/python-function.doctree deleted file mode 100644 index 055529e..0000000 Binary files a/_build/.doctrees/notebooks/python/python-function.doctree and /dev/null differ diff --git a/_build/.doctrees/notebooks/python/python-list.doctree b/_build/.doctrees/notebooks/python/python-list.doctree deleted file mode 100644 index e2d994d..0000000 Binary files a/_build/.doctrees/notebooks/python/python-list.doctree and /dev/null differ diff --git a/_build/.doctrees/notebooks/python/python-pandas.doctree b/_build/.doctrees/notebooks/python/python-pandas.doctree deleted file mode 100644 index a93e34f..0000000 Binary files a/_build/.doctrees/notebooks/python/python-pandas.doctree and /dev/null differ diff --git a/_build/html/.buildinfo b/_build/html/.buildinfo deleted file mode 100644 index f8eb8b0..0000000 --- a/_build/html/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: a7919d5a7c770158df1c4effa508876e -tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/_build/html/_sources/genindex.md b/_build/html/_sources/genindex.md deleted file mode 100644 index 8b013d6..0000000 --- a/_build/html/_sources/genindex.md +++ /dev/null @@ -1 +0,0 @@ -# Index diff --git a/_build/html/_sources/intro.md b/_build/html/_sources/intro.md deleted file mode 100644 index 7931edb..0000000 --- a/_build/html/_sources/intro.md +++ /dev/null @@ -1,24 +0,0 @@ -# Pyomo Tutorial - -Welcome to the *Pyomo Tutorial*, a project currently under development with completion expected by Winter, 2023. These notebooks -derives from the [Pyomo summer workshop 2018](http://www.pyomo.org/workshop-examples) and we update them with the latest version of Python and Pyomo. - -## Getting started - -[Pyomo](https://en.wikipedia.org/wiki/Pyomo) is a complete and versatile mathematical optimization package for the Python ecosystem. Pyomo provides a means to build models for optimization using the concepts of decision variables, constraints, and objectives from mathematical optimization, then transform and generate solutions using open source or commercial solvers. - -All notebooks in this repository can be opened and run in Google Colab. A launch icon appearing at the top of a page (look for the rocket) indicates the notebook can be opened as an executable document. Selecting Colab will reopen the notebook in Google Colab. Cells inside of the notebooks will perform any necessary installations of Pyomo and solvers needed to execute the code within the notebook. - -Start your journey with the [first chapter](/notebooks/python-dictionary.ipynb)! - -## Help us! - -We seek your feedback! If you encounter an issue or have suggestions on how to make these examples better, please open an issue using the link at the top of every page (look for the Github cat icon). - -## About Us - -We are a group of researchers and educators who came together with a common purpose of developing materials for use in our classroom teaching. Hopefully, these materials will find use in other classrooms and, most importantly, by those seeking entry into the world of mathematical programming. - -* David Bernal, Purdue University -* Zedong Peng, Purdue University -* Albert Lee, Purdue University diff --git a/_build/html/_sources/notebooks/PyomoFundamentals/Fundamentals.ipynb b/_build/html/_sources/notebooks/PyomoFundamentals/Fundamentals.ipynb deleted file mode 100644 index 0574d26..0000000 --- a/_build/html/_sources/notebooks/PyomoFundamentals/Fundamentals.ipynb +++ /dev/null @@ -1,1065 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Pyomo Summer Workshop 2018 Exercise Problem - Pyomo Fundamentals\n", - "\n", - "This notebook contains material from the Pyomo Summer Workshop 2018 by the Pyomo Developement Team and the notebook is developed by David Bernal (dbernaln at purdue.edu), Zedong Peng (peng_zedong at 123.com), and Albert Lee (lee4382 at purdue.edu); the content is available on **[Github](https://github.com/AlbertLee125/pyomo-summer-ws)**.\n", - "The original sources of this material are available on **[Pyomo](http://www.pyomo.org/workshop-examples)**.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import pyomo.environ as pyo\n", - "import pandas as pd" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Exercise 1: Pyomo Fundamentals\n", - "### 1.1. Knapsack example\n", - "\n", - "Solve the knapsack problem shown in tutorial using your IDE (e.g., Spyder) or the command lined: `> python knapsack.py`.\n", - "Which items are acquired in the optimal solution?\n", - "What is the value of the selected items?" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Model unknown\n", - "\n", - " Variables:\n", - " x : Size=4, Index=x_index\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " hammer : 0 : 1.0 : 1 : False : False : Binary\n", - " screwdriver : 0 : 1.0 : 1 : False : False : Binary\n", - " towel : 0 : 1.0 : 1 : False : False : Binary\n", - " wrench : 0 : 0.0 : 1 : False : False : Binary\n", - "\n", - " Objectives:\n", - " obj : Size=1, Index=None, Active=True\n", - " Key : Active : Value\n", - " None : True : 25.0\n", - "\n", - " Constraints:\n", - " weight_con : Size=1\n", - " Key : Lower : Body : Upper\n", - " None : None : 12.0 : 14.0\n" - ] - } - ], - "source": [ - "A = ['hammer', 'wrench', 'screwdriver', 'towel']\n", - "b = {'hammer':8, 'wrench':3, 'screwdriver':6, 'towel':11}\n", - "w = {'hammer':5, 'wrench':7, 'screwdriver':4, 'towel':3}\n", - "W_max = 14\n", - "\n", - "model = pyo.ConcreteModel()\n", - "model.x = pyo.Var( A, within=pyo.Binary )\n", - "\n", - "model.obj = pyo.Objective(\n", - " expr = sum( b[i]*model.x[i] for i in A ), \n", - " sense = pyo.maximize )\n", - "\n", - "model.weight_con = pyo.Constraint(\n", - " expr = sum( w[i]*model.x[i] for i in A ) <= W_max )\n", - "\n", - "opt = pyo.SolverFactory('glpk')\n", - "opt_success = opt.solve(model)\n", - "\n", - "model.display()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 1.2. Knapsack with improved printing\n", - "The `knapsack.py` in the tutorial uses `model.pprint()` to see the value of the solution variables.\n", - "Starting with the code in `knapsack_print_incomplete.py`, complete the missing lines to produce formatted output.\n", - "Note that the Pyomo value function should be used to get the floating point value of Pyomo modeling components (e.g., `print(value(model.x[i]))`). \n", - "Also print the value of the items selected (the objective), and the total weight. \n", - "(A solution can be found in `knapsack_print_soln.py`).\n", - "\n", - "```python\n", - "A = ['hammer', 'wrench', 'screwdriver', 'towel']\n", - "b = {'hammer':8, 'wrench':3, 'screwdriver':6, 'towel':11}\n", - "w = {'hammer':5, 'wrench':7, 'screwdriver':4, 'towel':3}\n", - "W_max = 14\n", - "\n", - "model = pyo.ConcreteModel()\n", - "model.x = pyo.Var( A, within=pyo.Binary )\n", - "\n", - "model.obj = pyo.Objective(\n", - " expr = sum( b[i]*model.x[i] for i in A ), \n", - " sense = pyo.maximize )\n", - " \n", - "model.weight_con = pyo.Constraint(\n", - " expr = sum( w[i]*model.x[i] for i in A ) <= W_max )\n", - "\n", - "opt = pyo.SolverFactory('glpk')\n", - "opt_success = opt.solve(model)\n", - "\n", - "total_weight = sum( w[i]*pyo.value(model.x[i]) for i in A )\n", - "# TODO: INSERT CODE HERE TO PRINT TOTAL WEIGHT AND BENEFIT\n", - "\n", - "print('%12s %12s' % ('Item', 'Selected'))\n", - "print('=========================')\n", - "for i in A:\n", - " # TODO: INSERT CODE HERE TO PRINT EACH ITEM AND WHETHER OR NOT IT WAS SELECTED\n", - "print('-------------------------')\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Total Weight: 12.0\n", - "Total Benefit: 25.0\n", - " Item Selected\n", - "=========================\n", - " hammer Yes\n", - " wrench No\n", - " screwdriver Yes\n", - " towel Yes\n", - "-------------------------\n" - ] - } - ], - "source": [ - "A = ['hammer', 'wrench', 'screwdriver', 'towel']\n", - "b = {'hammer':8, 'wrench':3, 'screwdriver':6, 'towel':11}\n", - "w = {'hammer':5, 'wrench':7, 'screwdriver':4, 'towel':3}\n", - "W_max = 14\n", - "\n", - "model = pyo.ConcreteModel()\n", - "model.x = pyo.Var( A, within=pyo.Binary )\n", - "\n", - "model.obj = pyo.Objective(\n", - " expr = sum( b[i]*model.x[i] for i in A ), \n", - " sense = pyo.maximize )\n", - "\n", - "model.weight_con = pyo.Constraint(\n", - " expr = sum( w[i]*model.x[i] for i in A ) <= W_max )\n", - "\n", - "opt = pyo.SolverFactory('glpk')\n", - "opt_success = opt.solve(model)\n", - "\n", - "total_weight = sum( w[i]*pyo.value(model.x[i]) for i in A )\n", - "print('Total Weight:', total_weight)\n", - "print('Total Benefit:', pyo.value(model.obj))\n", - "\n", - "print('%12s %12s' % ('Item', 'Selected'))\n", - "print('=========================')\n", - "for i in A:\n", - " acquired = 'No'\n", - " if pyo.value(model.x[i]) >= 0.5:\n", - " acquired = 'Yes'\n", - " print('%12s %12s' % (i, acquired))\n", - "print('-------------------------')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 1.3. Changing data\n", - "If we were to increase the value of the wrench, at what point would it become selected as part of the optimal solution?\n", - "(A solution can be found in `knapsack_wrench_soln.py`.)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Total Weight: 14.0\n", - "Total Benefit: 25.0\n", - " Item Selected\n", - "=========================\n", - " hammer No\n", - " wrench Yes\n", - " screwdriver Yes\n", - " towel Yes\n", - "-------------------------\n" - ] - } - ], - "source": [ - "A = ['hammer', 'wrench', 'screwdriver', 'towel']\n", - "b = {'hammer':8, 'wrench':8, 'screwdriver':6, 'towel':11}\n", - "w = {'hammer':5, 'wrench':7, 'screwdriver':4, 'towel':3}\n", - "W_max = 14\n", - "\n", - "model = pyo.ConcreteModel()\n", - "model.x = pyo.Var( A, within=pyo.Binary )\n", - "\n", - "model.obj = pyo.Objective(\n", - " expr = sum( b[i]*model.x[i] for i in A ), \n", - " sense = pyo.maximize )\n", - "\n", - "model.weight_con = pyo.Constraint(\n", - " expr = sum( w[i]*model.x[i] for i in A ) <= W_max )\n", - "\n", - "opt = pyo.SolverFactory('glpk')\n", - "opt_success = opt.solve(model)\n", - "\n", - "total_weight = sum( w[i]*pyo.value(model.x[i]) for i in A )\n", - "print('Total Weight:', total_weight)\n", - "print('Total Benefit:', pyo.value(model.obj))\n", - "\n", - "print('%12s %12s' % ('Item', 'Selected'))\n", - "print('=========================')\n", - "for i in A:\n", - " acquired = 'No'\n", - " if pyo.value(model.x[i]) >= 0.5:\n", - " acquired = 'Yes'\n", - " print('%12s %12s' % (i, acquired))\n", - "print('-------------------------')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 1.4. Loading data from Excel \n", - "In the knapsack example shown in the tutorial slides, the data is hardcoded at the top of the file. \n", - "Instead of hardcoding the data, use Python to load the data from a different source.\n", - "You can start from the file `knapsack_pandas_excel_incomplete.py`.\n", - "(A solution that uses pandas to load the data from Excel is shown in\n", - "`knapsack_pandas_excel_soln.py`.)\n", - "\n", - "```python\n", - "df_items = pd.read_excel('knapsack_data.xlsx', sheet_name='data', header=0, index_col=0)\n", - "W_max = 14\n", - "\n", - "A = df_items.index.tolist()\n", - "b = # TODO: WRITE CODE TO GET A DICTIONARY FROM THE DATAFRAME\n", - "w = # TODO: WRITE CODE TO GET A DICTIONARY FROM THE DATAFRAME\n", - "\n", - "model = pyo.ConcreteModel()\n", - "model.x = pyo.Var( A, within=pyo.Binary )\n", - "\n", - "model.obj = pyo.Objective(\n", - " expr = sum( b[i]*model.x[i] for i in A ), \n", - " sense = pyo.maximize )\n", - "\n", - "model.weight_con = pyo.Constraint(\n", - " expr = sum( w[i]*model.x[i] for i in A ) <= W_max )\n", - "\n", - "opt = pyo.SolverFactory('glpk')\n", - "opt_success = opt.solve(model)\n", - "\n", - "total_weight = sum( w[i]*pyo.value(model.x[i]) for i in A )\n", - "print('Total Weight:', total_weight)\n", - "print('Total Benefit:', pyo.value(model.obj))\n", - "\n", - "print('%12s %12s' % ('Item', 'Selected'))\n", - "print('=========================')\n", - "for i in A:\n", - " acquired = 'No'\n", - " if pyo.value(model.x[i]) >= 0.5:\n", - " acquired = 'Yes'\n", - " print('%12s %12s' % (i, acquired))\n", - "print('-------------------------')\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Total Weight: 12.0\n", - "Total Benefit: 25.0\n", - " Item Selected\n", - "=========================\n", - " hammer Yes\n", - " wrench No\n", - " screwdriver Yes\n", - " towel Yes\n", - "-------------------------\n" - ] - } - ], - "source": [ - "df_items = pd.read_excel('knapsack_data.xlsx', sheet_name='data', header=0, index_col=0)\n", - "W_max = 14\n", - "\n", - "A = df_items.index.tolist()\n", - "b = df_items['Benefit'].to_dict()\n", - "w = df_items['Weight'].to_dict()\n", - "\n", - "model = pyo.ConcreteModel()\n", - "model.x = pyo.Var( A, within=pyo.Binary )\n", - "\n", - "model.obj = pyo.Objective(\n", - " expr = sum( b[i]*model.x[i] for i in A ), \n", - " sense = pyo.maximize )\n", - "\n", - "model.weight_con = pyo.Constraint(\n", - " expr = sum( w[i]*model.x[i] for i in A ) <= W_max )\n", - "\n", - "opt = pyo.SolverFactory('glpk')\n", - "opt_success = opt.solve(model)\n", - "\n", - "total_weight = sum( w[i]*pyo.value(model.x[i]) for i in A )\n", - "print('Total Weight:', total_weight)\n", - "print('Total Benefit:', pyo.value(model.obj))\n", - "\n", - "print('%12s %12s' % ('Item', 'Selected'))\n", - "print('=========================')\n", - "for i in A:\n", - " acquired = 'No'\n", - " if pyo.value(model.x[i]) >= 0.5:\n", - " acquired = 'Yes'\n", - " print('%12s %12s' % (i, acquired))\n", - "print('-------------------------')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 1.5. NLP vs MIP\n", - "Solve the knapsack problem with `IPOPT` instead of `glpk`.\n", - "(Hint: switch `glpk` to `ipopt` in the call `SolverFactory`.) \n", - "Print the solution values for `model.x`. \n", - "What happened? \n", - "Why?" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 Set Declarations\n", - " x_index : Size=1, Index=None, Ordered=Insertion\n", - " Key : Dimen : Domain : Size : Members\n", - " None : 1 : Any : 4 : {'hammer', 'wrench', 'screwdriver', 'towel'}\n", - "\n", - "1 Var Declarations\n", - " x : Size=4, Index=x_index\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " hammer : 0 : 1.0000000095722053 : 1 : False : False : Binary\n", - " screwdriver : 0 : 1.0000000094153156 : 1 : False : False : Binary\n", - " towel : 0 : 1.000000009742034 : 1 : False : False : Binary\n", - " wrench : 0 : 0.2857142884855868 : 1 : False : False : Binary\n", - "\n", - "1 Objective Declarations\n", - " obj : Size=1, Index=None, Active=True\n", - " Key : Active : Sense : Expression\n", - " None : True : maximize : 8*x[hammer] + 3*x[wrench] + 6*x[screwdriver] + 11*x[towel]\n", - "\n", - "1 Constraint Declarations\n", - " weight_con : Size=1, Index=None, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " None : -Inf : 5*x[hammer] + 7*x[wrench] + 4*x[screwdriver] + 3*x[towel] : 14.0 : True\n", - "\n", - "4 Declarations: x_index x obj weight_con\n" - ] - } - ], - "source": [ - "A = ['hammer', 'wrench', 'screwdriver', 'towel']\n", - "b = {'hammer':8, 'wrench':3, 'screwdriver':6, 'towel':11}\n", - "w = {'hammer':5, 'wrench':7, 'screwdriver':4, 'towel':3}\n", - "W_max = 14\n", - "\n", - "model = pyo.ConcreteModel()\n", - "model.x = pyo.Var( A, within=pyo.Binary )\n", - "\n", - "model.obj = pyo.Objective(\n", - " expr = sum( b[i]*model.x[i] for i in A ), \n", - " sense = pyo.maximize )\n", - "\n", - "model.weight_con = pyo.Constraint(\n", - " expr = sum( w[i]*model.x[i] for i in A ) <= W_max )\n", - "\n", - "opt = pyo.SolverFactory('ipopt')\n", - "opt_success = opt.solve(model)\n", - "\n", - "model.pprint()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Exercise 2: Pyomo Fundamentals\n", - "### 2.1. Knapsack problem with rules\n", - "Rules are important for defining indexed constraints, however, they can also be used for single (i.e. scalar) constraints. \n", - "Starting with `knapsack.py`, reimplement the model using rules for the objective and the constraints. \n", - "(A solution can be found in `knapsack_rules_soln.py`.)" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 Set Declarations\n", - " x_index : Size=1, Index=None, Ordered=Insertion\n", - " Key : Dimen : Domain : Size : Members\n", - " None : 1 : Any : 4 : {'hammer', 'wrench', 'screwdriver', 'towel'}\n", - "\n", - "1 Var Declarations\n", - " x : Size=4, Index=x_index\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " hammer : 0 : 1.0 : 1 : False : False : Binary\n", - " screwdriver : 0 : 1.0 : 1 : False : False : Binary\n", - " towel : 0 : 1.0 : 1 : False : False : Binary\n", - " wrench : 0 : 0.0 : 1 : False : False : Binary\n", - "\n", - "1 Objective Declarations\n", - " obj : Size=1, Index=None, Active=True\n", - " Key : Active : Sense : Expression\n", - " None : True : maximize : 8*x[hammer] + 3*x[wrench] + 6*x[screwdriver] + 11*x[towel]\n", - "\n", - "1 Constraint Declarations\n", - " weight_con : Size=1, Index=None, Active=True\n", - " Key : Lower : Body : Upper : Active\n", - " None : -Inf : 5*x[hammer] + 7*x[wrench] + 4*x[screwdriver] + 3*x[towel] : 14.0 : True\n", - "\n", - "4 Declarations: x_index x obj weight_con\n" - ] - } - ], - "source": [ - "A = ['hammer', 'wrench', 'screwdriver', 'towel']\n", - "b = {'hammer':8, 'wrench':3, 'screwdriver':6, 'towel':11}\n", - "w = {'hammer':5, 'wrench':7, 'screwdriver':4, 'towel':3}\n", - "W_max = 14\n", - "\n", - "model = pyo.ConcreteModel()\n", - "model.x = pyo.Var( A, within=pyo.Binary )\n", - "\n", - "def obj_rule(m):\n", - " return sum( b[i]*m.x[i] for i in A )\n", - "model.obj = pyo.Objective(rule=obj_rule, sense = pyo.maximize )\n", - "\n", - "def weight_con_rule(m):\n", - " return sum( w[i]*m.x[i] for i in A ) <= W_max\n", - "model.weight_con = pyo.Constraint(rule=weight_con_rule)\n", - "\n", - "opt = pyo.SolverFactory('glpk')\n", - "opt_success = opt.solve(model)\n", - "\n", - "model.pprint()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 2.2. Integer formulation of the knapsack problem\n", - "Consider again, the knapsack problem. \n", - "Assume now that we can acquire multiple items of the same type. \n", - "In this new formulation, $x_i$ is now an integer variable instead of a binary variable. \n", - "One way to formulate this problem is as follows:\n", - "\n", - "$$\n", - "\\begin{aligned}\n", - "\\max_{q,x} &~ \\sum_{i \\in A} v_i x_i \\\\\n", - "\\text{s.t.} &~ \\sum_{i \\in A} w_i x_i \\leq W_{\\max} \\\\\n", - "&~ x_i - \\sum_{j=0}^N j q_{i,j} \\quad \\forall i \\in A \\\\\n", - "&~ 0 \\leq x \\leq N \\\\\n", - "&~ q_{i,j} \\in \\{0,1\\} \\quad~~ \\forall i \\in A, j \\in \\{0,1,\\dots,N\\}\n", - "\\end{aligned}\n", - "$$\n", - "\n", - "Starting with `knapsack_rules.py`, implement this new formulation\n", - "and solve. \n", - "Is the solution surprising? \n", - "(A solution can be found in `knapsack_integer_soln.py`.)" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Total Weight: 12.0\n", - "Total Benefit: 44.0\n", - " Item # Selected\n", - "=========================\n", - " hammer 0.0\n", - " wrench 0.0\n", - " screwdriver 0.0\n", - " towel 4.0\n", - "-------------------------\n" - ] - } - ], - "source": [ - "A = ['hammer', 'wrench', 'screwdriver', 'towel']\n", - "b = {'hammer':8, 'wrench':3, 'screwdriver':6, 'towel':11}\n", - "w = {'hammer':5, 'wrench':7, 'screwdriver':4, 'towel':3}\n", - "W_max = 14\n", - "N = range(6) # create a list from 0-5\n", - "\n", - "model = pyo.ConcreteModel()\n", - "model.x = pyo.Var( A )\n", - "model.q = pyo.Var( A, N, within=pyo.Binary )\n", - "\n", - "def obj_rule(m):\n", - " return sum( b[i]*m.x[i] for i in A )\n", - "model.obj = pyo.Objective(rule=obj_rule, sense = pyo.maximize )\n", - "\n", - "def weight_con_rule(m):\n", - " return sum( w[i]*m.x[i] for i in A ) <= W_max\n", - "model.weight_con = pyo.Constraint(rule=weight_con_rule)\n", - "\n", - "def x_integer_rule(m, i):\n", - " return m.x[i] == sum( j*m.q[i,j] for j in N )\n", - "model.x_integer = pyo.Constraint(A, rule=x_integer_rule)\n", - "\n", - "opt = pyo.SolverFactory('glpk')\n", - "result_obj = opt.solve(model)\n", - "\n", - "total_weight = sum( w[i]*pyo.value(model.x[i]) for i in A )\n", - "print('Total Weight:', total_weight)\n", - "print('Total Benefit:', pyo.value(model.obj))\n", - "\n", - "print('%12s %12s' % ('Item', '# Selected'))\n", - "print('=========================')\n", - "for i in A:\n", - " print('%12s %12s' % (i, pyo.value(model.x[i])))\n", - "print('-------------------------')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Exercies 3: Pyomo Fundamentals\n", - "### 3.1. Using the decorator notation for rules\n", - "In the slides, we saw an alternative notation for declaring and defining Pyomo components using decorators. \n", - "Starting with the warehouse location problem in `warehouse_location_decorator_incomplete.py` change the model to use the decorator notation. \n", - "(A solution for this problem can be found in `warehouse_location_decorator_soln.py`.)\n", - "```python\n", - "# warehouse_location.py: Warehouse location determination problem\n", - "model = pyo.ConcreteModel(name=\"(WL)\")\n", - "\n", - "W = ['Harlingen', 'Memphis', 'Ashland']\n", - "C = ['NYC', 'LA', 'Chicago', 'Houston']\n", - "d = {('Harlingen', 'NYC'): 1956, \\\n", - " ('Harlingen', 'LA'): 1606, \\\n", - " ('Harlingen', 'Chicago'): 1410, \\\n", - " ('Harlingen', 'Houston'): 330, \\\n", - " ('Memphis', 'NYC'): 1096, \\\n", - " ('Memphis', 'LA'): 1792, \\\n", - " ('Memphis', 'Chicago'): 531, \\\n", - " ('Memphis', 'Houston'): 567, \\\n", - " ('Ashland', 'NYC'): 485, \\\n", - " ('Ashland', 'LA'): 2322, \\\n", - " ('Ashland', 'Chicago'): 324, \\\n", - " ('Ashland', 'Houston'): 1236 }\n", - "P = 2\n", - "\n", - "model.x = pyo.Var(W, C, bounds=(0,1))\n", - "model.y = pyo.Var(W, within=pyo.Binary)\n", - "\n", - "@model.Objective()\n", - "def obj(m):\n", - " return sum(d[w,c]*m.x[w,c] for w in W for c in C)\n", - "\n", - "@model.Constraint(C)\n", - "def one_per_cust(m, c):\n", - " return sum(m.x[w,c] for w in W) == 1\n", - "\n", - "# TODO: ADD DECORATOR HERE\n", - "def warehouse_active(m, w, c):\n", - " return m.x[w,c] <= m.y[w]\n", - "\n", - "# TODO: ADD DECORATOR HERE\n", - "def num_warehouses(m):\n", - " return sum(m.y[w] for w in W) <= P\n", - "\n", - "pyo.SolverFactory('glpk').solve(model)\n", - "\n", - "model.y.pprint()\n", - "model.x.pprint()\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "y : Size=3, Index=y_index\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " Ashland : 0 : 1.0 : 1 : False : False : Binary\n", - " Harlingen : 0 : 1.0 : 1 : False : False : Binary\n", - " Memphis : 0 : 0.0 : 1 : False : False : Binary\n", - "x : Size=12, Index=x_index\n", - " Key : Lower : Value : Upper : Fixed : Stale : Domain\n", - " ('Ashland', 'Chicago') : 0 : 1.0 : 1 : False : False : Reals\n", - " ('Ashland', 'Houston') : 0 : 0.0 : 1 : False : False : Reals\n", - " ('Ashland', 'LA') : 0 : 0.0 : 1 : False : False : Reals\n", - " ('Ashland', 'NYC') : 0 : 1.0 : 1 : False : False : Reals\n", - " ('Harlingen', 'Chicago') : 0 : 0.0 : 1 : False : False : Reals\n", - " ('Harlingen', 'Houston') : 0 : 1.0 : 1 : False : False : Reals\n", - " ('Harlingen', 'LA') : 0 : 1.0 : 1 : False : False : Reals\n", - " ('Harlingen', 'NYC') : 0 : 0.0 : 1 : False : False : Reals\n", - " ('Memphis', 'Chicago') : 0 : 0.0 : 1 : False : False : Reals\n", - " ('Memphis', 'Houston') : 0 : 0.0 : 1 : False : False : Reals\n", - " ('Memphis', 'LA') : 0 : 0.0 : 1 : False : False : Reals\n", - " ('Memphis', 'NYC') : 0 : 0.0 : 1 : False : False : Reals\n" - ] - } - ], - "source": [ - "model = pyo.ConcreteModel(name=\"(WL)\")\n", - "\n", - "W = ['Harlingen', 'Memphis', 'Ashland']\n", - "C = ['NYC', 'LA', 'Chicago', 'Houston']\n", - "d = {('Harlingen', 'NYC'): 1956, \\\n", - " ('Harlingen', 'LA'): 1606, \\\n", - " ('Harlingen', 'Chicago'): 1410, \\\n", - " ('Harlingen', 'Houston'): 330, \\\n", - " ('Memphis', 'NYC'): 1096, \\\n", - " ('Memphis', 'LA'): 1792, \\\n", - " ('Memphis', 'Chicago'): 531, \\\n", - " ('Memphis', 'Houston'): 567, \\\n", - " ('Ashland', 'NYC'): 485, \\\n", - " ('Ashland', 'LA'): 2322, \\\n", - " ('Ashland', 'Chicago'): 324, \\\n", - " ('Ashland', 'Houston'): 1236 }\n", - "P = 2\n", - "\n", - "model.x = pyo.Var(W, C, bounds=(0,1))\n", - "model.y = pyo.Var(W, within=pyo.Binary)\n", - "\n", - "@model.Objective()\n", - "def obj(m):\n", - " return sum(d[w,c]*m.x[w,c] for w in W for c in C)\n", - "\n", - "@model.Constraint(C)\n", - "def one_per_cust(m, c):\n", - " return sum(m.x[w,c] for w in W) == 1\n", - "\n", - "@model.Constraint(W,C)\n", - "def warehouse_active(m, w, c):\n", - " return m.x[w,c] <= m.y[w]\n", - "\n", - "@model.Constraint()\n", - "def num_warehouses(m):\n", - " return sum(m.y[w] for w in W) <= P\n", - "\n", - "pyo.SolverFactory('glpk').solve(model)\n", - "\n", - "model.y.pprint()\n", - "model.x.pprint()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.2. Changing Parameter values\n", - "In the tutorial slides, we saw that a parameter could be specified to be mutable. \n", - "This tells Pyomo that the value of the parameter may change in the future, and allows the user to\n", - "change the parameter value and resolve the problem without the need to rebuild the entire model each time. \n", - "We will use this functionality to find a better solution to an earlier exercise. Considering again the knapsack problem, we would like to find when the wrench becomes valuable enough to be a part of the optimal solution. \n", - "Create a Pyomo Parameter for the value of the items, make it mutable, and then write a loop that prints the solution for different wrench values. \n", - "Start with the file `knapsack_mutable_parameter_incomplete.py`. \n", - "(A solution for this problem can be found in `knapsack_mutable_parameter_soln.py`.)\n", - "\n", - "```python\n", - "A = ['hammer', 'wrench', 'screwdriver', 'towel']\n", - "b = {'hammer':8, 'wrench':3, 'screwdriver':6, 'towel':11}\n", - "w = {'hammer':5, 'wrench':7, 'screwdriver':4, 'towel':3}\n", - "W_max = 14\n", - "\n", - "model = pyo.ConcreteModel()\n", - "model.x = pyo.Var( A, within=pyo.Binary )\n", - "model.item_benefit = # TODO: DEFINE THE PYOMO PARAM HERE\n", - "\n", - "def obj_rule(m):\n", - " return sum( m.item_benefit[i]*m.x[i] for i in A )\n", - "model.obj = pyo.Objective(rule=obj_rule, sense = pyo.maximize )\n", - "\n", - "def weight_rule(m):\n", - " return sum( w[i]*m.x[i] for i in A ) <= W_max\n", - "model.weight = pyo.Constraint(rule=weight_rule)\n", - "\n", - "opt = pyo.SolverFactory('glpk')\n", - "\n", - "for wrench_benefit in range(1,11):\n", - " model.item_benefit['wrench'] = wrench_benefit\n", - " result_obj = opt.solve(model)\n", - "\n", - " # TODO: PRINT THE BENEFIT OF THE WRENCH FOR EACH ITERATION IN THE LOOP\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Wrench benefit: 1 x['wrench']: 0.0\n", - "Wrench benefit: 2 x['wrench']: 0.0\n", - "Wrench benefit: 3 x['wrench']: 0.0\n", - "Wrench benefit: 4 x['wrench']: 0.0\n", - "Wrench benefit: 5 x['wrench']: 0.0\n", - "Wrench benefit: 6 x['wrench']: 0.0\n", - "Wrench benefit: 7 x['wrench']: 0.0\n", - "Wrench benefit: 8 x['wrench']: 1.0\n", - "Wrench benefit: 9 x['wrench']: 1.0\n", - "Wrench benefit: 10 x['wrench']: 1.0\n" - ] - } - ], - "source": [ - "A = ['hammer', 'wrench', 'screwdriver', 'towel']\n", - "b = {'hammer':8, 'wrench':3, 'screwdriver':6, 'towel':11}\n", - "w = {'hammer':5, 'wrench':7, 'screwdriver':4, 'towel':3}\n", - "W_max = 14\n", - "\n", - "model = pyo.ConcreteModel()\n", - "model.x = pyo.Var( A, within=pyo.Binary )\n", - "model.item_benefit = pyo.Param( A, within=pyo.NonNegativeReals, initialize=b, mutable=True)\n", - "\n", - "def obj_rule(m):\n", - " return sum( m.item_benefit[i]*m.x[i] for i in A )\n", - "model.obj = pyo.Objective(rule=obj_rule, sense = pyo.maximize )\n", - "\n", - "def weight_rule(m):\n", - " return sum( w[i]*m.x[i] for i in A ) <= W_max\n", - "model.weight = pyo.Constraint(rule=weight_rule)\n", - "\n", - "opt = pyo.SolverFactory('glpk')\n", - "\n", - "for wrench_benefit in range(1,11):\n", - " model.item_benefit['wrench'] = wrench_benefit\n", - " result_obj = opt.solve(model)\n", - "\n", - " print('Wrench benefit:', wrench_benefit, \"x['wrench']:\", pyo.value(model.x['wrench']))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.3. Integer cuts\n", - "Often, it can be important to find not only the \"best\" solution, but a number of solutions that are equally optimal, or close to optimal. \n", - "For discrete optimization problems, this can be done using something known as an integer cut. \n", - "Consider again the knapsack problem where the choice of which items to select is a discrete variable\n", - "$x_i \\forall i \\in A$. \n", - "Let $x_i^k$ be a particular set of $x$ values we want to remove from the feasible solution space. \n", - "We define an integer cut using two sets. \n", - "The first set $S_0$ contains the indices for those variables whose current solution is $0$, and the second set $S_1$ consists of indices for those variables whose current solution is $1$. \n", - "Given these two sets, an integer cut constraint that would prevent such a solution from appearing again is defined by,\n", - "\n", - "$$\n", - "\\sum_{i \\in S_0} x[i] + \\sum_{i \\in S_1} (1 - x[i]) \\geq 1.\n", - "$$\n", - "\n", - "Starting with `knapsack_rules.py`, write a loop that solves the problem $5$ times, adding an integer cut to remove the previous solution, and printing the value of the objective function and the solution at each\n", - "iteration of the loop. \n", - "(A solution for this problem can be found in `knapsack_integer_cut_soln.py`.)\n", - "\n", - "```python\n", - "A = ['hammer', 'wrench', 'screwdriver', 'towel']\n", - "b = {'hammer':8, 'wrench':3, 'screwdriver':6, 'towel':11}\n", - "w = {'hammer':5, 'wrench':7, 'screwdriver':4, 'towel':3}\n", - "W_max = 14\n", - "\n", - "model = pyo.ConcreteModel()\n", - "model.x = pyo.Var( A, within=Binary )\n", - "\n", - "def obj_rule(m):\n", - " return sum( b[i]*m.x[i] for i in A )\n", - "model.obj = pyo.Objective(rule=obj_rule, sense = pyo.maximize )\n", - "\n", - "def weight_con_rule(m):\n", - " return sum( w[i]*m.x[i] for i in A ) <= W_max\n", - "model.weight_con = pyo.Constraint(rule=weight_con_rule)\n", - "\n", - "opt = SolverFactory('glpk')\n", - "opt_success = opt.solve(model)\n", - "\n", - "model.pprint()\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Obj: 25.0 x[hammer]: 1.000000 x[wrench]: 0.000000 x[screwdriver]: 1.000000 x[towel]: 1.000000\n", - "Obj: 20.0 x[hammer]: 0.000000 x[wrench]: 1.000000 x[screwdriver]: 1.000000 x[towel]: 1.000000\n", - "Obj: 19.0 x[hammer]: 1.000000 x[wrench]: 0.000000 x[screwdriver]: 0.000000 x[towel]: 1.000000\n", - "Obj: 17.0 x[hammer]: 0.000000 x[wrench]: 0.000000 x[screwdriver]: 1.000000 x[towel]: 1.000000\n", - "Obj: 14.0 x[hammer]: 0.000000 x[wrench]: 1.000000 x[screwdriver]: 0.000000 x[towel]: 1.000000\n" - ] - } - ], - "source": [ - "A = ['hammer', 'wrench', 'screwdriver', 'towel']\n", - "b = {'hammer':8, 'wrench':3, 'screwdriver':6, 'towel':11}\n", - "w = {'hammer':5, 'wrench':7, 'screwdriver':4, 'towel':3}\n", - "W_max = 14\n", - "\n", - "model = pyo.ConcreteModel()\n", - "model.x = pyo.Var( A, within=pyo.Binary )\n", - "\n", - "def obj_rule(m):\n", - " return sum( b[i]*m.x[i] for i in A )\n", - "model.obj = pyo.Objective(rule=obj_rule, sense = pyo.maximize )\n", - "\n", - "def weight_con_rule(m):\n", - " return sum( w[i]*m.x[i] for i in A ) <= W_max\n", - "model.weight_con = pyo.Constraint(rule=weight_con_rule)\n", - "\n", - "opt = pyo.SolverFactory('glpk')\n", - "\n", - "\n", - "# create the ConstraintList to hold the integer cuts\n", - "model.int_cuts = pyo.ConstraintList()\n", - "\n", - "# loop 5 times\n", - "for l in range(5):\n", - " # solve the problem\n", - " result_obj = opt.solve(model)\n", - "\n", - " # print the solution\n", - " output_str = 'Obj: ' + str(pyo.value(model.obj))\n", - " for i in A:\n", - " output_str += \" x[%s]: %f\" % (str(i), pyo.value(model.x[i]))\n", - " print(output_str) \n", - " \n", - " # add the integer cut based on the current solution\n", - " cut_expr = 0\n", - " for i in A:\n", - " if pyo.value(model.x[i]) < 0.5:\n", - " cut_expr += model.x[i]\n", - " else:\n", - " cut_expr += (1.0 - model.x[i])\n", - " model.int_cuts.add(cut_expr >= 1)\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 3.4. Putting it all together with the lot sizing example: (Hart et al., 2017)\n", - "We will now write a complete model from scratch using a well-known multi-period optimization problem for optimal lot-sizing adapted from Hagen et al. (2001) shown below.\n", - "\n", - "$$\n", - "\\begin{align}\n", - "\\min &~ \\sum_{t \\in T} c_t y_t + h_t^+ I_t^+ + h_t^- I_t^- \\\\\n", - "\\text{s.t.} &~ I_t = I_{t-1} + X_t -d_t \\quad \\forall t \\in T \\\\\n", - "&~ I_t = I_t^+ - I_t^- \\quad \\quad \\quad ~~ \\forall t \\in T \\\\\n", - "&~ X_t \\leq P y_t \\quad \\quad \\quad \\quad \\quad \\forall t \\in T \\\\\n", - "&~ X_t, I_t^+, I_t^- \\geq 0 \\quad \\quad \\quad \\forall t \\in T \\\\\n", - "&~ y_t \\in \\{0, 1\\} \\quad \\quad \\quad \\quad ~~ \\forall t \\in T \\\\\n", - "\\end{align}\n", - "$$\n", - "\n", - "Our goal is to find the optimal production $X_t$ given known demands $d_t$, fixed cost $c_t$ associated with active production in a particular time period, an inventory holding cost $h^+_t$ and a shortage cost $h_t^-$ (cost of keeping a backlog) of orders. \n", - "The variable $y_t$ (binary) determines if we produce in time $t$ or not, and $I^+_t$ represents inventory that we are storing across time period $t$, while $I^-_t$ represents the magnitude of the backlog.\n", - "Note that equation $(4)$ is a constraint that only allows production in time period $t$ if the indicator variable $y_t=1$.\n", - "\n", - "Write a Pyomo model for this problem and solve it using glpk using the data provided below. \n", - "You can start with the file `lot_sizing_incomplete.py`.\n", - "(A solution is provided in `lot_sizing_soln.py`.)\n", - "\n", - "
Short
- */ - .o-tooltip--left { - position: relative; - } - - .o-tooltip--left:after { - opacity: 0; - visibility: hidden; - position: absolute; - content: attr(data-tooltip); - padding: .2em; - font-size: .8em; - left: -.2em; - background: grey; - color: white; - white-space: nowrap; - z-index: 2; - border-radius: 2px; - transform: translateX(-102%) translateY(0); - transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); -} - -.o-tooltip--left:hover:after { - display: block; - opacity: 1; - visibility: visible; - transform: translateX(-100%) translateY(0); - transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); - transition-delay: .5s; -} - -/* By default the copy button shouldn't show up when printing a page */ -@media print { - button.copybtn { - display: none; - } -} diff --git a/_build/html/_static/copybutton.js b/_build/html/_static/copybutton.js deleted file mode 100644 index 2ea7ff3..0000000 --- a/_build/html/_static/copybutton.js +++ /dev/null @@ -1,248 +0,0 @@ -// Localization support -const messages = { - 'en': { - 'copy': 'Copy', - 'copy_to_clipboard': 'Copy to clipboard', - 'copy_success': 'Copied!', - 'copy_failure': 'Failed to copy', - }, - 'es' : { - 'copy': 'Copiar', - 'copy_to_clipboard': 'Copiar al portapapeles', - 'copy_success': '¡Copiado!', - 'copy_failure': 'Error al copiar', - }, - 'de' : { - 'copy': 'Kopieren', - 'copy_to_clipboard': 'In die Zwischenablage kopieren', - 'copy_success': 'Kopiert!', - 'copy_failure': 'Fehler beim Kopieren', - }, - 'fr' : { - 'copy': 'Copier', - 'copy_to_clipboard': 'Copier dans le presse-papier', - 'copy_success': 'Copié !', - 'copy_failure': 'Échec de la copie', - }, - 'ru': { - 'copy': 'Скопировать', - 'copy_to_clipboard': 'Скопировать в буфер', - 'copy_success': 'Скопировано!', - 'copy_failure': 'Не удалось скопировать', - }, - 'zh-CN': { - 'copy': '复制', - 'copy_to_clipboard': '复制到剪贴板', - 'copy_success': '复制成功!', - 'copy_failure': '复制失败', - }, - 'it' : { - 'copy': 'Copiare', - 'copy_to_clipboard': 'Copiato negli appunti', - 'copy_success': 'Copiato!', - 'copy_failure': 'Errore durante la copia', - } -} - -let locale = 'en' -if( document.documentElement.lang !== undefined - && messages[document.documentElement.lang] !== undefined ) { - locale = document.documentElement.lang -} - -let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; -if (doc_url_root == '#') { - doc_url_root = ''; -} - -/** - * SVG files for our copy buttons - */ -let iconCheck = `` - -// If the user specified their own SVG use that, otherwise use the default -let iconCopy = ``; -if (!iconCopy) { - iconCopy = `` -} - -/** - * Set up copy/paste for code blocks - */ - -const runWhenDOMLoaded = cb => { - if (document.readyState != 'loading') { - cb() - } else if (document.addEventListener) { - document.addEventListener('DOMContentLoaded', cb) - } else { - document.attachEvent('onreadystatechange', function() { - if (document.readyState == 'complete') cb() - }) - } -} - -const codeCellId = index => `codecell${index}` - -// Clears selected text since ClipboardJS will select the text when copying -const clearSelection = () => { - if (window.getSelection) { - window.getSelection().removeAllRanges() - } else if (document.selection) { - document.selection.empty() - } -} - -// Changes tooltip text for a moment, then changes it back -// We want the timeout of our `success` class to be a bit shorter than the -// tooltip and icon change, so that we can hide the icon before changing back. -var timeoutIcon = 2000; -var timeoutSuccessClass = 1500; - -const temporarilyChangeTooltip = (el, oldText, newText) => { - el.setAttribute('data-tooltip', newText) - el.classList.add('success') - // Remove success a little bit sooner than we change the tooltip - // So that we can use CSS to hide the copybutton first - setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) - setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) -} - -// Changes the copy button icon for two seconds, then changes it back -const temporarilyChangeIcon = (el) => { - el.innerHTML = iconCheck; - setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) -} - -const addCopyButtonToCodeCells = () => { - // If ClipboardJS hasn't loaded, wait a bit and try again. This - // happens because we load ClipboardJS asynchronously. - if (window.ClipboardJS === undefined) { - setTimeout(addCopyButtonToCodeCells, 250) - return - } - - // Add copybuttons to all of our code cells - const COPYBUTTON_SELECTOR = 'div.highlight pre'; - const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) - codeCells.forEach((codeCell, index) => { - const id = codeCellId(index) - codeCell.setAttribute('id', id) - - const clipboardButton = id => - `` - codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) - }) - -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string -} - -/** - * Removes excluded text from a Node. - * - * @param {Node} target Node to filter. - * @param {string} exclude CSS selector of nodes to exclude. - * @returns {DOMString} Text from `target` with text removed. - */ -function filterText(target, exclude) { - const clone = target.cloneNode(true); // clone as to not modify the live DOM - if (exclude) { - // remove excluded nodes - clone.querySelectorAll(exclude).forEach(node => node.remove()); - } - return clone.innerText; -} - -// Callback when a copy button is clicked. Will be passed the node that was clicked -// should then grab the text and replace pieces of text that shouldn't be used in output -function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { - var regexp; - var match; - - // Do we check for line continuation characters and "HERE-documents"? - var useLineCont = !!lineContinuationChar - var useHereDoc = !!hereDocDelim - - // create regexp to capture prompt and remaining line - if (isRegexp) { - regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') - } else { - regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') - } - - const outputLines = []; - var promptFound = false; - var gotLineCont = false; - var gotHereDoc = false; - const lineGotPrompt = []; - for (const line of textContent.split('\n')) { - match = line.match(regexp) - if (match || gotLineCont || gotHereDoc) { - promptFound = regexp.test(line) - lineGotPrompt.push(promptFound) - if (removePrompts && promptFound) { - outputLines.push(match[2]) - } else { - outputLines.push(line) - } - gotLineCont = line.endsWith(lineContinuationChar) & useLineCont - if (line.includes(hereDocDelim) & useHereDoc) - gotHereDoc = !gotHereDoc - } else if (!onlyCopyPromptLines) { - outputLines.push(line) - } else if (copyEmptyLines && line.trim() === '') { - outputLines.push(line) - } - } - - // If no lines with the prompt were found then just use original lines - if (lineGotPrompt.some(v => v === true)) { - textContent = outputLines.join('\n'); - } - - // Remove a trailing newline to avoid auto-running when pasting - if (textContent.endsWith("\n")) { - textContent = textContent.slice(0, -1) - } - return textContent -} - - -var copyTargetText = (trigger) => { - var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); - - // get filtered text - let exclude = '.linenos'; - - let text = filterText(target, exclude); - return formatCopyText(text, '', false, true, true, true, '', '') -} - - // Initialize with a callback so we can modify the text before copy - const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) - - // Update UI with error/success messages - clipboard.on('success', event => { - clearSelection() - temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) - temporarilyChangeIcon(event.trigger) - }) - - clipboard.on('error', event => { - temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) - }) -} - -runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/_build/html/_static/copybutton_funcs.js b/_build/html/_static/copybutton_funcs.js deleted file mode 100644 index dbe1aaa..0000000 --- a/_build/html/_static/copybutton_funcs.js +++ /dev/null @@ -1,73 +0,0 @@ -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string -} - -/** - * Removes excluded text from a Node. - * - * @param {Node} target Node to filter. - * @param {string} exclude CSS selector of nodes to exclude. - * @returns {DOMString} Text from `target` with text removed. - */ -export function filterText(target, exclude) { - const clone = target.cloneNode(true); // clone as to not modify the live DOM - if (exclude) { - // remove excluded nodes - clone.querySelectorAll(exclude).forEach(node => node.remove()); - } - return clone.innerText; -} - -// Callback when a copy button is clicked. Will be passed the node that was clicked -// should then grab the text and replace pieces of text that shouldn't be used in output -export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { - var regexp; - var match; - - // Do we check for line continuation characters and "HERE-documents"? - var useLineCont = !!lineContinuationChar - var useHereDoc = !!hereDocDelim - - // create regexp to capture prompt and remaining line - if (isRegexp) { - regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') - } else { - regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') - } - - const outputLines = []; - var promptFound = false; - var gotLineCont = false; - var gotHereDoc = false; - const lineGotPrompt = []; - for (const line of textContent.split('\n')) { - match = line.match(regexp) - if (match || gotLineCont || gotHereDoc) { - promptFound = regexp.test(line) - lineGotPrompt.push(promptFound) - if (removePrompts && promptFound) { - outputLines.push(match[2]) - } else { - outputLines.push(line) - } - gotLineCont = line.endsWith(lineContinuationChar) & useLineCont - if (line.includes(hereDocDelim) & useHereDoc) - gotHereDoc = !gotHereDoc - } else if (!onlyCopyPromptLines) { - outputLines.push(line) - } else if (copyEmptyLines && line.trim() === '') { - outputLines.push(line) - } - } - - // If no lines with the prompt were found then just use original lines - if (lineGotPrompt.some(v => v === true)) { - textContent = outputLines.join('\n'); - } - - // Remove a trailing newline to avoid auto-running when pasting - if (textContent.endsWith("\n")) { - textContent = textContent.slice(0, -1) - } - return textContent -} diff --git a/_build/html/_static/design-style.4045f2051d55cab465a707391d5b2007.min.css b/_build/html/_static/design-style.4045f2051d55cab465a707391d5b2007.min.css deleted file mode 100644 index 3225661..0000000 --- a/_build/html/_static/design-style.4045f2051d55cab465a707391d5b2007.min.css +++ /dev/null @@ -1 +0,0 @@ -.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #007bff;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0069d9;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/_build/html/_static/design-tabs.js b/_build/html/_static/design-tabs.js deleted file mode 100644 index 36b38cf..0000000 --- a/_build/html/_static/design-tabs.js +++ /dev/null @@ -1,27 +0,0 @@ -var sd_labels_by_text = {}; - -function ready() { - const li = document.getElementsByClassName("sd-tab-label"); - for (const label of li) { - syncId = label.getAttribute("data-sync-id"); - if (syncId) { - label.onclick = onLabelClick; - if (!sd_labels_by_text[syncId]) { - sd_labels_by_text[syncId] = []; - } - sd_labels_by_text[syncId].push(label); - } - } -} - -function onLabelClick() { - // Activate other inputs with the same sync id. - syncId = this.getAttribute("data-sync-id"); - for (label of sd_labels_by_text[syncId]) { - if (label === this) continue; - label.previousElementSibling.checked = true; - } - window.localStorage.setItem("sphinx-design-last-tab", syncId); -} - -document.addEventListener("DOMContentLoaded", ready, false); diff --git a/_build/html/_static/doctools.js b/_build/html/_static/doctools.js deleted file mode 100644 index c3db08d..0000000 --- a/_build/html/_static/doctools.js +++ /dev/null @@ -1,264 +0,0 @@ -/* - * doctools.js - * ~~~~~~~~~~~ - * - * Base JavaScript utilities for all Sphinx HTML documentation. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ -"use strict"; - -const _ready = (callback) => { - if (document.readyState !== "loading") { - callback(); - } else { - document.addEventListener("DOMContentLoaded", callback); - } -}; - -/** - * 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))); - parent.insertBefore( - span, - parent.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling - ) - ); - node.nodeValue = val.substr(0, pos); - - 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 Documentation = { - init: () => { - Documentation.highlightSearchWords(); - 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; - }, - - /** - * highlight the search words provided in the url in the text - */ - highlightSearchWords: () => { - const highlight = - new URLSearchParams(window.location.search).get("highlight") || ""; - 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( - '' + - '' + - Documentation.gettext("Hide Search Matches") + - "
" - ) - ); - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords: () => { - document - .querySelectorAll("#searchbox .highlight-link") - .forEach((el) => el.remove()); - document - .querySelectorAll("span.highlighted") - .forEach((el) => el.classList.remove("highlighted")); - const url = new URL(window.location); - url.searchParams.delete("highlight"); - window.history.replaceState({}, "", url); - }, - - /** - * 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; - - const blacklistedElements = new Set([ - "TEXTAREA", - "INPUT", - "SELECT", - "BUTTON", - ]); - document.addEventListener("keydown", (event) => { - if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements - if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys - - 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; - case "Escape": - if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; - Documentation.hideSearchWords(); - event.preventDefault(); - } - } - - // 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/_build/html/_static/documentation_options.js b/_build/html/_static/documentation_options.js deleted file mode 100644 index 3063782..0000000 --- a/_build/html/_static/documentation_options.js +++ /dev/null @@ -1,14 +0,0 @@ -var DOCUMENTATION_OPTIONS = { - URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '', - LANGUAGE: 'en', - COLLAPSE_INDEX: false, - BUILDER: 'html', - FILE_SUFFIX: '.html', - LINK_SUFFIX: '.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '', - NAVIGATION_WITH_KEYS: true, - SHOW_SEARCH_SUMMARY: true, - ENABLE_SEARCH_SHORTCUTS: false, -}; \ No newline at end of file diff --git a/_build/html/_static/file.png b/_build/html/_static/file.png deleted file mode 100644 index a858a41..0000000 Binary files a/_build/html/_static/file.png and /dev/null differ diff --git a/_build/html/_static/images/logo_binder.svg b/_build/html/_static/images/logo_binder.svg deleted file mode 100644 index 45fecf7..0000000 --- a/_build/html/_static/images/logo_binder.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - diff --git a/_build/html/_static/images/logo_colab.png b/_build/html/_static/images/logo_colab.png deleted file mode 100644 index b7560ec..0000000 Binary files a/_build/html/_static/images/logo_colab.png and /dev/null differ diff --git a/_build/html/_static/images/logo_deepnote.svg b/_build/html/_static/images/logo_deepnote.svg deleted file mode 100644 index fa77ebf..0000000 --- a/_build/html/_static/images/logo_deepnote.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/_build/html/_static/images/logo_jupyterhub.svg b/_build/html/_static/images/logo_jupyterhub.svg deleted file mode 100644 index 60cfe9f..0000000 --- a/_build/html/_static/images/logo_jupyterhub.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/_build/html/_static/jquery-3.6.0.js b/_build/html/_static/jquery-3.6.0.js deleted file mode 100644 index fc6c299..0000000 --- a/_build/html/_static/jquery-3.6.0.js +++ /dev/null @@ -1,10881 +0,0 @@ -/*! - * jQuery JavaScript Library v3.6.0 - * https://jquery.com/ - * - * Includes Sizzle.js - * https://sizzlejs.com/ - * - * Copyright OpenJS Foundation and other contributors - * Released under the MIT license - * https://jquery.org/license - * - * Date: 2021-03-02T17:08Z - */ -( function( global, factory ) { - - "use strict"; - - if ( typeof module === "object" && typeof module.exports === "object" ) { - - // For CommonJS and CommonJS-like environments where a proper `window` - // is present, execute the factory and get jQuery. - // For environments that do not have a `window` with a `document` - // (such as Node.js), expose a factory as module.exports. - // This accentuates the need for the creation of a real `window`. - // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info. - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 -// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode -// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common -// enough that all such attempts are guarded in a try block. -"use strict"; - -var arr = []; - -var getProto = Object.getPrototypeOf; - -var slice = arr.slice; - -var flat = arr.flat ? function( array ) { - return arr.flat.call( array ); -} : function( array ) { - return arr.concat.apply( [], array ); -}; - - -var push = arr.push; - -var indexOf = arr.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var fnToString = hasOwn.toString; - -var ObjectFunctionString = fnToString.call( Object ); - -var support = {}; - -var isFunction = function isFunction( obj ) { - - // Support: Chrome <=57, Firefox <=52 - // In some browsers, typeof returns "function" for HTML