diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 12559bd45..c498f8f0c 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -1,6 +1,5 @@
on:
push:
- branches: main
pull_request:
merge_group:
@@ -8,7 +7,8 @@ name: CI
jobs:
test-software:
- runs-on: ubuntu-22.04
+ if: github.event.ref == 'refs/heads/main'
+ runs-on: ubuntu-latest
strategy:
matrix:
python-version:
@@ -54,7 +54,8 @@ jobs:
run: pdm run test
build-firmware:
- runs-on: ubuntu-22.04
+ if: github.event.ref == 'refs/heads/main'
+ runs-on: ubuntu-latest
steps:
- name: Check out source code
uses: actions/checkout@v3
@@ -71,11 +72,61 @@ jobs:
working-directory: ./firmware
run: make
- required: # group all `test (*)` workflows into one for the required status check
+ build-manual:
+ if: github.event.ref == 'refs/heads/main' || github.repository != 'GlasgowEmbedded/glasgow'
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: docs/manual
+ steps:
+ - name: Check out source code
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - name: Set up PDM
+ uses: pdm-project/setup-pdm@v3
+ - name: Install dependencies
+ run: |
+ pdm install
+ - name: Build documentation
+ run: |
+ pdm run build
+ - name: Upload documentation archive
+ uses: actions/upload-artifact@v3
+ with:
+ name: docs
+ path: docs/manual/out
+
+ required: # group all required workflows into one to avoid reconfiguring this in Actions settings
+ if: github.event.ref == 'refs/heads/main'
needs:
- test-software
- build-firmware
+ - build-manual
runs-on: ubuntu-latest
steps:
- run: |
true
+
+ publish-manual-dev:
+ needs: build-manual
+ if: github.repository != 'GlasgowEmbedded/glasgow'
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out source code
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - name: Download documentation archive
+ uses: actions/download-artifact@v3
+ with:
+ name: docs
+ path: pages/${{ github.ref_name }}/
+ - name: Disable Jekyll
+ run: |
+ touch pages/.nojekyll
+ - name: Publish documentation for a branch
+ uses: JamesIves/github-pages-deploy-action@releases/v4
+ with:
+ folder: pages/
+ clean: false
diff --git a/LICENSE-0BSD.txt b/LICENSE-0BSD.txt
index 08822d195..ad1a3eff9 100644
--- a/LICENSE-0BSD.txt
+++ b/LICENSE-0BSD.txt
@@ -1,4 +1,4 @@
-Copyright (C) 2018 whitequark@whitequark.org
+Copyright (C) Glasgow Interface Explorer contributors
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted.
diff --git a/README.md b/README.md
index 9bc8a5ba1..e73c91018 100644
--- a/README.md
+++ b/README.md
@@ -16,44 +16,6 @@ Please stay patient and keep in mind that hardware is made by people who have li
If you want to show appreciation or help with Catherine's living costs, she has a personal [Patreon](https://patreon.com/whitequark). These donations will not impact the progress of the project since the limiting factor is health first and time second, but they are very much appreciated.
-## What is Glasgow?
-
-Glasgow is a tool for exploring digital interfaces, aimed at embedded developers, reverse engineers, digital archivists, electronics hobbyists, and everyone else who wants to communicate to a wide selection of digital devices with high reliability and minimum hassle. It can be attached to most devices without additional active or passive components, and includes extensive protection from unexpected conditions and operator error.
-
-The Glasgow hardware can support many digital interfaces because it uses reconfigurable logic. Instead of only offering a small selection of standard hardware supported interfaces, it uses an FPGA to adapt on the fly to the task at hand without compromising on performance or reliability, even for unusual, custom or obsolete interfaces.
-
-The Glasgow software is a set of building blocks designed to eliminate incidental complexity. Each interface is packaged into a self-contained *applet* that can be used directly from the command line, or reused as a part of a more complex system. Using Glasgow does not require any programming knowledge, although it becomes much more powerful if you know a bit of Python.
-
-
-## What can I do with Glasgow?
-
-Some of the tasks Glasgow can do well are:
-
- * communicate via UART,
- * automatically determine and follow the baud rate of device under test,
- * initiate transactions via SPI or I²C,
- * read and write 24-series I²C EEPROMs,
- * read and write 25-series SPI Flash memories,
- * determine memory parameters via SFDP,
- * read and write ONFI-compatible Flash memories,
- * determine memory parameters via ONFI parameter page,
- * read and write parallel 27/28/29-series EPROMs, EEPROMs and Flash memories,
- * determine the extent of floating gate charge decay and rescue data,
- * program and verify AVR microcontrollers with SPI interface,
- * automatically determine unknown JTAG pinout,
- * play back JTAG SVF files,
- * debug ARC processors via JTAG,
- * debug some MIPS processors via EJTAG,
- * program and verify XC9500XL CPLDs via JTAG,
- * communicate using nRF24L01(+) radios,
- * program nRF24LE1 and nRF24LU1(+) microcontrollers,
- * synthesize sound using a Yamaha OPLx/OPM chip and play it in real time on a webpage,
- * read raw modulated data from 5.25"/3.5" floppy drives,
- * ... and more!
-
-Everything above can be done with only a Glasgow revC board, some wires, and depending on the device under test, external power.
-
-
## How does using Glasgow look like?
Watch a typical command-line workflow in this screencast:
@@ -61,26 +23,6 @@ Watch a typical command-line workflow in this screencast:
[![asciicast](https://asciinema.org/a/i9edqaUBVLLw7mRZCpdxe91Fu.svg)](https://asciinema.org/a/i9edqaUBVLLw7mRZCpdxe91Fu)
-## What hardware does Glasgow use?
-
-The Glasgow hardware evolves over time, with each major milestone called a "revision". Although all revisions are, and will always be supported with the same software, they vary significantly in their capabilities, and the chosen revision will limit the possible tasks.
-
-Glasgow boards use a version in the `revXN` format, where `X` is a revision letter (increased on major design changes) and `N` is a stepping number (increased on any layout or component changes). For example, `revC0` is the first stepping of revision C.
-
-
-### revA/revB
-
-Revisions A and B have not been produced in significant amounts, contain major design issues, and are therefore mostly of historical interest. Nevertheless, everyone who has one of the revA/revB boards can keep using them—forever.
-
-
-### revC
-
-![Overview of the Glasgow PCB](hardware/boards/glasgow/3drender-readme.png)
-
-Revision C is the latest revision and is being prepared for mass production. It provides 16 I/O pins with a data rate up to approx. 100 Mbps/pin (50 MHz)\*, independent direction control and independent programmable pull-up/pull-down resistors. The I/O pins are grouped into two I/O ports, each of which can use any voltage from 1.8 V to 5 V, sense and monitor I/O voltage of the device under test, as well as provide up to 150 mA of power. The board uses USB 2 for power, configuration, and communication, achieving up to 336 Mbps (42 MB/s) of sustained combined throughput.
-
-\* Data rate achievable in practice depends on many factors and will vary greatly with specific interface and applet design. 12 Mbps/pin (6 MHz) can be achieved with minimal development effort; reaching higher data rates requires careful HDL coding and a good understanding of timing analysis.
-
## What software does Glasgow use?
@@ -91,182 +33,3 @@ Glasgow would not be possible without the [open-source iCE40 FPGA toolchain](htt
Implementing reliable, high-performance USB communication is not trivial—packetization, buffering, and USB quirks add up. Glasgow abstracts away USB: on the FPGA, the applet gateware writes to or reads from a FIFO, and on the host, applet software writes to or reads from a socket-like interface. Idiomatic Python code can communicate at maximum USB 2 bulk bandwidth on a modern PC without additional effort. Moreover, when a future Glasgow revision will use Ethernet in addition to USB, no changes to applet code will be required.
Debugging new applets can be hard, especially if bidirectional buses are involved. Glasgow provides a built-in cycle-accurate logic analyzer that can relate the I/O pin level and direction changes to commands and responses received and sent by the applet. The logic analyzer compresses waveforms and can pause the applet if its buffer is about to overflow.
-
-
-## How do I use Glasgow?
-
-A lot of care and effort has been put into making the use of the software stack as seamless as possible. In particular, every dependency where it is possible is shipped via the [Python package index][pypi] (including the USB driver and the FPGA toolchains) to make installation and upgrades as seamless as they can be.
-
-[pypi]: https://pypi.org/
-
-**If these instructions don't work for you, please file it as a bug, so that the experience can be made smoother for everyone.**
-
-
-### ... with Linux?
-
-You will need to have git, Python, and pipx installed. To install these on an Ubuntu or Debian system, run:
-
-```shell
-sudo apt install --no-install-recommends git pipx
-pipx ensurepath
-```
-
-The `pipx ensurepath` command may prompt you to reopen the terminal window; do so.
-
-Navigate to a convenient working directory and download the source code:
-
-```shell
-git clone https://github.com/GlasgowEmbedded/glasgow
-```
-
-Configure your system to allow unprivileged access (for anyone in the `plugdev` group) to the Glasgow hardware:
-
-```shell
-sudo cp glasgow/config/99-glasgow.rules /etc/udev/rules.d
-```
-
-Install the Glasgow software for the current user:
-
-```shell
-pipx install -e 'glasgow/software[builtin-toolchain]'
-```
-
-To update the software to its newest revision, navigate to your working directory and run:
-
-```shell
-git -C glasgow pull
-pipx reinstall glasgow
-```
-
-
-### ... with Windows?
-
-You will need to have git, Python, and pipx installed. To install [git][git-win] and [Python][py-win], follow the instructions from their respective pages. To install pipx, run:
-
-[git-win]: https://git-scm.com/download/win
-[py-win]: https://www.python.org/downloads/windows/
-
-```cmd
-py -3 -m pip install --user pipx
-py -3 -m pipx ensurepath
-```
-
-The `py -3 -m pipx ensurepath` command may prompt you to reopen the terminal window; do so.
-
-Navigate to a convenient working directory (it is highly recommended to use a local directory, e.g. `%LOCALAPPDATA%`, since running Glasgow software from a network drive or a roaming profile causes significant slowdown) and download the source code:
-
-```cmd
-git clone https://github.com/GlasgowEmbedded/glasgow
-```
-
-Install the Glasgow software for the current user:
-
-```cmd
-pipx install -e glasgow/software[builtin-toolchain]
-```
-
-To update the software to its newest revision, navigate to your working directory and run:
-
-```cmd
-git -C glasgow pull
-pipx reinstall glasgow
-```
-
-
-### ... with macOS?
-
-You will need to have pipx installed. If you haven't already, install [Homebrew](https://brew.sh/). To install pipx, run:
-
-```shell
-brew install pipx
-pipx ensurepath
-```
-
-The `pipx ensurepath` command may prompt you to reopen the terminal window; do so.
-
-Navigate to a convenient working directory and download the source code:
-
-```shell
-git clone https://github.com/GlasgowEmbedded/glasgow
-```
-
-Install the Glasgow software for the current user:
-
-```shell
-pipx install -e 'glasgow/software[builtin-toolchain]'
-```
-
-To update the software to its newest revision, navigate to your working directory and run:
-
-```shell
-git -C glasgow pull
-pipx reinstall glasgow
-```
-
-
-### Advanced topic: Using a native FPGA toolchain
-
-The steps above install the [YoWASP][] FPGA toolchain, which is a good low-friction option, especially for people whose primary competence is not in software, since it does not require any additional steps besides those that are already necessary. However, the YoWASP toolchain is noticeably slower than the native one (usually by a factor of less than 2×). The YoWASP toolchain is also not available for all platforms and architectures; notably, 32-bit Raspberry Pi is not covered.
-
-If you already have the required tools (`yosys`, `nextpnr-ice40`, `icepack`) installed or are willing to [install][oss-cad-suite] them, you can update your profile to set the environment variable `GLASGOW_TOOLCHAIN` to `system,builtin`, which prioritizes using the native tools over the YoWASP tools. The default value is `builtin,system`, which causes the native tools to be used only if the YoWASP tools are unusable.
-
-[yowasp]: https://yowasp.org/
-[oss-cad-suite]: https://github.com/YosysHQ/oss-cad-suite-build
-
-
-### Advanced topic: Developing the Glasgow software
-
-The steps above install the Glasgow software using `pipx install -e`, which performs an _editable install_: changes to the downloaded source code modify the behavior of the next invocation of the `glasgow` tool. Changes to `pyproject.toml`, most importantly to the dependencies or list of applet entrypoints, are not picked up until `pipx reinstall` is manually run.
-
-If you want to have your global Glasgow installation be independent from the source code check-out, you can omit `-e` in the instructions above. You can use any way of managing virtual environments for your development workflow, but we use and recommend [PDM][].
-
-[pdm]: https://pdm.fming.dev/
-
-
-## How do I factory flash Glasgow?
-
-"Factory flashing" refers to the process of assigning a brand new Glasgow board (that you probably just assembled) a serial number, as well as writing a few critical configuration options that will let the normal Glasgow CLI pick up this device. Barring severe and unusual EEPROM corruption, this process is performed only once for each board.
-
-As a prerequisite to factory flashing, follow all steps from the "[How do I use Glasgow?](#how-do-i-use-glasgow)" section.
-
-Any board that is factory flashed must have a blank FX2_MEM EEPROM. If the FX2_MEM EEPROM is not completely erased (all bytes set to `FF`), the factory flashing process may fail.
-
-
-### ... with Linux?
-
-Configure your system to allow unprivileged access (for anyone in the `plugdev` group) to any hardware that enumerates as the Cypress FX2 ROM bootloader:
-
- sudo cp config/99-cypress.rules /etc/udev/rules.d
-
-Note that this udev rule will affect more devices than just Glasgow, since the Cypress VID:PID pair is shared.
-
-Plug in the newly assembled device. At this point, `lsusb | grep 04b4:8613` should list one entry. Assuming you are factory flashing a board revision C2, run:
-
- glasgow factory --rev C2
-
-Done! At this point, `lsusb | grep 20b7:9db1` should list one entry.
-
-
-### ... with Windows?
-
-The steps are similar to the steps for Linux above, but you will need to use Zadig to bind the WinUSB driver to the device, since this will not happen automatically with a device that hasn't been flashed yet.
-
-
-## Who made Glasgow?
-
- * [@whitequark](https://github.com/whitequark) came up with the design, coordinates the project and implements most of gateware and software;
- * [@awygle](https://github.com/awygle) designed the power/analog port circuitry and helped with layout of revB;
- * [@marcan](https://github.com/marcan) improved almost every aspect of hardware for revC;
- * [@esden](https://github.com/esden) is handling batch manufacturing;
- * [@smunaut](https://github.com/smunaut) provided advice crucial for stability and performance of USB communication;
- * [@electronic_eel](https://github.com/electronic_eel) improved the hardware for revC2, designed the test jig and is working on advanced protection circuitry;
- * [@Attie](https://github.com/attie) improved and refactored many applets;
- * [@mwkmwkmwk](https://github.com/mwkmwkmwk) did important maintenance work to keep the codebase in good shape;
- * ... and many [other people](https://github.com/GlasgowEmbedded/Glasgow/graphs/contributors).
-
-
-## License
-
-Glasgow is distributed under the terms of both 0-clause BSD license as well as Apache 2.0 license.
-
-See [LICENSE-0BSD](LICENSE-0BSD.txt) and [LICENSE-Apache-2.0.txt](LICENSE-Apache-2.0.txt) for details.
diff --git a/docs/.gitignore b/docs/.gitignore
deleted file mode 100644
index 69fa449dd..000000000
--- a/docs/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-_build/
diff --git a/docs/Makefile b/docs/Makefile
deleted file mode 100644
index 2fcf9b88b..000000000
--- a/docs/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-
-# Put it first so that "make" without argument is like "make help".
-help:
- @$(SPHINXBUILD) -M help . _build $(SPHINXOPTS) $(O)
-
-.PHONY: help Makefile
-
-# Catch-all target: route all unknown targets to Sphinx using the new
-# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
- @$(SPHINXBUILD) -M $@ . _build $(SPHINXOPTS) $(O)
diff --git a/docs/conf.py b/docs/conf.py
deleted file mode 100644
index 25b3975d5..000000000
--- a/docs/conf.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
-import sys, os
-import sphinx_rtd_theme
-
-# Configure our load path
-sys.path.insert(0, os.path.abspath('../software'))
-
-# Configure Sphinx
-extensions = ['sphinx.ext.viewcode', 'sphinx.ext.autodoc', 'sphinxarg.ext']
-autodoc_member_order = 'bysource'
-source_suffix = '.rst'
-master_doc = 'index'
-project = 'Glasgow Reference'
-author = 'whitequark'
-copyright = '2018-2019, whitequark'
-pygments_style = 'sphinx'
-html_theme = 'sphinx_rtd_theme'
diff --git a/docs/index.rst b/docs/index.rst
deleted file mode 100644
index 937d01289..000000000
--- a/docs/index.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Glasgow Reference
-=================
-
-Contents:
-
-.. toctree::
- :maxdepth: 2
-
- introduction
- internals
diff --git a/docs/internals.rst b/docs/internals.rst
deleted file mode 100644
index 90eeff02e..000000000
--- a/docs/internals.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Internals
-=========
-
-This section documents the parts of the Glasgow hardware and software stack that is not user-exposed. It is not required for using Glasgow applets, but can be helpful for working on the Glasgow system itself.
-
-Contents:
-
-.. toctree::
- :maxdepth: 1
-
- internals_startup
diff --git a/docs/introduction.rst b/docs/introduction.rst
deleted file mode 100644
index 9a8d11d2d..000000000
--- a/docs/introduction.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-Introduction
-============
-
-To be written.
diff --git a/docs/manual/.gitignore b/docs/manual/.gitignore
new file mode 100644
index 000000000..15c447b72
--- /dev/null
+++ b/docs/manual/.gitignore
@@ -0,0 +1,7 @@
+# pdm
+/.pdm-plugins
+/.pdm-python
+/.venv
+
+# Sphinx
+/out
\ No newline at end of file
diff --git a/docs/manual/pdm.lock b/docs/manual/pdm.lock
new file mode 100644
index 000000000..6893b91fc
--- /dev/null
+++ b/docs/manual/pdm.lock
@@ -0,0 +1,550 @@
+# This file is @generated by PDM.
+# It is not intended for manual editing.
+
+[metadata]
+groups = ["default"]
+cross_platform = true
+static_urls = false
+lock_version = "4.3"
+content_hash = "sha256:3dc6d00ead7cd65a97011cf68cf5f32eb39d3441c40dddf9ec8a092ae97951d7"
+
+[[package]]
+name = "alabaster"
+version = "0.7.13"
+requires_python = ">=3.6"
+summary = "A configurable sidebar-enabled Sphinx theme"
+files = [
+ {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"},
+ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"},
+]
+
+[[package]]
+name = "babel"
+version = "2.12.1"
+requires_python = ">=3.7"
+summary = "Internationalization utilities"
+dependencies = [
+ "pytz>=2015.7; python_version < \"3.9\"",
+]
+files = [
+ {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"},
+ {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"},
+]
+
+[[package]]
+name = "beautifulsoup4"
+version = "4.12.2"
+requires_python = ">=3.6.0"
+summary = "Screen-scraping library"
+dependencies = [
+ "soupsieve>1.2",
+]
+files = [
+ {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"},
+ {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"},
+]
+
+[[package]]
+name = "certifi"
+version = "2023.7.22"
+requires_python = ">=3.6"
+summary = "Python package for providing Mozilla's CA Bundle."
+files = [
+ {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"},
+ {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"},
+]
+
+[[package]]
+name = "charset-normalizer"
+version = "3.3.0"
+requires_python = ">=3.7.0"
+summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
+files = [
+ {file = "charset-normalizer-3.3.0.tar.gz", hash = "sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-win32.whl", hash = "sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d"},
+ {file = "charset_normalizer-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-win32.whl", hash = "sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786"},
+ {file = "charset_normalizer-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-win32.whl", hash = "sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df"},
+ {file = "charset_normalizer-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:67b8cc9574bb518ec76dc8e705d4c39ae78bb96237cb533edac149352c1f39fe"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac71b2977fb90c35d41c9453116e283fac47bb9096ad917b8819ca8b943abecd"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3ae38d325b512f63f8da31f826e6cb6c367336f95e418137286ba362925c877e"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:542da1178c1c6af8873e143910e2269add130a299c9106eef2594e15dae5e482"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30a85aed0b864ac88309b7d94be09f6046c834ef60762a8833b660139cfbad13"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aae32c93e0f64469f74ccc730a7cb21c7610af3a775157e50bbd38f816536b38"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b26ddf78d57f1d143bdf32e820fd8935d36abe8a25eb9ec0b5a71c82eb3895"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f5d10bae5d78e4551b7be7a9b29643a95aded9d0f602aa2ba584f0388e7a557"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:249c6470a2b60935bafd1d1d13cd613f8cd8388d53461c67397ee6a0f5dce741"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c5a74c359b2d47d26cdbbc7845e9662d6b08a1e915eb015d044729e92e7050b7"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:b5bcf60a228acae568e9911f410f9d9e0d43197d030ae5799e20dca8df588287"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:187d18082694a29005ba2944c882344b6748d5be69e3a89bf3cc9d878e548d5a"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:81bf654678e575403736b85ba3a7867e31c2c30a69bc57fe88e3ace52fb17b89"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-win32.whl", hash = "sha256:85a32721ddde63c9df9ebb0d2045b9691d9750cb139c161c80e500d210f5e26e"},
+ {file = "charset_normalizer-3.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:468d2a840567b13a590e67dd276c570f8de00ed767ecc611994c301d0f8c014f"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-win32.whl", hash = "sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a"},
+ {file = "charset_normalizer-3.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884"},
+ {file = "charset_normalizer-3.3.0-py3-none-any.whl", hash = "sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2"},
+]
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+summary = "Cross-platform colored terminal text."
+files = [
+ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
+]
+
+[[package]]
+name = "docutils"
+version = "0.20.1"
+requires_python = ">=3.7"
+summary = "Docutils -- Python Documentation Utilities"
+files = [
+ {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"},
+ {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"},
+]
+
+[[package]]
+name = "furo"
+version = "2023.9.10"
+requires_python = ">=3.8"
+summary = "A clean customisable Sphinx documentation theme."
+dependencies = [
+ "beautifulsoup4",
+ "pygments>=2.7",
+ "sphinx-basic-ng",
+ "sphinx<8.0,>=6.0",
+]
+files = [
+ {file = "furo-2023.9.10-py3-none-any.whl", hash = "sha256:513092538537dc5c596691da06e3c370714ec99bc438680edc1debffb73e5bfc"},
+ {file = "furo-2023.9.10.tar.gz", hash = "sha256:5707530a476d2a63b8cad83b4f961f3739a69f4b058bcf38a03a39fa537195b2"},
+]
+
+[[package]]
+name = "idna"
+version = "3.4"
+requires_python = ">=3.5"
+summary = "Internationalized Domain Names in Applications (IDNA)"
+files = [
+ {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
+ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
+]
+
+[[package]]
+name = "imagesize"
+version = "1.4.1"
+requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+summary = "Getting image size from png/jpeg/jpeg2000/gif file"
+files = [
+ {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
+ {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
+]
+
+[[package]]
+name = "importlib-metadata"
+version = "6.8.0"
+requires_python = ">=3.8"
+summary = "Read metadata from Python packages"
+dependencies = [
+ "zipp>=0.5",
+]
+files = [
+ {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"},
+ {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"},
+]
+
+[[package]]
+name = "jinja2"
+version = "3.1.2"
+requires_python = ">=3.7"
+summary = "A very fast and expressive template engine."
+dependencies = [
+ "MarkupSafe>=2.0",
+]
+files = [
+ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
+ {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
+]
+
+[[package]]
+name = "livereload"
+version = "2.6.3"
+summary = "Python LiveReload is an awesome tool for web developers"
+dependencies = [
+ "six",
+ "tornado; python_version > \"2.7\"",
+]
+files = [
+ {file = "livereload-2.6.3-py2.py3-none-any.whl", hash = "sha256:ad4ac6f53b2d62bb6ce1a5e6e96f1f00976a32348afedcb4b6d68df2a1d346e4"},
+ {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"},
+]
+
+[[package]]
+name = "markupsafe"
+version = "2.1.3"
+requires_python = ">=3.7"
+summary = "Safely add untrusted strings to HTML/XML markup."
+files = [
+ {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
+ {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"},
+ {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"},
+ {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"},
+ {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"},
+ {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"},
+ {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"},
+ {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"},
+ {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"},
+ {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"},
+ {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"},
+ {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
+]
+
+[[package]]
+name = "packaging"
+version = "23.2"
+requires_python = ">=3.7"
+summary = "Core utilities for Python packages"
+files = [
+ {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
+ {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
+]
+
+[[package]]
+name = "pygments"
+version = "2.16.1"
+requires_python = ">=3.7"
+summary = "Pygments is a syntax highlighting package written in Python."
+files = [
+ {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"},
+ {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"},
+]
+
+[[package]]
+name = "pytz"
+version = "2023.3.post1"
+summary = "World timezone definitions, modern and historical"
+files = [
+ {file = "pytz-2023.3.post1-py2.py3-none-any.whl", hash = "sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7"},
+ {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"},
+]
+
+[[package]]
+name = "requests"
+version = "2.31.0"
+requires_python = ">=3.7"
+summary = "Python HTTP for Humans."
+dependencies = [
+ "certifi>=2017.4.17",
+ "charset-normalizer<4,>=2",
+ "idna<4,>=2.5",
+ "urllib3<3,>=1.21.1",
+]
+files = [
+ {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
+ {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
+]
+
+[[package]]
+name = "six"
+version = "1.16.0"
+requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+summary = "Python 2 and 3 compatibility utilities"
+files = [
+ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
+ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
+]
+
+[[package]]
+name = "snowballstemmer"
+version = "2.2.0"
+summary = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
+files = [
+ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
+ {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
+]
+
+[[package]]
+name = "soupsieve"
+version = "2.5"
+requires_python = ">=3.8"
+summary = "A modern CSS selector implementation for Beautiful Soup."
+files = [
+ {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"},
+ {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"},
+]
+
+[[package]]
+name = "sphinx"
+version = "7.1.2"
+requires_python = ">=3.8"
+summary = "Python documentation generator"
+dependencies = [
+ "Jinja2>=3.0",
+ "Pygments>=2.13",
+ "alabaster<0.8,>=0.7",
+ "babel>=2.9",
+ "colorama>=0.4.5; sys_platform == \"win32\"",
+ "docutils<0.21,>=0.18.1",
+ "imagesize>=1.3",
+ "importlib-metadata>=4.8; python_version < \"3.10\"",
+ "packaging>=21.0",
+ "requests>=2.25.0",
+ "snowballstemmer>=2.0",
+ "sphinxcontrib-applehelp",
+ "sphinxcontrib-devhelp",
+ "sphinxcontrib-htmlhelp>=2.0.0",
+ "sphinxcontrib-jsmath",
+ "sphinxcontrib-qthelp",
+ "sphinxcontrib-serializinghtml>=1.1.5",
+]
+files = [
+ {file = "sphinx-7.1.2-py3-none-any.whl", hash = "sha256:d170a81825b2fcacb6dfd5a0d7f578a053e45d3f2b153fecc948c37344eb4cbe"},
+ {file = "sphinx-7.1.2.tar.gz", hash = "sha256:780f4d32f1d7d1126576e0e5ecc19dc32ab76cd24e950228dcf7b1f6d3d9e22f"},
+]
+
+[[package]]
+name = "sphinx-autobuild"
+version = "2021.3.14"
+requires_python = ">=3.6"
+summary = "Rebuild Sphinx documentation on changes, with live-reload in the browser."
+dependencies = [
+ "colorama",
+ "livereload",
+ "sphinx",
+]
+files = [
+ {file = "sphinx-autobuild-2021.3.14.tar.gz", hash = "sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05"},
+ {file = "sphinx_autobuild-2021.3.14-py3-none-any.whl", hash = "sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac"},
+]
+
+[[package]]
+name = "sphinx-basic-ng"
+version = "1.0.0b2"
+requires_python = ">=3.7"
+summary = "A modern skeleton for Sphinx themes."
+dependencies = [
+ "sphinx>=4.0",
+]
+files = [
+ {file = "sphinx_basic_ng-1.0.0b2-py3-none-any.whl", hash = "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b"},
+ {file = "sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9"},
+]
+
+[[package]]
+name = "sphinx-copybutton"
+version = "0.5.2"
+requires_python = ">=3.7"
+summary = "Add a copy button to each of your code cells."
+dependencies = [
+ "sphinx>=1.8",
+]
+files = [
+ {file = "sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd"},
+ {file = "sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e"},
+]
+
+[[package]]
+name = "sphinx-inline-tabs"
+version = "2023.4.21"
+requires_python = ">=3.8"
+summary = "Add inline tabbed content to your Sphinx documentation."
+dependencies = [
+ "sphinx>=3",
+]
+files = [
+ {file = "sphinx_inline_tabs-2023.4.21-py3-none-any.whl", hash = "sha256:06809ac613f7c48ddd6e2fa588413e3fe92cff2397b56e2ccf0b0218f9ef6a78"},
+ {file = "sphinx_inline_tabs-2023.4.21.tar.gz", hash = "sha256:5df2f13f602c158f3f5f6c509e008aeada199a8c76d97ba3aa2822206683bebc"},
+]
+
+[[package]]
+name = "sphinxcontrib-applehelp"
+version = "1.0.4"
+requires_python = ">=3.8"
+summary = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
+files = [
+ {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"},
+ {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"},
+]
+
+[[package]]
+name = "sphinxcontrib-devhelp"
+version = "1.0.2"
+requires_python = ">=3.5"
+summary = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document."
+files = [
+ {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"},
+ {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"},
+]
+
+[[package]]
+name = "sphinxcontrib-htmlhelp"
+version = "2.0.1"
+requires_python = ">=3.8"
+summary = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
+files = [
+ {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"},
+ {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"},
+]
+
+[[package]]
+name = "sphinxcontrib-jsmath"
+version = "1.0.1"
+requires_python = ">=3.5"
+summary = "A sphinx extension which renders display math in HTML via JavaScript"
+files = [
+ {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
+ {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
+]
+
+[[package]]
+name = "sphinxcontrib-qthelp"
+version = "1.0.3"
+requires_python = ">=3.5"
+summary = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document."
+files = [
+ {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"},
+ {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"},
+]
+
+[[package]]
+name = "sphinxcontrib-serializinghtml"
+version = "1.1.5"
+requires_python = ">=3.5"
+summary = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)."
+files = [
+ {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"},
+ {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
+]
+
+[[package]]
+name = "tornado"
+version = "6.3.3"
+requires_python = ">= 3.8"
+summary = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed."
+files = [
+ {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d"},
+ {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a"},
+ {file = "tornado-6.3.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f"},
+ {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a"},
+ {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2"},
+ {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0"},
+ {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16"},
+ {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17"},
+ {file = "tornado-6.3.3-cp38-abi3-win32.whl", hash = "sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3"},
+ {file = "tornado-6.3.3-cp38-abi3-win_amd64.whl", hash = "sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5"},
+ {file = "tornado-6.3.3.tar.gz", hash = "sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe"},
+]
+
+[[package]]
+name = "urllib3"
+version = "2.0.5"
+requires_python = ">=3.7"
+summary = "HTTP library with thread-safe connection pooling, file post, and more."
+files = [
+ {file = "urllib3-2.0.5-py3-none-any.whl", hash = "sha256:ef16afa8ba34a1f989db38e1dbbe0c302e4289a47856990d0682e374563ce35e"},
+ {file = "urllib3-2.0.5.tar.gz", hash = "sha256:13abf37382ea2ce6fb744d4dad67838eec857c9f4f57009891805e0b5e123594"},
+]
+
+[[package]]
+name = "zipp"
+version = "3.17.0"
+requires_python = ">=3.8"
+summary = "Backport of pathlib-compatible object wrapper for zip files"
+files = [
+ {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"},
+ {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"},
+]
diff --git a/docs/manual/pyproject.toml b/docs/manual/pyproject.toml
new file mode 100644
index 000000000..9db7ea814
--- /dev/null
+++ b/docs/manual/pyproject.toml
@@ -0,0 +1,14 @@
+[project]
+requires-python = "~=3.8"
+dependencies = [
+ "sphinx",
+ "sphinx-autobuild",
+ "sphinx-inline-tabs",
+ "sphinx-copybutton",
+ "furo",
+]
+
+[tool.pdm.scripts]
+check.cmd = "sphinx-build src out -b linkcheck"
+build.cmd = "sphinx-build src out -b html"
+live.cmd = "sphinx-autobuild src out"
\ No newline at end of file
diff --git a/docs/manual/src/_images/3drender-revC2.png b/docs/manual/src/_images/3drender-revC2.png
new file mode 100644
index 000000000..31b35389d
Binary files /dev/null and b/docs/manual/src/_images/3drender-revC2.png differ
diff --git a/docs/manual/src/_images/glasgow-in-case.webp b/docs/manual/src/_images/glasgow-in-case.webp
new file mode 100644
index 000000000..ce1e9644a
Binary files /dev/null and b/docs/manual/src/_images/glasgow-in-case.webp differ
diff --git a/docs/manual/src/_images/glasgow-pcba.webp b/docs/manual/src/_images/glasgow-pcba.webp
new file mode 100644
index 000000000..753166b9a
Binary files /dev/null and b/docs/manual/src/_images/glasgow-pcba.webp differ
diff --git a/docs/manual/src/conf.py b/docs/manual/src/conf.py
new file mode 100644
index 000000000..799a9aabc
--- /dev/null
+++ b/docs/manual/src/conf.py
@@ -0,0 +1,40 @@
+html_title = project = "Glasgow Interface Explorer"
+release = version = ""
+copyright = "2020—2023, Glasgow Interface Explorer contributors"
+
+extensions = [
+ "sphinx.ext.todo",
+ "sphinx_copybutton",
+ "sphinx_inline_tabs",
+]
+
+todo_include_todos = True
+todo_emit_warnings = True
+
+copybutton_prompt_is_regexp = True
+copybutton_prompt_text = r">>> |\.\.\. |\$ |> "
+copybutton_copy_empty_lines = False
+
+html_theme = "furo"
+html_css_files = [
+ "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/fontawesome.min.css",
+ "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/solid.min.css",
+ "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/brands.min.css",
+]
+html_theme_options = {
+ "top_of_page_button": "edit",
+ "source_repository": "https://github.com/GlasgowEmbedded/glasgow/",
+ "source_branch": "main",
+ "source_directory": "docs/manual/src/",
+ "footer_icons": [
+ {
+ "name": "GitHub",
+ "url": "https://github.com/GlasgowEmbedded/glasgow/",
+ "html": "",
+ "class": "fa-brands fa-solid fa-github fa-2x",
+ },
+ ],
+ "announcement": "The Early Bird units are being shipped by Mouser! Pre-Order yours now",
+}
+html_use_modindex = False
+html_use_index = False
diff --git a/docs/manual/src/credit.rst b/docs/manual/src/credit.rst
new file mode 100644
index 000000000..990730953
--- /dev/null
+++ b/docs/manual/src/credit.rst
@@ -0,0 +1,13 @@
+Contributors
+============
+
+The Glasgow project has been built by its many `contributors `_, including some without whom the project would not have been possible:
+
+* `@whitequark `_ originated the overall design, coordinates the project and implements most of gateware and software
+* `@awygle `_ designed the power/analog port circuitry and helped with layout of revB
+* `@marcan `_ improved almost every aspect of hardware for revC
+* `@esden `_ is handling batch manufacturing
+* `@smunaut `_ provided advice crucial for stability and performance of USB communication
+* `@electroniceel `_ improved the hardware for revC2, designed the test jig and is working on advanced protection circuitry
+* `@Attie `_ improved and refactored many applets, hardware photos
+* `@mwkmwkmwk `_ does important maintenance work to keep the codebase in good shape
diff --git a/docs/manual/src/factory.rst b/docs/manual/src/factory.rst
new file mode 100644
index 000000000..162557899
--- /dev/null
+++ b/docs/manual/src/factory.rst
@@ -0,0 +1,74 @@
+.. _manufacturing:
+
+Manufacturing & flashing
+========================
+
+Pre-assembled Glasgow devices and cases are :ref:`available for purchase `. As Glasgow is open hardware, you also have the option of building a device yourself.
+
+
+.. _build-your-own:
+
+Building your own
+-----------------
+
+.. attention::
+
+ If you manufacture your own devices from the design files in this repository, you must clearly distinguish the PCBs by modifying the silkscreen artwork such that the placeholder manufacturer name and/or logo are replaced with your own contact information.
+
+ If you use the PCBA design files and the BOM that are included in this repository without modifications (other than the modifications required above), the Glasgow project will provide the same degree of support for your device as it does for the CrowdSupply orders (except for repairs under warranty).
+
+ If you modify the design files (which the license allows you to do without restrictions), the Glasgow project will not in general provide support for such devices, and you must not call your modified devices "Glasgow". You must remove the name "Glasgow" from the PCB silkscreen artwork to ensure that the device is clearly identifiable as being modified from the original source files.
+
+ If you are modifying the BOM to replace passive components with equivalent parts from a different vendor (such as in response to shortages), you may call your modified device "Glasgow". In addition, exceptions to the rule above can be made after discussing your case with Catherine "whitequark" or Piotr Esden-Tempski.
+
+.. todo::
+
+ This section is not written yet.
+
+
+.. _factory-flashing:
+
+Factory flashing
+----------------
+
+"Factory flashing" refers to the process of assigning a brand new Glasgow board (that you probably just assembled) a serial number, as well as writing a few critical configuration options that will let the ``glasgow`` command use this device. Barring severe and unusual EEPROM corruption, this process is performed only once in the lifetime of a device.
+
+To prepare for factory flashing, follow the :ref:`installation steps `.
+
+Any board that is being factory flashed must have a blank ``FX2_MEM`` EEPROM. If the ``FX2_MEM`` EEPROM is not completely erased (all bytes set to ``FF``), the factory flashing process may fail.
+
+.. tab:: Linux
+
+ Configure your system to allow unprivileged access (for anyone in the ``plugdev`` group) to any hardware that enumerates as the Cypress FX2 ROM bootloader:
+
+ .. code-block:: console
+
+ $ sudo cp config/99-cypress.rules /etc/udev/rules.d
+
+ Note that this rule will allow unprivileged access to any device based on the Cypress FX2 that has a blank EEPROM, and not just the Glasgow.
+
+ Plug in the newly assembled device. At this point, ``lsusb -d 04b4:8613`` should list one entry. Note the revision of the board you are factory flashing. If the board has revision ``C3``, run:
+
+ .. code-block:: console
+
+ $ glasgow factory --rev C3
+
+ That's it! After running this command, the device will disconnect from USB and reconnect, and ``lsusb -d 20b7:9db1`` will list one entry.
+
+.. tab:: Windows
+
+ The steps are similar to the steps for Linux, but you will need to use Zadig to bind the WinUSB driver to the device, since this will not happen automatically with a device that hasn't been flashed yet.
+
+ .. todo::
+
+ Write a full explanation here.
+
+.. tab:: macOS
+
+ Plug in the newly assembled device. At this point, ``System Information.app`` should list the FX2 device with Vid ``04b4`` and Pid ``8613``. Note the revision of the board you are factory flashing. If the board has revision ``C3``, run:
+
+ .. code-block:: console
+
+ $ glasgow factory --rev C3
+
+ That's it! After running this command, the device will disconnect from USB and reconnect, and after refreshing (⌘R) the information in ``System Information.app`` you should see a new entry with Vid ``20b7`` and Pid ``9db1``.
\ No newline at end of file
diff --git a/docs/manual/src/index.rst b/docs/manual/src/index.rst
new file mode 100644
index 000000000..5bcc37cc5
--- /dev/null
+++ b/docs/manual/src/index.rst
@@ -0,0 +1,14 @@
+Glasgow Interface Explorer manual
+---------------------------------
+
+.. toctree::
+ :maxdepth: 2
+
+ intro
+ revisions
+ purchase
+ install
+ usage/index
+ factory
+ credit
+ license
\ No newline at end of file
diff --git a/docs/manual/src/install.rst b/docs/manual/src/install.rst
new file mode 100644
index 000000000..39044466e
--- /dev/null
+++ b/docs/manual/src/install.rst
@@ -0,0 +1,167 @@
+Installing & updating
+=====================
+
+.. _initial-setup:
+
+Initial setup
+-------------
+
+A lot of care and effort has been put into making the use of the software stack as seamless as possible. In particular, every dependency where it is possible is shipped via the `Python package index `__ (including the USB driver and the FPGA toolchains) to make installation and upgrades as seamless as they can be.
+
+If these instructions don't work for you, please `file it as a bug `__ so that the experience can be improved for everyone.
+
+.. _file-a-bug: https://github.com/GlasgowEmbedded/glasgow/issues/new
+
+.. tab:: Linux
+
+ You will need to have `git `__, `Python `__, and `pipx`_ installed. To install these, run:
+
+ .. tab:: Debian
+
+ .. code-block:: console
+
+ $ sudo apt install --no-install-recommends git pipx
+ $ pipx ensurepath
+
+ .. tab:: Arch
+
+ .. code-block:: console
+
+ $ sudo pacman -S git python-pipx
+ $ pipx ensurepath
+
+ The ``pipx ensurepath`` command may prompt you to reopen the terminal window; do so.
+
+ Navigate to a convenient working directory and download the source code:
+
+ .. code-block:: console
+
+ $ git clone https://github.com/GlasgowEmbedded/glasgow
+
+ Configure your system to allow unprivileged access (for anyone in the ``plugdev`` group) to the Glasgow hardware:
+
+ .. code-block:: console
+
+ $ sudo cp glasgow/config/99-glasgow.rules /etc/udev/rules.d
+
+ Install the Glasgow software for the current user:
+
+ .. code-block:: console
+
+ $ pipx install -e 'glasgow/software[builtin-toolchain]'
+
+ To update the software to its newest revision, navigate to your working directory and run:
+
+ .. code-block:: console
+
+ $ git -C glasgow pull
+ $ pipx reinstall glasgow
+
+ After setup, confirm that the Glasgow utility is operational by running:
+
+ .. code-block:: console
+
+ $ glasgow --version
+ $ glasgow build --rev C3 uart
+
+.. tab:: Windows
+
+ You will need to have `git `__, `Python `__, and `pipx`_ installed. To install git and Python, follow the instructions from their respective pages. To install pipx, run:
+
+ .. code-block:: doscon
+
+ > py -3 -m pip install --user pipx
+ > py -3 -m pipx ensurepath
+
+ The ``py -3 -m pipx ensurepath`` command may prompt you to reopen the terminal window; do so.
+
+ Navigate to a convenient working directory (it is highly recommended to use a local directory, e.g. ``%LOCALAPPDATA%``, since running Glasgow software from a network drive or a roaming profile causes significant slowdown) and download the source code:
+
+ .. code-block:: doscon
+
+ > git clone https://github.com/GlasgowEmbedded/glasgow
+
+ Install the Glasgow software for the current user:
+
+ .. code-block:: doscon
+
+ > pipx install -e glasgow/software[builtin-toolchain]
+
+ To update the software to its newest revision, navigate to your working directory and run:
+
+ .. code-block:: doscon
+
+ > git -C glasgow pull
+ > pipx reinstall glasgow
+
+ After setup, confirm that the Glasgow utility is operational by running:
+
+ .. code-block:: doscon
+
+ > glasgow --version
+ > glasgow build --rev C3 uart
+
+.. tab:: macOS
+
+ You will need to have `pipx`_ installed. If you haven't already, install `Homebrew `_. To install pipx, run:
+
+ .. code-block:: console
+
+ $ brew install pipx
+ $ pipx ensurepath
+
+ The ``pipx ensurepath`` command may prompt you to reopen the terminal window; do so.
+
+ Navigate to a convenient working directory and download the source code:
+
+ .. code-block:: console
+
+ $ git clone https://github.com/GlasgowEmbedded/glasgow
+
+ Install the Glasgow software for the current user:
+
+ .. code-block:: console
+
+ $ pipx install -e 'glasgow/software[builtin-toolchain]'
+
+ To update the software to its newest revision, navigate to your working directory and run:
+
+ .. code-block:: console
+
+ $ git -C glasgow pull
+ $ pipx reinstall glasgow
+
+ After setup, confirm that the Glasgow utility is operational by running:
+
+ .. code-block:: console
+
+ $ glasgow --version
+ $ glasgow build --rev C3 uart
+
+.. _git-lin: https://git-scm.com/download/linux
+.. _git-win: https://git-scm.com/download/win
+.. _python-lin: https://www.python.org/downloads/source/
+.. _python-win: https://www.python.org/downloads/windows/
+.. _pypi: https://pypi.org/
+.. _pipx: https://pypa.github.io/pipx/installation/
+
+
+Using a system FPGA toolchain
+-----------------------------
+
+The steps above install the `YoWASP`_ FPGA toolchain, which is a good low-friction option, especially for people whose primary competence is not in software, since it does not require any additional installation steps. However, the YoWASP toolchain is noticeably slower compared to a native code code toolchain (usually by a factor of less than 2×). The YoWASP toolchain is also not available for all platforms and architectures; notably, 32-bit Raspberry Pi is not covered.
+
+If you already have the required tools (``yosys``, ``nextpnr-ice40``, ``icepack``) installed or are willing to `install `__ them, you can update your profile to set the environment variable ``GLASGOW_TOOLCHAIN`` to ``system,builtin``, which prioritizes using the system tools over the YoWASP tools. The default value is ``builtin,system``, which causes the system tools to be used only if the YoWASP tools are not present or not runnable.
+
+.. _yowasp: https://yowasp.org/
+.. _oss-cad-suite: https://github.com/YosysHQ/oss-cad-suite-build
+
+
+Developing the Glasgow software
+-------------------------------
+
+The steps above install the Glasgow software using ``pipx install -e``, which performs an *editable install*: changes to the downloaded source code modify the behavior of the next invocation of the ``glasgow`` tool. Changes to ``pyproject.toml``, most importantly to the dependencies or list of applet entrypoints, are not picked up until ``pipx reinstall`` is manually run.
+
+If you want to have your global Glasgow installation be independent from the source code check-out, you can omit the ``-e`` argument in the instructions above. You can use any way of managing virtual environments for your development workflow, but we use and recommend `PDM`_.
+
+.. _pdm: https://pdm.fming.dev/
diff --git a/docs/manual/src/intro.rst b/docs/manual/src/intro.rst
new file mode 100644
index 000000000..ea8f5ca30
--- /dev/null
+++ b/docs/manual/src/intro.rst
@@ -0,0 +1,91 @@
+Introduction
+============
+
+.. image:: ./_images/glasgow-in-case.webp
+ :alt: Glasgow Interface Explorer, in a black anodized aluminum case
+
+
+What is Glasgow?
+----------------
+
+Glasgow is a tool for exploring digital interfaces, aimed at embedded developers, reverse engineers, digital archivists, electronics hobbyists, and everyone else who wants to communicate to a wide selection of digital devices with high reliability and minimum hassle. It can be attached to most devices without additional active or passive components, and includes extensive protection from unexpected conditions and operator error.
+
+The Glasgow hardware can support many digital interfaces because it uses reconfigurable logic. Instead of only offering a small selection of standard hardware supported interfaces, it uses an FPGA to adapt on the fly to the task at hand without compromising on performance or reliability, even for unusual, custom or obsolete interfaces.
+
+The Glasgow software is a set of building blocks designed to eliminate incidental complexity. Each interface is packaged into a self-contained applet that can be used directly from the command line, or reused as a part of a more complex system. Using Glasgow does not require any programming knowledge, although it becomes much more powerful if you know a bit of Python.
+
+.. image:: ./_images/glasgow-pcba.webp
+ :alt: Bare Glasgow Interface Explorer PCB assembly
+
+
+What can I do with Glasgow?
+---------------------------
+
+* communicate via UART
+
+ * automatically determine and follow the baud rate of device under test
+
+* initiate transactions via SPI or I²C
+
+* read and write 24-series I²C EEPROMs
+
+* read and write 25-series SPI Flash memories
+
+ * determine memory parameters via SFDP
+
+* read and write ONFI-compatible Flash memories
+
+ * determine memory parameters via ONFI parameter page
+
+* read and write parallel 27/28/29-series EPROMs, EEPROMs and Flash memories
+
+ * determine the extent of floating gate charge decay and rescue data
+
+* program and verify AVR microcontrollers with SPI interface
+
+* automatically determine unknown JTAG pinout
+
+* play back JTAG SVF files
+
+* debug ARC processors via JTAG
+
+* debug some MIPS processors via EJTAG
+
+* program and verify XC9500XL CPLDs via JTAG
+
+* communicate using nRF24L01(+) radios
+
+* program nRF24LE1 and nRF24LU1(+) microcontrollers
+
+* synthesize sound using a Yamaha OPLx/OPM chip and play it in real time on a webpage
+
+* read raw modulated data from 5.25"/3.5" floppy drives
+
+* ... and more!
+
+Everything above can be done with only a Glasgow revC board, some wires, and depending on the device under test, external power.
+
+How does using Glasgow look like?
+---------------------------------
+
+This screencast shows a typical command-line workflow:
+
+.. image:: https://asciinema.org/a/i9edqaUBVLLw7mRZCpdxe91Fu.svg
+ :target: https://asciinema.org/a/i9edqaUBVLLw7mRZCpdxe91Fu
+
+
+What software does Glasgow use?
+-------------------------------
+
+Glasgow is written entirely in `Python 3`_. The interface logic that runs on the FPGA is described using `Amaranth`_, which is a Python-based domain specific language. The supporting code that runs on the host PC is written in Python with `asyncio`_. This way, the logic on the FPGA can be assembled on demand for any requested configuration, keeping it as fast and compact as possible, and code can be shared between gateware and software, removing the need to add error-prone "glue" boilerplate.
+
+Glasgow would not be possible without the `open-source iCE40 FPGA toolchain `__, which is not only very reliable but also extremely fast. It is so fast it usually only takes a few seconds to build one from scratch for something like an UART. When developing a new applet it is rarely necessary to wait for the toolchain.
+
+Implementing reliable, high-performance USB communication is not trivial—packetization, buffering, and USB quirks add up. Glasgow abstracts away USB: on the FPGA, the applet gateware writes to or reads from a FIFO, and on the host, applet software writes to or reads from a socket-like interface. Idiomatic Python code can communicate at maximum USB 2 bulk bandwidth on a modern PC without additional effort. Moreover, when a future Glasgow revision adds Ethernet next to USB, no changes to applet code will be necessary.
+
+Debugging applets can be hard, especially if bidirectional communication over the same wires is involved. Glasgow provides a built-in cycle-accurate logic analyzer that can relate the I/O pin level and direction changes to commands and responses received and sent by the applet. The logic analyzer compresses waveforms and can pause the applet if its buffer is about to overflow.
+
+.. _Python 3: https://python.org/
+.. _Amaranth: https://github.com/amaranth-lang/amaranth/
+.. _asyncio: https://docs.python.org/3/library/asyncio.html
+.. _ice40: http://bygone.clairexen.net/icestorm/
\ No newline at end of file
diff --git a/docs/manual/src/license.rst b/docs/manual/src/license.rst
new file mode 100644
index 000000000..5c936190c
--- /dev/null
+++ b/docs/manual/src/license.rst
@@ -0,0 +1,16 @@
+License
+=======
+
+The Glasgow Interface Explorer source code and design files are distributed under a choice of two licenses: 0-clause BSD and Apache 2.
+
+0-clause BSD
+------------
+
+.. literalinclude:: /../../../LICENSE-0BSD.txt
+ :language: text
+
+Apache 2
+--------
+
+.. literalinclude:: /../../../LICENSE-Apache-2.0.txt
+ :language: text
\ No newline at end of file
diff --git a/docs/manual/src/purchase.rst b/docs/manual/src/purchase.rst
new file mode 100644
index 000000000..43f14d414
--- /dev/null
+++ b/docs/manual/src/purchase.rst
@@ -0,0 +1,18 @@
+.. _purchasing:
+
+Purchasing hardware
+-------------------
+
+Pre-assembled Glasgow devices and cases are available for purchase from the stores listed below.
+
+* `CrowdSupply`_
+* `1BitSquared USA`_
+* `1BitSquared Germany`_
+* `Mouser`_ (coming soon)
+
+.. _1BitSquared USA: https://1bitsquared.com/products/glasgow
+.. _1BitSquared Germany: https://1bitsquared.de/products/glasgow
+.. _CrowdSupply: https://crowdsupply.com/1bitsquared/glasgow
+.. _Mouser: https://mouser.com/
+
+As Glasgow is open hardware, you also have the option of :ref:`building a device yourself `!
diff --git a/docs/manual/src/revisions.rst b/docs/manual/src/revisions.rst
new file mode 100644
index 000000000..b19f38503
--- /dev/null
+++ b/docs/manual/src/revisions.rst
@@ -0,0 +1,27 @@
+Hardware revisions
+------------------
+
+.. tip::
+
+ The devices manufactured by 1BitSquared and :ref:`sold by CrowdSupply and Mouser ` use the hardware revision ``revC3``.
+
+The Glasgow hardware evolves over time, with each major milestone called a "revision". Although all revisions are, and will always be supported with the latest software stack, they vary significantly in their capabilities, and the revision that is being used will determine which tasks can be achieved using the hardware.
+
+Glasgow hardware revisions use the ``revXN`` format, where ``X`` is a revision letter (incremented alphabetically when major design changes are made) and ``N`` is a stepping number (increased on any layout or component changes). For example, ``revC0`` is the first stepping of revision C.
+
+
+revA, revB
+##########
+
+Revisions A and B have not been produced in significant amounts, have major design issues, and are therefore mostly of historical interest. Nevertheless, anyone who has one of the revA/revB boards can keep using them—forever.
+
+
+revC
+####
+
+.. image:: ./_images/3drender-revC2.png
+ :alt: Overview of the Glasgow PCB
+
+Revision C is the latest revision and is being prepared for mass production. It provides 16 I/O pins with a data rate up to approx. 100 Mbps/pin (50 MHz) [#]_, independent direction control and independent programmable pull-up/pull-down resistors. The I/O pins are grouped into two I/O ports, each of which can use any voltage from 1.8 V to 5 V, sense and monitor I/O voltage of the device under test, as well as provide up to 150 mA of power. The board uses USB 2 for power, configuration, and communication, achieving up to 336 Mbps (42 MB/s) of sustained combined throughput.
+
+.. [#] Data rate achievable in practice depends on many factors and will vary greatly with specific interface and applet design. 12 Mbps/pin (6 MHz) can be achieved with minimal development effort; reaching higher data rates requires careful HDL coding and a good understanding of timing analysis.
diff --git a/docs/manual/src/usage/basic.rst b/docs/manual/src/usage/basic.rst
new file mode 100644
index 000000000..11a0253ea
--- /dev/null
+++ b/docs/manual/src/usage/basic.rst
@@ -0,0 +1,130 @@
+Basic usage
+===========
+
+How do I use Glasgow?
+---------------------
+
+After :ref:`installing ` the Glasgow software, the ``glasgow`` utility should be operational:
+
+.. code-block:: console
+
+ $ glasgow --version
+
+Glasgow has a number of commands, the most basic being ``safe`` and ``run``.
+At all times, a ``--help`` argument may be appended for more details.
+
+.. warning::
+ Please be aware that Glasgow device will slowly fade the `FX2` LED on and off to indicate that it has been able to establish an USB connection. This can occur if you connect the Glasgow device to your computer via a power-only USB cable.
+
+
+``glasgow safe``
+################
+
+.. note:: This command has the same effect as pressing the physical `E-STOP / RESET` button on revC3 and later hardware.
+
+Set all I/O to a `safe` state - disable voltage outputs, and set all I/O pins to high impedance.
+
+.. code-block:: console
+
+ $ glasgow safe
+
+
+``glasgow run ...``
+###################
+
+Glasgow is based around the concept of `applets`, with each implementing a particular mode of operation or interface.
+For example, there are applets such as ``uart``, ``i2c`` and ``spi`` - each implementing the gateware (which runs on the FPGA) and software (which runs on the host PC).
+The Glasgow framework coordinates building, caching, and operating these applets for you.
+
+A common argument is ``-V ...``, which sets the I/O voltage, as well as the supply output voltage for the selected port(s).
+Be careful that you set the correct voltage for your connected devices.
+
+The following command will run the ``uart`` applet, with an I/O voltage of 3.3v, and will configure pin ``A0`` to be `Tx`, and pin ``A1`` to be `Rx` (from the Glasgow hardware's point of view):
+
+.. code-block:: console
+
+ $ glasgow run uart -V 3.3 --pin-tx 0 --pin-rx 1 tty
+
+A list of available applets can be retrieved by running ``glasgow run --help``.
+
+
+Command line format
+-------------------
+
+As you build up the Glasgow command line, the `context` changes - for example the output of the following ``--help`` are all different.
+
+.. code-block:: console
+
+ $ glasgow --help
+ $ glasgow run --help
+ $ glasgow run uart --help
+
+The upshot of this, is that different arguments need to be placed at different positions in the command line.
+The help section at each level should clarify where each argument should be placed.
+For example, the ``--serial`` parameter is for the top-level ``glasgow`` command, and not ``glasgow run uart``.
+
+.. code-block:: console
+
+ ## this is valid:
+ $ glasgow --serial ${my_serial} run uart -V 3.3 tty
+
+ ## this is invalid!
+ $ glasgow run uart --serial ${my_serial} -V 3.3 tty
+
+
+Ports and pin numbering
+-----------------------
+
+The revC hardware has two ports (A and B), each of which have 8× I/O pins.
+When running the ``glasgow`` utility, you will see reference to a ``--port`` argument, along with ``--pin-*``, as defined by each applet (e.g: ``--pin-tx`` for UART).
+
+By default, the `port` will typically be set to ``AB``, which results in all 16× I/O pins being available for use, numbered 0 to 15... e.g: "`pin 0`" is ``A0``, "`pin 7`" is ``A7``, "`pin 8`" is ``B0``, etc...
+
+In some cases, you may want to use ``B3`` without using port A, which can be achieved using the following:
+
+.. code-block:: console
+
+ $ glasgow run uart -V 3.3 --port B --pin-tx 3 tty
+
+
+Examples
+--------
+
+
+UART
+####
+
+The ``uart`` applet provides a basic full-duplex UART interface that can operate at virtually any reasonable baudrate, and also supports automatically detecting the baudrate based on frames sent by the remote device. The transmit and receive signals can also be trivially inverted.
+
+By running the applet using the ``tty`` mode, you will be delivered to a direct pipe to the UART - characters you enter into the terminal will be transmitted by the Glasgow hardware, and characters received by the Glasgow hardware will appear in the terminal.
+
+The baudrate can be set using `-b 57600`, and auto-baud can be enabled with `-a`.
+
+Other modes of operation are available (``tty``, ``pty``, ``socket``), which are explained further by the help text.
+
+.. code-block:: console
+
+ $ glasgow run uart -V 3.3 --pin-tx 0 --pin-rx 1 -b 57600 tty
+
+
+SPI Controller
+##############
+
+The ``spi-controller`` applet implements an SPI controller, allowing full-duplex transfer to an SPI device.
+The following command will assert ``#CS``, send the bytes ``03,01,23,5f,f5``, and then de-assert ``#CS``, before printing the received data to the console.
+
+.. code-block:: console
+
+ $ glasgow run spi-controller -V 3.3 --pin-sck 0 --pin-cs 1 --pin-copi 2 --pin-cipo 3 0301235ff5
+
+
+I²C Initiator
+#############
+
+The ``i2c-initiator`` applet implements an I²C initiator, which facilitates a simple bus scan from the command line, using the on-board pull-up resistors.
+
+.. code-block:: console
+
+ $ glasgow run i2c-initiator -V 3.3 --pulls scan
+
+Using the :ref:`repl or script modes `, it's possible to easily communicate with devices, obeying clock stretching and other factors that are often ignored with bit-banged interfaces.
\ No newline at end of file
diff --git a/docs/manual/src/usage/index.rst b/docs/manual/src/usage/index.rst
new file mode 100644
index 000000000..919b66572
--- /dev/null
+++ b/docs/manual/src/usage/index.rst
@@ -0,0 +1,7 @@
+Using the device
+================
+
+.. toctree::
+
+ basic
+ repl-script
\ No newline at end of file
diff --git a/docs/manual/src/usage/repl-script.rst b/docs/manual/src/usage/repl-script.rst
new file mode 100644
index 000000000..a73de0ade
--- /dev/null
+++ b/docs/manual/src/usage/repl-script.rst
@@ -0,0 +1,8 @@
+.. _repl-script:
+
+REPL & script operation
+=======================
+
+.. todo::
+
+ This section is not written yet.
\ No newline at end of file
diff --git a/docs/internals_startup.rst b/docs/old-manual/internals_startup.rst
similarity index 100%
rename from docs/internals_startup.rst
rename to docs/old-manual/internals_startup.rst
diff --git a/docs/known_issues.rst b/docs/old-manual/known_issues.rst
similarity index 100%
rename from docs/known_issues.rst
rename to docs/old-manual/known_issues.rst
diff --git a/docs/requirements.txt b/docs/requirements.txt
deleted file mode 100644
index cb3c1f2e3..000000000
--- a/docs/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-sphinx-argparse