diff --git a/docs/.gitignore b/docs/.gitignore
deleted file mode 100644
index c95219f3..00000000
--- a/docs/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-_build/
-.venv
-venv/
-.env
-.DS_Store
-
-queue.sqlite3
-index.sqlite3
diff --git a/docs/.mkdocs.unused/gen_docs_refs.py b/docs/.mkdocs.unused/gen_docs_refs.py
deleted file mode 100644
index 8447015f..00000000
--- a/docs/.mkdocs.unused/gen_docs_refs.py
+++ /dev/null
@@ -1,50 +0,0 @@
-"""Generate the code reference pages and navigation."""
-
-from pathlib import Path
-
-import mkdocs_gen_files
-
-nav = mkdocs_gen_files.Nav()
-mod_symbol = ''
-
-packages_dir = Path(__file__).parent
-doc_root = packages_dir / "docs"
-
-for path in sorted((packages_dir / "archivebox").rglob("*.py")):
- module_path = path.relative_to(packages_dir).with_suffix("")
- doc_path = path.relative_to(packages_dir).with_suffix(".md")
- full_doc_path = doc_root / "reference" / doc_path
-
- if (
- "management" in str(module_path)
- or "vendor" in str(module_path)
- or "machine" in str(module_path)
- or "migrations" in str(module_path)
- or "plugins" in str(module_path)
- ):
- continue
-
- parts = tuple(module_path.parts)
-
- if parts[-1] == "__init__":
- parts = parts[:-1]
- doc_path = doc_path.with_name("index.md")
- full_doc_path = full_doc_path.with_name("index.md")
- elif parts[-1].startswith("_"):
- continue
-
- full_doc_path = full_doc_path.relative_to(packages_dir)
-
- # import ipdb; ipdb.set_trace()
-
- nav_parts = [f"{mod_symbol} {part}" for part in parts]
- nav[tuple(nav_parts)] = doc_path.as_posix()
-
- with mkdocs_gen_files.open(full_doc_path, "w") as fd:
- ident = ".".join(parts)
- fd.write(f"---\ntitle: {ident}\n---\n\n::: {ident}")
-
- mkdocs_gen_files.set_edit_path(full_doc_path, path.relative_to(packages_dir))
-
-with mkdocs_gen_files.open(doc_root / "reference" / "SUMMARY.md", "w") as nav_file:
- nav_file.writelines(nav.build_literate_nav())
diff --git a/docs/.mkdocs.unused/mkdocs.yml b/docs/.mkdocs.unused/mkdocs.yml
deleted file mode 100644
index 1bf20389..00000000
--- a/docs/.mkdocs.unused/mkdocs.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-site_name: ArchiveBox
-site_url: https://github.com/ArchiveBox/ArchiveBox
-
-theme:
- name: material
-
-
-
-plugins:
-- exclude:
- glob:
- - archivebox/vendor
- - data/
- - data*/
- - '*.sqlite3'
- - deb_dist/
- - brew_dist/
- - dist/
-- search
-- autorefs
-- mkdocstrings:
- handlers:
- python:
- options:
- show_submodules: true
- import:
- - url: https://docs.python-requests.org/en/master/objects.inv
- domains: [std, py]
-
-- gen-files:
- scripts:
- - gen_docs_refs.py
diff --git a/docs/.readthedocs.yaml b/docs/.readthedocs.yaml
deleted file mode 100644
index 2540987a..00000000
--- a/docs/.readthedocs.yaml
+++ /dev/null
@@ -1,45 +0,0 @@
-# Read the Docs configuration file for ArchiveBox docs
-# See https://docs.readthedocs.io/en/stable/config-file/v2.html
-#
-# RTD Version Strategy:
-# - "stable" alias -> latest tag with no pre-release suffix (PEP 440)
-# - "latest" alias -> default branch (master) = current dev docs
-# - Tagged versions (v0.9.10, v0.8.6, v0.7.3, etc.) build from git tags
-#
-# This is fully automatic via PEP 440 version detection:
-# - pyproject.toml version = "0.9.10" -> stable release
-# - pyproject.toml version = "0.9.10rc1" -> pre-release (dev)
-# - pyproject.toml version = "0.9.10.dev1" -> dev release
-# - RTD "latest" from master branch -> always dev
-#
-# RTD Admin Settings (configure in RTD dashboard once):
-# - Default version: "stable"
-# - "latest" version: visible, shows dev docs with warning banner
-# - Enable "build on tag push" for automatic versioned releases
-#
-# To publish a new stable release:
-# 1. Set version = "0.9.10" in pyproject.toml (no rc/dev/alpha suffix)
-# 2. git tag v0.9.10 && git push wiki v0.9.10
-# 3. RTD auto-builds and "stable" alias updates to this version
-#
-# To access dev docs:
-# https://archivebox.readthedocs.io/en/latest/
-
-version: 2
-
-build:
- os: ubuntu-24.04
- tools:
- python: "3.13"
-
-sphinx:
- configuration: conf.py
-
-python:
- install:
- - requirements: requirements.txt
- # Install archivebox so autodoc2 can introspect the source
- - method: pip
- path: ..
- extra_requirements:
- - dev
diff --git a/docs/ArchiveBox-Architecture-Diagrams.md b/docs/ArchiveBox-Architecture-Diagrams.md
deleted file mode 100644
index d0d44a74..00000000
--- a/docs/ArchiveBox-Architecture-Diagrams.md
+++ /dev/null
@@ -1,200 +0,0 @@
-# ArchiveBox Architecture Diagrams
-
-## High-Level System Execution Flow
-
-```mermaid
-stateDiagram-v2
- archivebox.cli.main(sys.argv)
- state Supervisord {
- Scheduler
- state Orchestrator {
- [*] --> TICK
- TICK --> SPAWN_ACTORS: queued > 0
- SPAWN_ACTORS --> TICK
- TICK --> IDLE: queued == 0
- IDLE --> TICK: 1s
- }
- }
-
- note left of archivebox.cli.main(sys.argv)
- archivebox entrypoint
- end note
-
- state "archivebox.cli.SUBCOMMAND" as MAIN_THREAD
-
- archivebox.cli.main(sys.argv) --> run_subcommand(sys.argv)
- run_subcommand(sys.argv) --> setup_django()
- setup_django() --> Supervisord: spawns in background
- setup_django() --> MAIN_THREAD: runs in foreground
-
- MAIN_THREAD --> archivebox.main.SUBCOMMAND
- archivebox.main.SUBCOMMAND --> Storage: add_to_queue()
-
- state Actors {
- CrawlActor --> Crawl: tick()
- SnapshotActor --> Snapshot: tick()
- ArchiveResultActors --> ArchiveResult: tick()
- }
-
- state "State Machines" as JOBS {
-
- state Crawl {
- state "QUEUED" as CRAWL_QUEUED
- state "STARTED" as CRAWL_STARTED
- state "SEALED" as CRAWL_SEALED
- CRAWL_QUEUED --> CRAWL_STARTED: create_root_snapshot()
- CRAWL_STARTED --> CRAWL_SEALED: is_finished
- }
-
- state Snapshot {
- state "QUEUED" as SNAP_QUEUED
- state "STARTED" as SNAP_STARTED
- state "SEALED" as SNAP_SEALED
- SNAP_QUEUED --> SNAP_STARTED: create_pending_archiveresults()
- SNAP_STARTED --> SNAP_SEALED: is_finished
- }
-
- state ArchiveResult {
- QUEUED --> STARTED: run_extractor()
- STARTED --> BACKOFF: is_temp_error
- BACKOFF --> STARTED: is_retry_past
- STARTED --> FAILED: is_fatal_error
- STARTED --> SUCCEEDED: is_succeded
- }
-
-
- note right of ArchiveResult
- exec_crome()
- end note
-
- note right of ArchiveResult
- exec_wget()
- end note
-
- note right of ArchiveResult
- exec_curl()
- end note
-
- note right of ArchiveResult
- ... other extractor subprocesses ...
- end note
- }
-
- state Storage {
- state "DB" as SQLITE_DB
- sources/
- archive/
- state "index.json" as INDEX_JSONS
- }
-
- Storage: Storage
-
- Orchestrator --> Actors: spawns subprocesses
-
- Crawl --> Snapshot: create_root_snapshot()
- Snapshot --> ArchiveResult: create_pending_archiveresults()
-
- Crawl --> Storage: .save()
- Snapshot --> Storage: .save()
- ArchiveResult --> Storage: .save()
-
- Storage --> Actors: get_queue()
-
-
-```
-
----
-
-## State Diagrams for Main Models
-
-
-### `Crawl`
-
-- `crawls/models.py`: `Crawl`
-- `crawls/statemachines.py`: `CrawlMachine`
-
-```mermaid
-stateDiagram-v2
- STARTED --> SEALED: tick [is_finished]
- STARTED --> STARTED: tick [!is_finished]
- QUEUED --> STARTED: tick [can_start]
- QUEUED --> QUEUED: tick [!can_start]
-
-
- note left of QUEUED
- Crawl created
- end note
-
- note right of STARTED
- create_root_snapshot()
- crawl.retry_at = now + 5s
- end note
-```
-
-
-## `Snapshot`
-
-- `core/models.py`: `Snapshot`
-- `core/statemachines.py`: `SnapshotMachine`
-
-```mermaid
-stateDiagram-v2
- STARTED --> SEALED: tick [is_finished]
- STARTED --> STARTED: tick [!is_finished]
- QUEUED --> STARTED: tick [can_start]
- QUEUED --> QUEUED: tick [!can_start]
-
- note left of QUEUED
- Snapshot created
- end note
-
- note right of STARTED
- create_pending_archiveresults(extractors)
- snapshot.retry_at = now + 60s
- end note
-```
-
-
-### `ArchiveResult`
-
-- `core/models.py`: `ArchiveResult`
-- `core/statemachines.py`: `ArchiveResultMachine`
-
-
-
-```mermaid
-stateDiagram-v2
- QUEUED --> QUEUED: tick [!can_start]
- QUEUED --> STARTED: tick [can_start]
- STARTED --> STARTED: tick [!is_finished]
- STARTED --> BACKOFF: tick [is_backoff]
- STARTED --> FAILED: tick [is_failed]
- STARTED --> SUCCEEDED: tick [is_succeeded]
- BACKOFF --> BACKOFF: tick [!can_start]
- BACKOFF --> STARTED: tick [can_start]
-
- note left of QUEUED
- ArchiveResult created
- end note
-
- note left of STARTED
- start_ts = now
- retry_at = now + 60s
- create_output_dir()
- run_extractor()
- end note
-
- note right of BACKOFF
- retry_at = now + 60s
- end note
-
- note right of SUCCEEDED
- end_ts = now
- retry_at = None
- end note
-
- note right of FAILED
- end_ts = now
- retry_at = None
- end note
-```
diff --git a/docs/Changelog.md b/docs/Changelog.md
deleted file mode 100644
index 7e26cc00..00000000
--- a/docs/Changelog.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Changelog
-
-▶️ *If you're having an issue with a breaking change, or migrating your data between versions, open an [issue](https://github.com/ArchiveBox/ArchiveBox/issues) to get help.*
-
-**`ArchiveBox` was previously named `Pocket Archive Stream` and then `Bookmark Archiver`.**
-
-
-
-
-
-**`THIS PAGE HAS BEEN MOVED:` See the [releases](https://github.com/ArchiveBox/ArchiveBox/releases) page for versioned source downloads and full changelog.**
-
-
-🍰 Many thanks to our 100+ contributors and everyone in the web archiving community! 🏛
-
-
-
-
-Expand old release notes...
-
----
-
- - v0.4.9 released
- - `pip install archivebox` https://pypi.org/project/archivebox/
- - `docker run archivebox/archivebox` https://hub.docker.com/r/archivebox/archivebox
- - https://archivebox.readthedocs.io/en/latest/
- - https://github.com/ArchiveBox/ArchiveBox/releases
- - easy migration from previous versions
- ```bash
- cd path/to/your/archive/folder
- archivebox init
- archviebox add 'https://example.com'
- archviebox add 'https://getpocket.com/users/USERNAME/feed/all' --depth=1
- ```
- - full transition to Django Sqlite DB with migrations (making upgrades between versions much safer now)
- - maintains an intuitive and helpful CLI that's backwards-compatible with all previous archivebox data versions
- - uses argparse instead of hand-written CLI system: see `archivebox/cli/archivebox.py`
- - new subcommands-based CLI for `archivebox` (see below)
- - new Web UI with pagination, better search, filtering, permissions, and more
- - 30+ assorted bugfixes, new features, and tickets closed
- - for more info, see: https://github.com/ArchiveBox/ArchiveBox/releases/tag/v0.4.9
-
----
-
- - v0.2.4 released
- - better archive corruption guards (check structure invariants on every parse & save)
- - remove title prefetching in favor of new FETCH_TITLE archive method
- - slightly improved CLI output for parsing and remote url downloading
- - re-save index after archiving completes to update titles and urls
- - remove redundant derivable data from link json schema
- - markdown link parsing support
- - faster link parsing and better symbol handling using a new compiled URL_REGEX
-
----
-
- - v0.2.3 released
- - fixed issues with parsing titles including trailing tags
- - fixed issues with titles defaulting to URLs instead of attempting to fetch
- - fixed issue where bookmark timestamps from RSS would be ignored and current ts used instead
- - fixed issue where ONLY_NEW would overwrite existing links in archive with only new ones
- - fixed lots of issues with URL parsing by using `urllib.parse` instead of hand-written lambdas
- - ignore robots.txt when using wget (ssshhh don't tell anyone 😁)
- - fix RSS parser bailing out when there's whitespace around XML tags
- - fix issue with browser history export trying to run ls on wrong directory
-
----
-
- - v0.2.2 released
- - Shaarli RSS export support
- - Fix issues with plain text link parsing including quotes, whitespace, and closing tags in URLs
- - add USER_AGENT to archive.org submissions so they can track archivebox usage
- - remove all icons similar to archive.org branding from archive UI
- - hide some of the noisier youtubedl and wget errors
- - set permissions on youtubedl media folder
- - fix chrome data dir incorrect path and quoting
- - better chrome binary finding
- - show which parser is used when importing links, show progress when fetching titles
-
----
-
- - v0.2.1 released with new logo
- - ability to import plain lists of links and almost all other raw filetypes
- - WARC saving support via wget
- - Git repository downloading with git clone
- - Media downloading with youtube-dl (video, audio, subtitles, description, playlist, etc)
-
----
- - v0.2.0 released with new name
- - [renamed](https://github.com/ArchiveBox/ArchiveBox/issues/108) from **Bookmark Archiver** -> **ArchiveBox**
-
----
- - v0.1.0 released
- - support for browser history exporting added with `./bin/archivebox-export-browser-history`
- - support for chrome `--dump-dom` to output full page HTML after JS executes
-
----
- - v0.0.3 released
- - support for chrome `--user-data-dir` to archive sites that need logins
- - fancy individual html & json indexes for each link
- - smartly append new links to existing index instead of overwriting
-
----
- - v0.0.2 released
- - proper HTML templating instead of format strings (thanks to https://github.com/bardisty!)
- - refactored into separate files, wip audio & video archiving
-
----
- - v0.0.1 released
- - Index links now work without nginx url rewrites, archive can now be hosted on github pages
- - added setup.sh script & docstrings & help commands
- - made Chromium the default instead of Google Chrome (yay free software)
- - added [env-variable](https://github.com/ArchiveBox/ArchiveBox/pull/25) configuration (thanks to https://github.com/hannah98!)
- - renamed from **Pocket Archive Stream** -> **Bookmark Archiver**
- - added [Netscape-format](https://github.com/ArchiveBox/ArchiveBox/pull/20) export support (thanks to https://github.com/ilvar!)
- - added [Pinboard-format](https://github.com/ArchiveBox/ArchiveBox/pull/7) export support (thanks to https://github.com/sconeyard!)
- - front-page of HN, oops! apparently I have users to support now :grin:?
- - added Pocket-format export support
-
----
- - v0.0.0 released: created Pocket Archive Stream 2017/05/05
-
-
diff --git a/docs/Chromium-Install.md b/docs/Chromium-Install.md
deleted file mode 100644
index 944e6ab6..00000000
--- a/docs/Chromium-Install.md
+++ /dev/null
@@ -1,207 +0,0 @@
-# Chrome / Chromium Setup
-
-By default, ArchiveBox looks for any existing installed version of Chrome/Chromium and uses it if found. You can optionally install a specific version and set the environment variable `CHROME_BINARY` to force ArchiveBox to use that one, e.g.:
-
- - `CHROME_BINARY=google-chrome-beta`
- - `CHROME_BINARY=/usr/bin/chromium-browser`
- - `CHROME_BINARY='/Applications/Chromium.app/Contents/MacOS/Chromium'`
- - `CHROME_BINARY='~/Library/Caches/ms-playwright/chromium-857950/chrome-mac/Chromium.app/Contents/MacOS/Chromium'`
-
-If you don't already have Chrome installed, I recommend installing Chromium instead of Google Chrome, as it's the open-source fork of Chrome that doesn't send as much tracking data to Google.
-
-**Check for existing Chrome/Chromium install:**
-
-
-
-```bash
-google-chrome --version | chromium-browser --version
-Google Chrome 122.0.6261.49 beta # should be >v111
-```
-
-## Installing Chromium
-
-### ⭐️ Any OS (recommended)
-
-[`playwright`](https://playwright.dev/python/docs/browsers) (by the Microsoft team) and [`puppeteer`](https://github.com/puppeteer/puppeteer) (by the Google team) are two options to get stable, repeatable Chromium distributions on many OSs.
-```bash
-pip install --upgrade --ignore-installed playwright
-playwright install --with-deps chromium
-
-# alternatively use puppeteer to get Chromium instead of playwright:
-npm install puppeteer
-```
-
-### macOS
-
-If you already have a Chrome app installed like `/Applications/Chromium.app`, you don't need to run this.
-```bash
-brew install --cask chromium
-```
-
-### Ubuntu/Debian
-If you already have `chromium-browser` >= v111 installed (run `chromium-browser --version`, you don't need to run this.
-```bash
-sudo apt update
-sudo apt install chromium-browser
-# or on some systems:
-sudo apt install chromium
-```
-
-## Installing Google Chrome
-
-### macOS
-If you already have `/Applications/Google Chrome.app`, you don't need to run this.
-```bash
-brew install --cask google-chrome
-```
-### Ubuntu/Debian
-If you already have `google-chrome` >= v111 installed (run `google-chrome --version`, you don't need to run this.
-```bash
-wget -q -O - 'https://dl-ssl.google.com/linux/linux_signing_key.pub' | sudo apt-key add -
-echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee /etc/apt/sources.list.d/google-chrome.list
-sudo apt update
-sudo apt install -y google-chrome
-```
-
-## Troubleshooting Chromium Install
-
-If you encounter problems setting up Google Chrome or Chromium, see the [Troubleshooting](https://github.com/ArchiveBox/ArchiveBox/wiki/Troubleshooting#chromiumgoogle-chrome) page.
-
----
-
-# Setting Up a Chromium User Profile
-
-You may choose to set up a Chrome/Chromium user profile in order to use your cookies/sessions to log into sites behind authentication/paywall during archiving.
-
-*Note: not all extractors use Chrome (e.g. `wget`, `mercury`, `media`), so [`COOKIES_FILE`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration/#cookies_file) should be set up as well after this.*
-
-> [!WARNING]
-> **We strongly recommend you use [separate burner credentials dedicated to archiving](https://docs.sweeting.me/s/cookie-dilemma),** e.g. don't provide cookies for your normal daily Facebook/Instagram/Google/etc. accounts as server responses and page content will often contain your name/email/PII, session cookies, private tokens, etc. which then get preserved in your snapshots for eternity.
->
-> Future viewers of your archive may be able to use any reflected archived session tokens to log in as you, or at the very least, associate the content with your real identity. Even if this tradeoff seems acceptable now or you plan to keep your archive data private, you may want to share a snapshot with others in the future, and snapshots are very hard to sanitize/anonymize after-the-fact!
->
-> For this reason, it's best to set up dedicated fake profile accounts for each site you want to archive, and consider them burned if you ever share any of your archived snapshots of those sites with untrusted people.
-
-
-
-
-### Docker VNC Setup
-
-If using ArchiveBox in Docker, the easiest way to set up session credentials is by remote controlling the ArchiveBox Chrome browser over VNC, and using it to log in to the sites you want to save.
-
-1. Enable the `novnc` server using these settings in your `docker-compose.yml`:
-
-`docker-compose.yml`:
-```yaml
-services:
- archivebox:
- ...
- volumes:
- ...
- - ./data/personas/Default:/data/personas/Default
- environment:
- - CHROME_USER_DATA_DIR=/data/personas/Default/chrome_profile
- - DISPLAY=novnc:0.0
-
- novnc:
- image: theasp/novnc:latest
- environment:
- - DISPLAY_WIDTH=1920
- - DISPLAY_HEIGHT=1080
- - RUN_XTERM=no
- ports:
- - "8080:8080"
-```
-
-2. Start the `novnc` window server container
-```bash
-docker compose up -d novnc
-# wait a few seconds for novnc to start...
-```
-
-3. Start ArchiveBox's Chrome inside Docker
-```bash
-docker compose run archivebox /usr/bin/chromium-browser --user-data-dir=/data/personas/Default/chrome_profile --profile-directory=Default --disable-gpu --disable-features=dbus --disable-dev-shm-usage --start-maximized --no-sandbox --disable-setuid-sandbox --no-zygote --disable-sync --no-first-run
-```
-(make sure you set `DISPLAY` & `CHROME_USER_DATA_DIR` and added the line to `volumes:` above first!)
-
-4. Open [`http://localhost:8080/vnc.html`](http://localhost:8080/vnc.html) in your browser. You should see a remote linux desktop shown with Chrome open, allowing you to remote-control ArchiveBox's browser. Use it to log into any sites where you want to save credentials.
-
-5. ✅ Close the browser, stop & remove novnc, and then run archivebox normally. It will use the profile stored in `CHROME_USER_DATA_DIR=/data/personas/Default/chrome_profile` going forward, you should now be able to archive sites as if you were logged in!
-
-```bash
-# stop the archivebox and novnc containers
-docker compose down
-docker compose down --remove-orphans
-# edit docker-compose.yml to remove/comment out the novnc: section
-
-# test it all out by archiving something hosted on one of the domains you logged in to
-docker compose run archivebox add 'https://private.example.com/some/site/requiring/login.html'
-# check the SingleFile, Screenshot, DOM, or PDF snapshot output (only these use the Chrome profile)
-# make sure the content appears as your logged-in user would see it
-```
-
-Under the hood this uses [Xvfb](https://www.x.org/releases/X11R7.6/doc/man/man1/Xvfb.1.xhtml) + [Fluxbox](http://www.fluxbox.org/) + [`novnc`](https://github.com/theasp/docker-novnc) to provide a virtual display, window manager, and VNC server + novnc websocket viewer.
-
-
-### Non-Docker Setup (Local Host)
-
-If running ArchiveBox on your local machine without Docker, this process is fairly easy.
-
-First, tell archivebox where you want to store your Chrome profile.
-
-```bash
-# replace /Users/alice/.archivebox_chrome with a path to store your profile in
-archivebox config --set CHROME_USER_DATA_DIR=/Users/alice/.archivebox_chrome
-```
-
-Then run Chrome (with that profile dir) to open a visible browser window where you can log into things, e.g.:
-
-```bash
-# find your CHROME_BINARY path by running
-archivebox version | grep -i chrome
-
-# macOS example (using Google Chrome.app)
-/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=~/ArchiveBox/personas/Default/chrome_profile
-
-# Linux example (using Playwright Chromium)
-/root/.cache/ms-playwright/chromium-1105/chrome-linux/chrome --user-data-dir=~/archivebox/data/personas/Default/chrome_profile
-```
-
-Once it's open, log in to all the sites you want to be logged in to for archiving, then close/quit Chrome.
-
-✅ All ArchiveBox extractors that use Chrome (e.g. Screenshot, PDF, DOM, Singlefile) should now use that profile.
-*Don't forget to set up [`COOKIES_FILE`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration/#cookies_file) for the rest!*
-
-
-
-### Non-Docker Setup (Remote Host)
-
-You must set up the profile using the exact same version of chrome that ArchiveBox is running (which can be found with `archivebox version`).
-You can download the latest chromium with `pip install playwright && playwright install --with-deps chromium`, or get older versions of Chrome from https://chromium.cypress.io.
-
-**General steps:**
-
-1. Make sure you are running the same OS and have the same version of Chrome installed as the host running ArchiveBox
-2. Follow the `Non-Docker Setup (Local Host)` setups above to create a Chrome profile locally
-3. Rsync your chrome profile from your local machine to the remote archivebox host
- `rsync --archive /path/to/profile remotehost:/path/to/profile/on/remote/host`
-4. Configure ArchiveBox on the remote host to use the `rsync`'ed Chrome profile
- `archivebox config --set CHROME_USER_DATA_DIR=/path/to/profile/on/remote/host`
-
-You may need to run `chown -R archivebox /path/to/profile/on/remote/host` on the remote host to make the profile editable by the `archivebox` user on that machine.
-
-✅ All ArchiveBox extractors that use Chrome (e.g. Screenshot, PDF, DOM, Singlefile) should now use that profile.
-*Don't forget to set up [`COOKIES_FILE`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration/#cookies_file) for the rest!*
-
----
-
-## More Info & Troubleshooting
-
-- https://github.com/ArchiveBox/ArchiveBox/issues/952
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#archiving-private-content
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#%EF%B8%8F-things-to-watch-out-for-%EF%B8%8F
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#publishing
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#chrome_user_data_dir
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#chrome_binary
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#cookies_file
diff --git a/docs/Configuration.md b/docs/Configuration.md
deleted file mode 100644
index 26a51b62..00000000
--- a/docs/Configuration.md
+++ /dev/null
@@ -1,1175 +0,0 @@
-# Configuration
-
-Configuration of ArchiveBox is done by using the `archivebox config` command, modifying the `ArchiveBox.conf` file in the data folder, or by using environment variables. All three methods work equivalently when using Docker as well.
-
-*Some equivalent examples of setting some configuration options:*
-```bash
-archivebox config --set TIMEOUT=120
-# OR
-echo "TIMEOUT=120" >> ArchiveBox.conf
-# OR
-env TIMEOUT=120 archivebox add ~/Downloads/bookmarks_export.html
-```
-
-Environment variables take precedence over the config file, which is useful if you only want to use a certain option temporarily during a single run. For more examples see [Usage: Configuration](Usage#run-archivebox-with-configuration-options)...
-
-
-
-
-
-**Available Configuration Options:**
- - [General Settings:](#general-settings) Archiving process, output format, crawl limits, and retention.
- - [Server Settings:](#server-settings) Web UI, authentication, subdomain routing, and reverse proxy options.
- - [Storage Settings:](#storage-settings) File layout, permissions, and temp/lib directories.
- - [Database Settings:](#database-settings) SQLite tuning and lock-retry behavior.
- - [Search Settings:](#search-settings) Full-text search backend selection.
- - [Shell Options:](#shell-options) Format & behavior of CLI output.
- - [Plugin Configuration:](#plugin-configuration) Per-plugin options (now documented separately).
-
-
-
----
-
-
-
-In case this document is ever out of date, check the source code for config definitions: archivebox/config/common.py ➡️
-
-
-## General Settings
-
-*General options around the archiving process, output format, retention, and concurrency limits.*
-
----
-#### `ONLY_NEW`
-**Possible Values:** [`True`]/`False`
-Toggle whether or not to attempt rechecking old links when adding new ones, or leave old incomplete links alone and only archive the new links.
-
-By default, ArchiveBox will only archive new links on each import. If you want it to go back through all links in the index and download any missing files on every run, set this to `False`.
-
-*Note: Regardless of how this is set, ArchiveBox will never re-download sites that have already succeeded previously. When this is `False` it only attempts to fix previous pages that have *missing* archive extractor outputs, it does not re-archive pages that have already been successfully archived.*
-
----
-#### `TIMEOUT`
-**Possible Values:** [`60`]/`120`/...
-Maximum allowed runtime **per-extractor, per-Snapshot** in seconds. If you have a slow network connection or are seeing frequent timeout errors, you can raise this value.
-
-This is a *plugin-shared* setting — each individual extractor can override it with its own `_TIMEOUT` (e.g. [`WGET_TIMEOUT`](https://archivebox.github.io/abx-plugins/#wget), [`CHROME_TIMEOUT`](https://archivebox.github.io/abx-plugins/#chrome), [`YTDLP_TIMEOUT`](https://archivebox.github.io/abx-plugins/#ytdlp)). See the [per-plugin docs](https://archivebox.github.io/abx-plugins/) for the full list.
-
-> [!NOTE]
-> `TIMEOUT` only caps a single extractor invocation. To bound the *total* wall-clock runtime of an entire crawl, use [`CRAWL_TIMEOUT`](#crawl_timeout) instead.
-
-> [!WARNING]
-> Do not set this to anything less than `5` seconds — Chrome will hang indefinitely and many sites will fail completely. Anywhere between `30` and `3000` is the recommended range.
-
-*Related options:*
-[`CRAWL_TIMEOUT`](#crawl_timeout), [`CRAWL_MAX_URLS`](#crawl_max_urls), [`SNAPSHOT_MAX_SIZE`](#snapshot_max_size)
-
----
-#### `RESOLUTION`
-**Possible Values:** [`1440,2000`]/`1024,768`/...
-Default screenshot/PDF viewport resolution in `width,height` pixels. Used as the fallback for `SCREENSHOT_RESOLUTION`, `PDF_RESOLUTION`, and `CHROME_RESOLUTION`.
-
-This is a *plugin-shared* setting — individual extractors override it via `_RESOLUTION` (e.g. [`SCREENSHOT_RESOLUTION`](https://archivebox.github.io/abx-plugins/#screenshot), [`PDF_RESOLUTION`](https://archivebox.github.io/abx-plugins/#pdf), [`CHROME_RESOLUTION`](https://archivebox.github.io/abx-plugins/#chrome)). See the [per-plugin docs](https://archivebox.github.io/abx-plugins/) for plugin-specific overrides.
-
----
-#### `CHECK_SSL_VALIDITY`
-**Possible Values:** [`True`]/`False`
-Whether to enforce HTTPS certificate validity and HSTS chain of trust when archiving sites. Set this to `False` if you want to archive pages even if they have expired or invalid certificates.
-
-This is a *plugin-shared* setting — every HTTP-fetching extractor ([`wget`](https://archivebox.github.io/abx-plugins/#wget), [`yt-dlp`](https://archivebox.github.io/abx-plugins/#ytdlp), [`gallery-dl`](https://archivebox.github.io/abx-plugins/#gallerydl), [`chrome`](https://archivebox.github.io/abx-plugins/#chrome), etc.) honors it, and individual extractors can override with `_CHECK_SSL_VALIDITY`. See the [per-plugin docs](https://archivebox.github.io/abx-plugins/).
-
-> [!WARNING]
-> When `False`, ArchiveBox cannot guarantee that the captured content matches the real site — a man-in-the-middle could substitute responses. Only disable for trusted networks or for archiving legacy/internal sites with expired certs.
-
----
-#### `USER_AGENT`
-**Possible Values:** [`Mozilla/5.0 ... ArchiveBox/{VERSION} ...`]/`"Mozilla/5.0 ..."`/...
-The default `User-Agent` string sent during archiving. The built-in default identifies ArchiveBox and links back to the GitHub repo so site operators can identify and contact archivers if needed.
-
-This is a *plugin-shared* setting — each extractor ([`wget`](https://archivebox.github.io/abx-plugins/#wget), [`chrome`](https://archivebox.github.io/abx-plugins/#chrome), [`yt-dlp`](https://archivebox.github.io/abx-plugins/#ytdlp), [`singlefile`](https://archivebox.github.io/abx-plugins/#singlefile), …) can override it with its own `_USER_AGENT`, otherwise it falls back to this value. See the [per-plugin docs](https://archivebox.github.io/abx-plugins/) for per-extractor specifics.
-
-> [!NOTE]
-> Some sites block requests that look like bots or that don't match a real browser. If you're getting 403s or empty responses, try setting this to a current Chrome/Firefox UA string.
-
----
-#### `COOKIES_FILE`
-**Possible Values:** [`None`]/`/path/to/cookies.txt`/...
-
-> [!TIP]
-> **Prefer [personas](#default_persona) over `COOKIES_FILE` for authentication.** A persona bundles a `cookies.txt`, a Chrome user-data-dir, a user-agent, and any other per-identity state into one named profile that's swappable per-crawl and automatically scoped across every extractor. `COOKIES_FILE` (and the per-extractor `_COOKIES_FILE` overrides) is a low-level escape hatch for when you specifically need to point at a hand-rolled cookies file outside the persona system — most users should ignore it and configure auth through `archivebox persona create` instead.
-
-Path to a [Netscape-format `cookies.txt`](http://www.cookiecentral.com/faq/#3.5) file passed to `wget`, `curl`, `yt-dlp`, and other non-Chrome extractors for authentication. Required when archiving sites behind a login (paywalls, social media feeds, members-only forums, etc.) **if you're not using a persona**.
-
-This is a *plugin-shared* setting — each extractor can override it with `_COOKIES_FILE` (e.g. [`WGET_COOKIES_FILE`](https://archivebox.github.io/abx-plugins/#wget), [`YTDLP_COOKIES_FILE`](https://archivebox.github.io/abx-plugins/#ytdlp), [`GALLERYDL_COOKIES_FILE`](https://archivebox.github.io/abx-plugins/#gallerydl)). [Chrome](https://archivebox.github.io/abx-plugins/#chrome)-based extractors instead read auth state from the persona's `CHROME_USER_DATA_DIR`. See the [per-plugin docs](https://archivebox.github.io/abx-plugins/) for per-extractor variants.
-
-You can generate a `cookies.txt` using a [browser extension](https://chromewebstore.google.com/detail/get-cookiestxt-locally/cclelndahbckbenkjhflpdbgdldlbecc), or with `wget --save-cookies` + `--user=... --password=...`.
-
-The recommended path is to create a persona and let it manage cookies + Chrome profile state for you:
-
-```bash
-archivebox persona create --import=chrome personal
-archivebox add --persona=personal https://members.example.com/feed
-```
-
-> [!WARNING]
-> **Use separate burner credentials dedicated to archiving** — don't re-use your normal daily Facebook/Instagram/Youtube/etc. account cookies as server responses often contain your name/email/PII and session tokens, which then get preserved in your snapshots forever!
-
-*Related options:*
-[`DEFAULT_PERSONA`](#default_persona), [`ACTIVE_PERSONA`](#active_persona), [`CHROME_USER_DATA_DIR`](https://archivebox.github.io/abx-plugins/#chrome)
-
----
-#### `DEFAULT_PERSONA`
-**Possible Values:** [`Default`]/`personal`/`work`/...
-The persona profile used when no explicit persona is selected for a crawl. Personas bundle a Chrome user-data-dir, a `cookies.txt`, auth state, a user-agent, and any other per-identity config into a single named profile, letting you swap between archiving contexts (logged-out vs. signed-into-work-account vs. signed-into-personal-account) without manually juggling files.
-
-ArchiveBox auto-creates the named persona on disk if it doesn't already exist. See the [Personas wiki page](https://github.com/ArchiveBox/ArchiveBox/wiki/Personas) for the full directory layout.
-
-*Related options:*
-[`ACTIVE_PERSONA`](#active_persona), [`COOKIES_FILE`](#cookies_file)
-
----
-#### `ACTIVE_PERSONA`
-**Possible Values:** *auto-set, read-only at runtime*
-The name of the persona actually being used for the *current* crawl/snapshot. Where [`DEFAULT_PERSONA`](#default_persona) is the user-configured *fallback*, `ACTIVE_PERSONA` is **derived** — ArchiveBox sets it automatically based on the resolved persona for each Snapshot (explicit selection on the Crawl > persona on the URL > `DEFAULT_PERSONA`).
-
-You generally read this rather than write it. Plugins and templates can inspect `ACTIVE_PERSONA` to render persona-specific UI or pick persona-scoped paths. Setting it manually in `ArchiveBox.conf` has no effect — it will be overwritten on every run by the persona resolver.
-
-*Related options:*
-[`DEFAULT_PERSONA`](#default_persona)
-
----
-
-#### `URL_DENYLIST`
-**Possible Values:** [`\.(css|js|otf|ttf|woff|woff2|gstatic\.com|googleapis\.com/css)(\?.*)?$`]/`.+\.exe$`/...
-
-Regex pattern matched against every URL discovered during a crawl. Any matching URL is **excluded** from archiving — useful for blocking tracking pixels, ad networks, CDN-hosted CSS/fonts, or arbitrary file extensions you don't want to capture.
-
-The default skips common static assets (CSS, fonts, Google Fonts CDN) so they aren't re-fetched as separate Snapshots during recursive crawls — the parent page's `singlefile`/`dom` output already inlines them.
-
-*Note: This option is also recognized under its legacy alias `URL_BLACKLIST`.*
-
-*Related options:*
-[`URL_ALLOWLIST`](#url_allowlist)
-
----
-
-#### `URL_ALLOWLIST`
-**Possible Values:** [`None`]/`^http(s)?:\/\/(.+)?example\.com\/?.*$`/...
-
-Regex pattern matched against every URL discovered during a crawl. When set, any URL that does **not** match is excluded. Useful for recursive crawling scoped to a single domain or path prefix (e.g. only follow links within `docs.example.com/v2/`).
-
-When both are set, `URL_DENYLIST` takes precedence over `URL_ALLOWLIST`.
-
-*Note: This option is also recognized under its legacy alias `URL_WHITELIST`.*
-
-*Related options:*
-[`URL_DENYLIST`](#url_denylist)
-
----
-#### `TAG_SEPARATOR_PATTERN`
-**Possible Values:** [`[,]`]/`[,;]`/`[,;\s]`/...
-Regex character class used to split tag strings (e.g. `news,politics; longform`) into individual tags when importing URLs. The default splits on commas only; widen it if you paste in tags separated by semicolons, spaces, or other delimiters.
-
----
-#### `CRAWL_MAX_URLS`
-**Possible Values:** [`0`]/`50`/`500`/...
-Maximum number of unique URLs (Snapshots) a single crawl is allowed to produce. `0` means unlimited. Counts both seed URLs you submitted and URLs discovered by recursive crawlers (`parse_dom_outlinks`, `parse_html_urls`, etc.).
-
-Once the cap is reached, recursive crawlers stop emitting new Snapshots and the crawl is marked with `stop_reason = "crawl_max_urls"`. **Raising the cap later and re-queuing the crawl will resume discovery** — the limit state is persisted in `/.abx-dl/limits.json` and re-evaluated each tick.
-
-> [!NOTE]
-> Use this as a safety net for recursive crawls (`--depth=N`) that could otherwise blow up to thousands of pages on link-heavy sites.
-
-*Related options:*
-[`CRAWL_MAX_SIZE`](#crawl_max_size), [`CRAWL_TIMEOUT`](#crawl_timeout), [`CRAWL_MAX_CONCURRENT_SNAPSHOTS`](#crawl_max_concurrent_snapshots), [`SNAPSHOT_MAX_SIZE`](#snapshot_max_size)
-
----
-#### `CRAWL_MAX_SIZE`
-**Possible Values:** [`0`]/`50MB`/`5GB`/`104857600`/...
-Maximum cumulative output size (in bytes) a single crawl is allowed to produce across all of its Snapshots. `0` means unlimited.
-
-Accepts a raw byte count (`104857600`) or a unit-suffixed string (`100MB`, `5GB`, `1TiB`). Sizes are accumulated by the extractor service as each `ArchiveResult` writes its outputs to disk; once the cap is exceeded, in-flight Snapshots finish but no new ones are admitted and the crawl stops with `stop_reason = "crawl_max_size"`.
-
-> [!NOTE]
-> Bounds the **disk footprint** of a crawl, not the wire transfer — a 2MB HTML page can produce 50MB of screenshots, PDFs, SingleFile bundles, and media downloads, and this cap applies to the on-disk total.
-
-*Related options:*
-[`SNAPSHOT_MAX_SIZE`](#snapshot_max_size), [`CRAWL_MAX_URLS`](#crawl_max_urls), [`CRAWL_TIMEOUT`](#crawl_timeout)
-
----
-#### `CRAWL_TIMEOUT`
-**Possible Values:** [`0`]/`300`/`3600`/...
-Maximum total wall-clock runtime for a single crawl in seconds. `0` means unlimited.
-
-Distinct from [`TIMEOUT`](#timeout): `TIMEOUT` caps one extractor invocation on one Snapshot; `CRAWL_TIMEOUT` caps the *entire crawl* — all Snapshots, all extractors, all retries, all recursive discovery passes — together. Once exceeded the crawl is marked `stop_reason = "crawl_timeout"` and queued Snapshots are skipped.
-
-> [!NOTE]
-> Useful as a hard ceiling for unattended/scheduled crawls (e.g. "spend at most 1 hour archiving Hacker News tonight"). Pair with `CRAWL_MAX_URLS` and `CRAWL_MAX_SIZE` for belt-and-suspenders bounds.
-
-*Related options:*
-[`TIMEOUT`](#timeout), [`CRAWL_MAX_URLS`](#crawl_max_urls), [`CRAWL_MAX_SIZE`](#crawl_max_size)
-
----
-#### `CRAWL_MAX_CONCURRENT_SNAPSHOTS`
-**Possible Values:** [`4`]/`1`/`8`/`16`/...
-How many Snapshots within a single crawl ArchiveBox will archive in parallel. The runner schedules up to this many extractor pipelines at once, then waits for one to finish before starting the next.
-
-Raising this speeds up large crawls on beefy hardware, but each concurrent Snapshot launches its own Chrome instance (when Chrome-based extractors are enabled) — RAM and CPU pressure scale roughly linearly. On a typical laptop, `2-4` is sane; on a dedicated server with 32GB+ RAM, `8-16` can be reasonable.
-
-> [!NOTE]
-> This is **per-crawl** concurrency. If you run multiple crawls simultaneously, each one independently gets up to `CRAWL_MAX_CONCURRENT_SNAPSHOTS` parallel Snapshots.
-
-*Related options:*
-[`CRAWL_MAX_URLS`](#crawl_max_urls), [`TIMEOUT`](#timeout)
-
----
-#### `SNAPSHOT_MAX_SIZE`
-**Possible Values:** [`0`]/`10MB`/`500MB`/...
-Maximum cumulative output size (in bytes) **per individual Snapshot**. `0` means unlimited. Same unit-suffix parsing as `CRAWL_MAX_SIZE` (`10MB`, `2GB`, raw bytes, etc.).
-
-Where `CRAWL_MAX_SIZE` is a *crawl-wide* budget, `SNAPSHOT_MAX_SIZE` puts a ceiling on any *one* page's output. Once a Snapshot's outputs exceed the cap, remaining extractors for that Snapshot are skipped and the Snapshot is tagged with `stop_reason = "snapshot_max_size"` — but the rest of the crawl continues normally.
-
-> [!NOTE]
-> Particularly useful when crawling sites with occasional huge pages (e.g. a forum where most threads are small but a few are 500MB media galleries) — it caps the outliers without throttling the whole crawl.
-
-*Related options:*
-[`CRAWL_MAX_SIZE`](#crawl_max_size), [`CRAWL_MAX_URLS`](#crawl_max_urls)
-
----
-#### `DELETE_AFTER`
-**Possible Values:** [`0`]/`24h`/`7d`/`4w`/`6mo`/`1y`/...
-Retention policy: automatically delete Crawls, Snapshots, ArchiveResults, and Process rows (and their on-disk outputs) after this duration has elapsed. `0`, `""`, or `None` disables auto-deletion (the default — ArchiveBox never deletes anything unless you ask).
-
-Accepted units: `h`/`hr`/`hour`, `d`/`day`, `w`/`week`, `mo`/`month`, `y`/`yr`/`year`. The minimum non-zero duration is `1h`. Examples:
-
-```bash
-archivebox config --set DELETE_AFTER=24h # daily rolling buffer
-archivebox config --set DELETE_AFTER=30d # 30-day retention
-archivebox config --set DELETE_AFTER=6mo # 6 months
-```
-
-`DELETE_AFTER` can be set globally, per-persona, per-crawl, or per-snapshot — the most-specific value wins. When a Snapshot is created, its `delete_at` timestamp is computed from the effective `DELETE_AFTER` and persisted; the retention sweeper then deletes rows whose `delete_at` is in the past.
-
-> [!WARNING]
-> Deletion is **destructive and irreversible**. Files in the snapshot's output directory are removed from disk. Use with care on important archives — and *never* set this on the global config if you have legacy snapshots you don't want garbage-collected.
-
-*Related options:*
-[`PERMISSIONS`](#permissions)
-
----
-
-
-#### `PERMISSIONS`
-**Possible Values:** [`public`]/`unlisted`/`private`
-Default visibility for newly created Snapshots. Inherited by every Snapshot in a Crawl unless explicitly overridden at the Crawl or Snapshot level.
-
-- **`public`** — Snapshot appears in the public index *and* its content is directly accessible without login.
-- **`unlisted`** — Snapshot content is accessible via direct link, but it is **not** listed in the public index. Equivalent to a "secret URL."
-- **`private`** — Snapshot is hidden from the public index *and* its content requires admin login.
-
-This option supersedes the removed `PUBLIC_SNAPSHOTS` boolean and is also driven by the still-current [`PUBLIC_INDEX`](#public_index) flag — both are interpreted as a coarse mapping onto `PERMISSIONS` for backwards compatibility (`PUBLIC_SNAPSHOTS=False` ⇒ `private`, `PUBLIC_INDEX=False` ⇒ `unlisted`, either set to `True` ⇒ `public`). Setting `PERMISSIONS` directly wins over either legacy flag.
-
-> [!NOTE]
-> `PERMISSIONS` controls **per-Snapshot** visibility. Server-wide auth (whether the whole UI requires login, whether the add-view is open) is still controlled by [`PUBLIC_INDEX`](#public_index) and [`PUBLIC_ADD_VIEW`](#public_add_view) under Server Settings.
-
-*Related options:*
-[`PUBLIC_INDEX`](#public_index), [`PUBLIC_ADD_VIEW`](#public_add_view), [`DELETE_AFTER`](#delete_after)
-
----
-#### `PLUGINS`
-**Possible Values:** [`""`]/`wget,favicon,screenshot`/`chrome,singlefile,dom`/...
-Comma-separated **whitelist** of plugins to load and run for this archiving run. When empty (the default), ArchiveBox uses the installed/enabled plugin set — i.e. every plugin whose `_ENABLED` config evaluates true.
-
-When set, only the listed plugins (plus any plugins they declare as `required_plugins` in their `config.json` — e.g. picking `singlefile` automatically pulls in `chrome`) participate in the run. Equivalent to the CLI flag:
-
-```bash
-archivebox add --plugins=wget,favicon,screenshot https://example.com
-```
-
-Useful for one-off runs ("just grab a screenshot and skip everything else") or for reproducible per-crawl pipelines stored on the Crawl row.
-
-*Related options:*
-[`ENABLED_PLUGINS`](#enabled_plugins)
-
----
-#### `ENABLED_PLUGINS`
-**Possible Values:** [`""`]/`wget,chrome,singlefile`/...
-Comma-separated **override** of the enabled plugin set, used primarily by the admin UI and REST API to express "these are the plugins I want enabled for this Crawl/Snapshot/Persona" without having to flip every individual `_ENABLED` flag.
-
-The distinction vs. [`PLUGINS`](#plugins):
-- `PLUGINS` is the **run-time selector** (what to actually execute on this `add` invocation, with transitive dependency expansion).
-- `ENABLED_PLUGINS` is the **persisted enabled set** (what the UI/API thinks should be on for this scope, used to compute per-plugin `_ENABLED` defaults).
-
-When both are set, `PLUGINS` wins for the actual run; `ENABLED_PLUGINS` remains as the stored default for future runs at the same scope.
-
-*Related options:*
-[`PLUGINS`](#plugins)
-
----
-
-## Server Settings
-
-*Options for the web UI, authentication, subdomain routing, and reverse proxy configuration.*
-
----
-
-
-#### `ADMIN_USERNAME` / `ADMIN_PASSWORD`
-**Possible Values:** [`None`]/`"admin"`/...
-
-Only used on first run / initial setup in Docker. ArchiveBox will create an admin superuser with the specified username and password when both options are present in the environment at startup. After the user exists, changing these values has no effect — use `archivebox manage changepassword ` or the Django admin UI instead.
-
-> [!WARNING]
-> Setting `ADMIN_PASSWORD` via environment variable bakes the secret into your shell history, Docker inspect output, and process listings. For long-lived deployments, set it once during provisioning, create the user, then unset the variable.
-
-More info:
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-up-Authentication
-
-*Related options:*
-[`LDAP_ENABLED`](#ldap_enabled), [`REVERSE_PROXY_USER_HEADER`](#reverse_proxy_user_header)
-
----
-
-
-#### `PUBLIC_INDEX` / `PUBLIC_ADD_VIEW`
-**Possible Values:** [`True`]/`False` (for `PUBLIC_INDEX`), [`False`]/`True` (for `PUBLIC_ADD_VIEW`)
-
-Server-wide toggles for whether login is required to use each public area of ArchiveBox.
-
-```bash
-archivebox config --set PUBLIC_INDEX=True # allow viewing the snapshot index without login
-archivebox config --set PUBLIC_ADD_VIEW=False # require login to submit new URLs via the web UI
-```
-
-- `PUBLIC_INDEX` (default `True`) — when on, anonymous visitors can browse the snapshot list page. Individual snapshot visibility is still gated by each Snapshot's own [`PERMISSIONS`](#permissions) field.
-- `PUBLIC_ADD_VIEW` (default `False`) — when on, anonymous visitors can submit new URLs to be archived via the `/add` form. Leave this off on any internet-exposed instance unless you actively want a public submission endpoint.
-
-> [!NOTE]
-> **`PUBLIC_SNAPSHOTS` has been removed as a global toggle.** Snapshot visibility is now decided per-Snapshot via the [`PERMISSIONS`](#permissions) field (`public` / `unlisted` / `private`) under General Settings. The old anchors are preserved on `PERMISSIONS` so existing links keep working.
-
-*Related options:*
-[`PERMISSIONS`](#permissions), [`SERVER_SECURITY_MODE`](#server_security_mode), [`ADMIN_USERNAME`](#admin_username--admin_password)
-
----
-#### `SECRET_KEY`
-**Possible Values:** *auto-generated 50-character random string*
-
-Django's secret key, used for cryptographic signing of sessions, CSRF tokens, password reset links, and other signed payloads. Auto-generated on first server start and persisted to `ArchiveBox.conf` so it survives restarts. If the config file isn't writable (read-only mount, mid-init race), an in-memory random key is used and all users are logged out on the next boot.
-
-> [!WARNING]
-> Treat this value like a password. Anyone with the `SECRET_KEY` can forge sessions and CSRF tokens for your instance. Don't commit `ArchiveBox.conf` to public repos, and rotate it (forcing all users to log in again) if you suspect it's been exposed.
-
----
-#### `BIND_ADDR`
-**Possible Values:** [`127.0.0.1:8000`]/`0.0.0.0:8000`/`[::]:8000`/`0.0.0.0:80`/...
-
-The `host:port` socket the ArchiveBox web server actually listens on. **This is the local bind socket, not the public URL** — for the public URL clients see, set [`BASE_URL`](#base_url).
-
-- `127.0.0.1:8000` (default) — listen only on the loopback interface. Safest when you're running a reverse proxy on the same host and don't want the server reachable directly from the network.
-- `0.0.0.0:8000` — listen on **all** IPv4 interfaces. Required when running in Docker without `--network=host`, or when you want the server reachable from other machines on your LAN without a reverse proxy.
-- `[::]:8000` — listen on all IPv6 interfaces (most modern OSes will accept v4-mapped connections too).
-- `unix:/path/to/archivebox.sock` — bind to a Unix socket instead of a TCP port (useful for nginx/Caddy on the same host).
-
-IPv6 literal addresses must be bracketed: `[::1]:8000`, not `::1:8000`.
-
-> [!NOTE]
-> Inside Docker, binding to `127.0.0.1` means the server is unreachable from outside the container — use `0.0.0.0:8000` and let Docker handle the port-forwarding, or publish the port with `-p 127.0.0.1:8000:8000` on the host side instead.
-
-*Related options:*
-[`BASE_URL`](#base_url), [`SERVER_SECURITY_MODE`](#server_security_mode)
-
----
-
-
-#### `BASE_URL`
-**Possible Values:** [`""`]/`https://archive.example.com`/`http://archivebox.localhost:8000`/...
-
-The canonical public URL of your ArchiveBox instance. Used to build absolute links in templates, redirects (`/admin/login/?next=...`), admin notification emails, OG/meta tags, and — in subdomain security mode — to derive the `admin.`, `web.`, `api.`, `public.`, and per-snapshot `snap-.` subdomains.
-
-**When `BASE_URL` is set explicitly**, ArchiveBox treats it as the source of truth and ignores the incoming `Host` header for URL building. In `safe-subdomains-fullreplay` mode this is **required for redirects to work** — without an explicit base, the middleware can't safely emit `admin.` redirects (they'd compound onto whatever subdomain the request already arrived on).
-
-**When `BASE_URL` is empty**, the value is resolved at request time from the incoming request's `Host` header (with any leading `admin.` / `web.` / `api.` / `public.` / `snap-*.` label stripped to recover the canonical base). Loopback hostnames (`localhost`, `127.0.0.1`, `0.0.0.0`, `::`) are rewritten to `archivebox.localhost` so subdomain routing works without `/etc/hosts` edits. If there's no live request, [`BIND_ADDR`](#bind_addr) is used as a last resort.
-
-The scheme is taken from the explicit `BASE_URL` if set, otherwise from the request (so put a reverse proxy in front for HTTPS and trust `X-Forwarded-Proto`).
-
-ArchiveBox automatically derives the underlying Django `ALLOWED_HOSTS` and `CSRF_TRUSTED_ORIGINS` settings from `BASE_URL` + [`SERVER_SECURITY_MODE`](#server_security_mode), so you do **not** set those directly — the system widens them as needed to admit the admin/web/api/public subdomains.
-
-> [!NOTE]
-> **In `safe-subdomains-fullreplay` mode, pin `BASE_URL` explicitly.** Without it, the misconfig banner will surface in the rendered page and host-based redirects (`/admin` → `admin.`) are suppressed to avoid the `admin.admin.admin.` compounding bug.
-
-> [!NOTE]
-> **Legacy upgrade path (0.7.3 → 0.9):** older deployments that set `CSRF_TRUSTED_ORIGINS=https://archive.example.com` for their reverse-proxy login but never set `BASE_URL` still work — when exactly one CSRF origin is present and `BASE_URL` is empty, ArchiveBox uses that origin as the implicit base URL. New installs should set `BASE_URL` directly; `CSRF_TRUSTED_ORIGINS` is no longer a user-settable knob.
-
-*Related options:*
-[`SERVER_SECURITY_MODE`](#server_security_mode), [`BIND_ADDR`](#bind_addr)
-
----
-#### `SERVER_SECURITY_MODE`
-**Possible Values:** [`safe-subdomains-fullreplay`]/`safe-onedomain-nojsreplay`/`unsafe-onedomain-noadmin`/`danger-onedomain-fullreplay`
-
-The top-level security posture of the server. Controls how archived content is served, whether the admin/API control plane is reachable, and which host(s) the UI is split across. **This is the most important security knob** — pick the most restrictive mode that still works for your use case.
-
-ArchiveBox splits its surfaces across four logical hosts: `admin.*` (Django admin + session cookies, the entire control plane), `web.*` (logged-in browsing UI), `api.*` (REST/JSON endpoints), and `public.*` (unauthenticated browsing of `PERMISSIONS=public` snapshots). In subdomain mode each gets its own host derived from [`BASE_URL`](#base_url); session/CSRF cookies are scoped to `admin.*` only, so a compromised replay page on `snap-.*` can't read admin auth.
-
-| Mode | Host layout | JS replay | Control plane | Use when |
-|---|---|---|---|---|
-| **`safe-subdomains-fullreplay`** *(default, recommended)* | admin/web/api/public/snap-* on separate subdomains | Full JS replay enabled | Enabled on `admin.*` only | You have wildcard DNS (`*.archive.example.com`) and a TLS cert that covers it. Archived JS runs sandboxed away from the admin origin. |
-| **`safe-onedomain-nojsreplay`** | Everything on one host | JS in replays is neutered (served as `text/plain` or stripped) | Enabled | You can't get wildcard DNS. Trades replay fidelity for same-origin safety — archived pages won't execute scripts. |
-| **`unsafe-onedomain-noadmin`** | Everything on one host | Full JS replay enabled | **Disabled** — `/admin`, `/accounts`, `/api`, `/add`, `/web` return 403; only GET/HEAD/OPTIONS allowed | Read-only public archive on a single host. Operate the instance via CLI only; the web admin is unreachable. |
-| **`danger-onedomain-fullreplay`** | Everything on one host | Full JS replay enabled | Enabled | Local dev / trusted-network only. Archived JS runs on the **same origin as the admin UI** — a malicious archived page can call admin endpoints with your session. **Do not expose this mode to the internet.** |
-
-> [!WARNING]
-> Switching to any mode whose name starts with `unsafe-` or `danger-` is logged at startup and surfaces a banner in the UI. **Don't use these modes on a public hostname** — archived JavaScript will run on the same origin as your admin session.
-
-> [!NOTE]
-> Subdomain mode requires both wildcard DNS (`*.archive.example.com`) and (if using TLS) a wildcard certificate. Without those, fall back to `safe-onedomain-nojsreplay`.
-
-*Related options:*
-[`BASE_URL`](#base_url), [`PERMISSIONS`](#permissions)
-
-More info:
-- [Security Overview](Security-Overview)
-
----
-#### `SNAPSHOTS_PER_PAGE`
-**Possible Values:** [`40`]/`100`/...
-
-Maximum number of Snapshots to render per page on the snapshot list views (both the admin index and the public index). Larger values speed up bulk browsing at the cost of heavier per-request rendering.
-
----
-#### `FOOTER_INFO`
-**Possible Values:** [`Content is hosted for personal archiving purposes only. Contact server owner for any takedown requests.`]/...
-
-Free-form text rendered in the footer of every archive page. Useful for adding a takedown contact, an org disclaimer, or attribution. Plain text — no HTML.
-
----
-#### `CUSTOM_TEMPLATES_DIR`
-**Possible Values:** [`data/custom_templates`]/`/path/to/custom_templates`/...
-
-Path to a directory containing custom HTML / CSS / image overrides for the default ArchiveBox templates. Files placed here shadow the built-in templates of the same path, letting you rebrand the UI without forking. See the Django template loader docs for the resolution order.
-
----
-#### `REVERSE_PROXY_USER_HEADER`
-**Possible Values:** [`Remote-User`]/`X-Remote-User`/`X-Forwarded-User`/...
-
-HTTP header your reverse proxy (Authelia, oauth2-proxy, Authentik, nginx `auth_request`, etc.) sets to the authenticated username. ArchiveBox's `ReverseProxyAuthMiddleware` reads this header **only when the request's source IP is inside [`REVERSE_PROXY_WHITELIST`](#reverse_proxy_whitelist)** — otherwise the header is ignored to prevent direct-connect spoofing.
-
-The header name is matched case-insensitively and normalized to the `HTTP_*` form Django exposes (e.g. `Remote-User` → `HTTP_REMOTE_USER`).
-
-*Related options:*
-[`REVERSE_PROXY_WHITELIST`](#reverse_proxy_whitelist), [`LOGOUT_REDIRECT_URL`](#logout_redirect_url)
-
----
-#### `REVERSE_PROXY_WHITELIST`
-**Possible Values:** [`""`]/`172.16.0.0/16`/`10.0.0.5/32,fd00::/8`/...
-
-Comma-separated list of IPv4 / IPv6 addresses or CIDR networks that are trusted to set [`REVERSE_PROXY_USER_HEADER`](#reverse_proxy_user_header). When empty (the default), reverse-proxy auth is **completely disabled** — the header is never consulted no matter who set it.
-
-When non-empty, only requests whose `REMOTE_ADDR` falls inside one of the listed networks have the header honored. Anything else falls back to standard session auth. The CIDR list is validated on every request; an invalid entry raises `ImproperlyConfigured` and breaks the server, so test changes carefully.
-
-> [!WARNING]
-> **Set this to the actual IP of your reverse proxy, never `0.0.0.0/0` or a public network.** With a wide-open whitelist, anyone who can reach the server directly can forge any username they like via the header.
-
-*Related options:*
-[`REVERSE_PROXY_USER_HEADER`](#reverse_proxy_user_header), [`LOGOUT_REDIRECT_URL`](#logout_redirect_url)
-
----
-#### `LOGOUT_REDIRECT_URL`
-**Possible Values:** [`/`]/`https://example.com/some/other/app`/`/accounts/logout-landing/`/...
-
-URL users are redirected to after logging out. The default `/` keeps users on ArchiveBox; set this to an external URL when using reverse-proxy SSO so logout terminates the upstream session too (e.g. `https://auth.example.com/logout`).
-
-*Related options:*
-[`REVERSE_PROXY_USER_HEADER`](#reverse_proxy_user_header), [`REVERSE_PROXY_WHITELIST`](#reverse_proxy_whitelist)
-
----
-
-### LDAP Settings
-
-*Options for LDAP / Active Directory authentication via [django-auth-ldap](https://github.com/django-auth-ldap/django-auth-ldap). Requires `pip install archivebox[ldap]` (which also pulls in the system `libldap` / `libsasl` headers).*
-
----
-#### `LDAP_ENABLED`
-**Possible Values:** [`False`]/`True`
-
-Master switch for LDAP authentication. When `True`, ArchiveBox loads the `django-auth-ldap` backend and validates that `LDAP_SERVER_URI`, `LDAP_BIND_DN`, `LDAP_BIND_PASSWORD`, and `LDAP_USER_BASE` are all set — startup fails fast otherwise.
-
-```bash
-pip install archivebox[ldap]
-```
-
-Then set these configuration values:
-```yaml
-LDAP_ENABLED: True
-LDAP_SERVER_URI: "ldap://ldap.example.com:3389"
-LDAP_BIND_DN: "ou=archivebox,ou=services,dc=ldap.example.com"
-LDAP_BIND_PASSWORD: "secret-bind-user-password"
-LDAP_USER_BASE: "ou=users,ou=archivebox,ou=services,dc=ldap.example.com"
-LDAP_USER_FILTER: "(uid=%(user)s)"
-LDAP_USERNAME_ATTR: "username"
-LDAP_FIRSTNAME_ATTR: "givenName"
-LDAP_LASTNAME_ATTR: "sn"
-LDAP_EMAIL_ATTR: "mail"
-LDAP_CREATE_SUPERUSER: False
-```
-
-More info:
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-up-Authentication
-- https://github.com/django-auth-ldap/django-auth-ldap#example-configuration
-
-*Related options:*
-[`ADMIN_USERNAME`](#admin_username--admin_password), [`REVERSE_PROXY_USER_HEADER`](#reverse_proxy_user_header)
-
----
-#### `LDAP_SERVER_URI`
-**Possible Values:** [`None`]/`ldap://ldap.example.com:389`/`ldaps://ldap.example.com:636`/...
-
-URI of the LDAP server to bind against. Use `ldaps://` for TLS or `ldap://` for plaintext (plus optional StartTLS at the protocol level). Required when [`LDAP_ENABLED`](#ldap_enabled) is `True`.
-
----
-#### `LDAP_BIND_DN`
-**Possible Values:** [`None`]/`cn=archivebox,ou=services,dc=example,dc=com`/...
-
-Distinguished name of the service account used to perform user searches. This account only needs read access to the user subtree under [`LDAP_USER_BASE`](#ldap_user_base). Required when [`LDAP_ENABLED`](#ldap_enabled) is `True`.
-
----
-#### `LDAP_BIND_PASSWORD`
-**Possible Values:** [`None`]/``/...
-
-Password for the [`LDAP_BIND_DN`](#ldap_bind_dn) service account. Required when [`LDAP_ENABLED`](#ldap_enabled) is `True`.
-
-> [!WARNING]
-> Treat this like any other service credential — keep it out of shell history and version control. Prefer setting it via the config file (which has owner-only permissions) over environment variables.
-
----
-#### `LDAP_USER_BASE`
-**Possible Values:** [`None`]/`ou=users,dc=example,dc=com`/...
-
-Base DN under which to search for user entries. Required when [`LDAP_ENABLED`](#ldap_enabled) is `True`. The search is performed as `LDAP_BIND_DN` with the filter from [`LDAP_USER_FILTER`](#ldap_user_filter).
-
----
-#### `LDAP_USER_FILTER`
-**Possible Values:** [`(uid=%(user)s)`]/`(sAMAccountName=%(user)s)`/`(&(objectClass=person)(mail=%(user)s))`/...
-
-LDAP search filter used to find a user entry at login. The literal token `%(user)s` is replaced with the username the user typed into the login form. Common values:
-- `(uid=%(user)s)` — OpenLDAP-style
-- `(sAMAccountName=%(user)s)` — Active Directory
-- `(mail=%(user)s)` — match by email
-
----
-#### `LDAP_USERNAME_ATTR`
-**Possible Values:** [`username`]/`uid`/`sAMAccountName`/...
-
-LDAP attribute on the user entry that becomes the local Django `username`. Must be unique within the directory.
-
----
-#### `LDAP_FIRSTNAME_ATTR`
-**Possible Values:** [`givenName`]/...
-
-LDAP attribute mapped to Django's `User.first_name`.
-
----
-#### `LDAP_LASTNAME_ATTR`
-**Possible Values:** [`sn`]/...
-
-LDAP attribute mapped to Django's `User.last_name`.
-
----
-#### `LDAP_EMAIL_ATTR`
-**Possible Values:** [`mail`]/`userPrincipalName`/...
-
-LDAP attribute mapped to Django's `User.email`.
-
----
-#### `LDAP_CREATE_SUPERUSER`
-**Possible Values:** [`False`]/`True`
-
-When `True`, every LDAP user who successfully authenticates is auto-promoted to Django superuser. **Off by default** — leave it off unless your directory's user base is already restricted to operators, since superusers can modify config, delete snapshots, and run server commands.
-
-> [!WARNING]
-> Combining `LDAP_CREATE_SUPERUSER=True` with a broad [`LDAP_USER_BASE`](#ldap_user_base) (e.g. an entire company OU) effectively grants admin to every employee. Scope the user base or use group-based access control via `django-auth-ldap`'s `AUTH_LDAP_USER_FLAGS_BY_GROUP` (configured in custom `settings.py`) instead.
-
----
-
-## Storage Settings
-
-*Options for the on-disk layout, file permissions, and temp/lib directories that ArchiveBox reads and writes during archiving.*
-
----
-
-#### `OUTPUT_PERMISSIONS`
-**Possible Values:** [`644`]/`755`/...
-Permissions to set on output files written into the [`ARCHIVE_DIR`](#archive_dir). The directory mode is derived from this by OR-ing in the execute bits (so `644` files imply `755` dirs), which subsumes the legacy `DIR_OUTPUT_PERMISSIONS` option (formerly a separate `755`-default field) — directory mode is no longer settable on its own.
-
-> [!NOTE]
-> Set this to `600` if you want archives to be readable only by the ArchiveBox user, or `664`/`775` if you need a shared group to read/write the data dir.
-
-*Related options:*
-[`PUID` / `PGID`](#puid--pgid), [`ENFORCE_ATOMIC_WRITES`](#enforce_atomic_writes)
-
----
-
-
-#### `PUID` / `PGID`
-**Possible Values:** [`911`]/`1000`/...
-*Note: These are Docker-only environment variables — they only take effect when set on the Docker entrypoint at container startup. Setting them in `ArchiveBox.conf` or via `archivebox config --set` has no effect. Outside Docker the UID/GID is auto-detected from the ownership of the data directory (or the running user) and cannot be overridden.*
-
-The UID/GID that the ArchiveBox process should run as (and that all files in the data dir should be owned by). Honored by the Docker entrypoint, which `chown`s the data dir and drops privileges before running ArchiveBox. Outside Docker, ArchiveBox refuses to run as root and instead drops to the user that owns the data dir.
-
-*Learn more:*
-- https://docs.linuxserver.io/general/understanding-puid-and-pgid/
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Troubleshooting#docker-permissions-issues
-
----
-#### `ENFORCE_ATOMIC_WRITES`
-**Possible Values:** [`True`]/`False`
-Whether to write output files atomically (write to a tempfile + `rename()` into place) so that a crash or `kill -9` mid-write can never leave a partial file in the archive. Disable only if you are debugging a filesystem that doesn't support atomic renames (some FUSE mounts).
-
----
-#### `TMP_DIR`
-**Possible Values:** [`/tmp/`]/`/tmp/archivebox/abc5d851`/...
-Path for temporary files, the supervisord unix socket, and generated supervisor config. The default is a per-machine subdirectory under the data dir (`tmp/`) so multiple machines sharing the same data dir (e.g., over NFS) don't collide on socket files.
-
-> [!WARNING]
-> `TMP_DIR` *must* be a short, local path readable/writable by the ArchiveBox user. Unix socket paths have a hard ~96-character limit, so a deeply nested `TMP_DIR` will silently break the supervisor. It also must live on a real local filesystem (tmpfs/SSD) — FUSE, network mounts, and Docker bind mounts on macOS often cannot host unix sockets at all (see [`ALLOW_NO_UNIX_SOCKETS`](#allow_no_unix_sockets)).
-
-If ArchiveBox detects the configured `TMP_DIR` is unwritable or too long, it will auto-fall-back to `/tmp/archivebox/` at startup.
-
-*Related options:*
-[`LIB_DIR`](#lib_dir), [`ALLOW_NO_UNIX_SOCKETS`](#allow_no_unix_sockets)
-
----
-#### `LIB_DIR`
-**Possible Values:** [`/lib/-`]/`/opt/archivebox/lib`/`~/.config/abx/lib`/...
-Path for installed binary dependencies (`chromium`, `single-file`, `yt-dlp`, `ripgrep`, etc.) managed by `abxpkg`. The default is namespaced by architecture/OS (e.g. `arm64-darwin`, `x86_64-linux-docker`) so the same data dir can be safely mounted into containers with different CPU architectures without re-downloading binaries.
-
-> [!NOTE]
-> `LIB_DIR` can grow to several GB. Put it on a fast local disk — running extractors off a network-mounted `LIB_DIR` will be painfully slow.
-
-*Related options:*
-[`LIB_BIN_DIR`](#lib_bin_dir), [`TMP_DIR`](#tmp_dir)
-
----
-#### `LIB_BIN_DIR`
-**Possible Values:** [`/bin`]
-Path where installed binaries are symlinked for a flat, shared lookup `PATH`. Both `abxpkg` and `abx-dl` build the executable-resolution environment from this directory at exec time, so anything dropped (or symlinked) here becomes available to all extractor hooks.
-
-Almost no one needs to change this — it tracks [`LIB_DIR`](#lib_dir) automatically when `LIB_DIR` is overridden.
-
----
-#### `DATA_DIR`
-**Possible Values:** [``]/`/data`/`~/archivebox-data`/...
-The root of an ArchiveBox collection. Holds `index.sqlite3`, `ArchiveBox.conf`, the [`ARCHIVE_DIR`](#archive_dir), [`PERSONAS_DIR`](#personas_dir), `sources/`, `logs/`, `cache/`, etc.
-
-Normally you do *not* set this explicitly — instead you `cd` into the data folder and run `archivebox` there, and `DATA_DIR` defaults to the current working directory. The `DATA_DIR` environment variable is available as an override (used internally by the test suite and some wrappers), but if it's set it must match the cwd or ArchiveBox will refuse to start — this is a guardrail against accidentally pointing two different processes at different roots.
-
-> [!WARNING]
-> ArchiveBox refuses to run as root, refuses to run from an unwritable directory, and refuses to run when `DATA_DIR` disagrees with the current working directory. Always `cd` into your data folder first.
-
----
-#### `ARCHIVE_DIR`
-**Possible Values:** [`/archive`]
-Where Snapshot output directories are written. This is the heavy directory — every archived URL gets a subtree here. Override it when you want index/config to live on a small fast disk but snapshot data on bulk storage:
-
-```bash
-archivebox config --set ARCHIVE_DIR=/mnt/bulk/archivebox/archive
-```
-
-Relative paths are resolved against [`DATA_DIR`](#data_dir).
-
-*Related options:*
-[`USERS_DIR`](#users_dir), [`DATA_DIR`](#data_dir)
-
----
-#### `USERS_DIR`
-**Possible Values:** [`/users`]
-Root of the per-user namespace inside the archive. Each ArchiveBox user gets a subdir (`users//crawls/...` and `users//snapshots/...`) so multiple users sharing one collection do not collide on output paths, and per-user retention/permission policies are easy to enforce at the filesystem level.
-
-Relative paths are resolved against [`ARCHIVE_DIR`](#archive_dir).
-
----
-#### `PERSONAS_DIR`
-**Possible Values:** [`/personas`]
-Where persona state lives — Chrome user-data-dirs, cookie jars, sessionstorage, and any other auth/profile state that should follow a "persona" across snapshots. Each persona owns a subdirectory here that gets bind-mounted (or pointed at via `CHROME_USER_DATA_DIR`) when extractors run on its behalf.
-
-> [!WARNING]
-> `PERSONAS_DIR` typically contains plaintext cookies and logged-in browser sessions. Treat it as secret material — set restrictive [`OUTPUT_PERMISSIONS`](#output_permissions) (e.g. `600`) and never commit it to git or include it in shared backups without encryption.
-
----
-#### `CRAWL_DIR`
-**Possible Values:** *runtime-injected, default `None`*
-The output directory of the *currently running crawl* (e.g. `//crawls/YYYYMMDD///`). Crawl-level extractors (chrome launcher, parsers, etc.) write here.
-
-You almost never set this yourself — the snapshot/crawl orchestrator injects it into the per-call config and passes it through to plugin hooks via the `CRAWL_DIR` environment variable. It is documented here for plugin authors who need to read `config.CRAWL_DIR` from inside a hook to locate sibling crawl-level outputs.
-
-*Related options:*
-[`SNAP_DIR`](#snap_dir), [`USERS_DIR`](#users_dir)
-
----
-#### `SNAP_DIR`
-**Possible Values:** *runtime-injected, default `None`*
-The output directory of the *currently running snapshot* (e.g. `//snapshots/YYYYMMDD///`). Snapshot-level extractors (screenshot, pdf, dom, singlefile, etc.) write their output into per-plugin subdirectories of this path.
-
-Like [`CRAWL_DIR`](#crawl_dir), this is set per-call by the orchestrator and passed to hooks via the `SNAP_DIR` environment variable — it is not something users configure. Documented only so plugin authors know which config key to read inside a hook.
-
-*Related options:*
-[`CRAWL_DIR`](#crawl_dir), [`ARCHIVE_DIR`](#archive_dir)
-
----
-#### `ALLOW_NO_UNIX_SOCKETS`
-**Possible Values:** [`False`]/`True`
-**Alias:** `ARCHIVEBOX_ALLOW_NO_UNIX_SOCKETS`
-
-Skip the startup check that verifies [`TMP_DIR`](#tmp_dir) can host unix-domain sockets (a real `bind()` on a `.sock` file). Set to `True` only when running ArchiveBox on a filesystem that cannot back unix sockets — most commonly Docker Desktop on macOS with a host bind-mounted `TMP_DIR`, where the osxfs/virtiofs layer rejects `bind()` calls.
-
-> [!WARNING]
-> This disables a real safety check, not a cosmetic one. When unix sockets are unavailable some plugins that talk to long-lived helpers over `.sock` files (supervisord control socket, browser launcher RPC) may behave unpredictably. Prefer fixing [`TMP_DIR`](#tmp_dir) to point at a tmpfs/SSD inside the container; reach for `ALLOW_NO_UNIX_SOCKETS` only when that's genuinely not possible.
-
-*Related options:*
-[`TMP_DIR`](#tmp_dir)
-
----
-
-## Database Settings
-
-*Options for tuning the SQLite index database that backs ArchiveBox's snapshot, tag, and crawl metadata.*
-
-ArchiveBox stores all of its index metadata in a single SQLite database file (`index.sqlite3` inside your data directory). The defaults are tuned for nearly all users — the knobs below mostly govern **lock-contention behavior**, which matters when multiple workers touch the database concurrently (e.g. supervised orchestrators, parallel `archivebox add` runs, container restarts that race against an in-flight write, or long-running web/admin processes alongside CLI commands).
-
-> [!NOTE]
-> These are advanced operator tuning options. If you are not actively diagnosing `database is locked` errors or planning a non-default storage layout, you can safely leave everything in this section at its default.
-
-*Learn more:*
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Troubleshooting#sqlite-database-is-locked
-- https://www.sqlite.org/wal.html
-- https://www.sqlite.org/pragma.html
-
----
-#### `DATABASE_NAME`
-**Possible Values:** [`/index.sqlite3`]/`/absolute/path/to/index.sqlite3`/...
-Absolute filesystem path to the SQLite index database file. Settable as the environment variable `ARCHIVEBOX_DATABASE_NAME`.
-
-By default this resolves to `index.sqlite3` inside your data directory and you should not need to change it. Override only when you have a specific reason — e.g. pointing a temporary process at a snapshot of the DB for testing, running multiple ArchiveBox instances out of the same data directory against separate indexes, or relocating the index file onto a different volume.
-
-> [!WARNING]
-> The data directory layout (snapshots, tags, archive folders on disk) is keyed off the index database. Pointing `DATABASE_NAME` at a database that does not match the surrounding data directory will produce broken references and missing archive folders.
-
----
-#### `SQLITE_JOURNAL_MODE`
-**Possible Values:** [`WAL`]/`DELETE`/`TRUNCATE`/`PERSIST`/`MEMORY`/`OFF`
-SQLite [journal mode](https://www.sqlite.org/pragma.html#pragma_journal_mode), applied via `PRAGMA journal_mode = ...` on every new connection. Settable as `ARCHIVEBOX_SQLITE_JOURNAL_MODE`.
-
-The default `WAL` (Write-Ahead Logging) lets readers and a single writer operate concurrently without blocking each other — readers see a stable snapshot while a write is in progress, instead of being serialized behind it. This is a substantial win for ArchiveBox, where the web UI, admin, and CLI workers frequently read the index while an extractor is writing.
-
-> [!WARNING]
-> Do not change this unless you have a specific reason. `DELETE` and `TRUNCATE` serialize all readers against any writer (much worse concurrency). `MEMORY` and `OFF` disable durable journaling and can corrupt the database on crash or power loss. `WAL` requires the database to live on a real local filesystem — it does not work correctly over network filesystems like NFS or SMB.
-
----
-#### `SQLITE_MMAP_SIZE`
-**Possible Values:** [`134217728`] (128 MiB) on bare-metal, [`0`] (disabled) inside Docker / `0` / `268435456` / ...
-Maximum number of bytes of the database file SQLite is allowed to map into memory via `mmap()`, applied via `PRAGMA mmap_size = ...`. Settable as `ARCHIVEBOX_SQLITE_MMAP_SIZE`.
-
-When mmap is enabled, SQLite reads pages directly from the OS page cache instead of issuing `read()` syscalls and copying into a userspace buffer — meaningfully faster page reads on large databases when there is RAM available to cache them. Setting this to `0` disables memory-mapped I/O entirely and falls back to regular `read()` calls.
-
-*Note: The default is `0` (disabled) inside Docker, because the container's reported memory limits often do not reflect the host page cache and large mmap regions can interact poorly with `cgroup` accounting. On bare-metal installs the default is `134217728` (128 MiB).*
-
----
-#### `SQLITE_TIMEOUT`
-**Possible Values:** [`30.0`]/`5.0`/`60.0`/... (seconds, float)
-Python `sqlite3` connection-level busy timeout in **seconds**, passed as the `timeout=` argument when the Django backend opens a connection. Settable as `ARCHIVEBOX_SQLITE_TIMEOUT`.
-
-This is the maximum amount of time the underlying Python driver will wait on a contended lock before raising `OperationalError: database is locked`. Raise it if you see spurious lock errors under sustained write contention and you would rather block than fail; lower it if you want callers to fail fast.
-
-*Related options:*
-[`SQLITE_BUSY_TIMEOUT`](#sqlite_busy_timeout), [`SQLITE_LOCK_RETRY_TIMEOUT`](#sqlite_lock_retry_timeout)
-
----
-#### `SQLITE_BUSY_TIMEOUT`
-**Possible Values:** [`30000`]/`5000`/`60000`/... (milliseconds, integer)
-SQLite-internal busy-wait timeout in **milliseconds**, applied via `PRAGMA busy_timeout = ...` on every new connection. Settable as `ARCHIVEBOX_SQLITE_BUSY_TIMEOUT`.
-
-This is SQLite's own retry-on-busy loop, sitting one layer below [`SQLITE_TIMEOUT`](#sqlite_timeout): when a statement encounters a write lock, SQLite will sleep and retry internally for up to this many milliseconds before returning `SQLITE_BUSY` to the Python driver. The default (`30000` = 30 seconds) is deliberately matched to [`SQLITE_TIMEOUT`](#sqlite_timeout).
-
-> [!WARNING]
-> Easy to confuse with [`SQLITE_TIMEOUT`](#sqlite_timeout): this one is in **milliseconds**, that one is in **seconds**. Keep them aligned in real time when adjusting either.
-
----
-#### `SQLITE_LOCK_RETRY_TIMEOUT`
-**Possible Values:** [`60.0`]/`0`/`120.0`/... (seconds, float)
-Total wall-clock budget in **seconds** that ArchiveBox's own retry loop will spend re-attempting a single locked statement before aborting it. Settable as `ARCHIVEBOX_SQLITE_LOCK_RETRY_TIMEOUT`.
-
-When the SQLite driver eventually surfaces a `database is locked` error (after [`SQLITE_BUSY_TIMEOUT`](#sqlite_busy_timeout) / [`SQLITE_TIMEOUT`](#sqlite_timeout) have already elapsed), ArchiveBox wraps the cursor in a higher-level retry loop that logs the locking holders and re-issues the statement. This is the maximum total time spent in that outer loop, across all retries, before giving up and raising. Set to `0` to disable the cap and retry indefinitely.
-
-> [!NOTE]
-> The outer retry only applies to statements that are *not* inside an explicit `transaction.atomic()` block. Statements inside an explicit transaction propagate the error to the caller immediately, since silently retrying would re-execute statements the caller already considered committed.
-
-*Related options:*
-[`SQLITE_LOCK_RETRY_INTERVAL`](#sqlite_lock_retry_interval)
-
----
-#### `SQLITE_LOCK_RETRY_INTERVAL`
-**Possible Values:** [`5.0`]/`1.0`/`10.0`/... (seconds, float, must be `> 0`)
-Sleep duration in **seconds** between successive attempts inside the ArchiveBox lock-retry loop. Settable as `ARCHIVEBOX_SQLITE_LOCK_RETRY_INTERVAL`.
-
-Lower values retry more aggressively (useful if you expect locks to clear quickly and want to minimize end-to-end latency); higher values reduce log noise and wasted CPU when locks are typically held for a long time. Must be strictly greater than `0`.
-
-*Related options:*
-[`SQLITE_LOCK_RETRY_TIMEOUT`](#sqlite_lock_retry_timeout)
-
----
-
-## Search Settings
-
-*Options for full-text search backend configuration.*
-
-ArchiveBox can index Snapshot text/HTML output into a searchable index that powers the search bar in the Web UI and the `archivebox search ` CLI command. Multiple backend engines are supported — pick the one that best matches your collection size, available system resources, and tolerance for extra moving parts.
-
-> [!NOTE]
-> Each backend has its own tuning knobs (e.g. [Sonic](https://archivebox.github.io/abx-plugins/#search_backend_sonic) host/port, [ripgrep](https://archivebox.github.io/abx-plugins/#search_backend_ripgrep) flags, [SQLite FTS](https://archivebox.github.io/abx-plugins/#search_backend_sqlite) database path). Those backend-specific options now live with the plugin that implements them — see the [abx-plugins docs](https://archivebox.github.io/abx-plugins/) for the full per-backend schema.
-
----
-#### `SEARCH_BACKEND_ENGINE`
-**Possible Values:** [`ripgrep`]/`sqlite`/`sonic`
-
-Which search backend engine to use when running `archivebox search` and rendering the Web UI search bar.
-
-- **`ripgrep`** *(default)* — Pure filesystem grep across each Snapshot's archived output (HTML, text, metadata) via the [`search_backend_ripgrep`](https://archivebox.github.io/abx-plugins/#search_backend_ripgrep) plugin. No extra daemon, no extra database to maintain — just install `rg` and it works. Slow on very large collections (each query re-scans the disk) but always 100% correct: results reflect what's actually on disk *right now*, no stale index. Best choice for small-to-medium collections (≲50k snapshots) and for users who don't want to run extra services.
-
-- **`sonic`** — Fast, suggest-style fuzzy search via a running [Sonic](https://github.com/valeriansaliou/sonic) daemon (configured via the [`search_backend_sonic`](https://archivebox.github.io/abx-plugins/#search_backend_sonic) plugin). ArchiveBox pushes text into Sonic at index time and queries it at search time. Sub-millisecond queries even at very large scale, but you have to run and maintain the Sonic process (Docker compose has it built in). Best choice for large collections (≳100k snapshots) when query latency matters.
-
-- **`sqlite`** — FTS5 full-text index stored alongside ArchiveBox's main `index.sqlite3`, configured via the [`search_backend_sqlite`](https://archivebox.github.io/abx-plugins/#search_backend_sqlite) plugin. No extra processes, no extra binary — uses the SQLite already shipped with Python. Faster than `ripgrep` on large collections, slightly slower than `sonic`, but no daemon to babysit. Good middle ground for users who want a real index without operational overhead.
-
-*Note: Backend-specific tuning ([Sonic](https://archivebox.github.io/abx-plugins/#search_backend_sonic) host/port/password, [ripgrep](https://archivebox.github.io/abx-plugins/#search_backend_ripgrep) flag overrides, [SQLite FTS](https://archivebox.github.io/abx-plugins/#search_backend_sqlite) database path, indexer batch size, etc.) lives in each search-backend plugin's own config schema — see the [abx-plugins docs](https://archivebox.github.io/abx-plugins/) for the full per-backend option list.*
-
----
-
-## Shell Options
-
-*Options around the format & behavior of CLI output.*
-
-Most of the values in this section are auto-detected from your terminal at startup, but each can be overridden explicitly via env var, `ArchiveBox.conf`, or `archivebox config --set` — useful for CI logs, cron jobs, log files, and Docker stdout where the auto-detection isn't what you want.
-
----
-#### `DEBUG`
-**Possible Values:** [`False`]/`True`
-
-Enable verbose debug mode for the entire ArchiveBox process. Automatically set to `True` when `--debug` is passed on the command line; otherwise honors the env var / config value.
-
-When enabled this turns on:
-- Full Python tracebacks (instead of the trimmed friendly version) on any error
-- Django SQL query logging to stderr
-- Template auto-reload (no caching) for the web UI
-- Verbose plugin / hook lifecycle logging
-- Extra detail in `archivebox version`, `archivebox status`, and crash reports
-
-> [!WARNING]
-> **Do not leave `DEBUG=True` enabled on a production / publicly-reachable server.** It exposes tracebacks with file paths, SQL queries, and environment details that can leak sensitive info to anyone who triggers an error page.
-
-*Related options:* [`USE_COLOR`](#use_color), [`SHOW_PROGRESS`](#show_progress)
-
----
-#### `USE_COLOR`
-**Possible Values:** [`True` *(auto-detected)*]/`False`
-
-Whether to colorize console output with ANSI escape codes. Defaults to `True` when stdout is a TTY (interactive terminal) and `False` otherwise.
-
-Override to **force-off** when piping `archivebox` output into a log file or cron-mail wrapper that doesn't strip ANSI codes (otherwise you'll see `^[[31m...^[[0m` litter throughout your logs). Override to **force-on** for tools like `script(1)` or some CI runners that don't report as a TTY but *do* render ANSI correctly.
-
-```bash
-USE_COLOR=False archivebox add https://example.com >> archive.log
-```
-
-*Related options:* [`SHOW_PROGRESS`](#show_progress), [`DEBUG`](#debug)
-
----
-#### `SHOW_PROGRESS`
-**Possible Values:** [`True` *(auto-detected)*]/`False`
-
-Whether to render live progress bars during long-running operations (archiving, indexing, migrations). Defaults to `True` when stdout is a TTY, `False` otherwise.
-
-Override to **force-off** in environments where the auto-detection is fooled into thinking it has a TTY (some Docker setups, Kubernetes log collectors, `tmux`/`screen` pipes) but the redrawing carriage-return output ends up as garbage in your logs.
-
-```bash
-SHOW_PROGRESS=False archivebox add < urls.txt
-```
-
-*Related options:* [`USE_COLOR`](#use_color)
-
----
-
-## Plugin Configuration
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-> [!IMPORTANT]
-> **Per-plugin configuration has moved to its own documentation site.**
-> This `Configuration.md` doc covers only ArchiveBox's *core* settings. For everything that lives inside a plugin — extractor toggles, binary paths, timeouts, args, user agents, cookies, persona scoping, etc. — see:
->
-> ## ➡️ ** **
-
-That site is regenerated from each plugin's `config.json` schema on every release, so it stays in sync with the code. Looking for [`WGET_ARGS`](https://archivebox.github.io/abx-plugins/#wget), [`CHROME_USER_DATA_DIR`](https://archivebox.github.io/abx-plugins/#chrome), [`SCREENSHOT_RESOLUTION`](https://archivebox.github.io/abx-plugins/#screenshot), [`YTDLP_EXTRA_ARGS`](https://archivebox.github.io/abx-plugins/#ytdlp), [`SINGLEFILE_*`](https://archivebox.github.io/abx-plugins/#singlefile), [`SONIC_HOST`](https://archivebox.github.io/abx-plugins/#search_backend_sonic), etc.? They all live there now.
-
-### Shared core options that plugins fall back to
-
-A handful of *core* options (documented above on this page) act as the **fallback default** for every plugin that has a matching per-extractor override. If you set the core option, every plugin honors it; if you also set the plugin-specific override, that wins for just that one plugin.
-
-| Core option (this doc) | Plugin-level overrides (see [abx-plugins](https://archivebox.github.io/abx-plugins/)) |
-|---|---|
-| [`TIMEOUT`](#timeout) | [`WGET_TIMEOUT`](https://archivebox.github.io/abx-plugins/#wget), [`CHROME_TIMEOUT`](https://archivebox.github.io/abx-plugins/#chrome), [`YTDLP_TIMEOUT`](https://archivebox.github.io/abx-plugins/#ytdlp), [`SINGLEFILE_TIMEOUT`](https://archivebox.github.io/abx-plugins/#singlefile), [`TITLE_TIMEOUT`](https://archivebox.github.io/abx-plugins/#title), [`FAVICON_TIMEOUT`](https://archivebox.github.io/abx-plugins/#favicon), ... |
-| [`CHECK_SSL_VALIDITY`](#check_ssl_validity) | [`WGET_CHECK_SSL_VALIDITY`](https://archivebox.github.io/abx-plugins/#wget), [`YTDLP_CHECK_SSL_VALIDITY`](https://archivebox.github.io/abx-plugins/#ytdlp), [`GALLERYDL_CHECK_SSL_VALIDITY`](https://archivebox.github.io/abx-plugins/#gallerydl), [`CHROME_CHECK_SSL_VALIDITY`](https://archivebox.github.io/abx-plugins/#chrome), ... |
-| [`USER_AGENT`](#user_agent) | [`WGET_USER_AGENT`](https://archivebox.github.io/abx-plugins/#wget), [`CHROME_USER_AGENT`](https://archivebox.github.io/abx-plugins/#chrome), [`SINGLEFILE_USER_AGENT`](https://archivebox.github.io/abx-plugins/#singlefile), ... |
-| [`COOKIES_FILE`](#cookies_file) | [`WGET_COOKIES_FILE`](https://archivebox.github.io/abx-plugins/#wget), [`YTDLP_COOKIES_FILE`](https://archivebox.github.io/abx-plugins/#ytdlp), [`GALLERYDL_COOKIES_FILE`](https://archivebox.github.io/abx-plugins/#gallerydl), [`SINGLEFILE_COOKIES_FILE`](https://archivebox.github.io/abx-plugins/#singlefile), ... |
-| [`RESOLUTION`](#resolution) | [`SCREENSHOT_RESOLUTION`](https://archivebox.github.io/abx-plugins/#screenshot), [`PDF_RESOLUTION`](https://archivebox.github.io/abx-plugins/#pdf), [`CHROME_RESOLUTION`](https://archivebox.github.io/abx-plugins/#chrome) |
-| [`DEFAULT_PERSONA`](#default_persona) | per-plugin persona scoping (browser profile / cookie jar selection) |
-
-> [!TIP]
-> The resolution order for any plugin-tunable option is always:
-> **1.** `_` (explicit per-plugin override) →
-> **2.** the matching shared core option above →
-> **3.** the plugin's own hardcoded default.
->
-> So setting `TIMEOUT=120` once at the top of your `ArchiveBox.conf` raises the timeout for *every* extractor at once; setting `CHROME_TIMEOUT=300` on top of that lifts it further for just Chrome.
-
-### Listing & setting plugin options
-
-All plugin options can be set via the same three mechanisms as core options — env var, `ArchiveBox.conf`, or `archivebox config --set` — and inspected with `archivebox config`:
-
-```bash
-archivebox config # show every option (core + every installed plugin)
-archivebox config --get SCREENSHOT_RESOLUTION # read one value
-archivebox config --set SCREENSHOT_RESOLUTION=1920,1080
-archivebox config --search wget # search options by name/description
-```
-
-### Why is plugin config documented separately?
-
-Plugin schemas evolve on their own release cadence — new extractors ship between ArchiveBox releases, options are added/renamed as hooks revise, and pinning their docs to the core release schedule produced unavoidable drift. The per-plugin doc is auto-generated from each plugin's `config.json` schema at build time, so it never lags behind the code.
diff --git a/docs/Contents.rst b/docs/Contents.rst
deleted file mode 100644
index 2a577487..00000000
--- a/docs/Contents.rst
+++ /dev/null
@@ -1,82 +0,0 @@
-Contents
-########
-
-Overview
-########
-
-.. toctree::
- :maxdepth: 1
-
- Home.md
- README.md
-
-
-Getting Started
-###############
-
-.. toctree::
- :maxdepth: 1
-
- Quickstart.md
- Install.md
- Docker.md
- Configuration.md
- Security-Overview.md
-
-.. toctree::
- :maxdepth: 2
-
- Usage.md
-
-Guides
-######
-
-.. toctree::
- :maxdepth: 1
-
- Setting-Up-Storage.md
- Setting-up-Authentication.md
- Setting-up-Search.md
- Publishing-Your-Archive.md
- Scheduled-Archiving.md
- Chromium-Install.md
- Upgrading.md
- Upgrading-or-Merging-Archives.md
- Merging-Collections.md
- Troubleshooting.md
-
-Architecture
-############
-
-.. toctree::
- :maxdepth: 1
-
- ArchiveBox-Architecture-Diagrams.md
-
-
-API Reference
-#############
-
-.. toctree::
- :maxdepth: 3
-
- Filesystem
- SQL API
- REST API
- Python API
-
-Meta
-####
-
-.. toctree::
- :maxdepth: 1
-
- Roadmap.md
- Changelog.md
- Donations.md
-
-
-.. toctree::
- :maxdepth: 3
-
- Web-Archiving-Community.md
diff --git a/docs/Docker.md b/docs/Docker.md
deleted file mode 100644
index e2a739cc..00000000
--- a/docs/Docker.md
+++ /dev/null
@@ -1,281 +0,0 @@
-# Docker
-
-## Overview
-
-Running ArchiveBox with Docker allows you to manage it in a container without exposing it to the rest of your system. ArchiveBox generally works the same in Docker as it does outside Docker. You can even use `pip`-installed ArchiveBox and Docker ArchiveBox in tandem, as they both share the same data directory format.
-
-
-
-- [Overview](#Overview)
-- [Docker Compose](#docker-compose) ⭐️ (recommended)
- - [Setup](#setup)
- - [Upgrading](https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#upgrading-with-docker-compose-%EF%B8%8F)
- - [Usage](#usage)
- - [Accessing the data](#accessing-the-data)
- - [Configuration](#configuration)
-- [Plain Docker](#docker)
- - [Setup](#setup-1)
- - [Upgrading](https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#upgrading-with-plain-docker)
- - [Usage](#usage-1)
- - [Accessing the data](#accessing-the-data-1)
- - [Configuration](#configuration-1)
-
-
-
-**Official Docker Hub image: [`hub.docker.com/r/archivebox/archivebox`](https://hub.docker.com/r/archivebox/archivebox)**
-```bash
-docker pull archivebox/archivebox:latest
-```
-
-- [`Dockerfile`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/Dockerfile)
-- [`docker-compose.yml`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/docker-compose.yml)
-- [`archivebox-kubernetes.yml`](https://github.com/ArchiveBox/docker-archivebox/blob/master/archivebox.yml)
-
-Published [Docker tags](https://hub.docker.com/r/archivebox/archivebox/tags):
-- `:latest`, `:stable` (latest stable release, the default)
-- `:x.x` and `:x.x.x` for specific versions (e.g. `:0.7` or `:0.7.2`)
-- `:dev` for unstable alpha builds (breaks often, only for developers and willing beta testers)
-- `:sha-xxxxxxx` for builds of specific git commits (to test or pin specific PRs or commits)
-
-
-
-> [!IMPORTANT]
-> *Make sure Docker is **[installed](https://docs.docker.com/install/#supported-platforms)** and up-to-date before following any instructions below!* ➡️
-> To check installed version, run: `docker --version` (must be `>=17.04.0`)
-
-
-
-
-
-## Docker Compose
-
-
-
-### Setup
-
-A full [`docker-compose.yml`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/docker-compose.yml) file is provided with all the extras included.
-You can uncomment sections within it to enable extra features, or run the basic version as-is.
-
-
-```bash
-# create a folder to store your data (can be anywhere)
-mkdir -p ~/archivebox/data && cd ~/archivebox
-
-# download the compose file into the directory
-curl -fsSL 'https://docker-compose.archivebox.io' > docker-compose.yml
-# (shortcut for getting https://raw.githubusercontent.com/ArchiveBox/ArchiveBox/stable/docker-compose.yml)
-
-# initialize your collection and create an admin user for the Web UI (or set ADMIN_USERNAME/ADMIN_PASSWORD env vars)
-docker compose run archivebox init
-docker compose run archivebox manage createsuperuser
-```
-
-To use [Sonic](https://github.com/valeriansaliou/sonic) for improved full-text search, download this config & uncomment the sonic service in `docker-compose.yml`:
-```bash
-# download the sonic config file into your data folder (e.g. ~/archivebox)
-curl -fsSL 'https://raw.githubusercontent.com/ArchiveBox/ArchiveBox/dev/etc/sonic.cfg' > sonic.cfg
-
-# then uncomment the sonic-related sections in docker-compose.yml
-nano docker-compose.yml
-
-# to backfill any existing archive data into the search index, run:
-docker compose run archivebox update --index-only
-```
-
-
-
-### Upgrading
-
-See the wiki page on [Upgrading or Merging Archives: Upgrading with Docker Compose](https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#upgrading-with-docker-compose-%EF%B8%8F) for instructions. ➡️
-
-
-
-### Usage
-
-You can use `docker compose run archivebox [subcommand]` just like the non-Docker `archivebox [subcommand]` CLI.
-
-First, make sure you're `cd`'ed into the same folder as your `docker-compose.yml` file (e.g. `~/archivebox`):
-```bash
-docker compose run archivebox help
-```
-
-To add an individual URL, pass it in as an arg or via stdin:
-```bash
-docker compose run archivebox add 'https://example.com'
-# OR
-echo 'https://example.com' | docker compose run -T archivebox add
-```
-
-To add multiple URLs at once, pipe them in via stdin, or place them in a file inside `./data/sources` so that ArchiveBox can access it from within the container:
-```bash
-# pipe URLs in from a file outside Docker
-docker compose run -T archivebox add < ~/Downloads/example_urls.txt
-
-# OR ingest URLs from a file mounted inside Docker
-docker compose run archivebox add --depth=1 /data/sources/example_urls.txt
-
-# OR pipe in URLs from a remote source
-curl 'https://example.com/some/rss/feed.xml' | docker compose run archivebox add
-docker compose run archivebox add --depth=1 'https://example.com/some/rss/feed.xml'
-```
-
-The `--depth=1` flag tells ArchiveBox to look inside the provided source and archive all the URLs within:
-```bash
-# this archives just the RSS file itself (probably not what you want)
-docker compose run archivebox add 'https://example.com/some/feed.rss'
-
-# this archives the RSS feed file + all the URLs mentioned inside of it
-docker compose run archivebox add --depth=1 'https://example.com/some/feed.rss'
-```
-
-
-
-### Accessing the data
-
-The outputted archive data is stored in `data/` (relative to the project root), or whatever folder path you specified in the `docker-compose.yml` `volumes:` section. Make sure the `data/` folder on the host has permissions initially set to `777` so that the ArchiveBox command is able to set it to the specified `OUTPUT_PERMISSIONS` config setting on the first run.
-
-To access the results directly via the filesystem, open `./data/archive//index.html` (timestamp is shown in output of previous command).
-
-Alternatively, to use the web UI, start the server with:
-```bash
-docker compose up # add -d to run in the background
-```
-
-Then open [`http://127.0.0.1:8000`](http://127.0.0.1:8000).
-
-
-
-### Configuration
-
-ArchiveBox running with `docker compose` accepts all the same config options as other ArchiveBox distributions, see the full list of options available on the [[Configuration]] page.
-
-The recommended way configure ArchiveBox in Docker Compose is using `archivebox config --set ...` or by editing `ArchiveBox.conf`.
-```bash
-docker compose run archivebox config --set MEDIA_MAX_SIZE=750mb
-# OR
-echo 'MAX_MEDIA_SIZE=750mb' >> ./data/ArchiveBox.conf
-```
-This will apply the config to all containers or archivebox instances that access the collection.
-
-If you're only running one container, or if you want to scope config options to only apply to a particular container, you can set them in that container's `environment:` section:
-
-```yaml
-...
-
-services:
- archivebox:
- ...
- environment:
- - USE_COLOR=False
- - SHOW_PROGRESS=False
- - CHECK_SSL_VALIDITY=False
- - RESOLUTION=1900,1820
- - MEDIA_TIMEOUT=512000
- ...
-```
-
-You can also specify an env file via CLI when running compose using `docker compose --env-file=/path/to/config.env ...` although you must specify the variables in the `environment:` section that you want to have passed down to the ArchiveBox container from the passed env file.
-
-If you want to access your archive server with HTTPS, put a reverse proxy like Nginx or Caddy in front of `http://127.0.0.1:8000` to do SSL termination. Here is an example [ArchiveBox nginx container](https://github.com/ArchiveBox/ArchiveBox/blob/dev/docker-compose.yml#:~:text=nginx) + [`nginx.conf`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/etc/nginx.conf) that you can modify to add your preferred TLS settings.
-
-
-
----
-
-
-
-## Docker
-
-
-
-### Setup
-
-Fetch and run the ArchiveBox Docker image to create your initial archive.
-
-```bash
-docker pull archivebox/archivebox
-
-mkdkir -p ~/archivebox/data && cd ~/archivebox/data
-docker run -it -v $PWD:/data archivebox/archivebox init --setup
-```
-
-*(You can create a collection in any directory you want, `~/archivebox/data` is just used as an example here)*
-
-If you encounter permissions issues, you may need configure user/group ownership explicitly with [`PUID`/`PGID`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#puid--pgid).
-
-
-
-### Upgrading
-
-See the wiki page on [Upgrading or Merging Archives: Upgrading with plain Docker](https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#upgrading-with-plain-docker) for instructions. ➡️
-
-
-
-### Usage
-
-The Docker CLI `docker run ... archivebox/archivebox [subcommand]` works just like the non-Docker `archivebox [subcommand]` CLI.
-
-First, make sure you're `cd`'ed into your collection data folder (e.g. `~/archivebox/data`).
-
-```bash
-docker run -it -v $PWD:/data archivebox/archivebox help
-```
-
-To add a single URL, pass it as an arg or pipe it in via stdin:
-```bash
-docker run -it -v $PWD:/data archivebox/archivebox add 'https://example.com'
-# OR
-echo 'https://example.com' | docker run -i -v $PWD:/data archivebox/archivebox add
-```
-
-To archive multiple URLs at once, pass text containing URLs in via stdin:
-```bash
-docker run -i -v $PWD:/data archivebox/archivebox add < urls.txt
-# OR
-curl 'https://example.com/some/rss/feed.xml' | docker run -i -v $PWD:/data archivebox/archivebox add
-```
-
-You can also use the `--depth=1` flag to tell ArchiveBox to recursively archive the URLs within a provided source.
-```bash
-docker run -it -v $PWD:/data archivebox/archivebox add --depth=1 'https://example.com/some/rss/feed.xml'
-```
-
-
-
-### Accessing the data
-
-The `docker run` `-v /path/on/host:/path/inside/container` flag specifies where your data dir lives on the host.
-
-For example to use a folder on an external USB drive (instead of the current directory `$PWD` or `~/archivebox/data`):
-```bash
-docker run -it -v /media/USB-DRIVE/archivebox/data:/data archivebox/archivebox ...
-```
-
-Then to view your data, you can look in the folder on the host `/media/USB-DRIVE/archivebox/data`, or use the Web UI:
-```bash
-docker run -it -v /media/USB_DRIVE/archivebox/data:/data -p 8000:8000 archivebox/archivebox
-# then open https://127.0.0.1:8000
-```
-
-
-
-### Configuration
-
-The easiest way is to use `archivebox config --set KEY=value` or edit `./ArchiveBox.conf` (in your collection dir).
-
-For example, this sets `MEDIA_TIMEOUT=120` as a persistent setting for the collection:
-```bash
-docker run -it -v $PWD:/data archivebox/archivebox config --set MEDIA_TIMEOUT=120
-# OR
-echo 'MEDIA_TIMEOUT=120' >> ./ArchiveBox.conf
-```
-
-ArchiveBox in Docker also accepts config as environment variables, see more on the [[Configuration]] page.
-
-For example, this applies `FETCH_SCREENSHOT=False` to a single run (without persisting for other runs):
-```bash
-docker run -it -v $PWD:/data -e FETCH_SCREENSHOT=False archivebox/archivebox add 'https://example.com'
-# OR
-echo 'FETCH_SCREENSHOT=False' >> ./.env
-docker run ... --env-file=./.env archivebox/archivebox ...
-```
diff --git a/docs/Donations.md b/docs/Donations.md
deleted file mode 100644
index 7066430c..00000000
--- a/docs/Donations.md
+++ /dev/null
@@ -1,23 +0,0 @@
-## Supporting Development
-
-*ArchiveBox operates as a US 501(c)(3) nonprofit, donations are tax-deductible.*
-(ArchiveBox is fiscally sponsored by HCB EIN: 81-2908499)
-
-
-**💬 [Hire us](https://docs.sweeting.me/s/archivebox-consulting-services)** to help your NGO/org with archiving, or donate to directly support ArchiveBox open-source development.
-
-- ⭐️ **Direct donation via our `501(c)(3)` non-profit:** https://hcb.hackclub.com/donations/start/archivebox
-
-- ⭐️ **Github Sponsors:** https://github.com/sponsors/pirate
-
-- 👕 **Buy some swag:** https://archivebox-shop.fourthwall.com/
-
-- **Patreon:** https://www.patreon.com/theSquashSH
-
-- **Paypal:** https://paypal.me/NicholasSweeting
-
-- **Crypto:** *[Contact me to request wallet address...](https://zulip.archivebox.io/#narrow/dm/284-Nick-Sweeting)*
-
-
-
-If you have any questions or want to partner with this project, contact me at: `donations-hello` `@` `archivebox` `.` `io`.
diff --git a/docs/Home.md b/docs/Home.md
deleted file mode 100644
index f0c0ec44..00000000
--- a/docs/Home.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# ArchiveBox Documentation
-
-
-
-
-
-
-
-**📖 Use the sidebar on the right to browse documentation topics ➡️**
-
-(Expand the `Pages` section to 🔍 Search for a specific term)
-
-
-
-**📚 If you need help or have a question, you can:**
- - 💬 Chat with us on our [Public Zulip Server](https://zulip.archivebox.io)
- - 🐞 Open an [issue or feature request](https://github.com/ArchiveBox/ArchiveBox/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) in our bug tracker
- - 💠 Reach out to me on Twitter [@ArchiveBoxApp](https://twitter.com/ArchiveBoxApp) or [@theSquashSH](https://twitter.com/theSquashSH)
-
----
-
-
-
-
-
-
-
-
Readme |
Demo |
Quickstart |
Usage |
Community
-
-
-
-
-**🏛️ [Need professional support? Hire Us](https://docs.sweeting.me/s/archivebox-consulting-services) 💬**
-
-
-
-**✨ Or donate to support open-source development ✨**
-
-[](https://hcb.hackclub.com/donations/start/archivebox) [](https://github.com/sponsors/pirate)
-
-
-
ArchiveBox operates as a US 501(c)(3) nonprofit FSP, donations are tax-deductible. (fiscally sponsored by HCB EIN: 81-2908499)
-
-
The name ArchiveBox™️ is trademarked in the US and you can find the ArchiveBox brand kit here.
-
diff --git a/docs/Install.md b/docs/Install.md
deleted file mode 100644
index 76c83fc7..00000000
--- a/docs/Install.md
+++ /dev/null
@@ -1,311 +0,0 @@
-# Install
-
-ArchiveBox is primarily distributed as a Python package via `pip`, but it also depends on some system packages that can be installed manually or automatically with Docker. It usually takes less than ~10min to get ArchiveBox set up and running.
-
-
-
-
-
- - *[Supported Systems](#supported-systems)*
- - Install Instructions
- - **[Option A. Docker / Docker Compose ⭐️](#option-a-docker--docker-compose-setup-%EF%B8%8F)**
- - [Option B. Automatic Setup Script](#option-b-automatic-setup-script)
- - [Option C. System Package Manager Setup](#option-c-bare-metal-setup)
- - *[Upgrading ArchiveBox to a new version](#upgrading-archivebox-to-a-new-version)*
- - *[Next Steps](#next-steps)*
-
-
-## Supported Systems
-
-
-
-
-
-**CPU Architectures:** `amd64` (`x86_64`), `arm64` (`aarch64`), `arm7`
-*(Including 64-bit Intel/AMD, M1/M2/etc. Macs, Raspberry Pi >= 3)*
-
-* [**macOS:**](#macos) >=10.12 (with `pip`)
-* [**Linux:**](#ubuntudebian) Ubuntu (>= 18.04), Debian (>= 10), etc. (with `apt`)
-* [**BSD:**](#bsd) FreeBSD, OpenBSD, NetBSD etc (with `pkg`)
-
-Other systems are not officially supported but may work with degraded functionality:
-
-
-
-
- * **Windows:** Via [[Docker]], Docker in WSL2, or WSL2 without Docker (not recommended)
- * [Other UNIX systems:](https://github.com/ArchiveBox/ArchiveBox#-package-manager-setup) Arch, Nix, Guix, Fedora, SUSE, Arch, CentOS, etc.
-
-Note: On `arm7` the `playwright` package is not available, so `chromium` must be installed manually if needed.
-
-
-
-You will also need at least 500MB of RAM (bare minimum), 2GB or greater is recommended. You may be able to reduce the RAM requirements if you disable all the chrome-based archiving methods with `USE_CHROME=False`.
-
-It's also recommended to use a filesystem with compression and/or [deduplication](https://www.ixsystems.com/blog/ixsystems-and-klara-systems-celebrate-valentines-day-with-a-heartfelt-donation-of-fast-dedupe-to-openzfs-and-truenas/) (e.g. [ZFS](https://openzfs.github.io/openzfs-docs/Getting%20Started/index.html) or BTRFS) for maximum efficiency.
-
-
-
----
-
-
-
-## Option A. Docker / Docker Compose Setup ⭐️
-
-*Docker Compose is the recommended way to get ArchiveBox, as it includes all the extras out-of-the-box and provides the best security and upgrade UX.*
-
-1. If you don't already have docker installed, follow the official instructions to get Docker on Linux, macOS, or Windows:
- https://docs.docker.com/install/#supported-platforms ➡️
-
-2. Then follow the [Quickstart](https://github.com/ArchiveBox/ArchiveBox#quickstart) guide and read the [[Docker]] wiki page for next steps. ➡️
-
-> You can also run Dockerized ArchiveBox using [UNRAID/TrueNAS/Proxmox/etc.](https://github.com/ArchiveBox/ArchiveBox#-other-options) or [Kubernetes](https://github.com/ArchiveBox/docker-archivebox/blob/master/archivebox.yml).
-
-**More info:**
-- [`Dockerfile`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/Dockerfile)
-- [`docker-compose.yml`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/docker-compose.yml)
-- [`archivebox-kubernetes.yml`](https://github.com/ArchiveBox/docker-archivebox/blob/master/archivebox.yml)
-- [ArchiveBox Docker Quickstart](https://github.com/ArchiveBox/ArchiveBox#quickstart) + [Usage](https://github.com/ArchiveBox/ArchiveBox/wiki/Docker) + [Configuration](https://github.com/ArchiveBox/ArchiveBox/wiki/Docker#configuration) + [Upgrading](https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives) documentation
-
-
-
----
-
-
-
-
-## Option B. Automatic Setup Script
-
-If you're on Linux with `apt` or FreeBSD with `pkg` there is an optional auto-setup script provided.
-
-*(or scroll further down for manual install instructions)*
-
-```bash
-curl -fsSL 'https://get.archivebox.io' | bash
-# shortcut to run https://raw.githubusercontent.com/ArchiveBox/ArchiveBox/stable/bin/setup.sh
-```
-The script explains what it installs beforehand, and will prompt for user confirmation before making any changes to your system. The script uses Docker if already installed, but you can decline and it will attempt to auto-install everything using `apt`/`brew`/`pkg` + `pip` instead.
-
-Note: The script will currently still attempt to install via `brew` on macOS. This will fail as ArchiveBox is no longer distributed as a Homebrew formula.
-
-
-
-After running the setup script, continue with the [Quickstart](https://github.com/ArchiveBox/ArchiveBox#%EF%B8%8F-next-steps) guide... ➡️
-
-> *See here for our thoughts on the [inherent limitations of `curl | sh`](https://docs.monadical.com/s/against-curl-sh) as an install method...*
-
-
-
----
-
-
-
-## Option C. Bare Metal Setup
-
-If you'd rather not use [Docker](https://github.com/ArchiveBox/ArchiveBox#%EF%B8%8F-easy-setup) or our [auto-install script](https://github.com/ArchiveBox/ArchiveBox#%EF%B8%8F-easy-setup), you can follow these manual setup instructions to install ArchiveBox and its dependencies using `pip` & your system package manager of choice (e.g. `apt`, `brew`, `pkg`, `nix`, etc.).
-
-See our [Dependencies](https://github.com/ArchiveBox/ArchiveBox#dependencies) documentation to see the full list of dependencies and how they're used. Not all the dependencies are required for all modes. If you disable some archive methods you can skip installing those dependencies, for example, if you set `FETCH_MEDIA=False` you don't need to install `yt-dlp`, and if you set `FETCH_[PDF,SCREENSHOT,DOM]=False` you don't need `chromium`.
-
-
-
-**More info:**
- - For help installing these, see the [Manual Setup](#manual-setup), [[Troubleshooting]] and [[Chromium Install]] pages.
- - To use specific binaries for dependencies, see the [Configuration: Dependencies](Configuration#dependency-options) page.
- - To disable unwanted dependencies, see the [Configuration: Archive Method Toggles](Configuration#archive-method-toggles) page.
-
-
-
-
-
-### 1. Install base system dependencies needed for your OS
-
-*Be aware, you'll need to keep all these packages up-to-date yourself over time!*
-
-
-
-#### macOS
-
-Make sure you have [Homebrew](https://brew.sh/) installed first.
-
-```bash
-# Install ArchiveBox's dependencies manually (instead of using the all-in-one brew package)
-brew install python3 node git wget curl ffmpeg yt-dlp ripgrep sonic
-pip install archivebox
-archivebox install
-
-# Optional: get FFMPEG with the AAC addon
-# brew tap homebrew-ffmpeg/ffmpeg
-# brew uninstall ffmpeg; brew install homebrew-ffmpeg/ffmpeg/ffmpeg --with-fdk-aac
-
-# Optional: get Chromium with brew (not needed if you already have /Applications/{Google Chrome,Chromium}.app)
-# brew install --cask chromium
-```
-
-
-
-#### Ubuntu/Debian-based Systems
-
-Make sure `apt` and `dpkg` are available on your system.
-
-```bash
-# add the nodejs sources to your apt lists (optional, otherwise may use older node)
-curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
-
-# Install base system dependencies manually (check ArchiveBox/Dockerfile for more if needed)
-sudo apt install python3 python3-pip python3-minimal nodejs libatomic1 zlib1g-dev libssl-dev libldap2-dev libsasl2-dev python3-ldap python3-msgpack python3-mutagen python3-regex python3-pycryptodome procps dnsutils wget curl git yt-dlp ffmpeg ripgrep
-sudo apt install python3-setuptools # or: python3-distutils on older systems
-
-# Optional: get Chromium with pip (skip if you already have chromium-browser/google-chrome installed and in your $PATH)
-# pip install --upgrade playwright
-# playwright install --with-deps chromium
-# OR: get chromium and manually with apt (not recommended, often out-of-date)
-# sudo apt install chromium fontconfig fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-symbola fonts-noto fonts-freefont-ttf
-```
-
-
-
-
-#### FreeBSD
-
-```bash
-sudo pkg install python git wget curl youtube_dl ripgrep py311-pip py311-sqlite3 npm ffmpeg
-sudo pkg install chromium
-
-# or for older versions:
-# sudo pkg install python node wget curl git yt-dlp ffmpeg ripgrep chromium-browser
-```
-
-#### OpenBSD
-
-```bash
-sudo pkg_add python3 node wget git curl yt-dlp ffmpeg ripgrep chromium
-```
-
-#### Arch Linux / Nix / Guix / etc. Other OSs
-
-See the [Quickstart](https://github.com/ArchiveBox/ArchiveBox#-package-manager-setup) instructions for other operating systems and release channels. ➡️
-
-
-
-
-
-
-### 2. Install the Python dependencies using `pip`
-
-It's recommended to `pip`-install ArchiveBox even if you already installed `archivebox` with one of our official `apt`/`pkg` packages above (sometimes the `pip` version is newer). This step also ensures you have the latest `yt-dlp` and `playwright` versions.
-
-```bash
-# get the latest version of archivebox from PyPI
-pip install --upgrade --ignore-installed archivebox[ldap,sonic]
-
-# if you see errors about ldap, install the C++ build tools + ldap headers and retry (only needed on some OSs + if you want ldap)
-# apt install build-essensial python3-ldap
-```
-
-
-
-### 3. Install the JS dependencies using `archivebox setup`
-
-Finish installing the runtime JS dependencies that live inside your collection data dir (e.g. readability, singlefile, mercury).
-```bash
-# create a new empty folder anywhere to hold your collection, and cd into it
-mkdir -p ~/archivebox/data && cd ~/archivebox/data
-
-# instantiate the directory as an archivebox collection dir
-archivebox init
-
-# auto-install all the runtime JS dependencies inside ./node_modules
-archivebox setup
-# under the hood, this does:
-# - installs npm dependencies: singlefile, readability, puppeteer, etc.
-# - installs pip dependencies: yt-dlp, playwright, etc.
-# - checks for / installs system dependencies: curl, wget, etc
-# if you see "permission denied" errors, run 'sudo archivebox setup'
-
-# ✅ see a final detailed breakdown of all the installed dependencies and commands available
-archivebox version
-archivebox help
-```
-
-
-
-### Troubleshooting
-
-Make sure the `pip`-installed version of `archivebox` is available in your `$PATH`.
-```bash
-pip show archivebox # show info about the pip-installed version of archivebox
-
-echo $PATH # show the directories your system is searching for binaries
-which -a archivebox # show all installed archivebox binaries available
-which archivebox # show which archivebox binary is being called
-
-cd ~/archivebox/data
-archivebox version # ⭐️ show lots of useful info about installed dependencies and more
-archivebox status
-archivebox help
-```
-(ensure the version shown is the most recent available from [Releases](https://github.com/ArchiveBox/ArchiveBox/releases))
-
-Make sure to run `archivebox` **as an unprivileged user** (i.e. without `sudo` / not logged in as `root`).
-Make sure to run all commands, including `archivebox version`, `archivebox help`, etc. **inside a data directory** (or a new empty dir that will become a data dir).
-
-If you have issues getting Chromium / Google Chrome or other dependencies working with ArchiveBox, see the [[Chromium Install]] and [[Troubleshooting]] pages for more detailed instructions.
-
-
-
-### Next Steps: Add some URLs to archive and try out CLI / Web UI
-
-
-For guides on how to import URLs from different sources into ArchiveBox, check out [Input Formats](https://github.com/ArchiveBox/ArchiveBox#input-formats) and [Preparing URLs](https://github.com/ArchiveBox/ArchiveBox/wiki/Quickstart#2-get-your-list-of-urls-to-archive). ➡️
-
-```bash
-cd ~/archivebox/data
-```
-```bash
-# feed in your URLs to start archiving!
-archivebox add --help
-archivebox add < ~/Downloads/bookmarks_export.html
-```
-```bash
-# inspect the newly added Snapshots via the CLI
-archivebox list
-archivebox status
-```
-```bash
-# OR start the webserver and view them in the Web UI
-archivebox server 0.0.0.0:8000
-open http://localhost:8000
-```
-See our [[Usage]] Wiki documentation page for more examples.
-
-
-
-### Next Steps: *Upgrading Archivebox to a new version*
-
-Make sure all apt/brew/pkg/etc. dependencies from above are installed & up-to-date first.
-
-```bash
-# get the latest archivebox version from PyPI
-pip install --upgrade --ignore-installed archivebox
-
-# run init inside any data directories to migrate the index to the latest version
-cd ~/archivebox/data
-archivebox setup # update runtime dependencies to latest versions
-archivebox init # update collection index & apply any migrations
-```
-
-Check our more detailed [Upgrading](https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives) documentation and [Release Notes](https://github.com/ArchiveBox/ArchiveBox/releases) if you run into any problems. ➡️
-
-
-
----
-
-
-
-### Further Reading
-
- - Read [[Usage]] to learn how to use the ArchiveBox CLI and HTML output
- - Read [[Configuration]] to learn about the various archive method options
- - Read [[Scheduled Archiving]] to learn how to set up automatic daily archiving
- - Read [[Publishing Your Archive]] if you want to host your archive for others to access online
- - Read [[Troubleshooting]] if you encounter any problems
diff --git a/docs/Makefile b/docs/Makefile
deleted file mode 100644
index 51285967..00000000
--- a/docs/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# Minimal makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-SOURCEDIR = .
-BUILDDIR = _build
-
-# Put it first so that "make" without argument is like "make help".
-help:
- @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(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 $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/Merging-Collections.md b/docs/Merging-Collections.md
deleted file mode 100644
index 7ec5423a..00000000
--- a/docs/Merging-Collections.md
+++ /dev/null
@@ -1,124 +0,0 @@
-# Merging Collections
-
-Two or more existing ArchiveBox collection dirs can be merged together by simply combining the contents of `archive/*` and re-running `archivebox init` to pull the new Snapshots into the index.
-
-> [!WARNING]
-> Snapshot folders are identified by their timestamp (in milliseconds), this is normally not a problem for archives collected on one machine, but when merging archives from two different instances that ran at the same time it means there is a small chance of conflicts. Check the contents of `archive/` before merging, and backup any directories that may conflict before proceeding.
-
-1. Upgrade both old collections to the most recent ArchiveBox version (following instructions above)
- ```bash
- pip install --upgrade archivebox # or follow instructions above for upgrading w/ Docker
-
- cd /path/to/archivebox1/data
- archivebox init
- archivebox status
-
- cd /path/to/archivebox2/data
- archivebox init
- archivebox status
-
- # ... repeat the same for each collection if merging more than two
- ```
-
-2. Create a new empty archivebox collection in a new folder somewhere, this will hold the new merged collection
- ```bash
- mkdir /path/to/archivebox_new
- cd /path/to/archivebox_new
- archivebox init
- ```
-
-3. Copy everything under `./archive/*` in each old collection into the new collection's `./archive/` folder
- ```bash
- rsync --archive --info=progress2 /path/to/archivebox1/data/archive/ /path/to/archivebox_new/data/archive
- rsync --archive --info=progress2 /path/to/archivebox2/data/archive/ /path/to/archivebox_new/data/archive
- # ...repeat the same for each collection if merging more than two
- ```
-
-4. Run `archivebox init` in the new merged collection to regenerate the new index
- ```bash
- cd /path/to/archivebox_new
- archivebox init
- ```
-
-5. The new collection should now contain all the entries from the old collections combined
- ```bash
- cd /path/to/archivebox_new
- archivebox status
-
- # optionally force an update of the snapshot index files (normally done lazily)
- archivebox update --index-only
- ```
- For more information about why Snapshot index files are usually updated lazily, see: https://github.com/ArchiveBox/ArchiveBox/issues/962
-
-After you've confirmed your Snapshots are present in the new index, the old `index.sqlite3`, `index.json`, `index.html`, etc. main index files from the old archives can be safely deleted. You can optionally merge the contents of `ArchiveBox.conf` (your ArchiveBox config options), `sources/` (copies of all URLs imported in their original format), `logs/` (ArchiveBox error logs and debug info), and other root-level items yourself if that data is important to you.
-
----
-
-## Modify the ArchiveBox SQLite3 DB directly
-
-If you need to automate changes to the ArchiveBox DB (for example adding a User from an Ansible script), you can modify the SQLite3 DB directly.
-
-Note, this is often unnecessary for modifying ArchiveBox on a host that doesn't have the CLI installed, as you can also copy the `index.sqlite3` to a local machine that has it, do the modifications locally, then copy the modified db back into place on the host. (Docker/CLI/GUI/Web ArchiveBox all share the same DB schema/format)
-
-```bash
-cd ~/archivebox/data # cd into your archivebox collection dir
-sqlite3 index.sqlite3 # open the db with sqlite3 shell
-```
-
-#### Example: Modifying an existing user's email
-
-```sql
-UPDATE auth_user
-SET email = 'someNewEmail@example.com', is_superuser = 1
-WHERE username = 'someUsernameHere';
-```
-
-#### Example: Adding a new user with a hashed password
-
-*Note: this is just an example to demonstrate direct database usage. If you are trying to create a user on initial setup, use the [`ADMIN_USERNAME` & `ADMIN_PASSWORD`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#admin_username--admin_password) configuration options.*
-
-1. First, generate the hashed password in a Python shell using Django's `make_password` function.
-
-This can be done on any machine with Python 3+, it doesn't have to have ArchiveBox installed.
- ```bash
-pip3 install django==3.1.3 # install the django version used by ArchiveBox
-python3 # open any python shell with django available, doesn't have to be the archivebox shell
-```
-```python3
->>> from django.contrib.auth.hashers import make_password
->>> make_password('somePasswordHere', 'someSaltHere', 'pbkdf2_sha256') # choose a password and a salt (can be anything 12 chars long)
-'pbkdf2_sha256$216000$someSaltHere$styW1Uoy8SHp3zbSwGRp20C9mPjOHVjP9rl5a8/UOVE='
-```
-2. Use the generated hashed password to insert a new User row in the SQLite3 database directly:
- ```bash
-cd ~/archivebox/data # cd into your archivebox collection dir
-sqlite3 index.sqlite3 # open the db with sqlite3 shell
-```
-```sql
-INSERT INTO "auth_user" ("password", "last_login", "is_superuser", "username", "first_name", "last_name", "email", "is_staff", "is_active", "date_joined")
-VALUES ('pbkdf2_sha256$216000$someSaltHere$+2beZufc3JUXnmn0tG+2peJEBh7MjxPYmT3YfIFzEl0=', NULL, 0, 'someUsername', '', '', 'someEmail@example.com', 0, 1, '2022-03-22 23:34:02.333042')
-```
- Replace the values above with the desired username, email, and password hash from python output^.
-
-3. Log in using the new generated user to confirm it works
- https://localhost:8000/admin/login/ user: `someUsername` pass:`somePasswordHere`
-
-More info:
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#python-shell-usage
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#sql-shell-usage
-
----
-
-## Database Troubleshooting
-
-See here [Troubleshooting: Database](https://github.com/ArchiveBox/ArchiveBox/wiki/Troubleshooting#database)...
-
----
-
-## Related Documents
-
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#disk-layout
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#large-archives
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#output-folder
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#python-shell-usage
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#sql-shell-usage
diff --git a/docs/Publishing-Your-Archive.md b/docs/Publishing-Your-Archive.md
deleted file mode 100644
index 125abbc3..00000000
--- a/docs/Publishing-Your-Archive.md
+++ /dev/null
@@ -1,130 +0,0 @@
-# Publishing Your Archive
-
-There are two ways to publish your archive: using the `archivebox server` or by exporting and hosting it as static HTML.
-
-
-
-## 1. Use the built-in web server
-
-```bash
-# set the permissions depending on how public/locked down you want it to be
-archivebox config --set PUBLIC_INDEX=True
-archivebox config --set PUBLIC_SNAPSHOTS=True
-archivebox config --set PUBLIC_ADD_VIEW=True
-
-# create an admin username and password for yourself
-archivebox manage createsuperuser
-
-# then start the webserver and open the web UI in your browser
-archivebox server 0.0.0.0:8000
-open http://127.0.0.1:8000
-```
-
-This server is enabled out-of-the-box if you're using `docker-compose` to run ArchiveBox,
-and there is a commented-out example nginx config with SSL set up as well. If hosting publicly, it's essential to place an SSL termination server in front of ArchiveBox (e.g. [`traefik`](https://github.com/traefik/traefik), [`caddy`](https://caddyserver.com/docs/automatic-https#activation), or [`cloudflared`](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/)),
-
-> [!TIP]
-> Advanced: You can use nginx to serve the static `/archive/` dir directly from the filesystem to increase performance.
-> To protect the `/admin/` dashboard, it should ideally be served from a [different domain](#security-concerns) using redirects.
-
-
-
-## 2. Export and host it as static HTML
-
-```bash
-archivebox list --html --with-headers > index.html
-archivebox list --json --with-headers > index.json
-
-# then upload the entire output folder containing index.html and archive/ somewhere
-# e.g. github pages or another static hosting provider
-
-# you can also serve it with the simple python HTTP server
-python3 -m http.server --bind 0.0.0.0 --directory . 8000
-open http://127.0.0.1:8000
-```
-
-Here's a sample nginx configuration that works to serve your static archive folder:
-
-```nginx
-location / {
- alias /path/to/your/ArchiveBox/data/;
- index index.html;
- autoindex on;
- try_files $uri $uri/ =404;
-}
-```
-
-Make sure you're not running any content as CGI or PHP, you only want to serve static files!
-
-Urls look like: `https://demo.archivebox.io/archive/1493350273/en.wikipedia.org/wiki/Dining_philosophers_problem.html`
-
-
-
----
-
-
-
-## Security Concerns
-
-> [!CAUTION]
-> Re-hosting untrusted archived content on a domain can potentially compromise *all apps on that domain*!
-> (including other subdomains)
-
-Make sure you thoroughly understand the dangers of [hosting untrusted HTML/JS/CSS that may be captured during archiving](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy), and how viewing it can enable [CSRF attacks](https://en.wikipedia.org/wiki/Cross-site_request_forgery) across all apps on the same domain. If a logged-in user happens to visit an archived page with malicious Javascript embedded, it would allow the JS to hijack any cookies on the domain and pretend to be them, potentially exfiltrating or modifying other Snapshots/data on your server.
-
-(This is why we don't support serving ArchiveBox from a subdirectory like `myapps.example.com/archivebox/`, it's too dangerous to share domains)
-
-The industry standard approach is to use a separate domain for untrusted content, for example Github uses `githubusercontent.com` and Google uses `googleusercontent.com` for all user-uploaded files. If hosting ArchiveBox publicly, do the same and keep it on an isolated domain in order to mitigate potential damage of leaked cookies, CORS, and CSRF attack.
-
-### Protecting the Admin Dashboard
-
-To protect the Admin dashboard, it's also recommended to serve all content under `/archive/` on a separate domain from `/admin/`. We do this on our servers using a simple redirect rule in nginx/cloudflare like so:
-
-- https://demo.archivebox.io: only serves `/`, redirects `/archive/*` to `demo-static.`
-- https://demo-static.archivebox.io: only serves `/archive/`, redirects everything else to `demo.`
-
-
-
-> Note: This is still recommended, but less critical if your `/archive/` folder does not contain any archived JS (e.g. if you [set `SAVE_WGET=False` and `SAVE_DOM=False`](https://github.com/ArchiveBox/ArchiveBox#security-risks-of-viewing-archived-js)).
-
-More info:
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#publishing
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#%EF%B8%8F-things-to-watch-out-for-%EF%B8%8F
-
-
-
----
-
-
-
-## Copyright Concerns
-
-> [!WARNING]
-> Be aware that some sites you archive may not allow you to rehost their content publicly for copyright reasons, it's up to you to host responsibly and respond to takedown requests appropriately based on the laws in your jurisdiction.
-
-Archiving for personal backups, research, and some other use-cases are covered by [fair use copyright exemptions](https://guides.library.oregonstate.edu/copyright/libraries) in the USA, but if your archive can deprive the original author of revenue (e.g. if you rehost it for profit), then your use case might no longer be covered and you have to respond to DMCA takedown notices.
-
-**As a general rule of thumb:**
-
-- Copies cannot be made for commercial purposes
-- The copying cannot be systematic (e.g., to replace subscriptions)
-- All copies made must include a notice stating that the materials may be protected under copyright.
-
-Please modify the [`FOOTER_INFO`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#footer_info) config variable to add your contact info to the footer of your index.
-
-Note: ArchiveBox prevents search engines from indexing your archives using [`/robots.txt`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/templates/static/robots.txt#L2) by default. It's not recommended to [disable](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#custom_templates_dir) this as it often leads to a flood of automated takedown requests and abuse reports to your hosting provider (from anti-piracy bots that scan for cloned copyrighted content via search engines).
-
-*Keep in mind individuals, companies, schools, and libraries all have different copyright exemptions in different countries. Double check the specific laws for your situation in your own jurisdiction!*
-
-#### Further Reading: USA Copyright Law & Fair Use Exemptions
-
-- https://www.copyright.gov/title17/
-- https://help.archive.org/help/rights/
-- https://blog.archive.org/2024/03/01/fair-use-in-action-at-the-internet-archive/
-- https://www.lib.ncsu.edu/workshops/understanding-copyright-and-fair-use-archival-research
-- https://libguides.colorado.edu/c.php?g=1154758&p=8428124
-- https://fairuse.stanford.edu/2003/11/10/digital_preservation_and_copyr/
-- https://guides.library.oregonstate.edu/copyright/libraries
-- https://www.clir.org/pubs/reports/pub112/body/
-- https://github.com/pirate/internet-archiving-talk
diff --git a/docs/Quickstart.md b/docs/Quickstart.md
deleted file mode 100644
index 7b208ba3..00000000
--- a/docs/Quickstart.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# Quickstart
-
-
-
-
-
-▶️ *It only takes about 5 minutes to get up and running with ArchiveBox.*
-
-ArchiveBox [officially supports](https://github.com/ArchiveBox/ArchiveBox/wiki/Install#supported-systems) **macOS**, **Ubuntu/Debian**, and **BSD**, but likely runs on many other systems. You can run it on any system that supports **Docker** and/or Python. Windows *is not supported* unless you run it inside Docker Desktop, Docker in WSL2, or WSL2.
-
-For more detailed Docker and Docker Compose-specific instructions, see the [[Docker]] page.
-
----
-
-## 1. Set up ArchiveBox
-
-Follow the [README Instructions](https://github.com/ArchiveBox/ArchiveBox#quickstart) for your platform to get archivebox set up.
-
-## 2. Get your list of URLs to archive
-
-Follow the links here to find instructions for exporting a list of URLs from each service.
-
- - [Pocket](https://github.com/ArchiveBox/pocket-exporter)
- - [Pinboard](https://pinboard.in/export/)
- - [Instapaper](https://instapaper.zendesk.com/hc/en-us/articles/30080578815245-Import-export-content-from-into-Instapaper)
- - [Reddit Saved Posts](https://github.com/csu/export-saved-reddit)
- - [Shaarli](https://www.mypersonnaldata.eu/shaarli/doc/Backup,-restore,-import-and-export.html#export-links-as)
- - [Unmark.it](http://help.unmark.it/import-export)
- - [Wallabag](https://doc.wallabag.org/en/user/import/wallabagv2.html)
- - [Chrome Bookmarks](https://support.google.com/chrome/answer/96816?hl=en)
- - [Firefox Bookmarks](https://support.mozilla.org/en-US/kb/export-firefox-bookmarks-to-backup-or-transfer)
- - [Safari Bookmarks](http://imgur.zervice.io/AtcvUZA.png)
- - [Opera Bookmarks](http://help.opera.com/Windows/12.10/en/importexport.html)
- - [Internet Explorer Bookmarks](https://support.microsoft.com/en-us/help/211089/how-to-import-and-export-the-internet-explorer-favorites-folder-to-a-32-bit-version-of-windows)
- - Chrome History: `./bin/export_browser_history.sh --chrome`
- - Firefox History: `./bin/export_browser_history.sh --firefox`
- - Safari History: `./bin/export_browser_history.sh --safari`
- - Other File or URL: (e.g. RSS feed url, text file path) pass as second argument in the next step
-
- (If any of these links are broken, please submit an issue and I'll fix it)
-
-## 3. Add your URLs to the archive
-
-Pass in URLs directly, import a list of links from a file, or import from a feed URL. All via stdin:
-```bash
-archivebox add < your_urls.txt
-
-# or if using plain Docker
-docker run -v $PWD:/data -it archivebox/archivebox add < your_urls.txt
-
-# or if using Docker Compose
-docker compose run -T archivebox add < your_urls.txt
-
-# any text containing URLs can ingested via stdin or as args
-curl -fsSL 'https://getpocket.com/users/YOURUSERNAME/feed/all' | archivebox add
-archivebox add 'https://example.com'
-```
-
-## ✅ Done!
-
-Open `./archive` to view your archive data in the filesystem.
-
-You can also use the interactive Web UI to view/manage/add links to your archive:
-```bash
-# with plain Docker:
-docker run -v $PWD:/data -it -p 8000:8000 archivebox/archivebox
-
-# with Docker Compose:
-docker compose up -d
-
-# or without Docker:
-archivebox server
-
-open http://127.0.0.1:8000
-```
-
----
-
-**Next Steps:**
-
-```bash
-archivebox help # see info about all the available commands
-```
-
- - Read [[Usage]] to learn about the various CLI and web UI functions
- - Read [[Configuration]] to learn about the various archive method options
- - Read [[Scheduled Archiving]] to learn how to set up automatic daily archiving
- - Read [[Publishing Your Archive]] if you want to host your archive for others to access online
- - Read [[Troubleshooting]] if you encounter any problems
diff --git a/docs/README.md b/docs/README.md
deleted file mode 120000
index 32d46ee8..00000000
--- a/docs/README.md
+++ /dev/null
@@ -1 +0,0 @@
-../README.md
\ No newline at end of file
diff --git a/docs/Roadmap.md b/docs/Roadmap.md
deleted file mode 100644
index 651f5116..00000000
--- a/docs/Roadmap.md
+++ /dev/null
@@ -1,237 +0,0 @@
-# Roadmap
-
-
-
-▶️ *Comment here to discuss the contribution roadmap:
-[Official Roadmap Discussion](https://github.com/ArchiveBox/ArchiveBox/issues/120).*
-
----
-
-## Planned Specification
-
-(this is not set in stone, just a rough estimate)
-
-### `v0.7: Schema improvements`
- - move config loading logic into settings.py
- - move all the extractors into "plugin" style folders that register their own config
- - right now, the paths of the extractor output are scattered all over the codebase, e.g. `output.pdf` (should be moved to constants at the top of the plugin config file)
- - make out_dir, link_dir, extractor_dir, naming consistent across codebase
- - remove `timestamps` as primary keys in favor of hashes, UUIDs, or some other slug https://github.com/ArchiveBox/ArchiveBox/issues/74
- - create a migration system for folder layout independent of the index (`mv` is atomic at the FS level, so we just need a `transaction.atomic(): move(oldpath, newpath); snap.data_dir = newpath; snap.save()`)
- - make `Tag` a real model `ManyToMany` with Snapshots
- - allow multiple Snapshots of the same site over time + CLI / UI to manage those, + migration from old style `#2020-01-01` hack to proper versioned snapshots
- - upgrade from Django 3 to Django 5 https://github.com/ArchiveBox/ArchiveBox/issues/988
-
-### `v0.8: Security`
- - Add CSRF/CSP/XSS protection to rendered archive pages
- - Provide secure reverse proxy in front of archivebox server in docker-compose.yml
- - Create UX flow for users to setup session cookies / auth for archiving private sites
- - cookies for wget, curl, etc low-level commands
- - localstorage, cookies, indexedb setup for chrome archiving methods
-
-### `v0.9: Performance`
- - setup huey, break up archiving process into tasks on a queue that a worker pool executes
- - setup pyppeteer2 to wrap chrome so that it's not open/closed during each extractor
-
-### `v1.0: Full headless browser control`
- - run user-scripts / extensions in the context of the page during archiving
- - community userscripts for unrolling twitter threads, reddit threads, youtube comment sections, etc.
- - pywb-based headless browser session recording and warc replay
- - archive proxy support
- - support sending upstream requests through an external proxy
- - support for exposing a proxy that archives all downstream traffic
-
-...
-
-### `v2.0 Federated or distributed archiving + paid hosted service offering`
- - ZFS / merkel tree for storing archive output subresource hashes
- - DHT for assigning merkel tree hash:file shards to nodes
- - tag system for tagging certain hashes with human-readable names, e.g. title, url, tags, filetype etc.
- - distributed tag lookup system
-
-
-
-
----
-
-### Major long-term changes
- - ✅ release **`pip`, `apt`, `pkg`, and `brew` packaged distributions** for installing ArchiveBox
- - ✅ add an **optional web GUI** for managing sources, adding new links, and viewing the archive
- - ✅ switch to django + **sqlite db with migrations system** & json/html export for managing archive schema changes and persistence
- - modularize internals to allow importing individual components
- - switch to sha256 of URL as unique link ID
- - support **storing multiple snapshots** of pages over time
- - support **custom user puppeteer scripts to run while archiving** (e.g. for expanding reddit threads, scrolling thread on twitter, etc)
- - support named collections of archived content with different user access permissions
- - support sharing archived assets via DHT + torrent / ipfs / ZeroNet / other sharing system
-
-### Smaller planned features
- - support pushing pages to multiple 3rd party services using ArchiveNow instead of just archive.org
- - ✅ body text extraction to markdown (using ~~[fathom](https://hacks.mozilla.org/2017/04/fathom-a-framework-for-understanding-web-pages/)~~ readability and mercury)
- - featured image / thumbnail extraction
- - auto-tagging links based on important/frequent keywords in extracted text (like pocket)
- - automatic article summary paragraphs from extracted text with nlp summarization library
- - ✅ full-text search of extracted text with ~~elasticsearch/elasticlunr/ag~~ sonic and ripgrep
- - ✅ download closed-caption subtitles from Youtube and other video sites (TODO: submit the subtitle files to the full-text search index)
- - try pulling dead sites from archive.org and other sources if original is down (https://github.com/hartator/wayback-machine-downloader)
- - And more in the [issues list](https://github.com/ArchiveBox/ArchiveBox/issues/)...
-
----
-
-**IMPORTANT**: *Please don't work on any of these major long-term tasks without [contacting me first](https://nicksweeting.com/blog#Contact-Me), work is already in progress for many of these, and I may have to reject your PR if it doesn't align with the existing work!*
-
-
----
-
-## Past Releases
-
-To see how this spec has been scheduled / implemented / released so far, read these pull requests:
- - ✅ v0.1.x pre-git-history (~2017)
- - ✅ [v0.2.x](https://github.com/ArchiveBox/ArchiveBox/tree/483a3bef9e2b1a7b80611947a3be99b0cf4f9959) (~2018/12)
- - ✅ [v0.3.x](https://github.com/ArchiveBox/ArchiveBox/pull/197) (~2019/03)
- - ✅ [v0.4.x](https://github.com/ArchiveBox/ArchiveBox/pull/207) (~2019/04)
- - ✅ [v0.5.x](https://github.com/ArchiveBox/ArchiveBox/pull/552) (~2020/11)
- - ✅ [v0.6.x](https://github.com/ArchiveBox/ArchiveBox/pull/680) (~2021/03)
- - 🏖️ `sabbatical / coding hiatus during 2022`
- - ✅ [v0.7.x](https://github.com/ArchiveBox/ArchiveBox/pull/721) (~2023/11)
- - 🛠 [v0.8.x](https://github.com/ArchiveBox/ArchiveBox/pull/1311) (~2024/05)
- - 📅 v0.9.x up next...
-
----
-
-## UI / UX Improvements Planned
-
-- https://github.com/ArchiveBox/ArchiveBox/issues/1358
-- https://github.com/ArchiveBox/ArchiveBox/issues/1273
-- https://github.com/ArchiveBox/ArchiveBox/issues/988
-- https://github.com/ArchiveBox/ArchiveBox/issues/930
-
----
-
-## New Extractors Planned
-
-- `gallery-dl`: https://github.com/ArchiveBox/ArchiveBox/issues/564
-- `forum-dl`: https://github.com/ArchiveBox/ArchiveBox/issues/1368
-- `scihub-dl`: https://github.com/ArchiveBox/ArchiveBox/issues/720
-- `cad-dl`: https://github.com/ArchiveBox/ArchiveBox/issues/668
-- `aria2`: https://github.com/ArchiveBox/ArchiveBox/issues/1355
-- `podcast-archiver`: https://github.com/ArchiveBox/ArchiveBox/issues/1357
-- `bdfr`: https://github.com/ArchiveBox/ArchiveBox/issues/778
-- `cutycapt` screenshots: https://github.com/ArchiveBox/ArchiveBox/issues/253
-- sourcemap downloader: https://github.com/ArchiveBox/ArchiveBox/issues/1291
-
-[ArchiveBox Developer Documentation: Contributing a New Extractor](https://github.com/ArchiveBox/ArchiveBox#contributing-a-new-extractor)
-
-And others we're considering for the future:
-
-### Social Media
-
-- Instagram
- - https://github.com/instaloader/instaloader (instagram downloader)
- - https://github.com/althonos/InstaLooter (stale)
-- Telegram
- - https://github.com/iyear/tdl (telegram downloader)
-- TikTok
- - https://github.com/charmparticle/tiktokget (tiktok downloader using yt-dlp)
- - https://github.com/TerminalWarlord/TikTok-Downloader-Bot
- - https://github.com/n0l3r/tiktok-downloader
- - https://github.com/hansputera/tiktok-dl
- - https://github.com/naseif/tiktok-scraper
- - https://github.com/irevenko/tiktik
- - https://github.com/samirelanduk/tiktok-save
- - https://github.com/Dinoosauro/tiktok-to-ytdlp
- - https://github.com/krypton-byte/tiktok-downloader
-- Twitter
- - https://github.com/HoloArchivists/twspace-dl (stale, twitter spaces archiver)
-
-
-### Video/Streams
-
-- https://github.com/soimort/you-get ⭐️
-- https://github.com/lay295/TwitchDownloader
-- https://github.com/ihabunek/twitch-dl
-- https://github.com/iawia002/lux (generic video/audio downloader)
-- https://github.com/wukko/cobalt (generic video/audio downloader)
-- https://github.com/jaysonlong/webvideo-downloader (Bilibili, iQIYI, Tencent Video, MGTV and WeTV)
-- https://github.com/spaam/svtplay-dl (comedy central, twitch, HBO, etc. video downloader)
-- https://github.com/aajanki/yle-dl (Yle Areena Finnish broadcasting video downloader)
-- https://github.com/WHTJEON/widevine-dl (encrypted widevine video downloader)
-
-### Audio/Music
-
-- https://github.com/nathom/streamrip (Qobuz, Tidal, Deezer and SoundCloud)
-- https://github.com/0xHJK/music-dl
-- https://github.com/guanguans/music-dl
-- https://github.com/CharlesPikachu/musicdl
-- https://github.com/iheanyi/bandcamp-dl
-- https://github.com/spotDL/spotify-downloader
-- https://github.com/Shabinder/SpotiFlyer
-- https://github.com/SathyaBhat/spotify-dl / https://github.com/SwapnilSoni1999/spotify-dl / https://github.com/dhruv-ahuja/spoti-dl
-- https://github.com/vitiko98/qobuz-dl (Qobuz music downloader)
-- https://github.com/akhilrex/podgrab (stale)
-- https://github.com/yaronzz/Tidal-Media-Downloader-PRO (stale)
-- https://github.com/flyingrub/scdl (stale)
-- https://github.com/ravishi/rdio-dl (stale, Rdio song downloader)
-- https://github.com/carlosflorencio/laracasts-downloader (stale?)
-
-### Photos/Images/Comics
-
-- https://github.com/mikf/gallery-dl ⭐️
-- https://github.com/Bionus/imgbrd-grabber (generic image board downloader like gallery-dl)
-- https://github.com/Xonshiz/comic-dl (comic, anime, manga, etc. downloader)
-- https://github.com/justfoolingaround/animdl (anime downloader)
-- https://github.com/metafates/mangal (manga downloader)
-- https://github.com/boredazfcuk/docker-icloudpd (iCloud Photos downloader)
-- https://github.com/Oshan96/monkey-dl (stale? anime downloader)
-- https://github.com/QianyanTech/Image-Downloader (stale?)
-- https://github.com/Xonshiz/anime-dl (stale?)
-
-### Text/Forums
-
-- https://github.com/mikwielgus/forum-dl ⭐️
-- https://github.com/AndyTheFactory/newspaper4k ⭐️
-- https://github.com/AAndyProgram/SCrawler (Twitter, Reddit, Instagram, Threads, Facebook, Pinterest, nsfw sites downloader)
-- https://github.com/extractus/article-extractor
-- https://github.com/shadowmoose/RedditDownloader (stale?)
-- https://github.com/aliparlakci/bulk-downloader-for-reddit (stale?)
-
-### MOOC/Educational Content
-
-- https://github.com/coursera-dl/coursera-dl
-- https://github.com/rand-net/khan-dl
-- https://github.com/C0D3D3V/Moodle-DL
-- https://github.com/r0oth3x49/acloud-dl
-- https://github.com/Puyodead1/udemy-downloader
-- https://github.com/PyJun/Mooc_Downloader (stale)
-- https://github.com/yann0917/dedao-dl (stale, MOOC course downloader)
-- https://github.com/coursera-dl/edx-dl (stale?)
-- https://github.com/SigureMo/mooc-dl (stale?)
-- https://github.com/calvinhobbes23/Skillshare-DL (stale)
-- https://github.com/r0oth3x49/lynda-dl (stale, Lynda.com course downloader)
-
-### Re-Archiving / WARC Creation
-
-- https://github.com/hartator/wayback-machine-downloader
-- https://github.com/MiniGlome/Archive.org-Downloader
-- https://github.com/ArchiveTeam/grab-site
-- https://github.com/oduwsdl/archivenow
-- https://github.com/wabarc/warcraft
-- https://github.com/sul-dlss/wasapi-downloader
-- https://github.com/KellyStathis/warc_downloader
-- https://github.com/internetarchive/heritrix3
-- https://github.com/AhmadIbrahiim/Website-downloader (wget wrapper)
-- https://github.com/igrigorik/gharchive.org (stale? Github downloader)
-
-### Other
-
-- https://github.com/KurtBestor/Hitomi-Downloader
-- https://github.com/nilaoda/BBDown
-- https://github.com/biliup/biliup
-- https://github.com/yutto-dev/bilili
-- https://github.com/nICEnnnnnnnLee/BilibiliDown
-- https://github.com/matlink/gplaycli (Google Play store Android app downloader)
-- https://github.com/AlphaSlayer1964/kemono-dl (Patreon, gumroad, etc. archiver)
-- https://github.com/manga-download/hakuneko
-- https://github.com/cancerian0684/dli-downloader (Digital Library of India ebook downloader)
-- https://github.com/tusharbabbar/gaana-dl (gaana.com bollywood song downloader)
-- https://github.com/rebane2001/matterport-dl (stale? virtual house tour downloader)
diff --git a/docs/Scheduled-Archiving.md b/docs/Scheduled-Archiving.md
deleted file mode 100644
index d777f1ed..00000000
--- a/docs/Scheduled-Archiving.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Scheduled Archiving
-
-ArchiveBox now stores schedules in the database and lets the orchestrator materialize them into queued `Crawl` records at the right time. You no longer need host cron, user crontabs, or a separate `archivebox_scheduler` container when `archivebox server` is running.
-
-## How It Works
-
-1. `archivebox schedule ...` creates a `CrawlSchedule` record plus a sealed template `Crawl`.
-2. The long-running global orchestrator inside `archivebox server` watches enabled schedules.
-3. When a schedule becomes due, the orchestrator creates a new queued `Crawl`.
-4. That queued crawl is processed the same way as UI/API-submitted work.
-
-One-shot foreground flows such as `archivebox add ...` continue to process only the crawl they were asked to run. They do not also sweep and execute unrelated scheduled crawls.
-
-## CLI Usage
-
-```bash
-cd ~/archivebox/data
-
-archivebox schedule --every=daily --depth=1 https://example.com/feed.xml
-archivebox schedule --every='0 */6 * * *' https://example.com/feed.xml
-archivebox schedule --show
-archivebox schedule --clear
-archivebox schedule --run-all
-archivebox schedule --foreground
-```
-
-Accepted schedule formats:
-
-- Aliases: `minute`, `hour`, `day`, `week`, `month`, `year`, `daily`, `weekly`, `monthly`, `yearly`
-- Cron expressions: e.g. `0 */6 * * *`
-
-`archivebox schedule --run-all` enqueues every enabled schedule immediately.
-
-`archivebox schedule --foreground` runs the global orchestrator in the foreground, which is useful outside `archivebox server` if you want a dedicated long-running scheduler/worker process without the web UI.
-
-Running `archivebox schedule --every=day` with no `import_path` creates a recurring maintenance schedule that queues `archivebox://update` crawls.
-
-## Docker Compose
-
-With the new orchestrator flow, you only need the main `archivebox` service:
-
-```yaml
-services:
- archivebox:
- image: archivebox/archivebox:dev
- command: server --quick-init 0.0.0.0:8000
- volumes:
- - ./data:/data
-```
-
-Create schedules with:
-
-```bash
-docker compose run --rm archivebox schedule --every=weekly --depth=1 https://example.com/feed.xml
-docker compose run --rm archivebox schedule --show
-```
-
-If the main `archivebox server` container is already running, its orchestrator will pick up future scheduled runs automatically. There is no scheduler sidecar to restart.
-
-## Examples
-
-Archive a Twitter mirror once a week:
-
-```bash
-archivebox schedule --every=weekly --depth=1 'https://nitter.net/ArchiveBoxApp'
-```
-
-Archive a subreddit and linked discussions once a week:
-
-```bash
-archivebox config --set URL_WHITELIST='^http(s)?:\/\/(.+)?teddit\.net\/?.*$'
-archivebox schedule --every=weekly --overwrite --depth=1 'https://teddit.net/r/DataHoarder/'
-```
-
-Archive Hacker News every day:
-
-```bash
-archivebox config --set URL_BLACKLIST='^http(s)?:\/\/(.+\.)?(youtube\.com)|(amazon\.com)\/.*$'
-archivebox schedule --every=daily --depth=1 'https://news.ycombinator.com'
-```
-
-Queue a daily maintenance update:
-
-```bash
-archivebox schedule --every=day
-```
diff --git a/docs/Security-Overview.md b/docs/Security-Overview.md
deleted file mode 100644
index a5158cbc..00000000
--- a/docs/Security-Overview.md
+++ /dev/null
@@ -1,189 +0,0 @@
-# Security Overview
-
-> *💬 We offer [consulting services](https://docs.monadical.com/s/archivebox-consulting-services) to set up, secure, and maintain ArchiveBox on your preferred hosting environment.*
-> We use this revenue (from corporate clients who can afford to pay) to support open source development and keep ArchiveBox free.
-
-## Web UI Permissions
-
-```bash
-archivebox config --set PUBLIC_INDEX=False # require login to access the list of Snapshots
-archivebox config --set PUBLIC_SNAPSHOTS=False # require login to access Snapshot content
-archivebox config --set PUBLIC_ADD_VIEW=False # require log-in to submit new URLs for archiving
-
-archivebox manage [createsuperuser|changepassword] # create/modify admin UI users
-```
-
-See [[Setting Up Authentication]] for more...
-
-
-
-## ArchiveBox Use-Cases
-
-
-
-
-
-#### Archiving Public Content Only ⭐️ `[Default, recommended for most people]`
-
-This is the default (lax) mode, intended for archiving public (non-secret) URLs without authenticating the headless browser. This is the mode used if you're archiving news articles, audio, video, etc. browser bookmarks to a folder published on your webserver. This allows you to access and link to content on `http://your.archive.com/archive...` after the originals go down.
-
-The default mode should not be used for archiving entire browser history or authenticated private content like Google Docs, paywalled content, invite-only subreddits, private photo share urls, etc.
-
-```bash
-# (these are the defaults)
-archivebox config --set SAVE_ARCHIVE_DOT_ORG=True
-archivebox config --set CHROME_USER_DATA_DIR=None
-archivebox config --set COOKIES_FILE=None
-```
-
-
-
-
-#### Archiving Content Behind Log-Ins 🚨 `[Advanced users only]`
-
-ArchiveBox is able to archive content that requires authentication or cookies, but it comes with some caveats. Create dedicated logins for archiving to access paywalled content, private forums, LAN-only content, etc. then share them with ArchiveBox via Chrome profile + cookies.txt file.
-
-```bash
-archivebox config --set SAVE_ARCHIVE_DOT_ORG=False
-archivebox config --set CHROME_USER_DATA_DIR=/path/to/chrome/profile
-archivebox config --set COOKIES_FILE=/path/to/cookies.txt
-```
-
-To get started, set [`CHROME_USER_DATA_DIR`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#chrome_user_data_dir) and [`COOKIES_FILE`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#COOKIES_FILE) to point to a Chrome user folder that has your sessions and a wget `cookies.txt` file respectively.
-
-➡️ For full instructions on setting up a Chromium user profile see here: https://github.com/ArchiveBox/ArchiveBox/wiki/Chromium-Install#setting-up-a-chromium-user-profile
-
-If you're importing private links or authenticated content, you probably don't want to share your archive folder publicly on a webserver, so don't follow the [[Publishing Your Archive]] instructions unless you are only serving it on a trusted LAN or have some sort of authentication in front of it. Make sure to point ArchiveBox to an output folder with conservative permissions, as it may contain archived content with secret session tokens or pieces of your user data. You may also wish to encrypt the archive using an encrypted disk image or filesystem like ZFS as it will contain all requests and response data, including session keys, user data, usernames, etc.
-
-#### ⚠️ Things to watch out for: ⚠️
-
-- any cookies / secret state present in a Chrome user profile or `cookies.txt` file may be [reflected in server responses and saved in the Snapshot output (e.g. in `headers.json`)](https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/extractors/headers.py) making it [visible in cleartext to anyone viewing the Snapshot](https://archive.sweeting.me/archive/1613417792.264667/headers.json), (don't use your personal Chrome profile for archiving or people viewing your archive can then authenticate as you!)
-- any secret tokens embedded in URLs (e.g. secret invite links, Google Doc URLs, etc.) will be visible on `archive.org` as the URLs are not filtered [when saving to `archive.org`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/extractors/archivedotorg.py#L46) (disable submitting to Archive.org entirely with `SAVE_ARCHIVE_DOT_ORG=False`)
-- the domain portion in archived URLs is [sent to a favicon service](https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/extractors/favicon.py#L43) in order to retrieve an icon more reliably than a janky internal implementation would be able to (if leaking domains is a concern, you can change the [`FAVICON_PROVIDER`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/config.py#:~:text=FAVICON_PROVIDER) or disable favicon fetching entirely with `SAVE_FAVICON=False`)
-- [viewing malicious archived JS could allow an attacker to access your other archive items + the admin interface (JS executes on the same origin as the admin panel right now, fix is pending, set `SAVE_WGET=False SAVE_DOM=False` to disable the risky extractors entirely or avoid viewing their output directly in a browser)](https://github.com/ArchiveBox/ArchiveBox/issues/239)
-
-
-
-
-*An example of a session cookie reflected in `headers.json` visible in the archive.*
-
-
-
-
----
-
-
-
-### Publishing
-
-> [!CAUTION]
-> Re-hosting untrusted archived content on a domain can potentially compromise *all apps on that domain*!
-> (including other subdomains)
-
-Make sure you thoroughly understand the dangers of [hosting untrusted HTML/JS/CSS that may be captured during archiving](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy), and how viewing it can enable [CSRF attacks](https://en.wikipedia.org/wiki/Cross-site_request_forgery) across all apps on the same domain. If a logged-in user happens to visit an archived page with malicious Javascript embedded, it would allow the JS to hijack any cookies on the domain and pretend to be them, potentially exfiltrating or modifying other Snapshots/data on your server.
-
-(This is why we don't support serving ArchiveBox from a subdirectory like `myapps.example.com/archivebox/`, it's too dangerous to share domains)
-
-The industry standard approach is to use a separate domain for untrusted content, for example Github uses `githubusercontent.com` and Google uses `googleusercontent.com` for all user-uploaded files. If hosting ArchiveBox publicly, do the same and keep it on an isolated domain in order to mitigate potential damage of leaked cookies, CORS, and CSRF attacks.
-
-To protect the Admin dashboard, it's also recommended to serve all content under `/archive/` on a separate domain from `/admin/`. We do this on our servers using a simple redirect rule in nginx/cloudflare like so:
-
-- https://demo.archivebox.io: only serves `/`, redirects `/archive/*` to `demo-static.`
-- https://demo-static.archivebox.io: only serves `/archive/`, redirects everything else to `demo.`
-
-
-
-Published archives automatically include a `robots.txt` `Disallow: /` to block search engines from indexing them. You may still wish to publish your contact info in the index footer though using [`FOOTER_INFO`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#FOOTER_INFO) so that you can respond to any DMCA and copyright takedown notices if you accidentally rehost copyrighted content.
-
-⚠️ Make sure to read all the warnings [above](https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#%EF%B8%8F-things-to-watch-out-for-%EF%B8%8F) about the dangers of exposing Chrome profile data, cookies, secret tokens in URLs, and the risks of viewing archived JS on a shared origin before publishing your archive.
-
-More info:
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Publishing-Your-Archive
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Publishing-Your-Archive#security-concerns
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Publishing-Your-Archive#copyright-concerns
-- https://en.wikipedia.org/wiki/Cross-site_request_forgery
-- https://github.com/ArchiveBox/ArchiveBox/issues/239
-
-
-
----
-
-
-
-## Do not run as root
-
-
-
-> [!WARNING]
-> **Did you run a command in Docker with `exec` instead of `run` by accident and end up here?**
-> Make sure you use `docker run` instead of `docker exec` to run ArchiveBox commands.
->
-> *For example:*
-> ✅ `docker compose run archivebox manage createsuperuser`
-> ✅ `docker run -it -v $PWD:/data archivebox/archivebox manage createsuperuser`
-> (`docker run` automatically uses the correct `archivebox` user & file permissions enforced via [`./bin/docker_entrypoint.sh`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/bin/docker_entrypoint.sh))
->
-> *instead of:*
-> ❌ `docker compose exec archivebox manage createsuperuser`
-> ❌ `docker exec -it archivebox manage createsuperuser`
-> (`docker exec` will skip the [entrypoint](https://github.com/ArchiveBox/ArchiveBox/blob/dev/bin/docker_entrypoint.sh) and attempt to run everything as root and fail)
->
-> If you must use `exec` for some reason (e.g. if you only have access to a live container shell), you can run `su archivebox` within the shell, or add the arg `--user=archivebox` after `exec`.
-
-Do not run ArchiveBox as root for a number of reasons:
- - Chrome will execute as root and fail immediately because Chrome sandboxing is pointless when the data directory is opened as root (do not set `CHROME_SANDBOX=False` just to bypass that error!)
- - All dependencies will be run as root, if any of them have a vulnerability that's exploited by sites you're archiving you're opening yourself up to full system compromise
- - ArchiveBox does lots of HTML parsing, filesystem access, and shell command execution. A bug in any one of those subsystems could potentially lead to deleted/damaged data on your hard drive, or full system compromise unless restricted to a user that only has permissions to access the directories needed
- - Do you really trust a project created by a Github user called `@pirate` 😉? Why give a random program off the internet root access to your entire system? (I don't have malicious intent, I'm just saying in principle you should not be running random Github projects as root)
-
-**Instead, you should run ArchiveBox under a separate user account with less privileged access:**
-```bash
-useradd -r -g archivebox -G audio,video archivebox # the audio & video groups are used by chrome
-mkdir -p /home/archivebox/data
-chown -R archivebox:archivebox /home/archivebox
-...
-sudo -u archivebox archivebox add ...
-```
-
-~~If you absolutely must run it as root for some reason, a footgun is provided: you can set [`ALLOW_ROOT=True`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#ALLOW_ROOT) via environment variable or in your ArchiveBox.conf file.~~ This footgun option was removed (I'm sorry, the support burden of helping people who messed up their systems by running everything as root was too high).
-
-
-
-
-
----
-
-
-
-## Output Folder
-
-### Database
-
-The ArchiveBox database is an unencrypted, uncompressed SQLite3 `index.sqlite3` file on disk, and such does not require an authenticated admin SQL login to access (like PostgreSQL/MySQL would). Make sure to protect your database file adequately as anyone who can read it can read your entire collection contents. Passwords for the admin users are stored as salted and PBKDF2 hashed strings in the `auth_user` table.
-
-More info:
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#disk-layout
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#database-troubleshooting
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#modify-the-archivebox-sqlite3-db-directly
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#example-adding-a-new-user-with-a-hashed-password
-
-### Filesystem
-
-How much are you planning to archive? Only a few bookmarked articles, or thousands of pages of browsing history a day? If it's only 1-50 pages a day, you can probably just stick it in a normal folder on your hard drive, but if you want to go over 100 pages a day, you will likely want to put your archive on a compressed/deduplicated/encrypted disk image or filesystem like ZFS. Other distributed/networked/checksummed filesystems that have also been reported to work (but are not technically officially supported) include SMB, NFS, Ceph, Unraid, and BTRFS. Make sure the filesystem you're using supports FSYNC. Some filesystems are unable to store more than a certain number of directory entries, and your total number of snapshots in `./archive` may be capped as a result. Some other filesystems begin to have performance degradations but continue to function when the directory entry count gets too high. Generally this isn't an issue unless you have more than ~20,000 Snapshot folders in `./archive`.
-
-#### Purging entries
-
-When `--yes` is passed to `archivebox remove`, matching Snapshots are removed from the index and their archived content folders are deleted from disk. Imported URLs are also logged separately in `./sources`, `./logs`, and the Sonic full-text index `./sonic` and should be removed manually as well to clear all traces of a URL added by accident. You can search for a URL on the filesystem you're trying to remove using `grep -a -r "https://example.com/url/to/search/for"`.
-
-#### Permissions
-
-Consider what permissioning to apply to your archive folder carefully. Limit access to the fewest possible users by checking folder ownership and setting [`OUTPUT_PERMISSIONS`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#OUTPUT_PERMISSIONS) accordingly. Generally the `index.sqlite3` file, `archive/` folder, and `ArchiveBox.conf` file must all be owned and writable by the `archivebox` user or a dedicated non-root user.
-
-[`PUID` & `PGID`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#puid--pgid) can be set when running with Docker to control what user and group ArchiveBox expects to own the data directory within the container.
-
-More info:
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#disk-layout
-- https://github.com/ArchiveBox/ArchiveBox#output-formats
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#database-troubleshooting
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#filesystem-doesnt-support-fsync-eg-network-mounts
-- https://github.com/ArchiveBox/ArchiveBox#storage-requirements
diff --git a/docs/Setting-Up-Storage.md b/docs/Setting-Up-Storage.md
deleted file mode 100644
index 925e5292..00000000
--- a/docs/Setting-Up-Storage.md
+++ /dev/null
@@ -1,301 +0,0 @@
-# Setting Up Storage
-
-> *💬 We offer [consulting services](https://docs.monadical.com/s/archivebox-consulting-services) to set up, secure, and maintain ArchiveBox on your preferred storage provider.*
-> We use this revenue (from corporate clients who can afford to pay) to support open source development and keep ArchiveBox free.
-
-
-
-ArchiveBox supports a wide range of local and remote filesystems using `rclone` and/or Docker storage plugins. The examples below use [Docker Compose bind mounts](https://docs.docker.com/storage/bind-mounts/) to demonstrate the concepts, you can adapt them to your OS and environment needs.
-
-Example [`docker-compose.yml`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/docker-compose.yml) storage setup:
-```yaml
-services:
- archivebox:
- ...
- volumes:
- # your index db, config, logs, etc. should be stored on a local SSD (usually <10Gb)
- - ./data:/data
-
- # but bulk archive/ content can be located on an HDD or remote filesystem
- - /mnt/archivebox-s3/data/archive:/data/archive
-```
-
-Related Docs
-
-
----
-
-## Supported Local Filesystems
-
-
-
-
-
-### `EXT4` (default on Linux), `APFS` (default on macOS)
-
-> [!TIP]
-> These default filesystems are fully supported by ArchiveBox on Linux and macOS (w/wo Docker).
-
-
-
-### `ZFS` (recommended for best experience on Linux/BSD) ⭐️
-
-> [!TIP]
-> *This is the recommended filesystem for ArchiveBox on Linux, macOS, and BSD (w/wo Docker).*
-> [`apt install zfsutils-linux`](https://openzfs.github.io/openzfs-docs/Getting%20Started/Ubuntu/index.html)
-> Provides RAID, compression, encryption, deduping, 0-cost point-in-time backups, remote sync, integrity verification, and more...
-
-- https://openzfs.github.io/openzfs-docs/
-- https://openzfs.github.io/openzfs-docs/man/v2.2/8/zpool-create.8.html
-- https://openzfs.github.io/openzfs-docs/man/v2.2/8/zfs-create.8.html
-- https://docs.docker.com/storage/storagedriver/zfs-driver/
-- https://www.ixsystems.com/blog/fast-dedup-is-a-valentines-gift-to-the-openzfs-and-truenas-communities/
-
-```bash
-# create a new archivebox pool to hold your dataset
-zpool create -f \
- -O mountpoint=/mnt/archivebox \
- -O sync=standard \
- -O compression=lz4 \
- -O recordsize=128K \
- -O dnodesize=auto \
- -O atime=off \
- -O xattr=sa \
- -O acltype=posixacl \
- -O aclinherit=passthrough \
- -O utf8only=on \
- -O normalization=formD \
- -O casesensitivity=sensitive \
- archivebox /dev/disk/by-uuid/disk1... /dev/disk/by-uuid/disk2...
-
-# create the archivebox/data ZFS dataset
-zfs create \
- -o mountpoint=/mnt/archivebox/data \
- archivebox/data
-
-# optional: add encryption
- -o encryption=on \
- -o keysource=passphrase,prompt \
-```
-
-
-
-### `NTFS`, `HFS+`, `BTRFS`
-
-> [!WARNING]
-> These filesystems are likely supported, but are not officially tested.
-
-
-
-### `EXT2`, `EXT3`, `FAT32`, `exFAT`
-
-> [!CAUTION]
-> Not recommended. Cannot store files >4GB or more than 31k ~ 65k Snapshot entries due to directory entry limits.
-
-
-
----
-
-
-
-
-## Supported Remote Filesystems
-
-
-
-ArchiveBox supports many common types of remote filesystems using RClone, FUSE, Docker Storage providers, and Docker Volume Plugins.
-
-The `data/archive/` subfolder contains the bulk archived content, and it supports being stored on a slower remote server (SMB/NFS/SFTP/etc.) or object store (S3/B2/R2/etc.). For data integrity and performance reasons, the rest of the `data/` directory (`data/ArchiveBox.conf`, `data/logs`, etc.) must be stored locally while ArchiveBox is running.
-
-> [!IMPORTANT]
-> `data/index.sqlite3` is your main archive DB, *it must be on a fast, reliable, local filesystem* which supports [FSYNC](https://stackoverflow.com/questions/40849596/git-clone-fsync-input-output-error-in-linux#:~:text=Some%20filesystems%20%2D%20especially%20remote%20filesystems%20like%20NFS%2C%20sshfs%2C&text=do%20not%20support%20fsync()%20but%20git%20has%20no%20flag%20to%20disable%20these%20calls) (SSD/NVMe recommended for best experience).
-
-> [!TIP]
-> If you use a remote filesystem, you should switch ArchiveBox's search backend from [`ripgrep`](https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-up-Search#ripgrep) to [`sonic`](https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-up-Search#sonic) (or [`FTS5`](https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-up-Search#fts5)).
-> (`ripgrep` scans over every byte in the archive to do each search, which is **slow and potentially costly** on remote cloud storage)
-
-
-
-### `NFS` (Docker Driver)
-
-`docker-compose.yml`:
-```yaml
-services:
- archivebox:
- volumes:
- - ./data:/data
- - archivebox-archive:/data/archive
-
-volumes:
- archivebox-archive:
- driver_opts:
- type: "nfs"
- o: "addr=some-remote-server.example.com,nolock,soft,rw,nfsvers=4"
- device: ":/archivebox-archive"
-```
-
-
-
-### `SMB` / `Ceph` (Docker CIFS Driver)
-
-`docker-compose.yml`:
-```yaml
-services:
- archivebox:
- volumes:
- - ./data:/data
- - archivebox-archive:/data/archive
-
-volumes:
- archivebox-archive:
- driver: local
- driver_opts:
- type: cifs
- device: "//some-remote-server.example.com/archivebox-archive"
- o: "username=XXX,password=YYY,uid=911,gid=911"
-```
-
-
-
-
-
-
-
-### Amazon S3 / Backblaze B2 / Google Drive / etc. (RClone)
-
-```bash
-# install the RClone and FUSE packages on your host
-apt install rclone fuse # or brew install
-
-# IMPORTANT: needed to allow FUSE drives to be shared with Docker
-echo 'user_allow_other' >> /etc/fuse.conf
-```
-
-Then define your remote storage config `~/.config/rclone/rclone.conf`:
-
-> [!TIP]
-> You can also create `rclone.conf` using the RClone Web GUI: `rclone rcd --rc-web-gui`
-
-```ini
-# Example rclone.conf using Amazon S3 for storage:
-[archivebox-s3]
-type = s3
-provider = AWS
-access_key_id = XXX
-secret_access_key = YYY
-region = us-east-1
-```
-
-#### RClone Config Examples
-
-- [SMB](https://rclone.org/smb/) / [Ceph](https://rclone.org/s3/#ceph) / [SFTP](https://rclone.org/sftp/) / [FTP](https://rclone.org/ftp/) / [WebDAV (e.g. Nextcloud)](https://rclone.org/webdav/)
-- [Google Drive](https://rclone.org/drive/) / [Dropbox](https://rclone.org/dropbox/) / [OneDrive](https://rclone.org/onedrive/)
-- [Amazon S3](https://rclone.org/s3/#configuration) / [Backblaze B2](https://rclone.org/b2/) / [Cloudflare R2](https://rclone.org/s3/#cloudflare-r2) / [DigitalOcean Spaces](https://rclone.org/s3/#digitalocean-spaces)
-- [Google Cloud Storage](https://rclone.org/s3/#google-cloud-storage) / [Azure Blob](https://rclone.org/azureblob/) / [Azure Files](https://rclone.org/azurefiles/)
-- [Storj](https://rclone.org/s3/#storj) / [Sia](https://rclone.org/sia/) / [Archive.org Storage](https://rclone.org/internetarchive/)
-- And many more...
- - https://rclone.org/s3/
- - https://rclone.org/overview/
-
-*Bonus:*
-- Set up gzip compression: https://rclone.org/compress/
-- Set up file encryption: https://rclone.org/crypt/
-- Set up hashing engine: https://rclone.org/hasher/
-
-
-
-#### Option A: Running RClone on Bare Metal host
-
-1. *If Needed:* Transfer any existing local archive data to the remote volume first
-```bash
-rclone sync --fast-list --transfers 20 --progress /opt/archivebox/data/archive/ archivebox-s3:/data/archive
-mv /opt/archivebox/data/archive /opt/archivebox/data/archive.localbackup
-```
-2. **Mount the remote storage volume as FUSE filesystem**
-```
-rclone mount
- --allow-other \ # essential, allows Docker to access FUSE mounts
- --uid 911 --gid 911 \ # 911 is the default used by ArchiveBox
- --vfs-cache-mode=full \ # cache both file metadata and contents
- --transfers=16 --checkers=4 \ # use 16 threads for transfers & 4 for checking
- archivebox-s3/data/archive:/opt/archivebox/data/archive # remote:local
-```
-
-See here for full more detailed instructions here: [RClone Documentation: The `rclone mount` command](https://rclone.org/commands/rclone_mount/)
-
-> [!TIP]
-> You can use any RClone FUSE mounts as a normal volumes (bind mount) for Docker ArchiveBox, typically no storage plugin is needed as long as `allow-other` is setup properly.
-
-`docker run -v $PWD:/data -v /opt/archivebox/data/archive:/data/archive`
-
-`docker-compose.yml`:
-```yaml
-services:
- archivebox:
- ...
- volumes:
- - ./data:/data
- - /opt/archivebox/data/archive:/data/archive
-```
-
-
-
-#### Option B: Running RClone with Docker Storage Plugin
-
-*This is only needed if you are unable to `Option A` for compatibility or performance reasons, or if you prefer defining your remote storage config in `docker-compose.yml` instead of `rclone.conf`.*
-
-See here for full instructions: [RClone Documentation: Docker Plugin](https://rclone.org/docker/)
-
-1. First, install the [Rclone Docker Volume Plugin](https://rclone.org/docker/#installing-as-managed-plugin) for your CPU architecture (e.g. `amd64` or `arm64`):
-```bash
-docker plugin install rclone/docker-volume-rclone:amd64 --grant-all-permissions --alias rclone
-ln -sf ~/.config/rclone/rclone.conf /var/lib/docker-plugins/rclone/config/rclone.conf
-```
-
-2. Then, [create a volume using the Docker CLI](https://rclone.org/docker/#creating-volumes-via-cli) or [define one using Docker Compose / Swarm](https://rclone.org/docker/#using-with-swarm-or-compose):
-
-`docker-compose.yml`:
-```yaml
-services:
- archivebox:
- volumes:
- - ./data:/data
- - archivebox-s3:/data/archive
-
-volumes:
- archivebox-s3:
- driver: rclone
- driver_opts:
- remote: 'archivebox-s3/data/archive'
- allow_other: 'true'
- vfs_cache_mode: full
- poll_interval: 0
- uid: 911
- gid: 911
- transfers: 16
- checkers: 4
-```
-
-
-To start the container and verify the filesystem is accessible within it:
-```bash
-docker compose run archivebox /bin/bash 'ls -lah /data/archive/ | tee /data/archive/.write_test.txt'
-```
-
-
----
-
-
-### More Docker Storage Plugins
-
-- [IPFS](https://github.com/djdv/go-filesystem-utils/pull/40) / [Peergos](https://github.com/peergos/peergos) / [GlusterFS](https://github.com/calavera/docker-volume-glusterfs)
-- [DigitalOcean Block Storage Volumes](https://github.com/djmaze/dobs-volume-plugin) / [Linode Block Storage Volumes](https://github.com/linode/docker-volume-linode)
-- [More volume plugins...](https://docs.docker.com/engine/extend/legacy_plugins/#volume-plugins)
diff --git a/docs/Setting-up-Authentication.md b/docs/Setting-up-Authentication.md
deleted file mode 100644
index eae05d2d..00000000
--- a/docs/Setting-up-Authentication.md
+++ /dev/null
@@ -1,245 +0,0 @@
-# Setting Up Authentication
-
-> *💬 We offer [consulting services](https://docs.monadical.com/s/archivebox-consulting-services) to set up, integrate, and maintain ArchiveBox with your org's auth & hosting.
-> If you need support, advanced development to capture difficult sites, audit logging, and more, we can provide it!*
-> We use this revenue (from corporate clients who can afford to pay) to support open source development and keep ArchiveBox free.
-
----
-
-ArchiveBox supports several types of authentication for users logging in via the Admin Web UI or REST API.
-
-## Set Up Admin Web UI Permissions
-
-
-
-Use these three options to set up your desired permissions for non-admin guest users:
-- [`PUBLIC_INDEX=True`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#public_index--public_snapshots--public_add_view): Default *allows* non-logged-in users to see Snapshot list
-- [`PUBLIC_SNAPSHOTS=True`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#public_index--public_snapshots--public_add_view): Default *allows* non-logged-in users to see Snapshot content
-- [`PUBLIC_ADD_VIEW=False`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#public_index--public_snapshots--public_add_view): Default *doesn't allow* non-logged-in users to submit new URLs
-
-> [!NOTE]
-> **Open source ArchiveBox does not support setting up *non-admin* users** & groups with custom permissions. We do offer this feature, audit logging, and more to [paying clients](https://docs.monadical.com/s/archivebox-consulting-services).
-
-- [Wiki: Configuration (`PUBLIC_ADD_VIEW`, `PUBLIC_SNAPSHOTS`, `PUBLIC_INDEX`)]()
-- [Wiki: Security Overview](https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview)
-
-
-
-
-## Admin Web UI Authentication Methods
-
-
-
-
-### Username & Password (the default)
-
-You need a user account to access the Admin UI, you can run the commands below to create/edit a user from the CLI:
-
-```bash
-archivebox manage createsuperuser
-archivebox manage changepassword
-
-# equivalent: docker compose run archivebox manage [...]
-# equivalent: docker run -v $PWD:/data archivebox/archivebox manage [...]
-```
-
-> [!TIP]
-> If using Docker, you can set [`ADMIN_USERNAME` & `ADMIN_PASSWORD`](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#admin_username--admin_password) to auto-create an admin account on first run.
-
-Existing users can be managed from the Admin UI here: [`/admin/auth/user/`](http://127.0.0.1:8000/admin/auth/user/),
-and you can change your password in the UI here: [`/admin/password_change/`](http://127.0.0.1:8000/admin/password_change/).
-
-
-
-
-### Reverse Proxy Authentication
-
-> Can be used with a reverse proxy auth provider like [oauth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy), [Cloudflare Zero Trust](https://developers.cloudflare.com/cloudflare-one/tutorials/access-workers/#create-a-worker-with-custom-headers), [Authentik](https://docs.goauthentik.io/docs/providers/proxy/), and others.
-
-Set these ArchiveBox configuration values based on your reverse proxy setup and needs:
-```bash
-# REQUIRED: the header where your upstream reverse proxy will place the authenticated user's username/email
-# EXAMPLE: Cf-Access-Authenticated-User-Email (if using Cloudflare Access / Zero Trust)
-REVERSE_PROXY_USER_HEADER=X-Remote-User
-
-# REQUIRED: the IP/CIDR of your upstream reverse proxy server
-# WARNING: make sure this range contains ONLY your reverse proxy server!
-# ArchiveBox will completely trust any IP in this range for authentication
-REVERSE_PROXY_WHITELIST=192.0.2.3/32
-
-# OPTIONAL: redirect users to an external URL after they log out
-LOGOUT_REDIRECT_URL=https://auth.yourcompany.example.com/after/logout
-```
-
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#reverse_proxy_user_header
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#reverse_proxy_whitelist
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#logout_redirect_url
-- https://github.com/ArchiveBox/ArchiveBox/pull/866
-
-
-
-### LDAP Authentication
-
-> Can be used with an SSO provider like [Authentik](https://github.com/goauthentik/authentik), [Authelia](https://github.com/authelia/authelia), [Okta / Auth0](https://www.okta.com/), [Keycloak](https://www.keycloak.org/), and others.
-
-First, `pip`-install the `ldap` add-on to use this feature (not needed for Docker Archivebox).
-```bash
-pip install archivebox[ldap]
-```
-
-Then set these configuration values to finish configuring LDAP:
-```bash
-LDAP=True
-LDAP_SERVER_URI="ldap://ldap.example.com:3389"
-LDAP_BIND_DN="ou=archivebox,ou=services,dc=ldap.example.com"
-LDAP_BIND_PASSWORD="secret-bind-user-password"
-LDAP_USER_BASE="ou=users,ou=archivebox,ou=services,dc=ldap.example.com"
-LDAP_USER_FILTER="(objectClass=user)"
-
-LDAP_USERNAME_ATTR="uid"
-LDAP_FIRSTNAME_ATTR="givenName"
-LDAP_LASTNAME_ATTR="sn"
-LDAP_EMAIL_ATTR="mail"
-```
-
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#ldap
-- https://github.com/ArchiveBox/ArchiveBox/pull/1214
-- https://github.com/django-auth-ldap/django-auth-ldap#example-configuration
-- https://jumpcloud.com/blog/what-is-ldap-authentication
-
-
-
-### Not Yet Supported: SAML / OAuth2 / OpenID Authentication
-
-> *We'd welcome PRs to add support for these using `django-allauth`!*
-
-These methods are not natively supported by ArchiveBox at the moment. However it is still possible to use them with ArchiveBox by running your own [IdP (Identity Provider)](https://www.cloudflare.com/learning/access-management/what-is-an-identity-provider/) server to act as a bridge (e.g. [Authentik](https://docs.goauthentik.io/docs/providers/saml/), [Authelia](https://www.authelia.com/configuration/identity-providers/introduction/#openid-connect-10), [oauth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy)).
-
-The IdP server can act as a middleman gateway to authenticate users using an external SAML/OAuth/OpenID/etc. provider (e.g. Google, Microsoft, Github, Facebook, etc.), and then pass on the authenticated user's session info to ArchiveBox using LDAP or reverse proxy headers (as described above).
-
-- https://www.cloudflare.com/learning/access-management/what-is-saml/
-- https://docs.goauthentik.io/docs/providers/saml/
-- https://docs.goauthentik.io/docs/providers/oauth2/
-- https://www.authelia.com/configuration/identity-providers/introduction/#openid-connect-10
-- https://github.com/oauth2-proxy/oauth2-proxy
-- https://oauth2-proxy.github.io/oauth2-proxy/configuration/overview
-
-
-
----
-
-
-
-## REST API
-
-The REST API (available starting in v0.8.0) supports several methods of authentication for convenience.
-
-To see API docs, try endpoints interactively, and see how auth works, visit this URL on your ArchiveBox server:
-[`http://127.0.0.1:8000/api/v1/docs`](http://127.0.0.1:8000/api/v1/docs)
-
-
-
-
-
-To get started using the REST API, you can generate an API key for your user in the Admin Web UI:
-[`http://127.0.0.1:8000/admin/api/apitoken/add/`](http://127.0.0.1:8000/admin/api/apitoken/add/)
-
-or by calling the `http://127.0.0.1:8000/api/v1/auth/get_api_token` endpoint with a username & password:
-```bash
-curl -X 'POST' \
- 'http://127.0.0.1:8000/api/v1/auth/get_api_token' \
- -H 'Content-Type: application/json'
- -d '{"username": "YOURUSERNAMEHERE", "password": "YOURPASSWORDHERE"}'
-```
-
-
-
-> [!TIP]
-> Bearer Tokens are the recommended method for the best balance of security and convenience.
-
-
-### API Bearer Token Authentication
-
-Pass `Authorization=Bearer YOURAPITOKENHERE` as a request header.
-
-```bash
-curl -X 'GET' \
- 'http://127.0.0.1:8000/api/v1/core/snapshots?limit=10' \
- -H 'accept: application/json' \
- -H 'Authorization: Bearer YOURAPITOKENHERE'
-```
-
-### API Request Header Authentication
-
-> This method is provided in case you have a reverse proxy in front of ArchiveBox that consumes the bearer header.
-
-Pass `X-ArchiveBox-API-Key=YOURAPITOKENHERE` as a request header.
-
-```bash
-curl -X 'GET' \
- 'http://127.0.0.1:8000/api/v1/core/snapshots?limit=10' \
- -H 'accept: application/json' \
- -H 'X-ArchiveBox-API-Key: YOURAPITOKENHERE'
-```
-
-
-
-### API Query Parameter Authentication
-
-> [!WARNING]
-> This method is sometimes known as ["Capability URLs"](https://w3ctag.github.io/capability-urls/) because anyone in possession of the URL can perform API actions. It comes with [important security caveats](https://security.stackexchange.com/questions/118975/is-it-safe-to-include-an-api-key-in-a-requests-url) and is not recommended unless you fully understand the risks.
-
-Pass `api_key=YOURAPITOKENHERE` as a GET/POST query parameter.
-
-```bash
-curl -X 'GET' \
- 'http://127.0.0.1:8000/api/v1/core/snapshots?limit=10&api_key=YOURAPITOKENHERE' \
- -H 'accept: application/json'
-```
-
-
-
-### API Session Cookie Authentication
-
-> [!CAUTION]
-> We recommend sticking to header-based authentication and not using this method unless you deeply understand the CSRF/CORS security risks.
-> This method is mostly useful when accessing the API from external apps where CSRF/CORS is not a concern (e.g. `curl`, mobile apps, other servers, etc.).
-
-> Browsers enforce that requests made to the ArchiveBox API from *other origins* will not include any session cookies by default. This is is a [foundational security principle of the web](https://docs.djangoproject.com/en/5.0/ref/csrf/) that protects you from API requests being initiated by JS on websites you don't control (aka CSRF/CORS attacks).
->
-> To allow incoming POST/PUT/DELETE requests from other domains **that you trust**, you must add them to [`CSRF_TRUSTED_ORIGINS`](https://docs.djangoproject.com/en/5.0/ref/settings/#csrf-trusted-origins) in the `archivebox/core/settings.py` source code on your machine ([open an issue](https://github.com/ArchiveBox/ArchiveBox/issues/new/choose) and explain your use-case for help).
-
-Log in via the Admin Web UI: `/admin/login/`, you can then re-use your login session id (stored in the `sessionid` cookie) for REST API requests. By default, this only allows you to make requests from the same domain ArchiveBox is being served on (e.g. from browser devtools open on an ArchiveBox page or CLI tools).
-
-```bash
-curl -X 'GET' \
- 'http://127.0.0.1:8000/api/v1/core/snapshots?limit=10' \
- -H 'accept: application/json' \
- -H 'Cookie: sessionid=YOURSESSIONIDVALUEHERE'
-```
-
-
-
-### API HTTP Basic Authentication
-
-> [!CAUTION]
-> This method is fairly uncommon and is only useful in a few niche situations where the other methods are not available.
-> **We will likely remove this method in a future ArchiveBox release if nobody uses it.**
-> *If you rely on this method and want us to keep it, please [open an issue](https://github.com/ArchiveBox/ArchiveBox/issues/new/choose) and explain your use-case!*
-
-Pass your ArchiveBox admin username & password via HTTP Basic Authentication.
-
-```bash
-curl -X 'GET' \
- 'http://127.0.0.1:8000/api/v1/core/snapshots?limit=10' \
- -u 'YOURUSERNAMEHERE:YOURPASSWORDHERE'
- -H 'accept: application/json'
-```
-
-
-
-#### Further Reading
-
-- The ArchiveBox API auth implementation: [`archivebox/api/auth.py`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/api/auth.py#:~:text=API_AUTH_METHODS) + [`archivebox/api/v1_auth.py`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/api/v1_auth.py)
-- The [`django-ninja` auth documentation](https://django-ninja.dev/guides/authentication/) (which powers our API)
-- The [Swagger auth documentation](https://swagger.io/docs/specification/authentication/) for the interactive API Docs UI
diff --git a/docs/Setting-up-Search.md b/docs/Setting-up-Search.md
deleted file mode 100644
index cbcef77a..00000000
--- a/docs/Setting-up-Search.md
+++ /dev/null
@@ -1,258 +0,0 @@
-# Setting Up Search
-
-## How to Search in ArchiveBox
-
-You can search your ArchiveBox data in a number of ways:
-
-- using the CLI: `archivebox list --filter-type=search 'text to search'` (`archivebox list --help` for more)
-- using the Web UI: both the `/public` index and `/admin/core/snapshot` pages provide a search box
-- using the REST API: `/api/v1/list?filter_type=search` provides the same search interface as the CLI
-- by searching the archive data folder directly with external tools (e.g. macOS Spotlight, [Cerebro](https://www.cerebroapp.com/), `ag`, [Yacy](https://yacy.net/), etc.)
-
-
-
-
-
----
-
-## How Search Works
-
-ArchiveBox search works by doing substring matches in `Snapshot` metadata fields (`url`, `title`, `timestamp`, `tags`), and by searching the full archived content within each Snapshot (using the selected search backend below). You can find the search implementation source code here: [`archivebox/core/views.py: PublicIndex.get_queryset()`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/core/views.py#:~:text=title__icontains).
-
-> *Note: ArchiveBox currently only returns the bare list of snapshots that match when performing a search.*
->
-> This will be [improved in the future](https://zulip.archivebox.io/#narrow/stream/154-support/topic/Full.20Text.20Search.20works.2E.2E.2E.20but.20is.20there.20a.20UI.3F) to highlight the *specific paragraph/line/area that matched* within a Snapshot.
-> For now we recommend using Ctl+F in the browser or one of the external tools listed above to further filter for a term within a Snapshot's contents.
-
-
-
-## ArchiveBox Search Backends
-
-ArchiveBox provides a number of "Search Backend Engines" to tune its performance & behavior for different use-cases.
-```bash
-# this setting controls which search backend ArchiveBox uses
-archivebox config --set SEARCH_BACKEND_ENGINE=[ripgrep]|sonic|sqlite
-
-# to see information about the backend you are currently using, run:
-archivebox version
-archivebox config --get SEARCH_BACKEND_ENGINE
-```
-
-By default out-of-the-box, the selected engine is a simple but efficient tool similar to `grep -r` called [`ripgrep`](https://github.com/BurntSushi/ripgrep).
-
-Ripgrep is [currently the fastest](https://blog.burntsushi.net/ripgrep/) available *filesystem search* tool that scans over the raw archived files on every search. We chose it as the default so that beginners and 95% of users with small collections can have an experience that "just works", without needing to install and maintain complex additional dependencies or background workers.
-
-However, there are some fundamental limitations of scanning through every file on disk each time a search is done, so ArchiveBox provides a number of additional search backend options for when users outgrow `ripgrep`.
-
-> [!TIP]
-> **You should consider switching ArchiveBox to use `sonic` or another backend IF:**
->
-> - you have more than 1,000 Snapshots saved in your archive
-> - your archive data is stored on a slower filesystem like a spinning hard drive or remote network mount
-> - you want more advanced search features like stemming, boolean operators, and ability to search PDFs, eBooks, ZIP/tar files, etc.
-
-
-
-
-
-### `ripgrep` *(the default)*
-
-If you do not already have `ripgrep` installed, follow the [instructions here](https://github.com/BurntSushi/ripgrep#installation) to get it.
-ArchiveBox will use `ripgrep` by default if it is found, however you can explicitly configure it to be used like so:
-
-```bash
-archivebox config --set SEARCH_BACKEND_ENGINE=ripgrep
-archivebox config --set RIPGREP_BINARY=rg
-
-# check that archivebox detects the installed version:
-archivebox version
-
-# then try it out by searching via the Web UI or CLI:
-archivebox list --filter-type=search 'text to search for'
-```
-
-#### Pros
-- supports advanced searching with regex patterns
-- simple, few moving parts, and broadly available for all OSs and CPU architectures
-- 0 idle resource use as there is no background indexer process running
-- 0 additional disk storage needed as it searches the original data instead of maintaining a separate index
-- reasonably fast on NVMe and SSD drives for small collections
-
-#### Cons
-- very slow as archive collection size increases (doesn't scale well beyond 500~1,000 Snapshots)
-- very slow if underlying filesystem is slow (e.g. HDDs or network mounts)
-- doesn't support stemming, boolean operators, or other advanced full-text search features
-
-
-
-
-
-### `ripgrep-all` (aka `rga`)
-
-The same as ripgrep except that it supports searching more binary filetypes like PDFs, eBooks, Office documents, zip, tar.gz, etc.
-
-To use it, follow the [install instruction for your OS](https://github.com/phiresky/ripgrep-all#installation), then configure ArchiveBox to use it like so:
-
-```bash
-archivebox config --set SEARCH_BACKEND_ENGINE=ripgrep
-archivebox config --set RIPGREP_BINARY=rga
-
-# check that archivebox detects the installed version:
-archivebox version
-
-# then try it out by searching via the Web UI or CLI:
-archivebox list --filter-type=search 'text to search for'
-```
-
-
-
-
-
-### `ugrep`
-
-Not tested by the ArchiveBox team but it's very similar to `ripgrep` and may work as a drop-in replacement, with some caveats. (contributions welcome to improve support)
-
-`ugrep` is similar to `ripgrep` and `ripgrep-all` in that it's an indexless disk-search tool, but it provides some more of the full-text search features without the performance overhead of maintaining a separate search backend worker with an independent index.
-
-https://github.com/Genivia/ugrep
-
-```bash
-archivebox config --set RIPGREP_BINARY=ugrep+
-```
-
-#### Pros
-
-- supports [boolean operators](https://github.com/Genivia/ugrep#bool) in search queries
-- supports binary formats like compressed archives, PDFs, eBooks, etc.
-- better support for Unicode, special characters, and searching across multiple lines of text
-- supports [fuzzy search](https://github.com/Genivia/ugrep#fuzzy)
-
-#### Cons
-
-- not as fast as `sonic` and but also not as simple as `ripgrep`
-- not all of its features are fully integrated with ArchiveBox yet
-
-
-
-
-
-### `sonic` ⭐️ (the recommended upgrade path for most people)
-
-[Sonic](https://github.com/valeriansaliou/sonic) is a fast, lightweight, rust-based alternative to super-heavy traditional search backends like Elasticsearch. It is capable of normalizing natural language search queries, fuzzy matching, and searching Unicode, without needing to maintain a duplicate document store index of all the searchable text.
-
-Internally it functions as an index store, storing only the original IDs of the Snapshots with a super-compressed representation of the text. This allows it to scale to searching terabytes of archive data while maintaining an index only a fraction of that size.
-
-*ArchiveBox has supported Sonic for years, and it is the most thoroughly tested and recommended backend for ArchiveBox users that need to scale beyond `ripgrep`.*
-
-Using [sonic with ArchiveBox in Docker Compose](https://github.com/ArchiveBox/ArchiveBox/blob/dev/docker-compose.yml) is the easiest way to get started, though you can also use it without Docker by [installing it manually](https://github.com/valeriansaliou/sonic#installation) and then running `pip install archivebox[sonic]`.
-
-```bash
-# edit docker-compose.yml to uncomment the lines that enable sonic
-nano docker-compose.yml
-
-# make sure ArchiveBox is configured to use the Sonic backend
-docker compose run archivebox config --set SEARCH_BACKEND_ENGINE=sonic
-
-# restart the containers to apply changes and start the Sonic worker
-docker compose down
-docker compose up
-
-# check that the sonic container started without issues
-docker compose logs sonic
-docker compose run archivebox version
-
-# backfill any existing archivebox data into the Sonic index (may take an hour or longer depending on storage speed and collection size)
-docker compose run archivebox update --index-only
-
-# then test it out:
-docker compose run archivebox list --filter-type=search 'some text to search'
-```
-
-*Fore more detailed instructions [see here](https://github.com/ArchiveBox/ArchiveBox/issues/956#issuecomment-1320587158)...*
-
-#### Pros
-
-- extremely fast, most queries complete in microseconds even with 100k+ snapshots
-- maintains lightweight, compressed search index that is minuscule compared to original data
-- all-in-one binary written in rust, available cross-platform and easy to deploy
-- supports advanced full-text search features like normalization, stemming, etc.
-- supports indexing and querying on a remote server (many ArchiveBox instances can share a single `sonic` instance)
-
-#### Cons
-
-- one extra dependency to install and background worker to keep running (Docker Compose makes this easy though)
-- does not support searching binary files like PDFs, eBooks, compressed archives, etc.
-
-
-
-
-
-### `SQLite FTS5`
-
-This is a [recently added](https://github.com/ArchiveBox/ArchiveBox/pull/1241) experimental option that uses a separate SQLite3 Database (similar to the one ArchiveBox already uses for Snapshot metadata) to provide full-text search.
-
-```bash
-archivebox config --set SEARCH_BACKEND_ENGINE=sqlite
-
-# add existing data to index by running update:
-archivebox update --index-only
-
-# test it out using the archivebox Web UI or CLI:
-archivebox list --filter-type=search 'some text to search'
-
-# or using SQLite3 directly;
-sqlite3 ./search.sqlite3
-
-> SELECT snapshot_id FROM snapshot_fts
- INNER JOIN snapshot_id_fts ON snapshot_id_fts.rowid = snapshot_fts.rowid
- WHERE snapshot_fts MATCH "some text to search";
-```
-
-```bash
-# optional advanced tuning:
-archivebox config --set FTS_SEPARATE_DATABASE=True
-archivebox config --set FTS_TOKENIZERS="porter unicode61 remove_diacritics 2"
-archivebox config --set FTS_SQLITE_MAX_LENGTH=1000000000
-```
-
-- https://www.sqlite.org/fts5.html
-- https://github.com/ArchiveBox/ArchiveBox/pull/1241
-
-#### Pros
-
-- No additional dependencies needed to install, SQLite3 is already available and used by ArchiveBox
-- No long-running background search worker process needed, 0 idle resource use
-- Supports advanced full-text search features like boolean operators, stemming, phrases, etc.
-- Comparable speed and efficiency to `sonic` for most use-cases (much faster than `ripgrep`/`ugrep`)
-- Durability and portability, SQLite is widely used and supported by every major platform on earth
-
-#### Cons
-
-- Not as thoroughly-tested by ArchiveBox team as our `sonic` or `ripgrep` backends
-- Maintains a (compressed, but still potentially large) duplicate copy of all searchable text in `search.sqlite3` db
-- Does not support searching binary files PDFs, eBooks, compressed archives, etc.
-- Search indexing and querying must be performed on same server as ArchiveBox data (we don't yet support sending FTS5 queries to a remote server)
-
-
-
----
-
-
-
-### Further Reading
-
-- https://github.com/ArchiveBox/ArchiveBox/blob/dev/docker-compose.yml#:~:text=SEARCH_BACKEND_ENGINE
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#ripgrep_binary
-
-* [#22 Original Issue where full-text search functionality was proposed](https://github.com/ArchiveBox/ArchiveBox/issues/22)
-* [#543 + #570 Original PR where full-text search functionality was implemented](https://github.com/ArchiveBox/ArchiveBox/pull/543)
-* [#956 Documentation: Document how search works](https://github.com/ArchiveBox/ArchiveBox/issues/956#issuecomment-1320587158)
-* [#654 Support: Search Backend only searching admin Snapshot fields instead of archive content](https://github.com/ArchiveBox/ArchiveBox/issues/654)
-* [#1087 Support: Help setting up full text search](https://github.com/ArchiveBox/ArchiveBox/issues/1087)
-* [#1091 Support: Help switching to ripgrep-all](https://github.com/ArchiveBox/ArchiveBox/issues/1091)
-* [#1318 Troubleshooting: Search times out on v0.7.2 installed on Synology using Portainer](https://github.com/ArchiveBox/ArchiveBox/issues/1318)
-* [#1333 + #1316 Text Search and Filters don't work at the same time in the web UI](https://github.com/ArchiveBox/ArchiveBox/pull/1333)
-* [#1320 Troubleshooting: Sonic backend Error: ENDED authentication_failed doesn't contain protocol(NUMBER)](https://github.com/ArchiveBox/ArchiveBox/pull/1320)
-
-- [#1139 Feature Request: Add AI-assisted summarization, tagging, search, and more using LLMs / RAG](https://github.com/ArchiveBox/ArchiveBox/issues/1139)
-- [#1358 Django Admin general improvements: tree view, better filters, better sorting, custom pages, etc.](https://github.com/ArchiveBox/ArchiveBox/issues/1358)
diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md
deleted file mode 100644
index 522ca307..00000000
--- a/docs/Troubleshooting.md
+++ /dev/null
@@ -1,335 +0,0 @@
-# Troubleshooting
-
-▶️ *If you need help or have a question, you can open an [issue](https://github.com/ArchiveBox/ArchiveBox/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) or reach out on [Twitter](https://twitter.com/theSquashSH).*
-
-What are you having an issue with?:
-
-- [Installing ArchiveBox](#Installing)
-- [Upgrading ArchiveBox](https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives)
-- [Configuring ArchiveBox](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration)
-- [Archiving content with ArchiveBox](#Archiving)
-- [Hosting your collection publicly](#Hosting-the-Archive)
-- [Database and filesystem issues](#database)
-
----
-
-## Installing
-
-If using `archivebox` without Docker, make sure you've followed the full guide in the [[Install]] instructions first. Then check here for help depending on what component you need help with.
-
-Then make sure `archivebox` is installed available in your `$PATH`.
-```bash
-apt show archivebox # show info about the apt-installed version of archivebox
-brew info archivebox # show info about the brew-installed version of archivebox
-pip show archivebox # show info about the pip-installed version of archivebox
-
-echo $PATH # show the directories your system is searching for binaries
-which -a archivebox # show all installed archivebox binaries available
-which archivebox # show which archivebox binary is being called
-```
-**⭐️ Show the full archivebox version info + info about all installed dependencies:**
-```bash
-archivebox version # shows lots of useful info about installed dependencies and more
-```
-(ensure the version shown is the most recent available from [Releases](https://github.com/ArchiveBox/ArchiveBox/releases))
-
-### macOS
-**✨ ArchiveBox no longer needs to be `brew`-installed:**
-✅ ArchiveBox still fully supports macOS, don't worry!
-📦 Just install it using `pip` (or `pipx`) instead now:
-```bash
-mkdir -p ~/archivebox/data
-cd ~/archivebox/data # (for example, can be anywhere)
-
-pip install archivebox # just use pip to get archivebox
-archivebox install # then finish installing dependencies
-```
-More info: https://github.com/ArchiveBox/homebrew-archivebox
-
-### Python
-
-Make sure you have at least Python 3.9 installed on your system.
-
-```bash
-python3 --version
-pip --version
-pip install --upgrade pip setuptools
-```
-
-If you still need help getting Python installed, [the official Python docs](https://docs.python.org/3.9/using/unix.html) are a good place to start.
-
-### Chromium/Google Chrome
-
-For more info, see the [[Chromium Install]] page.
-
-ArchiveBox depends on being able to access a `chromium-browser`/`google-chrome` executable. The executable used
-defaults to `chromium-browser` but can be manually specified with the environment variable `CHROME_BINARY`:
-
-```bash
-env CHROME_BINARY=/usr/local/bin/chromium-browser archivebox add ~/Downloads/bookmarks_export.html
-```
-
-1. Test to make sure you have Chrome on your `$PATH` with:
-
-```bash
-which chromium-browser || which google-chrome
-```
-If no executable is displayed, follow the setup instructions to install and link one of them.
-
-2. If a path is displayed, the next step is to check that it's runnable:
-
-```bash
-chromium-browser --version || google-chrome --version
-```
-If no version is displayed, try the setup instructions again, or confirm that you have permission to access chrome.
-
-3. If a version is displayed and it's `<111`, upgrade it:
-
-```bash
-apt upgrade chromium-browser -y
-# OR
-brew cask upgrade chromium-browser
-```
-
-4. If a version is displayed and it's `>=111`, make sure ArchiveBox is running the right one:
-
-```bash
-env CHROME_BINARY=/path/from/step/1/chromium-browser archivebox version # replace the path with the one you got from step 1
-```
-
-
-### Wget & Curl
-
-If you're missing `wget` or `curl`, simply install them using `apt` or your package manager of choice.
-See the "Manual Setup" instructions for more details.
-
-If wget times out or randomly fails to download some sites that you have confirmed are online,
-upgrade wget to the most recent version with `brew upgrade wget` or `apt upgrade wget`. There is
-a bug in versions `<=1.19.1_1` that caused wget to fail for perfectly valid sites.
-
-### NPM Dependencies
-
-NPM packages like `readability`, `singlefile`, etc. are auto-installed by `archivebox setup` into `data/node_modules`.
-
-Make sure you have installed NodeJS + NPM first, here are their [official install docs](https://nodejs.org/en/download/package-manager/).
-
-```bash
-node --version # make sure you have node >=19 installed
-npm --version # make sure you have npm installed
-
-cd ~/archivebox/data # go into your data directory
-archivebox setup # auto-installs all JS dependencies into ./node_modules
-# equivalent to:
-# curl -fsSL 'https://raw.githubusercontent.com/ArchiveBox/ArchiveBox/stable/archivebox/package.json' > package.json
-# npm install
-
-# install npm dependencies should then be present in ~/archivebox/data/node_modules/.bin
-archivebox version # show version full info to make sure they're loaded correctly
-```
-
----
-
-## Archiving
-
-### No links parsed from export file
-
-Please open an [issue](https://github.com/ArchiveBox/ArchiveBox/issues) with a description of where you got the export, and
-preferably your export file attached (you can redact the links). We'll fix the parser to support your format.
-
-### Lots of skipped sites
-
-If you ran the archiver once, it wont re-download sites subsequent times, it will only download new links.
-If you haven't already run it, make sure you have a working internet connection and that the parsed URLs look correct.
-You can check the ArchiveBox stdout logs or the Web UI to see what links it's downloading.
-
-If you're still having issues, try deleting or moving the `./archive` folder (back it up first!) and running `archivebox init` again.
-
-### Lots of errors
-
-Make sure you have all the dependencies installed and that you're able to visit the links from your browser normally.
-Open an [issue](https://github.com/ArchiveBox/ArchiveBox/issues) with a description of the errors if you're still having problems.
-
-### Lots of broken links from the index
-
-Not all sites can be effectively archived with each method, that's why it's best to use a combination of `wget`, PDFs, and screenshots.
-If it seems like more than 10-20% of sites in the archive are broken, open an [issue](https://github.com/ArchiveBox/ArchiveBox/issues)
-with some of the URLs that failed to be archived and I'll investigate.
-
-### Removing unwanted links from the index
-
-`archivebox remove --help`
-
-## Hosting the Archive
-
-If you're having issues trying to host the archive via nginx, make sure you already have nginx running with SSL.
-If you don't, google around, there are plenty of tutorials to help get that set up. Open an [issue](https://github.com/ArchiveBox/ArchiveBox/issues)
-if you have problem with a particular nginx config.
-
-### Other database or filesystem issues
-
-#### Docker Permissions issues
-
-Try Setting `PUID` & `PGID`: https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#puid--pgid
-
-Try using [`bindfs`](https://github.com/clecherbauer/docker-volume-bindfs) to work around issues by remapping permissions, for example to remap `uid:33 gid:33` on the host to `911:911` inside the container:
-`docker-compose.yml`:
-```yaml
-services:
- archivebox:
- volumes:
- - archivebox-data:/data
-
-volumes:
- archivebox-data:
- driver: lebokus/bindfs:latest
- driver_opts:
- sourcePath: "${EXTERNAL_MOUNT_PARENT}/external-parent/external/archivebox"
- map: "33/911:@33/@911"
-```
-
-
-
----
-
-
-
-## Database
-
-Database and filesystem issues are uncommon but do come up from time to time (especially when using networked storage, large archives, or multiple ArchiveBox processes for a single collection).
-
-*ℹ️ Generally, these commands can help you resolve most issues:*
-```bash
-archivebox init # upgrade the archivebox collection
-archivebox init --setup # upgrade the archivebox collection and all dependencies
-archivebox update --index-only # force an upgrade of some of the archivebox index/collection files
-archivebox server --debug # run the server with more verbose debug log output
-archivebox shell # access the Python API / Django management shell
-sqlite3 index.sqlite3 # access the SQLite3 SQL database shell
-```
-
-Don't be scared by the volume of content here. Almost all of these issues linked below are duplicates or old resolved bugs, but they contain valuable context and troubleshooting steps if you're trying to figure out the cause of a problem with your setup.
-
-#### Filesystem doesn't support FSYNC (e.g. network mounts)
-
-The `index.sqlite3` file must be stored on a filesystem that supports FSYNC (most local filesystems) in order to ensure SQLite3 database integrity when multiple ArchiveBox processes may be accessing it simultaneously. However, the `./archive` folder can be on a NAS or other filesystem that does not support FSYNC.
-
-- [Archivebox hangs when initializing collection on network drive that doesn't support FSYNC #742](https://github.com/ArchiveBox/ArchiveBox/issues/742)
-- [Question: How to run AB on localhost but store data on NAS? #894](https://github.com/ArchiveBox/ArchiveBox/issues/894)
-- [Question: Docker on Windows archiving to an SMB path that doesn't support FSYNC #722](https://github.com/ArchiveBox/ArchiveBox/issues/722)
-- [Support for network drives or filesystems that don't implement FSYNC #456](https://github.com/ArchiveBox/ArchiveBox/issues/456)
-
-More info:
-- https://www.geeksforgeeks.org/python-os-fsync-method/
-- https://man7.org/linux/man-pages/man2/fdatasync.2.html
-- https://www.samba.org/samba/docs/current/man-html/smb.conf.5.html
-- https://eclecticlight.co/2022/02/18/how-can-you-trust-a-disk-to-write-data/
-
-#### Database and filesystem contention issues when running multiple ArchiveBox processes
-
-ArchiveBox can sometimes struggle when archiving many links in parallel with multiple ArchiveBox processes trying to write to the database at the same time, leading to errors like this:
-```bash
-Unable to create the django_migrations table (database is locked)
-```
-
-These errors can also be encountered when there are permissions, network, or filesystem issues preventing writes to `index.sqlite3`.
-
-- [Question: Unable to create the django_migrations table (database is locked) - When OUTPUT_DIR to SAMBA share #946](https://github.com/ArchiveBox/ArchiveBox/issues/946)
-- [Question: ...Unable to create the django_migrations table (database is locked) #880](https://github.com/ArchiveBox/ArchiveBox/issues/880)
-- [Database is locked and other weird behavior when doing simultaneous adds #781](https://github.com/ArchiveBox/ArchiveBox/issues/781)
-- [Bugfix: Retry on "database locked" error (or add support for PostgreSQL/MySQL DB backend) #601](https://github.com/ArchiveBox/ArchiveBox/issues/601)
-- [Architecture: Use multiple cores to run link archiving in parallel #91](https://github.com/ArchiveBox/ArchiveBox/issues/91)
-- [ArchiveBox index corruption when running multiple import processes on v0.5.0 #454](https://github.com/ArchiveBox/ArchiveBox/issues/454)
-- [Architecture: Concurrent runs accidentally delete each other's temp files, leaving the index broken #234](https://github.com/ArchiveBox/ArchiveBox/issues/234)
-- [Database is locked and other weird behavior when doing simultaneous adds #781](https://github.com/ArchiveBox/ArchiveBox/issues/781)
-- [Bugfix: Retry on "database locked" error (or add support for PostgreSQL/MySQL DB backend) #601](https://github.com/ArchiveBox/ArchiveBox/issues/601)
-
-More info:
-- https://www.sqlite.org/lockingv3.html
-- https://charlesleifer.com/blog/going-fast-with-sqlite-and-python/
-- https://victoria.dev/blog/sqlite-in-production-with-wal/
-- https://code.djangoproject.com/ticket/29280
-- https://stackoverflow.com/questions/47761570/how-can-i-avoid-database-is-locked-sqlite3-errors-in-django
-
-#### Database migrations errors or upgrade issues
-
-Migration or upgrade issues happen occasionally with some niche setups or when skipping major versions during archiving.
-Always backup your archive before upgrading, but know that migrations are deterministic and atomic using Django's migration system, so a failed migration does not mean your archive is unrecoverable, you just have to downgrade to the previous stable major version then continue upgrading.
-
-```bash
-archivebox init # this usually applies any necessary migrations (atomically and idempotently, safe to run multiple times)
-```
-
-- [Bug: NOT NULL constraint failed: core_archiveresult.output when upgrading v0.4.24 archive to v0.6 #705](https://github.com/ArchiveBox/ArchiveBox/issues/705)
-- [Bugfix: sqlite3.IntegrityError: NOT NULL constraint failed: core_archiveresult.cmd_version and .output #597](https://github.com/ArchiveBox/ArchiveBox/issues/597)
-- [Error: django.db.utils.IntegrityError: UNIQUE constraint failed: core_tag.slug #596](https://github.com/ArchiveBox/ArchiveBox/issues/596)
-- [Bugfix: django.db.utils.IntegrityError: UNIQUE constraint failed: core_snapshot.timestamp #412](https://github.com/ArchiveBox/ArchiveBox/issues/412)
-- [Best Practices for Backup/Restore #341](https://github.com/ArchiveBox/ArchiveBox/issues/341)
-- [Bug: Running archivebox update --index-only doesn't upgrade Snapshot index.{html,json} files #962](https://github.com/ArchiveBox/ArchiveBox/issues/962)
-- [Feature Request: Deduplicate files on archives #704](https://github.com/ArchiveBox/ArchiveBox/issues/704)
-
-More info:
-- https://docs.djangoproject.com/en/4.0/topics/migrations/
-- https://realpython.com/django-migrations-a-primer/
-- https://realpython.com/digging-deeper-into-migrations/
-- https://www.kite.com/blog/python/django-database-migrations-overview/
-- https://markusholtermann.eu/2021/06/writing-safe-database-migrations-in-django/
-
-
-#### Repairing a corrupted SQLite3 database file
-
-A corrupted database file can theoretically only happen if an external process or filesystem error corrupts the SQLite3 database (there have only been [two](https://github.com/ArchiveBox/ArchiveBox/issues/1699) [reports](https://github.com/ArchiveBox/ArchiveBox/issues/955) of a user encountering this in real life). If you ever need to repair a corrupted ArchiveBox index you can run the following steps.
-
-Note this is specific to this error, these steps do not apply to other migrations/db errors (see above/below for other issues):
-```bash
-sqlite3.DatabaseError: database disk image is malformed
-```
-
-Generally all index issues should be fixable by running `archivebox init`.
-You can see the status of Snapshots and find any invalid/orphan/missing snapshots with `archivebox status`.
-
-**Error output:**
-
-```python3
-[i] [2022-03-24 20:37:27] ArchiveBox v0.6.2: archivebox init
- > /data
-
-[^] Verifying and updating existing ArchiveBox collection to v0.6.2...
-----------------------------------------------------------------------
-
-[*] Verifying archive folder structure...
- + ./archive, ./sources, ./logs...
- + ./ArchiveBox.conf...
-
-[*] Verifying main SQL index and running any migrations needed...
-Traceback (most recent call last):
- File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 82, in _execute
- return self.cursor.execute(sql)
- File "/usr/local/lib/python3.9/site-packages/django/db/backends/sqlite3/base.py", line 411, in execute
- return Database.Cursor.execute(self, query)
-sqlite3.DatabaseError: database disk image is malformed
-```
-
-**Steps to fix:**
-
-```bash
-cd ~/archivebox/data
-echo '.dump' | sqlite3 index.sqlite3 | sqlite3 repaired_index.sqlite3
-mv index.sqlite3 corrupt_index.sqlite3
-mv repaired_index.sqlite3 index.sqlite3
-```
-
-More info:
-- https://github.com/ArchiveBox/ArchiveBox/issues/955 and https://github.com/ArchiveBox/ArchiveBox/issues/1699
-- https://stackoverflow.com/questions/5274202/sqlite3-database-or-disk-is-full-the-database-disk-image-is-malformed
-
-
----
-
-See here for more info:
-
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Merging-Collections
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#python-shell-usage
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#sql-shell-usage
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#do-not-run-as-root
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#output-folder
diff --git a/docs/Upgrading-or-Merging-Archives.md b/docs/Upgrading-or-Merging-Archives.md
deleted file mode 100644
index 16b6a211..00000000
--- a/docs/Upgrading-or-Merging-Archives.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Upgrading or Merging Archives
-
-Moved to:
-
-- [[Upgrading]]
-- [[Merging Collections]]
-- [Database Troubleshooting](./Troubleshooting#database)
diff --git a/docs/Upgrading.md b/docs/Upgrading.md
deleted file mode 100644
index a4da2ed2..00000000
--- a/docs/Upgrading.md
+++ /dev/null
@@ -1,143 +0,0 @@
-# Upgrading Versions
-
-```bash
-# cd /path/to/your/archivebox/data
-cd ~/archivebox/data
-
-pip install --upgrade --ignore-installed archivebox
-# or
-docker pull archivebox/archivebox:latest
-
-# upgrade the collection to a new version
-archivebox init
-```
-
-
-**✅ Upgrading checklist:**
-
-1. Find the version you want to upgrade to on https://github.com/ArchiveBox/ArchiveBox/releases
-2. **Read the release notes carefully** for any instructions or extra steps around upgrading for each release you're skipping or installing
-3. **Make a full backup** of your `index.sqlite3` and `archive/` content before upgrading!
-`gzip -9 < index.sqlite3 > "index.sqlite3.$(date +%s).bak"`
-4. Follow the steps below depending on your setup to run `archivebox init` (repeating as necessary for each major version if upgrading across multiple major versions)
-5. Confirm the upgrade succeeded and check for any orphan/corrupted snapshots with `archivebox status`
-
-💬 [Open an issue](https://github.com/ArchiveBox/ArchiveBox/issues/new/choose) in our bug tracker if you experience any problems with upgrading/merging/modifying collections.
-
----
-
-*Note: It's recommended to only upgrade one major version at a time. e.g. if you're on `v0.4.14`, upgrade to `v0.5.6` next, then `v0.6.3`, and finally `v0.7.1` (as 3 separate steps).
-You can specify exact versions with pip like so: `pip install archivebox==0.6.3` or with docker `docker pull archivebox/archivebox:0.6.3`. Upgrading directly across multiple major versions may work in some cases, but is not recommended for maximum data safety.*
-
-
----
-
-**ℹ️ How it works internally:**
-
-The same command is used for initializing a new archive and upgrading an existing one. `archivebox init` is idempotent and safely be run multiple times. Running it will ensure your collection is on the latest version and all the files are in their correct locations. `archivebox status` can be used to check for orphan/corrupted snapshots or invalid index data.
-
-There are three main areas on disk that ArchiveBox modifies during upgrades:
-- `index.sqlite3` contains the SQLite3 DB index that gets upgraded automatically by Django based on the changes in [`archivebox/core/models.py`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/core/models.py).
-- `archive/*/index.json` these files are redundant json exports of the data for each Snapshot in `index.sqlite3`, these files are overwritten on every `archivebox update` run or anytime the Snapshot is modified from the GUI or CLI. These files will be [lazily updated](https://github.com/ArchiveBox/ArchiveBox/issues/962) to the latest schema versions as ArchiveBox accesses them, but are usually not modified in bulk during `archivebox init` when upgrading.
-- `archive/*` the Snapshot output files may be moved or renamed by future upgrades (so far they have remained unchanged since v0.1, but future versions reserve the right to change their locations)
-
-The `ArchiveBox.conf` file is not modified by upgrades and should remain forward-compatible across future versions (even when config options are renamed, we check the old names internally to maintain compatibility).
-
-As of v0.4 and above, ArchiveBox uses the Django migrations system for deterministic, atomic, safe upgrades, so your DB should always be left in a consistent state in the event of a failure or power outage. If you need help fixing a corrupted collection, open an issue using the link above.
-
-More info:
-- https://docs.djangoproject.com/en/4.0/topics/migrations/
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#database-migrations-errors-or-upgrade-issues
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Troubleshooting
-
----
-
-### Upgrading with Docker Compose ⭐️
-
-Using Docker Compose is recommended because it makes upgrading a breeze! ✨
-Pulling and running the latest version automatically upgrades the ArchiveBox collection and all of ArchiveBox's internal dependencies.
-
-```bash
-cd ~/archivebox # or wherever your folder containing docker-compose.yml is
-docker-compose down # stop the currently running archivebox containers
-docker-compose down # run twice to clear stopped containers
-docker-compose pull # pull the latest image version from Docker Hub
-docker-compose up # collection will be automatically upgraded as it starts
-```
-
-More info:
-- https://github.com/ArchiveBox/ArchiveBox#%EF%B8%8F-easy-setup
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Docker#docker-compose
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Docker#setup
-
-### Upgrading with plain Docker
-
-Upgrading with plain Docker is similar to the process with Docker Compose, but you have to run `archivebox init` manually at the end to finish the process.
-
-```bash
-docker ps -a -q --filter ancestor=archivebox/archivebox # find any currently running archivebox containers
-docker kill # stop any currently running archivebox versions
-
-docker pull archivebox/archivebox
-docker run -v $PWD:/data -it archivebox/archivebox init # upgrade the collection to the latest version
-
-# restart the archivebox server container if needed
-docker run -v $PWD:/data -it -p 8000:8000 archivebox/archivebox server 0.0.0.0:8000
-```
-
-More info:
-- https://github.com/ArchiveBox/ArchiveBox#%EF%B8%8F-easy-setup
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Docker#docker
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Docker#setup-1
-
-### Upgrading with a package manager
-
-Package manager releases take a lot of effort to maintain ([contributions welcome!](https://github.com/ArchiveBox/ArchiveBox/wiki/Donations)) and sometimes lag behind the Docker releases. We make a best effort to have the latest release available through all channels within a reasonable timeframe.
-
-```bash
-cd ~/archivebox/data # or wherever your data folder is
-killall archivebox # stop the currently running archivebox version
-
-# upgrade ArchiveBox using the package manager you originally used to install it
-pip install --upgrade --ignore-installed archivebox
-# or
-apt install --upgrade archivebox
-# or with the optional auto-installer script
-curl -sSL 'https://get.archivebox.io' | sh
-
-archivebox init # run init to upgrade the collection to the latest version
-
-archivebox update --index-only # optionally force an update of the snapshot index files (normally done lazily, see issue #962 for more info)
-
-archivebox status # check that everything succeeded
-```
-
-More info:
-- https://github.com/ArchiveBox/ArchiveBox#-package-manager-setup
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Install#manual-setup
-- https://github.com/ArchiveBox/pip-archivebox
-- https://github.com/ArchiveBox/homebrew-archivebox
-- https://github.com/ArchiveBox/docker-archivebox
-- https://github.com/ArchiveBox/debian-archivebox
-- https://github.com/ArchiveBox/electron-archivebox
-- https://aur.archlinux.org/packages/archivebox
-- https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/archivebox/default.nix
-
-
-
-## Merge two or more existing archives
-
-See [[Merging Collections]]...
-
-
-
-
-
-## Related Documents
-
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Troubleshooting#database
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#disk-layout
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#large-archives
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#output-folder
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#python-shell-usage
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#sql-shell-usage
diff --git a/docs/Usage.md b/docs/Usage.md
deleted file mode 100644
index 4edc3fd1..00000000
--- a/docs/Usage.md
+++ /dev/null
@@ -1,430 +0,0 @@
-# Usage
-
-▶️ _Make sure the dependencies are [fully installed](https://github.com/ArchiveBox/ArchiveBox/wiki/Install) before running any ArchiveBox commands._
-
-**ArchiveBox API Reference:**
-
-
-
-- [CLI Usage](#CLI-Usage): Docs and examples for the ArchiveBox command line interface.
-- [Admin UI Usage](#UI-Usage): Docs and screenshots for the outputted HTML archive interface.
-- [Browser Extension Usage](#Browser-Extension-Usage): Docs and screenshots for the outputted HTML archive interface.
-- [Disk Layout](#Disk-Layout): Description of the archive folder structure and contents.
-
-**Related:**
-
-- [[Docker]]: Learn about ArchiveBox usage with Docker and Docker Compose
-- [[Configuration]]: Learn about the various archive method options
-- [[Scheduled Archiving]]: Learn how to set up automatic daily archiving
-- [[Publishing Your Archive]]: Learn how to host your archive for others to access
-- [[Troubleshooting]]: Resources if you encounter any problems
-
-## CLI Usage
-
-
-
-All three of these ways of running ArchiveBox are equivalent and interchangeable:
-
-- `archivebox [subcommand] [...args]`
- *Using the PyPI package via `pip install archivebox`*
-- `docker run ... archivebox/archivebox [subcommand] [...args]`
- *Using the official Docker image*
-- `docker-compose run archivebox [subcommand] [...args]`
- *Using the official Docker image w/ Docker Compose*
-
-You can share a single archivebox data directory between Docker and non-Docker instances as well, allowing you to run the server in a container but still execute CLI commands on the host for example.
-
-For more examples see [README: Usage](https://github.com/ArchiveBox/ArchiveBox#%EF%B8%8F-cli-usage) and [[Docker]] pages.
-
-- [Run ArchiveBox with configuration options](#Run-ArchiveBox-with-configuration-options)
-- [Import a single URL](#Import-a-single-URL)
-- [Import a list of URLs from a text file](#Import-a-list-of-URLs-from-a-text-file)
-- [Import list of links from browser history](#Import-list-of-links-from-browser-history)
-
----
-
-### Run ArchiveBox with configuration options
-
-You can set environment variables in your shell profile, a config file, or by using the `env` command.
-
-```bash
-# set config via the CLI
-archivebox config --set MEDIA_MAX_SIZE=750mb
-
-# OR modify the config file directly
-echo 'MEDIA_MAX_SIZE=750mb' >> ArchiveBox.conf
-
-# OR use environment variables
-env MEDIA_MAX_SIZE=750mb archivebox add 'https://example.com'
-```
-
-See [[Configuration]] page for more details about the available options and ways to pass config.
-If you're using Docker, also make sure to read the Configuration section on the [[Docker]] page.
-
-> [!TIP]
-> You can run ArchiveBox commands from anywhere (without having to `cd` into a data directory first):
-> `/usr/bin/env --chdir=/path/to/archivebox/data archivebox update`
-
----
-
-### Import a single URL
-
-```bash
-archivebox add 'https://example.com'
-# OR
-echo 'https://example.com' | archivebox add
-```
-
-You can also add `--depth=1` to any of these commands if you want to recursively archive the URLs and all URLs one hop away. (e.g. all the outlinks on a page + the page).
-
-### Import a list of URLs from a text file
-
-```bash
-cat urls_to_archive.txt | archivebox add
-# OR
-archivebox add < urls_to_archive.txt
-# OR
-curl 'https://example.com/some/rss/feed.xml' | archivebox add
-# OR
-archivebox add --depth=1 'https://example.com/some/rss/feed.xml'
-```
-
-You can also pipe in RSS, XML, Netscape, or any of the other [supported import formats](https://github.com/ArchiveBox/ArchiveBox/wiki/Quickstart#2-get-your-list-of-urls-to-archive) via stdin.
-
-```bash
-archivebox add < ~/Downloads/browser_bookmarks_export.html
-# OR
-archivebox add < ~/Downloads/pinboard_bookmarks.json
-# OR
-archivebox add < ~/Downloads/any_text_containing_urls.txt
-```
-
----
-
-### Import list of links from browser history
-
-Look in the `bin/` folder of this repo to find a script to parse your browser's SQLite history database for URLs.
-Specify the type of the browser as the first argument, and optionally the path to the SQLite history file as the second argument.
-
-```bash
-./bin/export-browser-history --chrome
-archivebox add < output/sources/chrome_history.json
-# or
-./bin/export-browser-history --firefox
-archivebox add < output/sources/firefox_history.json
-# or
-./bin/export-browser-history --safari
-archivebox add < output/sources/safari_history.json
-```
-
-
-
----
-
-
-
-### Import browser cookies into a persona
-
-To archive logged-in sites, you can import cookies from your browser into a persona. This generates a `cookies.txt` file in the persona directory (used by wget/curl/yt-dlp, etc.) and, for Chromium-based browsers, also copies the profile into the persona so Chrome-based extractors can reuse it.
-
-```bash
-archivebox persona create --import=chrome personal
-# supported: chrome/chromium/brave/edge (Chromium-based only)
-# use --profile to target a specific profile (e.g. Default, Profile 1)
-# re-running import merges/dedupes cookies.txt (by domain/path/name) but replaces chrome_user_data
-```
-
-If cookie extraction fails, you can still export a Netscape-format `cookies.txt` using a browser extension and place it at `data/personas//cookies.txt`.
-
-
-
----
-
-
-
-## UI Usage
-
-```bash
-# configure which areas you want to require login to use vs make publicly available
-archivebox config --set PUBLIC_INDEX=False
-archivebox config --set PUBLIC_SNAPSHOTS=False
-archivebox config --set PUBLIC_ADD_VIEW=False
-
-archivebox manage createsuperuser # set an admin password to use for any areas requiring login
-archivebox server 0.0.0.0:8000 # start the archivebox web server
-
-open http://127.0.0.1:8000 # open the admin UI in a browser to view your archive
-```
-
-*See the [Configuration Wiki](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#public_index--public_snapshots--public_add_view) and [Security Wiki](https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#archiving-private-content) for more info...*
-
-Or if you prefer to generate a [static HTML index](https://github.com/ArchiveBox/ArchiveBox#static-archive-exporting) instead of using the built-in web server, you can run `archivebox list --html --with-headers > ./index.html` and then open `./index.html` in a browser. You should see something [like this](https://demo.archivebox.io).
-
-You can sort by column, search using the box in the upper right, and see the total number of links at the bottom.
-
-Click the Favicon under the "Files" column to go to the details page for each link.
-
-
-
-
-
-
-### Explanation of buttons in the web UI - admin snapshots list
-
-
-
-A logged-in admin user may select ☑️ one or more snapshots from the list and perform Snapshot actions:
-
-- Search Search text in the Snapshot title, URL, tags, or archived content (supports regex with the default ripgrep search backend, or enable the [Sonic](https://github.com/ArchiveBox/ArchiveBox/blob/dev/docker-compose.yml#L35) full-text search backend in `docker-compose.yml` and set `SEARCH_BACKEND_ENGINE=sonic`, `SEARCH_BACKEND_HOST`, `SEARCH_BACKEND_PASSWORD` for full-text fuzzy searching) https://github.com/ArchiveBox/ArchiveBox/issues/956
-- Tags Start typing in the field to select some tags, then click `+` to add them or `-` remove them from the checked snapshots (`Tags` can be created/edited from the `/admin/core/tag/` page)
-- Title Pull the latest title and favicon without doing a full snapshot. (helpful to quickly ping any URLs that are stuck showing up as `Pending...` or are missing a title)
-- Pull Finish downloading the Snapshot, pulls any missing/failed outputs/extractors methods (pdf, wget... etc). Resumes running the same archiving steps as when you add new URL. Useful to finish pulling when previous import was paused or interrupted by a reboot or something. https://github.com/ArchiveBox/ArchiveBox#output-formats
-- Re-Snapshot Re-archive the original URL from scratch as a new separate snapshot. Differs from pulling in that it doesn't resume/update existing snapshot, it creates a new separate entry and re-snapshots the URL at the current point in time. (useful for saving multiple Snapshots of a single URL over time) https://github.com/ArchiveBox/ArchiveBox#saving-multiple-snapshots-of-a-single-url
-- Reset Keep the Snapshot entry, but delete all its archive results and redownload them from scratch immediately. Useful for re-trying a bad Snapshot and overwriting its previous results, e.g. if it initially archived a temporary error page or hit a transient rate-limit/CAPTCHA/login page.
-- Delete Delete a snapshot and all its archive results entirely. This action cannot be undone. (Note: to thoroughly remove every trace of a URL ever being added, you should also manually scrub log output found in `sources/` and `logs/`)
-
-
-
----
-
-
-
-## Browser Extension Usage
-
-Set up the official [ArchiveBox Browser Extension](https://github.com/ArchiveBox/archivebox-browser-extension) to submit URLs directly from your browser to ArchiveBox.
-
-1. Install the extension in your browser:
- - [Google Chrome / Edge / All Chromium-based browsers...](https://chrome.google.com/webstore/detail/habonpimjphpdnmcfkaockjnffodikoj)
- - [Firefox](https://addons.mozilla.org/en-US/firefox/addon/archivebox-exporter/)
-
-2. Log into your ArchiveBox server's admin UI in the same browser where you installed the extension, e.g.
- [`http://localhost:8000/admin/`](http://localhost:8000/admin/) or `https://demo.archivebox.io/admin/`
- The extension will re-use your admin UI login session to submit URLs to your server, so *make sure to log in!*
- . . .
- *Alternatively:* You can configure Archivebox to [allow submitting URLs without requiring log-in](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#public_index--public_snapshots--public_add_view)
- `archivebox config --set PUBLIC_ADD_VIEW=True`
-
-3. Click the ArchiveBox extension in your browser and set `Config > ArchiveBox Base URL` to your server's URL, e.g.
- `http://localhost:8000` or `https://demo.archivebox.io`
-
-4. ✅ Done! Test it out: `Right-click on any page > ArchiveBox Exporter > Archive Current Page`
- *Then check your ArchiveBox instance to confirm the URL was added.*
-
-
-
-
-#### More Info
-
-- https://github.com/ArchiveBox/archivebox-browser-extension
-- https://github.com/ArchiveBox/archivebox-browser-extension#setup
-- https://github.com/ArchiveBox/archivebox-browser-extension#features
-- https://github.com/ArchiveBox/archivebox-browser-extension#alternative-extensions-for-archiving
-- https://github.com/ArchiveBox/ArchiveBox/issues/577
-
-
-
----
-
-
-
-## Disk Layout
-
-The `OUTPUT_DIR` folder (usually whatever folder you run the `archivebox` command in), contains the UI HTML and archived data with the structure outlined below.
-
-Simply back up the entire `data/` folder to back up your archive, e.g. `zip -r data.backup.zip data`.
-
-```yaml
- - data/
- - index.sqlite3 # Main index of all archived URLs
- - ArchiveBox.conf # Main config file in ini format
-
- - archive/
- - 155243135/ # Archived links are stored in folders by timestamp
- - index.json # Index/details page for individual archived link
- - index.html
-
- # Archive method outputs:
- - warc/
- - media/
- - git/
- ...
-
- - sources/ # Each imported URL list is saved as a copy here
- - getpocket.com-1552432264.txt
- - stdin-1552291774.txt
- ...
-```
-
-For more info about ArchiveBox's database/filesystem layout and troubleshooting steps:
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#output-folder
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#modify-the-archivebox-sqlite3-db-directly
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#database-troubleshooting
-
-
-### Large Archives
-
-I've found it takes about an hour to download 1000 articles, and they'll take up roughly 1GB.
-Those numbers are from running it single-threaded on my i5 machine with 50mbps down. YMMV.
-
-Storage requirements go up immensely if you're using `FETCH_MEDIA=True` and are archiving many pages with audio & video.
-
-You can try to run it in parallel by manually splitting your URLs into separate chunks (though this may not work with `database locked` errors on slower filesystems):
-```bash
-archivebox add < urls_chunk_1.txt &
-archivebox add < urls_chunk_2.txt &
-archivebox add < urls_chunk_3.txt &
-```
-(though this may not be faster if you have a very large collection/main index)
-
-Users have reported running it with 50k+ bookmarks with success (though it will take more RAM while running).
-
-If you already imported a huge list of bookmarks and want to import only new
-bookmarks, you can use the `ONLY_NEW` environment variable. This is useful if
-you want to import a bookmark dump periodically and want to skip broken links
-which are already in the index.
-
-For more info about troubleshooting filesystem permissions, performance, or issues when running on a NAS:
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#output-folder
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#database-troubleshooting
-
-
-
----
-
-
-
-## SQL Shell Usage
-
-Explore the SQLite3 DB a bit to see what's available using the SQLite3 shell:
-```bash
-cd ~/archivebox/data
-sqlite3 index.sqlite3
-
-# example usage:
-SELECT * FROM core_snapshot;
-UPDATE auth_user SET email = 'someNewEmail@example.com' WHERE username = 'someUsernameHere';
-...
-```
-
-More info:
-- https://github.com/ArchiveBox/ArchiveBox#-sqlpythonfilesystem-usage
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#modify-the-archivebox-sqlite3-db-directly
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#database-troubleshooting
-- https://stackoverflow.com/questions/1074212/how-can-i-see-the-raw-sql-queries-django-is-running
-- https://adamobeng.com/wddbfs-mount-a-sqlite-database-as-a-filesystem/
-
-
-
----
-
-
-
-## Python Shell Usage
-
-Explore the Python API a bit to see what's available using the archivebox shell:
-
-**Python API Documentation:** https://docs.archivebox.io/dev/apidocs/index.html
-
-```bash
-$ archivebox shell
-[i] [2020-09-17 16:57:07] ArchiveBox v0.4.21: archivebox shell
- > /Users/squash/Documents/opt/ArchiveBox/data
-
-# Shell Plus Model Imports
-from core.models import Snapshot
-from django.contrib.admin.models import LogEntry
-from django.contrib.auth.models import Group, Permission, User
-from django.contrib.contenttypes.models import ContentType
-from django.contrib.sessions.models import Session
-# Shell Plus Django Imports
-from django.core.cache import cache
-from django.conf import settings
-from django.contrib.auth import get_user_model
-from django.db import transaction
-from django.db.models import Avg, Case, Count, F, Max, Min, Prefetch, Q, Sum, When
-from django.utils import timezone
-from django.urls import reverse
-from django.db.models import Exists, OuterRef, Subquery
-# ArchiveBox Imports
-from archivebox.core.models import Snapshot, User
-from archivebox import *
- help
- version
- init
- config
- add
- remove
- update
- list
- shell
- server
- status
- manage
- oneshot
- schedule
-
-[i] Welcome to the ArchiveBox Shell!
- https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#Shell-Usage
- https://docs.archivebox.io/dev/apidocs/index.html
-
- Hint: Example use:
- print(Snapshot.objects.filter(is_archived=True).count())
- Snapshot.objects.get(url="https://example.com").as_json()
- add("https://example.com/some/new/url")
-
-# run Python API queries/function calls directly
->>> print(Snapshot.objects.filter(is_archived=True).count())
-24
-
-# get help info on an object or function
->>> help(Snapshot)
-...
-
-# show raw SQL queries run
->>> from django.db import connection
->>> print(connection.queries)
-```
-
-For more info and example usage:
-- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives#example-adding-a-new-user-with-a-hashed-password
-- https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/main.py
-- https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/config.py
-- https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/core/models.py
-- https://stackoverflow.com/questions/1074212/how-can-i-see-the-raw-sql-queries-django-is-running
-
-
-
----
-
-
-
-## Python API Usage
-
-You can interact with ArchiveBox as a Python library from external scripts or programs.
-
-This API is a *local* API, designed to be used on the same machine as the ArchiveBox collection.
-
-For example you could creat a script `add_archivebox_url.py` like so:
-```python
-import os
-DATA_DIR = '~/archivebox/data'
-os.chdir(DATA_DIR)
-
-# you must import and setup django first to establish a DB connection
-from archivebox.config.legacy import setup_django
-setup_django()
-
-# then you can import all the main functions
-from archivebox.main import add, remove, server
-
-add('https://example.com', index_only=True, out_dir=DATA_DIR)
-remove(...)
-server(...)
-...
-```
-
-For more information see:
-- [ArchiveBox Python API Reference (ReadTheDocs)](https://docs.archivebox.io/dev/apidocs/index.html)
-- [ArchiveBox Developer Documentation](https://github.com/ArchiveBox/ArchiveBox#archivebox-development)
-- [ArchiveBox Python source code](https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/)
diff --git a/docs/Web-Archiving-Community.md b/docs/Web-Archiving-Community.md
deleted file mode 100644
index f3e7dbc9..00000000
--- a/docs/Web-Archiving-Community.md
+++ /dev/null
@@ -1,510 +0,0 @@
-# Web Archiving Community
-
-
-
-
-
-💬 Join us on our new ArchiveBox community chat server: https://Zulip.ArchiveBox.io
-
-🔢 **Just getting started and want to learn more about why Web Archiving is important? ** Check out this article: [On the Importance of Web Archiving](https://items.ssrc.org/parameters/on-the-importance-of-web-archiving/).
-
-
-
----
-
-The internet archiving community is surprisingly far-reaching and almost universally friendly! It has some overlap with the scraping and OSINT worlds, but it's also kinda its own thing.
-
-Whether you want to learn which organizations are the big players in the web archiving space, want to find a specific open source tool for your web archiving need, or just want to see where archivists hang out online, this is my attempt at an index of the entire web archiving community. I cant promise that this list is up-to-date, the bulk of it was written in ~2022.
-
-
-
-- [The Master Lists](#The-Master-Lists)
- *Community-maintained indexes of web archiving tools and groups by IIPC, COPTR, ArchiveTeam, Wikipedia, & the ASA.*
-
-- [Web Archiving Software](#Web-Archiving-Projects)
- *Open source tools and projects in the internet archiving space.*
- - [Bookmarking Services](#bookmarking-services)
- - [Well-Known Open Source Projects](#from-the-archiveorg--archive-it-teams)
- - [Public Archiving Services](#other-public-archiving-services)
- - [ArchiveBox Alternatives](#other-archivebox-alternatives)
- - [Smaller Utilities](#smaller-utilities)
-
-- [Reading List](#Reading-List)
- *Articles, posts, and blogs relevant to ArchiveBox and web archiving in general.*
- - [Blogs](#Blogs)
- - [Articles](#Articles)
- - [ArchiveBox-Specific Posts, Tutorials, and Guides](#archivebox-specific-posts-tutorials-and-guides)
- - [ArchiveBox Discussions in News & Social Media](#archivebox-discussions-in-news--social-media)
-
-- [Communities](#Communities)
- *A collection of the most active internet archiving communities and initiatives.*
- - [Most Active Web-Archiving Communities](#most-active-communities)
- - [Other Web Archiving Communities](#web-archiving-communities)
- - [General Archiving Foundations, Coalitions, Initiatives, and Institutes](#general-archiving-foundations-coalitions-initiatives-and-institutes)
-
----
-
-## The Master Lists
-
-
-
-Indexes of archiving institutions and software maintained by other people. If there's anything archivists love doing, it's making lists.
-
- - **[COPTR Wiki of Web Archiving Tools](http://coptr.digipres.org/Category:Tools) (COPTR)**
- - **[Awesome Web Archiving Tools](https://github.com/iipc/awesome-web-archiving) (IIPC)**
- - **[My up-to-date list of starred archiving github projects](https://github.com/stars/pirate/lists/internet-archiving)**
- - [Spreadsheet Comparison of Archiving Tools](https://github.com/datatogether/research/tree/master/web_archiving) (DataTogether)
- - [Awesome Web Crawling Tools](https://github.com/BruceDone/awesome-crawler)
- - [Awesome Web Scraping Tools](https://github.com/duyetdev/awesome-web-scraper)
- - [ArchiveTeam's List of Software](https://www.archiveteam.org/index.php?title=Software) (ArchiveTeam.org)
- - [List of Web Archiving Initiatives](https://en.wikipedia.org/wiki/List_of_Web_archiving_initiatives) (Wikipedia.org)
- - [Directory of Archiving Organizations](https://www2.archivists.org/assoc-orgs) (American Society of Archivists)
-
----
-
-## Web Archiving Projects
-
-
-
-### Bookmarking Services
-
-- **[Linkwarden](https://github.com/linkwarden/linkwarden)** Modern bookmarking UI with singlefile archiving
-- [Hoarder](https://github.com/hoarder-app/hoarder)
-- **[Gosuki](https://github.com/blob42/gosuki/releases/tag/v1.3.0) A lightweight, open-source, privacy-first bookmark manager that unifies bookmarks across multiple browsers**
-- ~[Pocket Premium](https://getpocket.com) Bookmarking tool that provides an archiving service in their paid version, run by Mozilla~
-- **[Pinboard](https://pinboard.in) Bookmarking tool that provides archiving in a paid version, run by a single independent developer**
-- **[Raindrop](https://raindrop.io) Bookmarking tool with archiving in their paid version, run by a company est. 2011**
-- [Instapaper](https://www.instapaper.com) Bookmarking alternative to Pocket/Pinboard (with no archiving)
-- [Wallabag](https://wallabag.org) / [Wallabag.it](https://wallabag.it) Self-hostable web archiving server that can import via RSS
-- [Shaarli](https://github.com/shaarli/Shaarli) Self-hostable bookmark tagging, archiving, and sharing service
-- [ReadWise](https://readwise.io/) A paid Pocket/Pinboard alternative that includes article snippet and highlight saving
-- [Diigo](https://www.diigo.com/) Another brookmarking/annotation service with archiving as a paid feature
-
----
-
-### From the Archive.org & Archive-It teams
-
-
-
-
-- **[Archive.org](https://archive.org) The O.G. Wayback Machine provided publicly by the Internet Archive (Archive.org)**
-- **[Archive.it](https://archive-it.org) commercial Wayback Machine solution**
-- **[Heritrix](https://github.com/internetarchive/heritrix3) The king of internet archiving crawlers, powers the Wayback Machine**
-- **[Brozzler](https://github.com/internetarchive/brozzler) chrome headless crawler + WARC archiver maintained by Archive.org**
-- [WarcProx](https://github.com/internetarchive/warcprox) WARC proxy recording and playback utility
-- [WarcTools](https://github.com/internetarchive/warctools) utilities for dealing with WARCs
-- [Grab-Site](https://github.com/ArchiveTeam/grab-site) An easy preconfigured web crawler designed for backing up websites
-- [WPull](https://github.com/ArchiveTeam/wpull) A pure python implementation of wget with WARC saving
-- [More on their GitHub...](https://github.com/internetarchive)
-
----
-
-### From Webrecorder
-
-
-
-[Webrecorder](https://webrecorder.net/) develops a suite of open source tools, to capture websites and replay them at a later time as accurately as possible. Webrecorder also publishes the [WACZ file format spec](https://specs.webrecorder.net/wacz/latest).
-
-- **[Browsertrix](https://webrecorder.net/browsertrix)** Fully integrated (self hostable) SaaS web archiving platform
-- **[ArchiveWeb.page](https://webrecorder.net/archivewebpage)** Chrome extension for manual, interactive archiving of websites as you browse the web. Good for capturing high-fidelity complex interactions
-- **[ReplayWeb.page](https://webrecorder.net/replaywebpage)** Web archive viewer that runs entirely in the browser and doesn't require any server-hosted component to view WARC and WACZ files. Also available as a standalone electron app for local desktop use
-- **[Browsertrix Crawler](https://github.com/webrecorder/browsertrix-crawler)** Command-line crawling application that powers Browsertrix's core crawling features
-- [pywb](https://github.com/webrecorder/pywb) aka *Python Wayback*, the open source toolkit forked from archive.org for self-hosting your own wayback machine among other web archiving tools
-- [warcit](https://github.com/webrecorder/warcit) Create a WARC file out of a folder full of assets
-- [warcio](https://github.com/webrecorder/warcio) fast streaming asynchronous WARC reader and writer
-- [More on their GitHub...](https://github.com/webrecorder)
-
----
-
-### From Rhizome.org (Conifer)
-
-
-
-- **[Conifer by Rhizome.org](https://conifer.rhizome.org/)** **An open-source personal archiving server that uses pywb under the hood.** [Previously affiliated with Webrecorder](https://blog.conifer.rhizome.org/2020/06/11/webrecorder-conifer.html)
-
----
-
-### From the Old Dominion University: Web Science Team
-
-
-
-- **[ipwb](https://github.com/oduwsdl/ipwb) A distributed web archiving solution using pywb with IPFS for storage**
-- **[archivenow](https://github.com/oduwsdl/archivenow) tool that pushes urls into all the online archive services like Archive.is and Archive.org**
-- [node-warc](https://github.com/N0taN3rd/node-warc) Parse And Create Web ARChive (WARC) files with node.js
-- [WAIL](https://machawk1.github.io/wail/) Web archiver GUI using Heritrix and OpenWayback
-- [Squidwarc](https://github.com/N0taN3rd/Squidwarc) User-scriptable, archival crawler using Chrome
-- [WAIL (Electron)](https://github.com/n0tan3rd/wail) Electron app version of the original [wail](https://github.com/machawk1/wail) for creating and interacting with web archives
-- **[warcreate](https://github.com/machawk1/warcreate) a Chrome extension for creating WARCs from any webpage**
-- [More on their GitHub...](https://github.com/oduwsdl)
-
----
-
-### From the Archives Unleashed Team
-
-
-
-- [AUT](https://github.com/archivesunleashed/aut) Archives Unleashed Toolkit for analyzing web archives (formerly WarcBase)
-- [Warclight](https://github.com/archivesunleashed/warclight) A Rails engine for finding and searching web archives
-- [More on their GitHub...](https://github.com/archivesunleashed)
-
----
-
-### From the IIPC team
-
-
-
-- **[OpenWayback](https://github.com/iipc/openwayback/wiki) Open source project developing core Wayback Machine components**
-- **[awesome-web-archiving](https://github.com/iipc/awesome-web-archiving) Large list of archiving projects and orgs**
-- [JWARC](https://github.com/iipc/jwarc) A Java library for reading and writing WARC files.
-- [More on their GitHub...](https://github.com/iipc)
-
----
-
-### Other Public Archiving Services
-
-
-
-- https://archive.is / https://archive.today
-- https://ghostarchive.org
-- https://perma.cc
-- https://arquivo.pt
-- https://www.pagefreezer.com
-- https://www.smarsh.com
-- https://www.stillio.com
-- https://archive.st
-- https://theoldnet.com/
-- https://timetravel.mementoweb.org/
-- https://freezepage.com/
-- https://webcitation.org/archive
-- https://archiveofourown.org/
-- https://megalodon.jp/
-- https://www.webarchive.org.uk/ukwa/
-- https://github.com/HelloZeroNet/ZeroNet (super cool project)
-- Google, Bing, DuckDuckGo, and other [search engine caches](https://www.clickminded.com/google-cache-search/)
-
----
-
-### Other ArchiveBox Alternatives
-
-> *There are **much more recent** projects listed here: https://github.com/stars/pirate/lists/internet-archiving*
-
-- **[Browsertrix](https://webrecorder.net/browsertrix) + [ArchiveWeb.page](https://webrecorder.net/archivewebpage) + [ReplayWeb.page](https://webrecorder.net/replaywebpage) Webrecorder's archiving suite has the highest fidelity, and can flawlessly archive YouTube, X, Facebook, and other complex, JS-heavy SPAs**
-- **[SingleFile](https://github.com/gildas-lormeau/SingleFile/) Web Extension / CLI util for Firefox and Chrome to save a web page as a single HTML file**
-- **[Memex by Worldbrain.io](https://github.com/WorldBrain/Memex) a beautiful, user-friendly browser extension that archives all history with full-text search, annotation support, and more**
-- **[Hypothes.is](https://web.hypothes.is/) a web/pdf/ebook annotation tool that also archives content**
-- **[Reminiscence](https://github.com/kanishka-linux/reminiscence/) extremely similar to ArchiveBox, uses a Django backend + UI and provides auto-tagging and summary features with NLTK**
-- **[Shaarchiver](https://github.com/nodiscc/shaarchiver) very similar project that archives Firefox, Shaarli, or Delicious bookmarks and all linked media, generating a markdown/HTML index**
-- **[Archivy](https://github.com/archivy/archivy) Python-based self-hosted knowledge base embedded into your filesystem**
-- **[Polarized](https://web.archive.org/web/20221225012011/https://getpolarized.io/) a desktop application for bookmarking, annotating, and archiving articles offline**
-- **[LinkWarden](https://github.com/linkwarden/linkwarden) Link archival and curation web app, very similar to ArchiveBox**
-- **[Photon](https://github.com/s0md3v/Photon) a fast crawler with archiving and asset extraction support**
-- **[Scoop](https://github.com/harvard-lil/scoop)** Create high-fidelity WARC/WACZ captures using a playwright browser, with support for signing, media extraction, PDFs, etc. ([by the Perma.cc team](https://lil.law.harvard.edu/blog/2023/04/13/scoop-witnessing-the-web/))
-
-Ones I haven't personally vetted:
-
-- [Shiori](https://github.com/go-shiori/shiori) Simple bookmark manager + readability archiver built with Go (like a clone of Pocket)
-- [Percollate](https://github.com/danburzo/percollate) A command-line tool to turn web pages into beautiful, readable PDF, EPUB, or HTML docs.
-- [LinkAce](https://www.linkace.org/) A self-hosted bookmark management tool that saves snapshots to archive.org
-- [LinkDing](https://github.com/sissbruecker/linkding) Self-hosted bookmark manager that is designed be to be minimal, fast, and easy to set up using Docker.
-- [LinkWallet](https://github.com/tardisx/linkwallet) A self-hosted bookmark database with full-text page content search and limited archiving features
-- [Espial](https://github.com/jonschoning/espial) Bookmark manager and search tool with limited archiving features
-- [Diskernet](https://github.com/dosyago/DiskerNet) Archiving tool that uses the Chrome debugger protocol to save each page as-loaded in the browser** (aka 22120 by c0fe or i5ik)
-- [Trilium](https://github.com/zadam/trilium) Personal web UI based knowledge-base with web clipping and note-taking
-- [Herodotus](https://github.com/alaskanpuffin/herodotus-core) Django-based web archiving tool with a focus on collecting text-based content
-- [Buku](https://github.com/jarun/buku) Browser-independent bookmark manager CLI written in Python3 and SQLite3
-- [ReadableWebProxy](https://github.com/fake-name/ReadableWebProxy) A proxying archiver that downloads content from sites and can snapshot multiple versions of sites over time
-- [Perkeep](https://perkeep.org/) "Perkeep lets you permanently keep your stuff, for life."
-- [Fossilo](https://www.fossilo.com/) A commercial archiving solution that appears to be very similar to ArchiveBox
-- [NeonLink](https://github.com/AlexSciFier/neonlink) Simple self-hosted bookmark management + [Benotes](https://noted.lol/benotes/) note-taking app with limited archiving features
-- [Archivematica](https://github.com/artefactual/archivematica) web GUI for institutional long-term archiving of web and other content
-- [Headless Chrome Crawler](https://github.com/yujiosaka/headless-chrome-crawler) distributed web crawler built on puppeteer with screenshots
-- [WWWofle](http://www.gedanken.org.uk/software/wwwoffle/) old proxying recorder software similar to ArchiveBox
-- [Erised](https://github.com/marvelm/erised) Super simple CLI utility to bookmark and archive webpages
-- [Zotero](https://www.zotero.org/) collect, organize, cite, and share research (mainly for technical/scientific papers & citations)
-- [TiddlyWiki](https://tiddlywiki.com/) Non-linear bookmark and note-taking tool with archiving support
-- [Joplin](https://joplinapp.org/) Desktop + mobile app for knowledge-base-style info collection and notes (w/ optional plugin for archiving)
-- [Hunchly](https://www.hunch.ly/) A paid web archiving / session recording tool design for OSINT
-- [Monolith](https://github.com/Y2Z/monolith) CLI tool for saving complete web pages as a single HTML file
-- [Obelisk](https://github.com/go-shiori/obelisk) Go package and CLI tool for saving web page as single HTML file
-- [Munin Archiver](https://github.com/peterk/munin-indexer) Social media archiver for Facebook, Instagram and VKontakte accounts.
-- **[Wayback](https://github.com/wabarc/wayback) Archiving in style like ArchiveBox, but with a chat.**
----
-
-### Smaller Utilities
-
-Random helpful utilities for web archiving, WARC creation and replay, and more...
-
-- https://github.com/TheCakeIsNaOH/xbs-to-archivebox A utility to sync xBrowserSync bookmarks with ArchiveBox
-- https://github.com/karlicoss/promnesia A browser extension that [collects and collates all the URLs you visit](https://beepb00p.xyz/promnesia.html) into a hierarchical/graph structure with metadata
-- https://github.com/vrtdev/save-page-state A Chrome extension for saving the state of a page in multiple formats
-- https://github.com/jsvine/waybackpack command-line tool that lets you download the entire Wayback Machine archive for a given URL
-- https://github.com/hartator/wayback-machine-downloader Download an entire website from the Internet Archive Wayback Machine.
-- https://github.com/Lifesgood123/prevent-link-rot Replace any broken URLs in some content with Wayback machine URL equivalents
-- https://en.archivarix.com download an archived page or entire site from the Wayback Machine
-- https://proofofexistence.com prove that a certain file existed at a given time using the blockchain
-- https://github.com/chfoo/warcat for merging, extracting, and verifying WARC files
-- https://github.com/mozilla/readability tool for extracting article contents and text
-- https://github.com/mholt/timeliner All your digital life on a single timeline, stored locally
-- https://github.com/wkhtmltopdf/wkhtmltopdf Webkit HTML to PDF archiver/saver
-- [Sheetsee-Pocket](http://jlord.us/sheetsee-pocket/) project that provides a pretty auto-updating index of your Pocket links (without archiving them)
-- [Pocket -> IFTTT -> Dropbox](https://christopher.su/2013/saving-pocket-links-file-day-dropbox-ifttt-launchd/) Post by Christopher Su on his Pocket saving IFTTT recipe
-- http://squidman.net/squidman/index.html
-- https://wordpress.org/plugins/broken-link-checker/
-- https://github.com/ArchiveTeam/wpull
-- http://freedup.org/
-- https://en.wikipedia.org/wiki/Furl
-- https://preservica.com/digital-archive-software-1/active-digital-preservation For-profit company offering a digital preservation software suite
-- https://github.com/karlicoss/grasp capture webpages from Firefox and Chrome into Org-mode documents
-- https://github.com/dgtlmoon/changedetection.io Change detection and monitoring of web page content changes
-- [And many more on the other lists...](#the-master-lists)
-
-
----
-
-## Reading List
-
-A collection of blog posts and articles about internet archiving, contact me / open an issue if you want to add a link here!
-
----
-
-### Blogs Friends of ArchiveBox
-
-
-
-- https://blog.archive.org
-- https://webrecorder.net/blog
-- https://netpreserveblog.wordpress.com
-- https://blog.conifer.rhizome.org/
-- https://ws-dl.blogspot.com
-- https://siarchives.si.edu/blog
-- https://parameters.ssrc.org
-- https://sr.ithaka.org/publications
-- https://ait.blog.archive.org
-- https://brewster.kahle.org
-- https://ianmilligan.ca
-- https://medium.com/@giovannidamiola
-
----
-
-### Articles We Like About Internet Archiving
-
-- https://items.ssrc.org/parameters/on-the-importance-of-web-archiving/
-- https://theconversation.com/your-internet-data-is-rotting-115891
-- https://www.bbc.com/future/story/20190401-why-theres-so-little-left-of-the-early-internet
-- https://sr.ithaka.org/publications/the-state-of-digital-preservation-in-2018/
-- https://gizmodo.com/delete-never-the-digital-hoarders-who-collect-tumblrs-1832900423
-- https://siarchives.si.edu/blog/we-are-not-alone-progress-digital-preservation-community
-- https://www.gwern.net/Archiving-URLs
-- http://brewster.kahle.org/2015/08/11/locking-the-web-open-a-call-for-a-distributed-web-2/
-- https://lwn.net/Articles/766374/
-- https://en.wikipedia.org/wiki/List_of_Web_archiving_initiatives
-- https://medium.com/@giovannidamiola/making-the-internet-archives-full-text-search-faster-30fb11574ea9
-- https://xkcd.com/1909/
-- https://samsaffron.com/archive/2012/06/07/testing-3-million-hyperlinks-lessons-learned#comment-31366
-- https://www.gwern.net/docs/linkrot/2011-muflax-backup.pdf
-- https://thoughtstreams.io/higgins/permalinking-vs-transience/
-- http://ait.blog.archive.org/files/2014/04/archiveit_life_cycle_model.pdf
-- https://blog.archive.org/2016/05/26/web-archiving-with-national-libraries/
-- https://blog.archive.org/2014/10/28/building-libraries-together/
-- https://ianmilligan.ca/2018/03/27/ethics-and-the-archived-web-presentation-the-ethics-of-studying-geocities/
-- https://ianmilligan.ca/2018/05/22/new-article-if-these-crawls-could-talk-studying-and-documenting-web-archives-provenance/
-- https://ws-dl.blogspot.com/2019/02/2019-02-08-google-is-being-shuttered.html
-
-If any of these links are dead, you can find an archived version on https://archive.sweeting.me or https://web.archive.org.
-
----
-
-
-### ArchiveBox-Specific Posts, Tutorials, and Guides
-
-*Beware: many of these may be outdated, as ArchiveBox has frequent updates and continual improvement.*
-
-- "Install ArchiveBox on SaltBox.dev" https://docs.saltbox.dev/sandbox/apps/archivebox/#3-setup
-- "ArchiveBox is an open-source self-hosted web archiving system for the web and the desktop" https://medevel.com/archivebox/
-- "Install ArchiveBox on a One-Click Docker Application" https://www.vultr.com/docs/install-archivebox-on-a-oneclick-docker-application/
-- "ArchiveBox, una solución para crear nuestro propio Archive.org en miniatura y personalizado" https://www.genbeta.com/herramientas/archivebox-solucion-para-crear-nuestro-propio-archive-org-miniatura-personalizado
-- "网页存档的开源工具ArchiveBox,可以将网页文字、图片、媒体文件等都保存下来,供日后查看。基于Python的开源项目,可搭建私人的网络存档服务。" https://www.bilibili.com/s/video/BV1ib4y1X7SL
-- "Персональный интернет-архив без боли" https://habr.com/ru/company/vdsina/blog/550180/
-- "ArchiveBox, una solución para crear nuestro propio Archive.org en miniatura y personalizado" https://www.genbeta.com/herramientas/archivebox-solucion-para-crear-nuestro-propio-archive-org-miniatura-personalizado
-- "Preserve the Internet With ArchiveBox" https://www.cyberpunks.com/preserve-the-internet-with-archivebox/
-- "Сам себе архивариус. Изучаем возможности ArchiveBox" https://xakep.ru/2021/02/01/archivebox/
-- "使用存档盒制作自己的Internet存档" http://www.diglog.com/story/1045192.html
-- "How to Make Your Own Internet Archive With ArchiveBox" https://nixintel.info/osint-tools/make-your-own-internet-archive-with-archive-box/
-- "Mit ArchiveBox Webseiten auf der Festplatte archivieren" https://www.linux-community.de/ausgaben/linuxuser/2020/12/mit-archivebox-webseiten-auf-der-festplatte-archivieren/
-- "ArchiveBox:开源的WEB存档" https://zhen.bushini.de/14738.html / https://www.1fishsauce.com/?p=4206
-- "两个基于爬虫的项目: Kiwix & ArchiveBox" https://blog.csdn.net/JackLang/article/details/108328791
-- "如何创建自己的私人自托管即时阅读应用程序" https://www.pcpc.me/tech/self-hosted-read-later-app
-- "How to install ArchiveBox to preserve websites you care about"
- https://blog.sleeplessbeastie.eu/2019/06/19/how-to-install-archivebox-to-preserve-websites-you-care-about/
-- "How to remotely archive websites using ArchiveBox"
- https://blog.sleeplessbeastie.eu/2019/06/26/how-to-remotely-archive-websites-using-archivebox/
-- "How to Create Your Own Private Self-Hosted Read-It-Later App" https://www.makeuseof.com/tag/self-hosted-read-later-app/
-- "How to use CutyCapt inside ArchiveBox"
- https://blog.sleeplessbeastie.eu/2019/07/10/how-to-use-cutycapt-inside-archivebox/
-- "Automate ArchiveBox with Google Spreadsheet to Backup your internet"
- https://manfred.life/archivebox
-- "【デモ有♪】ConoHaのArchiveBoxアプリケーションを使ってみたよ"
- https://qiita.com/CloudRemix/items/691caf91efa3ef19a7ad
-- "WEB-ARCHIV TEIL 8: WALLABAG UND ARCHIVEBOX"
-http://webermartin.net/blog/web-archiv-teil-8-wallabag-und-archivebox/
-- https://metaxyntax.neocities.org/entries/7.html
-
-### ArchiveBox Discussions in News & Social Media
-
-
-
-- **Aggregators:**
- **[ProductHunt](https://www.producthunt.com/posts/archivebox)**, **[AlternativeTo](https://alternativeto.net/software/archivebox/)**, **[SaaSHub](https://www.saashub.com/archivebox)**, [Logiciels](https://www.logiciels.pro/logiciel-saas/archivebox/), [SteemHunt](https://steemhunt.com/@adnan556644/archivebox-the-open-source-self-hosted-internet-archiving-solution), [Recurse Center: The Joy of Computing](https://joy.recurse.com/posts/224-archivebox), [GitHub Changelog](https://changelog.com/news/archivebox-opensource-selfhosted-web-archive-6D0d), [Dev.To Ultra List](https://dev.to/teamxenox/-ultra-list-one-list-to-rule-them-all-march-19-4p4f), [O'Reilly 4 Short Links](https://www.oreilly.com/ideas/four-short-links-15-april-2019), [JaxEnter](https://jaxenter.com/github-trending-march-2019-157470.html)
-- **Blog Posts & Podcasts:**
- [Korben.info](https://korben.info/archivebox-un-clone-darchive-org-et-de-la-wayback-machine-a-auto-heberger.html), [Defining Desktop Linux Podcast #296 (0:55:00)](https://linuxunplugged.com/296), [Binärgewitter Podcast #221](http://blog.binaergewitter.de/2019/01/18/binaergewitter-talk-number-221-vertieft-in-die-andere-richtung/), [Schrankmonster.de](https://www.schrankmonster.de/2019/04/10/archive-your-slice-of-the-web/), [La Ferme Du Web](https://www.lafermeduweb.net/veille/archivebox-archivez-des-copies-de-sites-en-local-avec-tous-les-medias-lies)
-- **Hacker News threads and comments:**
- [#1](https://news.ycombinator.com/item?id=14272133), [#2](https://news.ycombinator.com/item?id=18728546), [#3](https://news.ycombinator.com/item?id=18876685), **[#4](https://news.ycombinator.com/item?id=19346985)**, [and many more...](https://www.google.com/search?q=site%3Anews.ycombinator.com+%22archivebox%22)
-- **Reddit r/DataHoarder, r/SelfHosted, etc. posts and comments**:
- [#1](https://www.reddit.com/r/DataHoarder/comments/69e6i9/archive_a_browseable_copy_of_your_saved_pocket/), [#2](https://www.reddit.com/r/DataHoarder/comments/6kepv6/bookmarkarchiver_now_supports_archiving_all_major/), [#3](https://www.reddit.com/r/DataHoarder/comments/apnud4/continually_archive_websites_and_keep_the_older/), [#4](https://www.reddit.com/r/DataHoarder/comments/azdhd9/archivebox_open_source_selfhosted_web_archive/), [#5](https://www.reddit.com/r/DataHoarder/comments/b0o10h/archivebox_self_hosting_clone_of_archiveorg/) , **[#6](https://www.reddit.com/r/DataHoarder/comments/b4nrlc/in_case_you_havent_seen_it_archivebox_has_a/)**, [#7](https://www.reddit.com/r/selfhosted/comments/69eoi3/pocket_stream_archive_your_own_personal_wayback/), [#8](https://www.reddit.com/r/selfhosted/comments/an2368/archivebox_the_opensource_selfhosted_web_archive/), [and many more...](https://www.google.com/search?q=site%3Areddit.com+%22archivebox%22)
-- **Twitter:**
- [Python Trending](https://twitter.com/pythontrending/status/1092492387182628865), [PyCoder's Weekly](https://twitter.com/pycoders/status/1105803699799105536), [Python Hub](https://twitter.com/PythonHub/status/1107601343395651589), [Smashing Magazine](https://twitter.com/smashingmag/status/1107990604774928386), and many more...
-
-
----
-
-## Communities
-
-### Most Active Communities
-
-
-
-- **[The Internet Archive (Archive.org)](https://archive.org/iathreads/forums.php)** (USA)
-- **[International Internet Preservation Consortium (IIPC)](http://netpreserve.org/)** (International)
-- **[The Archive Team](https://www.archiveteam.org/), [URL Team](https://www.archiveteam.org/index.php?title=URLTeam), [r/ArchiveTeam](https://reddit.com/r/ArchiveTeam)** (International)
-- **[Rhizome.org](http://archive.rhizome.org/)** The digital preservation group that works on [Conifer by Rhizome](https://conifer.rhizome.org/) formerly Webrecorder.io (USA)
-- **[Webrecorder](https://webrecorder.net/)** (formerly known[¹](https://blog.conifer.rhizome.org/2020/06/11/webrecorder-conifer.html) as Webrecorder.io) is a company led by Ilya Kreymer, that researches and develops web archiving tools, widely used by the community.
-- **[Old Dominion University: Web Science and Digital Libraries (WS-DL @ ODU)](https://ws-dl.cs.odu.edu)** (Virginia, USA)
-- **[r/DataHoarder](https://www.reddit.com/r/DataHoarder), [r/Archivists](https://www.reddit.com/r/Archivists/), [r/DHExchange](https://www.reddit.com/r/DHExchange/)** (International)
-- [The Eye](https://the-eye.eu) Non-profit working on content archival and long-term preservation (Europe)
-- [Digital Preservation Coalition](https://www.dpconline.org/about) & their [Software Tool Registry (COPTR)](http://coptr.digipres.org/Main_Page) (UK & Wales)
-- [Archives Unleashed Project](https://archivesunleashed.org/about-project/) and [UAP GitHub](https://github.com/archivesunleashed) (Canada)
-
----
-
-### Web Archiving Communities
-
-
-
-Follow these technological and organizational archiving hubs for the latest archiving news.
-
-- [Canadian Web Archiving Coalition](https://www.carl-abrc.ca/advancing-research/digital-preservation/cwac/) (Canada)
-- [Web Archives for Historical Research Group](https://uwaterloo.ca/web-archive-group/about) (Canada)
-- [Smithsonian Institution Archives: Digital Curation](https://siarchives.si.edu/what-we-do/digital-curation) (Washington D.C., USA)
-- [National Digital Stewardship Alliance (NDSA)](http://www.digitalpreservation.gov/ndsa/NDSAtoDLF.html) (USA)
-- [Digital Library Federation (DLF)](https://www.diglib.org/about/) (USA)
-- [Council on Library and Information Resources (CLIR)](http://www.clir.org/about) (USA)
-- [Digital Curation Centre (DCC)](http://www.dcc.ac.uk/about-us) (UK)
-- [ArchiveMatica](https://www.archivematica.org/en/) & their [Community Wiki](https://wiki.archivematica.org/Community) (International)
-- [Professional Development Institutes for Digital Preservation (POWRR)](https://digitalpowrr.niu.edu/) (USA)
-- [Institute of Museum and Library Services (IMLS)](https://www.imls.gov/about/mission) (USA)
-- [Stanford Libraries Web Archiving](https://library.stanford.edu/projects/web-archiving) (USA)
-- [Society of American Archivists: Electronic Records (SAA)](https://www2.archivists.org/groups/electronic-records-section) (USA)
-- [BitCurator Consortium (BCC)](https://bitcuratorconsortium.org/mission) (USA)
-- [Ethics & Archiving the Web Conference (Rhizome)](https://eaw.rhizome.org/) (USA)
-- [Archivists Round Table of NYC](https://www.nycarchivists.org/) (USA)
-
----
-
-### General Archiving Foundations, Coalitions, Initiatives, and Institutes
-
-
-
-Find your local archiving group in the list and see how you can contribute!
-
-- [Community Archives and Heritage Group](https://www.communityarchives.org.uk/content/about/history-and-purpose) (UK & Ireland)
-- [Open Preservation Foundation (OPF)](https://openpreservation.org/about/organisation/) (UK & Europe)
-- [Software Preservation Network](https://www.softwarepreservationnetwork.org/about/) (International)
-- [ITHAKA](https://www.ithaka.org/content/our-mission), [Portico](https://www.portico.org/why-portico/), [JSTOR](https://www.jstor.org/), [ARTSTOR](http://www.artstor.org/), [S+R](https://sr.ithaka.org/our-work/collections-and-preservation/) (USA)
-- [Archives and Records Association](https://www2.archivists.org/assoc-orgs/archives-and-records-association-united-kingdom-ireland) (UK & Ireland)
-- [Arkivrådet](http://www.arkivradet.se/) (Sweden)
-- [Asociación Española de Archiveros, Bibliotecarios, Museologos y Documentalistas (ANABAD)](https://www2.archivists.org/assoc-orgs/asociaci%C3%B3n-espa%C3%B1ola-de-archiveros-bibliotecarios-museologos-y-documentalistas-anabad) (Spain)
-- [Associação dos Arquivistas Brasileiros (AAB)](https://www2.archivists.org/assoc-orgs/associacao-dos-arquivistas-brasileiros-aab) (Brazil)
-- [Associação Portuguesa de Bibliotecários, Archivistas e Documentalistas (BAD)](https://www2.archivists.org/assoc-orgs/associacao-portuguesa-de-bibliotecarios-archivistas-e-documentalistas-bad) (Portugal)
-- [Association des archivistes français (AAF)](https://www2.archivists.org/assoc-orgs/association-des-archivistes-francais-aaf) (France)
-- [Associazione Nazionale Archivistica Italiana (ANAI)](https://www2.archivists.org/assoc-orgs/associazione-nazionale-archivistica-italiana-anai) (Italy)
-- [Australian Society of Archivists Inc.](https://www2.archivists.org/assoc-orgs/australian-society-of-archivists-inc) (Australia)
-- [International Council on Archives (ICA)](https://www2.archivists.org/assoc-orgs/international-council-on-archives-ica)
-- [International Records Management Trust (IRMT)](https://www2.archivists.org/assoc-orgs/international-records-management-trust-irmt)
-- [Irish Society for Archives](https://www2.archivists.org/assoc-orgs/irish-society-for-archives) (Ireland)
-- [Koninklijke Vereniging van Archivarissen in Nederland](https://www2.archivists.org/assoc-orgs/koninklijke-vereniging-van-archivarissen-in-nederland) (Netherlands)
-- [State Archives Administration of the People's Republic of China](https://www2.archivists.org/assoc-orgs/state-archives-administration-of-the-peoples-republic-of-china) (China)
-- [Academy of Certified Archivists](https://www2.archivists.org/assoc-orgs/academy-of-certified-archivists)
-- [Archivists and Librarians in the History of the Health Sciences](https://www2.archivists.org/assoc-orgs/archivists-and-librarians-in-the-history-of-the-health-sciences)
-- [Archivists for Congregations of Women Religious](https://www2.archivists.org/assoc-orgs/archivists-for-congregations-of-women-religious)
-- [Archivists of Religious Institutions](https://www2.archivists.org/assoc-orgs/archivists-of-religious-institutions)
-- [Association of Catholic Diocesan Archivists](https://www2.archivists.org/assoc-orgs/association-of-catholic-diocesan-archivists)
-- [Association of Moving Image Archivists](https://www2.archivists.org/assoc-orgs/association-of-moving-image-archivists)
-- [Council of State Archivists](https://www2.archivists.org/assoc-orgs/council-of-state-archivists)
-- [National Association of Government Archives and Records Administrators](https://www2.archivists.org/assoc-orgs/national-association-of-government-archives-and-records-administrators)
-- [National Episcopal Historians and Archivists](https://www2.archivists.org/assoc-orgs/national-episcopal-historians-and-archivists)
-- [Archival Education and Research Institute](https://www2.archivists.org/assoc-orgs/archival-education-and-research-institute)
-- [Archives Leadership Institute](https://www2.archivists.org/assoc-orgs/archives-leadership-institute)
-- [Georgia Archives Institute](https://www2.archivists.org/assoc-orgs/georgia-archives-institute)
-- [Modern Archives Institute](https://www2.archivists.org/assoc-orgs/modern-archives-institute)
-- [Western Archives Institute](https://www2.archivists.org/assoc-orgs/western-archives-institute)
-- [Association des archivistes du Québec](https://www2.archivists.org/assoc-orgs/association-des-archivistes-du-quebec)
-- [Association of Canadian Archivists](https://www2.archivists.org/assoc-orgs/association-of-canadian-archivists)
-- [Canadian Council of Archives/Conseil canadien des archives](https://www2.archivists.org/assoc-orgs/canadian-council-of-archivesconseil-canadien-des-archives)
-- [Archives Association of British Columbia](https://www2.archivists.org/assoc-orgs/archives-association-of-british-columbia)
-- [Archives Association of Ontario](https://www2.archivists.org/assoc-orgs/archives-association-of-ontario)
-- [Archives Council of Prince Edward Island](https://www2.archivists.org/assoc-orgs/archives-council-of-prince-edward-island)
-- [Archives Society of Alberta](https://www2.archivists.org/assoc-orgs/archives-society-of-alberta)
-- [Association for Manitoba Archives](https://www2.archivists.org/assoc-orgs/association-for-manitoba-archives)
-- [Association of Newfoundland and Labrador Archives](https://www2.archivists.org/assoc-orgs/association-of-newfoundland-and-labrador-archives)
-- [Council of Nova Scotia Archives](https://www2.archivists.org/assoc-orgs/council-of-nova-scotia-archives)
-- [Réseau des services d'archives du Québec](https://www2.archivists.org/assoc-orgs/reseau-des-services-darchives-du-quebec)
-- [Saskatchewan Council for Archives and Archivists](https://www2.archivists.org/assoc-orgs/saskatchewan-council-for-archives-and-archivists)
-
-You can find more organizations and initiatives on these other lists:
-
-- [Wikipedia.org List of Web Archiving Initiatives](https://en.wikipedia.org/wiki/List_of_Web_archiving_initiatives)
-- [SAA List of USA & Canada Based Archiving Organizations](https://www2.archivists.org/assoc-orgs/directory)
-- [SAA List of International Archiving Organizations](https://www2.archivists.org/assoc-orgs/i_a_o)
-- [Digital Preservation Coalition's Member List](https://www.dpconline.org/about/members)
-
----
-
-## ArchiveBox Community Resources
-
-### ArchiveBox Chat Rooms
-
-- [Official ArchiveBox Zulip Chat Server](https://zulip.archivebox.io)
-- [Unofficial ArchiveBox Matrix chat room](https://matrix.to/#/#archivebox:matrix.org) (old)
-- [GitHub Discussions](https://github.com/ArchiveBox/ArchiveBox/discussions)
-
-### ArchiveBox on Social Media
-
-- [Twitter: @ArchiveBoxApp](https://twitter.com/ArchiveBoxApp)
-- [LinkedIn: ArchiveBox](https://www.linkedin.com/company/archivebox/)
-- [YouTube: @ArchiveBoxApp](https://www.youtube.com/@ArchiveBoxApp)
-- [Reddit: r/ArchiveBox](https://www.reddit.com/r/ArchiveBox/)
-- [Alternative.to](https://alternativeto.net/software/archivebox/about/)
-- [ReposHub](https://reposhub.com/python/web-crawling/pirate-ArchiveBox.html)
-
-### ArchiveBox on Package Distribution Platforms
-
-- [Python PyPI](https://pypi.org/project/archivebox/)
-- [Docker Hub](https://hub.docker.com/r/archivebox/archivebox)
-- [ArchLinux AUR](https://aur.archlinux.org/packages/archivebox)
-- [Ubuntu Launchpad PPA](https://launchpad.net/~archivebox/+archive/ubuntu/archivebox)
-
----
-
-
-
-[](https://www.patreon.com/theSquashSH)
-[](https://archive.org/donate/)
-
-
-
^ Back to Top ^
-
diff --git a/docs/_Footer.md b/docs/_Footer.md
deleted file mode 100644
index c552e502..00000000
--- a/docs/_Footer.md
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-[✏️ Help improve our documentation...](https://github.com/ArchiveBox/ArchiveBox/issues/new?template=3-documentation_change.yml)
-
-
-
-
diff --git a/docs/_Sidebar.md b/docs/_Sidebar.md
deleted file mode 100644
index 288d845d..00000000
--- a/docs/_Sidebar.md
+++ /dev/null
@@ -1,58 +0,0 @@
-[](Home)
-
-# [Getting Started](Quickstart)
-
- - 🔢 [[Quickstart]]
- - 🖥️ [[Install]]
- - 🐳 [[Docker]]
- - ➡️ [Supported Sources](https://github.com/ArchiveBox/ArchiveBox/wiki/Quickstart#2-get-your-list-of-urls-to-archive)
- - ⬅️ [Supported Outputs](https://github.com/ArchiveBox/ArchiveBox#output-formats)
-
-# [[Usage]]
-
- - ﹩[Command Line](Usage#cli-usage)
- - 🌐 [Web UI](Usage#ui-usage)
- - 🧩 [Browser Extension](Usage#browser-extension-usage)
- - 👾 [REST API](https://github.com/ArchiveBox/ArchiveBox/issues/496#issuecomment-2080174235) / [Webhooks](https://github.com/ArchiveBox/ArchiveBox/pull/1418)
- - 📜 [Python API](https://docs.archivebox.io/dev/apidocs/index.html) / [REPL](Usage#python-shell-usage) / [SQL API](Usage#sql-shell-usage)
-
-# Reference
-
- - ⚙️ [[Configuration]]
- - 📦 [Dependencies](https://github.com/ArchiveBox/ArchiveBox#dependencies)
- - 💿 [Disk Layout](https://github.com/ArchiveBox/ArchiveBox#archive-layout)
- - 🔒 [[Security Overview]]
- - 📝 [Developer Documentation](https://github.com/ArchiveBox/ArchiveBox#archivebox-development)
-
-# Guides
-
- - [[Upgrading]]
- - [[Setting up Storage]] (NFS/SMB/S3/etc)
- - [[Setting up Authentication]] (SSO/LDAP/etc)
- - [[Setting up Search]] (rg/sonic/etc)
- - [[Scheduled Archiving]]
- - [[Publishing Your Archive]]
- - [[Chromium Install]]
- - [Cookies & Sessions Setup](https://github.com/ArchiveBox/ArchiveBox/wiki/Chromium-Install#setting-up-a-chromium-user-profile)
- - [[Merging Collections]]
- - [[Troubleshooting]]
-
-# More Info
-
- - ⭐️ [[Web Archiving Community]]
- - [Background & Motivation](https://github.com/ArchiveBox/ArchiveBox#background--motivation)
- - [Comparison to Other Tools](https://github.com/ArchiveBox/ArchiveBox#comparison-to-other-projects)
- - [Architecture Diagram](https://github.com/ArchiveBox/ArchiveBox/wiki/ArchiveBox-Architecture-Diagrams)
- - [Changelog](https://github.com/ArchiveBox/ArchiveBox/releases) & [[Roadmap]]
-
----
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/_static/css/theme.css b/docs/_static/css/theme.css
deleted file mode 100644
index 1b33335c..00000000
--- a/docs/_static/css/theme.css
+++ /dev/null
@@ -1,6154 +0,0 @@
-html {
- box-sizing: border-box
-}
-
-*,:after,:before {
- box-sizing: inherit
-}
-
-article,aside,details,figcaption,figure,footer,header,hgroup,nav,section {
- display: block
-}
-
-audio,canvas,video {
- display: inline-block;
- display: inline;
- zoom: 1;
-}
-
-[hidden],audio:not([controls]) {
- display: none
-}
-
-* {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box
-}
-
-html {
- font-size: 100%;
- -webkit-text-size-adjust: 100%;
- -ms-text-size-adjust: 100%
-}
-
-body {
- margin: 0
-}
-
-a:active,a:hover {
- outline: 0
-}
-
-abbr[title] {
- border-bottom: 1px dotted
-}
-
-b,strong {
- font-weight: 700
-}
-
-blockquote {
- margin: 0
-}
-
-dfn {
- font-style: italic
-}
-
-ins {
- background: #ff9;
- text-decoration: none
-}
-
-ins,mark {
- color: #000
-}
-
-mark {
- background: #ff0;
- font-style: italic;
- font-weight: 700
-}
-
-.rst-content code,.rst-content tt,code,kbd,pre,samp {
- font-family: monospace,serif;
- _font-family: courier new,monospace;
- font-size: 1em
-}
-
-pre {
- white-space: pre
-}
-
-q {
- quotes: none
-}
-
-q:after,q:before {
- content: "";
- content: none
-}
-
-small {
- font-size: 85%
-}
-
-sub,sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline
-}
-
-sup {
- top: -.5em
-}
-
-sub {
- bottom: -.25em
-}
-
-dl,ol,ul {
- margin: 0;
- padding: 0;
- list-style: none;
- list-style-image: none
-}
-
-li {
- list-style: none
-}
-
-dd {
- margin: 0
-}
-
-img {
- border: 0;
- -ms-interpolation-mode: bicubic;
- vertical-align: middle;
- max-width: 100%
-}
-
-svg:not(:root) {
- overflow: hidden
-}
-
-figure,form {
- margin: 0
-}
-
-label {
- cursor: pointer
-}
-
-button,input,select,textarea {
- font-size: 100%;
- margin: 0;
- vertical-align: baseline;
- vertical-align: middle;
-}
-
-button,input {
- line-height: normal
-}
-
-button,input[type=button],input[type=reset],input[type=submit] {
- cursor: pointer;
- -webkit-appearance: button;
- overflow: visible;
-}
-
-button[disabled],input[disabled] {
- cursor: default
-}
-
-input[type=search] {
- -webkit-appearance: textfield;
- -moz-box-sizing: content-box;
- -webkit-box-sizing: content-box;
- box-sizing: content-box
-}
-
-textarea {
- resize: vertical
-}
-
-table {
- border-collapse: collapse;
- border-spacing: 0
-}
-
-td {
- vertical-align: top
-}
-
-.chromeframe {
- margin: .2em 0;
- background: #ccc;
- color: #000;
- padding: .2em 0
-}
-
-.ir {
- display: block;
- border: 0;
- text-indent: -999em;
- overflow: hidden;
- background-color: transparent;
- background-repeat: no-repeat;
- text-align: left;
- direction: ltr;
- line-height: 0;
-}
-
-.ir br {
- display: none
-}
-
-.hidden {
- display: none!important;
- visibility: hidden
-}
-
-.visuallyhidden {
- border: 0;
- clip: rect(0 0 0 0);
- height: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- width: 1px
-}
-
-.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus {
- clip: auto;
- height: auto;
- margin: 0;
- overflow: visible;
- position: static;
- width: auto
-}
-
-.invisible {
- visibility: hidden
-}
-
-.relative {
- position: relative
-}
-
-big,small {
- font-size: 100%
-}
-
-@media print {
- body,html,section {
- background: none!important
- }
-
- * {
- box-shadow: none!important;
- text-shadow: none!important;
- filter: none!important;
- -ms-filter: none!important
- }
-
- a,a:visited {
- text-decoration: underline
- }
-
- .ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after {
- content: ""
- }
-
- blockquote,pre {
- page-break-inside: avoid
- }
-
- thead {
- display: table-header-group
- }
-
- img,tr {
- page-break-inside: avoid
- }
-
- img {
- max-width: 100%!important
- }
-
- @page {
- margin: .5cm
- }
-
- .rst-content .toctree-wrapper>p.caption,h2,h3,p {
- orphans: 3;
- widows: 3
- }
-
- .rst-content .toctree-wrapper>p.caption,h2,h3 {
- page-break-after: avoid
- }
-}
-
-.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea {
- -webkit-font-smoothing: antialiased
-}
-
-.clearfix {
- zoom: 1;
-}
-
-.clearfix:after,.clearfix:before {
- display: table;
- content: ""
-}
-
-.clearfix:after {
- clear: both
-}
-
-/*!
- * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
- * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
- */
-@font-face {
- font-family: FontAwesome;
- src: url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);
- src: url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");
- font-weight: 400;
- font-style: normal
-}
-
-.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand {
- display: inline-block;
- font: normal normal normal 14px/1 FontAwesome;
- font-size: inherit;
- text-rendering: auto;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale
-}
-
-.fa-lg {
- font-size: 1.33333em;
- line-height: .75em;
- vertical-align: -15%
-}
-
-.fa-2x {
- font-size: 2em
-}
-
-.fa-3x {
- font-size: 3em
-}
-
-.fa-4x {
- font-size: 4em
-}
-
-.fa-5x {
- font-size: 5em
-}
-
-.fa-fw {
- width: 1.28571em;
- text-align: center
-}
-
-.fa-ul {
- padding-left: 0;
- margin-left: 2.14286em;
- list-style-type: none
-}
-
-.fa-ul>li {
- position: relative
-}
-
-.fa-li {
- position: absolute;
- left: -2.14286em;
- width: 2.14286em;
- top: .14286em;
- text-align: center
-}
-
-.fa-li.fa-lg {
- left: -1.85714em
-}
-
-.fa-border {
- padding: .2em .25em .15em;
- border: .08em solid #eee;
- border-radius: .1em
-}
-
-.fa-pull-left {
- float: left
-}
-
-.fa-pull-right {
- float: right
-}
-
-.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand {
- margin-right: .3em
-}
-
-.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand {
- margin-left: .3em
-}
-
-.pull-right {
- float: right
-}
-
-.pull-left {
- float: left
-}
-
-.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand {
- margin-right: .3em
-}
-
-.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand {
- margin-left: .3em
-}
-
-.fa-spin {
- -webkit-animation: fa-spin 2s linear infinite;
- animation: fa-spin 2s linear infinite
-}
-
-.fa-pulse {
- -webkit-animation: fa-spin 1s steps(8) infinite;
- animation: fa-spin 1s steps(8) infinite
-}
-
-@-webkit-keyframes fa-spin {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg)
- }
-
- to {
- -webkit-transform: rotate(359deg);
- transform: rotate(359deg)
- }
-}
-
-@keyframes fa-spin {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg)
- }
-
- to {
- -webkit-transform: rotate(359deg);
- transform: rotate(359deg)
- }
-}
-
-.fa-rotate-90 {
- -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
- -webkit-transform: rotate(90deg);
- -ms-transform: rotate(90deg);
- transform: rotate(90deg)
-}
-
-.fa-rotate-180 {
- -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
- -webkit-transform: rotate(180deg);
- -ms-transform: rotate(180deg);
- transform: rotate(180deg)
-}
-
-.fa-rotate-270 {
- -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
- -webkit-transform: rotate(270deg);
- -ms-transform: rotate(270deg);
- transform: rotate(270deg)
-}
-
-.fa-flip-horizontal {
- -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
- -webkit-transform: scaleX(-1);
- -ms-transform: scaleX(-1);
- transform: scaleX(-1)
-}
-
-.fa-flip-vertical {
- -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
- -webkit-transform: scaleY(-1);
- -ms-transform: scaleY(-1);
- transform: scaleY(-1)
-}
-
-:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270 {
- filter: none
-}
-
-.fa-stack {
- position: relative;
- display: inline-block;
- width: 2em;
- height: 2em;
- line-height: 2em;
- vertical-align: middle
-}
-
-.fa-stack-1x,.fa-stack-2x {
- position: absolute;
- left: 0;
- width: 100%;
- text-align: center
-}
-
-.fa-stack-1x {
- line-height: inherit
-}
-
-.fa-stack-2x {
- font-size: 2em
-}
-
-.fa-inverse {
- color: #fff
-}
-
-.fa-glass:before {
- content: ""
-}
-
-.fa-music:before {
- content: ""
-}
-
-.fa-search:before,.icon-search:before {
- content: ""
-}
-
-.fa-envelope-o:before {
- content: ""
-}
-
-.fa-heart:before {
- content: ""
-}
-
-.fa-star:before {
- content: ""
-}
-
-.fa-star-o:before {
- content: ""
-}
-
-.fa-user:before {
- content: ""
-}
-
-.fa-film:before {
- content: ""
-}
-
-.fa-th-large:before {
- content: ""
-}
-
-.fa-th:before {
- content: ""
-}
-
-.fa-th-list:before {
- content: ""
-}
-
-.fa-check:before {
- content: ""
-}
-
-.fa-close:before,.fa-remove:before,.fa-times:before {
- content: ""
-}
-
-.fa-search-plus:before {
- content: ""
-}
-
-.fa-search-minus:before {
- content: ""
-}
-
-.fa-power-off:before {
- content: ""
-}
-
-.fa-signal:before {
- content: ""
-}
-
-.fa-cog:before,.fa-gear:before {
- content: ""
-}
-
-.fa-trash-o:before {
- content: ""
-}
-
-.fa-home:before,.icon-home:before {
- content: ""
-}
-
-.fa-file-o:before {
- content: ""
-}
-
-.fa-clock-o:before {
- content: ""
-}
-
-.fa-road:before {
- content: ""
-}
-
-.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before {
- content: ""
-}
-
-.fa-arrow-circle-o-down:before {
- content: ""
-}
-
-.fa-arrow-circle-o-up:before {
- content: ""
-}
-
-.fa-inbox:before {
- content: ""
-}
-
-.fa-play-circle-o:before {
- content: ""
-}
-
-.fa-repeat:before,.fa-rotate-right:before {
- content: ""
-}
-
-.fa-refresh:before {
- content: ""
-}
-
-.fa-list-alt:before {
- content: ""
-}
-
-.fa-lock:before {
- content: ""
-}
-
-.fa-flag:before {
- content: ""
-}
-
-.fa-headphones:before {
- content: ""
-}
-
-.fa-volume-off:before {
- content: ""
-}
-
-.fa-volume-down:before {
- content: ""
-}
-
-.fa-volume-up:before {
- content: ""
-}
-
-.fa-qrcode:before {
- content: ""
-}
-
-.fa-barcode:before {
- content: ""
-}
-
-.fa-tag:before {
- content: ""
-}
-
-.fa-tags:before {
- content: ""
-}
-
-.fa-book:before,.icon-book:before {
- content: ""
-}
-
-.fa-bookmark:before {
- content: ""
-}
-
-.fa-print:before {
- content: ""
-}
-
-.fa-camera:before {
- content: ""
-}
-
-.fa-font:before {
- content: ""
-}
-
-.fa-bold:before {
- content: ""
-}
-
-.fa-italic:before {
- content: ""
-}
-
-.fa-text-height:before {
- content: ""
-}
-
-.fa-text-width:before {
- content: ""
-}
-
-.fa-align-left:before {
- content: ""
-}
-
-.fa-align-center:before {
- content: ""
-}
-
-.fa-align-right:before {
- content: ""
-}
-
-.fa-align-justify:before {
- content: ""
-}
-
-.fa-list:before {
- content: ""
-}
-
-.fa-dedent:before,.fa-outdent:before {
- content: ""
-}
-
-.fa-indent:before {
- content: ""
-}
-
-.fa-video-camera:before {
- content: ""
-}
-
-.fa-image:before,.fa-photo:before,.fa-picture-o:before {
- content: ""
-}
-
-.fa-pencil:before {
- content: ""
-}
-
-.fa-map-marker:before {
- content: ""
-}
-
-.fa-adjust:before {
- content: ""
-}
-
-.fa-tint:before {
- content: ""
-}
-
-.fa-edit:before,.fa-pencil-square-o:before {
- content: ""
-}
-
-.fa-share-square-o:before {
- content: ""
-}
-
-.fa-check-square-o:before {
- content: ""
-}
-
-.fa-arrows:before {
- content: ""
-}
-
-.fa-step-backward:before {
- content: ""
-}
-
-.fa-fast-backward:before {
- content: ""
-}
-
-.fa-backward:before {
- content: ""
-}
-
-.fa-play:before {
- content: ""
-}
-
-.fa-pause:before {
- content: ""
-}
-
-.fa-stop:before {
- content: ""
-}
-
-.fa-forward:before {
- content: ""
-}
-
-.fa-fast-forward:before {
- content: ""
-}
-
-.fa-step-forward:before {
- content: ""
-}
-
-.fa-eject:before {
- content: ""
-}
-
-.fa-chevron-left:before {
- content: ""
-}
-
-.fa-chevron-right:before {
- content: ""
-}
-
-.fa-plus-circle:before {
- content: ""
-}
-
-.fa-minus-circle:before {
- content: ""
-}
-
-.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before {
- content: ""
-}
-
-.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before {
- content: ""
-}
-
-.fa-question-circle:before {
- content: ""
-}
-
-.fa-info-circle:before {
- content: ""
-}
-
-.fa-crosshairs:before {
- content: ""
-}
-
-.fa-times-circle-o:before {
- content: ""
-}
-
-.fa-check-circle-o:before {
- content: ""
-}
-
-.fa-ban:before {
- content: ""
-}
-
-.fa-arrow-left:before {
- content: ""
-}
-
-.fa-arrow-right:before {
- content: ""
-}
-
-.fa-arrow-up:before {
- content: ""
-}
-
-.fa-arrow-down:before {
- content: ""
-}
-
-.fa-mail-forward:before,.fa-share:before {
- content: ""
-}
-
-.fa-expand:before {
- content: ""
-}
-
-.fa-compress:before {
- content: ""
-}
-
-.fa-plus:before {
- content: ""
-}
-
-.fa-minus:before {
- content: ""
-}
-
-.fa-asterisk:before {
- content: ""
-}
-
-.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before {
- content: ""
-}
-
-.fa-gift:before {
- content: ""
-}
-
-.fa-leaf:before {
- content: ""
-}
-
-.fa-fire:before,.icon-fire:before {
- content: ""
-}
-
-.fa-eye:before {
- content: ""
-}
-
-.fa-eye-slash:before {
- content: ""
-}
-
-.fa-exclamation-triangle:before,.fa-warning:before {
- content: ""
-}
-
-.fa-plane:before {
- content: ""
-}
-
-.fa-calendar:before {
- content: ""
-}
-
-.fa-random:before {
- content: ""
-}
-
-.fa-comment:before {
- content: ""
-}
-
-.fa-magnet:before {
- content: ""
-}
-
-.fa-chevron-up:before {
- content: ""
-}
-
-.fa-chevron-down:before {
- content: ""
-}
-
-.fa-retweet:before {
- content: ""
-}
-
-.fa-shopping-cart:before {
- content: ""
-}
-
-.fa-folder:before {
- content: ""
-}
-
-.fa-folder-open:before {
- content: ""
-}
-
-.fa-arrows-v:before {
- content: ""
-}
-
-.fa-arrows-h:before {
- content: ""
-}
-
-.fa-bar-chart-o:before,.fa-bar-chart:before {
- content: ""
-}
-
-.fa-twitter-square:before {
- content: ""
-}
-
-.fa-facebook-square:before {
- content: ""
-}
-
-.fa-camera-retro:before {
- content: ""
-}
-
-.fa-key:before {
- content: ""
-}
-
-.fa-cogs:before,.fa-gears:before {
- content: ""
-}
-
-.fa-comments:before {
- content: ""
-}
-
-.fa-thumbs-o-up:before {
- content: ""
-}
-
-.fa-thumbs-o-down:before {
- content: ""
-}
-
-.fa-star-half:before {
- content: ""
-}
-
-.fa-heart-o:before {
- content: ""
-}
-
-.fa-sign-out:before {
- content: ""
-}
-
-.fa-linkedin-square:before {
- content: ""
-}
-
-.fa-thumb-tack:before {
- content: ""
-}
-
-.fa-external-link:before {
- content: ""
-}
-
-.fa-sign-in:before {
- content: ""
-}
-
-.fa-trophy:before {
- content: ""
-}
-
-.fa-github-square:before {
- content: ""
-}
-
-.fa-upload:before {
- content: ""
-}
-
-.fa-lemon-o:before {
- content: ""
-}
-
-.fa-phone:before {
- content: ""
-}
-
-.fa-square-o:before {
- content: ""
-}
-
-.fa-bookmark-o:before {
- content: ""
-}
-
-.fa-phone-square:before {
- content: ""
-}
-
-.fa-twitter:before {
- content: ""
-}
-
-.fa-facebook-f:before,.fa-facebook:before {
- content: ""
-}
-
-.fa-github:before,.icon-github:before {
- content: ""
-}
-
-.fa-unlock:before {
- content: ""
-}
-
-.fa-credit-card:before {
- content: ""
-}
-
-.fa-feed:before,.fa-rss:before {
- content: ""
-}
-
-.fa-hdd-o:before {
- content: ""
-}
-
-.fa-bullhorn:before {
- content: ""
-}
-
-.fa-bell:before {
- content: ""
-}
-
-.fa-certificate:before {
- content: ""
-}
-
-.fa-hand-o-right:before {
- content: ""
-}
-
-.fa-hand-o-left:before {
- content: ""
-}
-
-.fa-hand-o-up:before {
- content: ""
-}
-
-.fa-hand-o-down:before {
- content: ""
-}
-
-.fa-arrow-circle-left:before,.icon-circle-arrow-left:before {
- content: ""
-}
-
-.fa-arrow-circle-right:before,.icon-circle-arrow-right:before {
- content: ""
-}
-
-.fa-arrow-circle-up:before {
- content: ""
-}
-
-.fa-arrow-circle-down:before {
- content: ""
-}
-
-.fa-globe:before {
- content: ""
-}
-
-.fa-wrench:before {
- content: ""
-}
-
-.fa-tasks:before {
- content: ""
-}
-
-.fa-filter:before {
- content: ""
-}
-
-.fa-briefcase:before {
- content: ""
-}
-
-.fa-arrows-alt:before {
- content: ""
-}
-
-.fa-group:before,.fa-users:before {
- content: ""
-}
-
-.fa-chain:before,.fa-link:before,.icon-link:before {
- content: ""
-}
-
-.fa-cloud:before {
- content: ""
-}
-
-.fa-flask:before {
- content: ""
-}
-
-.fa-cut:before,.fa-scissors:before {
- content: ""
-}
-
-.fa-copy:before,.fa-files-o:before {
- content: ""
-}
-
-.fa-paperclip:before {
- content: ""
-}
-
-.fa-floppy-o:before,.fa-save:before {
- content: ""
-}
-
-.fa-square:before {
- content: ""
-}
-
-.fa-bars:before,.fa-navicon:before,.fa-reorder:before {
- content: ""
-}
-
-.fa-list-ul:before {
- content: ""
-}
-
-.fa-list-ol:before {
- content: ""
-}
-
-.fa-strikethrough:before {
- content: ""
-}
-
-.fa-underline:before {
- content: ""
-}
-
-.fa-table:before {
- content: ""
-}
-
-.fa-magic:before {
- content: ""
-}
-
-.fa-truck:before {
- content: ""
-}
-
-.fa-pinterest:before {
- content: ""
-}
-
-.fa-pinterest-square:before {
- content: ""
-}
-
-.fa-google-plus-square:before {
- content: ""
-}
-
-.fa-google-plus:before {
- content: ""
-}
-
-.fa-money:before {
- content: ""
-}
-
-.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before {
- content: ""
-}
-
-.fa-caret-up:before {
- content: ""
-}
-
-.fa-caret-left:before {
- content: ""
-}
-
-.fa-caret-right:before {
- content: ""
-}
-
-.fa-columns:before {
- content: ""
-}
-
-.fa-sort:before,.fa-unsorted:before {
- content: ""
-}
-
-.fa-sort-desc:before,.fa-sort-down:before {
- content: ""
-}
-
-.fa-sort-asc:before,.fa-sort-up:before {
- content: ""
-}
-
-.fa-envelope:before {
- content: ""
-}
-
-.fa-linkedin:before {
- content: ""
-}
-
-.fa-rotate-left:before,.fa-undo:before {
- content: ""
-}
-
-.fa-gavel:before,.fa-legal:before {
- content: ""
-}
-
-.fa-dashboard:before,.fa-tachometer:before {
- content: ""
-}
-
-.fa-comment-o:before {
- content: ""
-}
-
-.fa-comments-o:before {
- content: ""
-}
-
-.fa-bolt:before,.fa-flash:before {
- content: ""
-}
-
-.fa-sitemap:before {
- content: ""
-}
-
-.fa-umbrella:before {
- content: ""
-}
-
-.fa-clipboard:before,.fa-paste:before {
- content: ""
-}
-
-.fa-lightbulb-o:before {
- content: ""
-}
-
-.fa-exchange:before {
- content: ""
-}
-
-.fa-cloud-download:before {
- content: ""
-}
-
-.fa-cloud-upload:before {
- content: ""
-}
-
-.fa-user-md:before {
- content: ""
-}
-
-.fa-stethoscope:before {
- content: ""
-}
-
-.fa-suitcase:before {
- content: ""
-}
-
-.fa-bell-o:before {
- content: ""
-}
-
-.fa-coffee:before {
- content: ""
-}
-
-.fa-cutlery:before {
- content: ""
-}
-
-.fa-file-text-o:before {
- content: ""
-}
-
-.fa-building-o:before {
- content: ""
-}
-
-.fa-hospital-o:before {
- content: ""
-}
-
-.fa-ambulance:before {
- content: ""
-}
-
-.fa-medkit:before {
- content: ""
-}
-
-.fa-fighter-jet:before {
- content: ""
-}
-
-.fa-beer:before {
- content: ""
-}
-
-.fa-h-square:before {
- content: ""
-}
-
-.fa-plus-square:before {
- content: ""
-}
-
-.fa-angle-double-left:before {
- content: ""
-}
-
-.fa-angle-double-right:before {
- content: ""
-}
-
-.fa-angle-double-up:before {
- content: ""
-}
-
-.fa-angle-double-down:before {
- content: ""
-}
-
-.fa-angle-left:before {
- content: ""
-}
-
-.fa-angle-right:before {
- content: ""
-}
-
-.fa-angle-up:before {
- content: ""
-}
-
-.fa-angle-down:before {
- content: ""
-}
-
-.fa-desktop:before {
- content: ""
-}
-
-.fa-laptop:before {
- content: ""
-}
-
-.fa-tablet:before {
- content: ""
-}
-
-.fa-mobile-phone:before,.fa-mobile:before {
- content: ""
-}
-
-.fa-circle-o:before {
- content: ""
-}
-
-.fa-quote-left:before {
- content: ""
-}
-
-.fa-quote-right:before {
- content: ""
-}
-
-.fa-spinner:before {
- content: ""
-}
-
-.fa-circle:before {
- content: ""
-}
-
-.fa-mail-reply:before,.fa-reply:before {
- content: ""
-}
-
-.fa-github-alt:before {
- content: ""
-}
-
-.fa-folder-o:before {
- content: ""
-}
-
-.fa-folder-open-o:before {
- content: ""
-}
-
-.fa-smile-o:before {
- content: ""
-}
-
-.fa-frown-o:before {
- content: ""
-}
-
-.fa-meh-o:before {
- content: ""
-}
-
-.fa-gamepad:before {
- content: ""
-}
-
-.fa-keyboard-o:before {
- content: ""
-}
-
-.fa-flag-o:before {
- content: ""
-}
-
-.fa-flag-checkered:before {
- content: ""
-}
-
-.fa-terminal:before {
- content: ""
-}
-
-.fa-code:before {
- content: ""
-}
-
-.fa-mail-reply-all:before,.fa-reply-all:before {
- content: ""
-}
-
-.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before {
- content: ""
-}
-
-.fa-location-arrow:before {
- content: ""
-}
-
-.fa-crop:before {
- content: ""
-}
-
-.fa-code-fork:before {
- content: ""
-}
-
-.fa-chain-broken:before,.fa-unlink:before {
- content: ""
-}
-
-.fa-question:before {
- content: ""
-}
-
-.fa-info:before {
- content: ""
-}
-
-.fa-exclamation:before {
- content: ""
-}
-
-.fa-superscript:before {
- content: ""
-}
-
-.fa-subscript:before {
- content: ""
-}
-
-.fa-eraser:before {
- content: ""
-}
-
-.fa-puzzle-piece:before {
- content: ""
-}
-
-.fa-microphone:before {
- content: ""
-}
-
-.fa-microphone-slash:before {
- content: ""
-}
-
-.fa-shield:before {
- content: ""
-}
-
-.fa-calendar-o:before {
- content: ""
-}
-
-.fa-fire-extinguisher:before {
- content: ""
-}
-
-.fa-rocket:before {
- content: ""
-}
-
-.fa-maxcdn:before {
- content: ""
-}
-
-.fa-chevron-circle-left:before {
- content: ""
-}
-
-.fa-chevron-circle-right:before {
- content: ""
-}
-
-.fa-chevron-circle-up:before {
- content: ""
-}
-
-.fa-chevron-circle-down:before {
- content: ""
-}
-
-.fa-html5:before {
- content: ""
-}
-
-.fa-css3:before {
- content: ""
-}
-
-.fa-anchor:before {
- content: ""
-}
-
-.fa-unlock-alt:before {
- content: ""
-}
-
-.fa-bullseye:before {
- content: ""
-}
-
-.fa-ellipsis-h:before {
- content: ""
-}
-
-.fa-ellipsis-v:before {
- content: ""
-}
-
-.fa-rss-square:before {
- content: ""
-}
-
-.fa-play-circle:before {
- content: ""
-}
-
-.fa-ticket:before {
- content: ""
-}
-
-.fa-minus-square:before {
- content: ""
-}
-
-.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before {
- content: ""
-}
-
-.fa-level-up:before {
- content: ""
-}
-
-.fa-level-down:before {
- content: ""
-}
-
-.fa-check-square:before {
- content: ""
-}
-
-.fa-pencil-square:before {
- content: ""
-}
-
-.fa-external-link-square:before {
- content: ""
-}
-
-.fa-share-square:before {
- content: ""
-}
-
-.fa-compass:before {
- content: ""
-}
-
-.fa-caret-square-o-down:before,.fa-toggle-down:before {
- content: ""
-}
-
-.fa-caret-square-o-up:before,.fa-toggle-up:before {
- content: ""
-}
-
-.fa-caret-square-o-right:before,.fa-toggle-right:before {
- content: ""
-}
-
-.fa-eur:before,.fa-euro:before {
- content: ""
-}
-
-.fa-gbp:before {
- content: ""
-}
-
-.fa-dollar:before,.fa-usd:before {
- content: ""
-}
-
-.fa-inr:before,.fa-rupee:before {
- content: ""
-}
-
-.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before {
- content: ""
-}
-
-.fa-rouble:before,.fa-rub:before,.fa-ruble:before {
- content: ""
-}
-
-.fa-krw:before,.fa-won:before {
- content: ""
-}
-
-.fa-bitcoin:before,.fa-btc:before {
- content: ""
-}
-
-.fa-file:before {
- content: ""
-}
-
-.fa-file-text:before {
- content: ""
-}
-
-.fa-sort-alpha-asc:before {
- content: ""
-}
-
-.fa-sort-alpha-desc:before {
- content: ""
-}
-
-.fa-sort-amount-asc:before {
- content: ""
-}
-
-.fa-sort-amount-desc:before {
- content: ""
-}
-
-.fa-sort-numeric-asc:before {
- content: ""
-}
-
-.fa-sort-numeric-desc:before {
- content: ""
-}
-
-.fa-thumbs-up:before {
- content: ""
-}
-
-.fa-thumbs-down:before {
- content: ""
-}
-
-.fa-youtube-square:before {
- content: ""
-}
-
-.fa-youtube:before {
- content: ""
-}
-
-.fa-xing:before {
- content: ""
-}
-
-.fa-xing-square:before {
- content: ""
-}
-
-.fa-youtube-play:before {
- content: ""
-}
-
-.fa-dropbox:before {
- content: ""
-}
-
-.fa-stack-overflow:before {
- content: ""
-}
-
-.fa-instagram:before {
- content: ""
-}
-
-.fa-flickr:before {
- content: ""
-}
-
-.fa-adn:before {
- content: ""
-}
-
-.fa-bitbucket:before,.icon-bitbucket:before {
- content: ""
-}
-
-.fa-bitbucket-square:before {
- content: ""
-}
-
-.fa-tumblr:before {
- content: ""
-}
-
-.fa-tumblr-square:before {
- content: ""
-}
-
-.fa-long-arrow-down:before {
- content: ""
-}
-
-.fa-long-arrow-up:before {
- content: ""
-}
-
-.fa-long-arrow-left:before {
- content: ""
-}
-
-.fa-long-arrow-right:before {
- content: ""
-}
-
-.fa-apple:before {
- content: ""
-}
-
-.fa-windows:before {
- content: ""
-}
-
-.fa-android:before {
- content: ""
-}
-
-.fa-linux:before {
- content: ""
-}
-
-.fa-dribbble:before {
- content: ""
-}
-
-.fa-skype:before {
- content: ""
-}
-
-.fa-foursquare:before {
- content: ""
-}
-
-.fa-trello:before {
- content: ""
-}
-
-.fa-female:before {
- content: ""
-}
-
-.fa-male:before {
- content: ""
-}
-
-.fa-gittip:before,.fa-gratipay:before {
- content: ""
-}
-
-.fa-sun-o:before {
- content: ""
-}
-
-.fa-moon-o:before {
- content: ""
-}
-
-.fa-archive:before {
- content: ""
-}
-
-.fa-bug:before {
- content: ""
-}
-
-.fa-vk:before {
- content: ""
-}
-
-.fa-weibo:before {
- content: ""
-}
-
-.fa-renren:before {
- content: ""
-}
-
-.fa-pagelines:before {
- content: ""
-}
-
-.fa-stack-exchange:before {
- content: ""
-}
-
-.fa-arrow-circle-o-right:before {
- content: ""
-}
-
-.fa-arrow-circle-o-left:before {
- content: ""
-}
-
-.fa-caret-square-o-left:before,.fa-toggle-left:before {
- content: ""
-}
-
-.fa-dot-circle-o:before {
- content: ""
-}
-
-.fa-wheelchair:before {
- content: ""
-}
-
-.fa-vimeo-square:before {
- content: ""
-}
-
-.fa-try:before,.fa-turkish-lira:before {
- content: ""
-}
-
-.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before {
- content: ""
-}
-
-.fa-space-shuttle:before {
- content: ""
-}
-
-.fa-slack:before {
- content: ""
-}
-
-.fa-envelope-square:before {
- content: ""
-}
-
-.fa-wordpress:before {
- content: ""
-}
-
-.fa-openid:before {
- content: ""
-}
-
-.fa-bank:before,.fa-institution:before,.fa-university:before {
- content: ""
-}
-
-.fa-graduation-cap:before,.fa-mortar-board:before {
- content: ""
-}
-
-.fa-yahoo:before {
- content: ""
-}
-
-.fa-google:before {
- content: ""
-}
-
-.fa-reddit:before {
- content: ""
-}
-
-.fa-reddit-square:before {
- content: ""
-}
-
-.fa-stumbleupon-circle:before {
- content: ""
-}
-
-.fa-stumbleupon:before {
- content: ""
-}
-
-.fa-delicious:before {
- content: ""
-}
-
-.fa-digg:before {
- content: ""
-}
-
-.fa-pied-piper-pp:before {
- content: ""
-}
-
-.fa-pied-piper-alt:before {
- content: ""
-}
-
-.fa-drupal:before {
- content: ""
-}
-
-.fa-joomla:before {
- content: ""
-}
-
-.fa-language:before {
- content: ""
-}
-
-.fa-fax:before {
- content: ""
-}
-
-.fa-building:before {
- content: ""
-}
-
-.fa-child:before {
- content: ""
-}
-
-.fa-paw:before {
- content: ""
-}
-
-.fa-spoon:before {
- content: ""
-}
-
-.fa-cube:before {
- content: ""
-}
-
-.fa-cubes:before {
- content: ""
-}
-
-.fa-behance:before {
- content: ""
-}
-
-.fa-behance-square:before {
- content: ""
-}
-
-.fa-steam:before {
- content: ""
-}
-
-.fa-steam-square:before {
- content: ""
-}
-
-.fa-recycle:before {
- content: ""
-}
-
-.fa-automobile:before,.fa-car:before {
- content: ""
-}
-
-.fa-cab:before,.fa-taxi:before {
- content: ""
-}
-
-.fa-tree:before {
- content: ""
-}
-
-.fa-spotify:before {
- content: ""
-}
-
-.fa-deviantart:before {
- content: ""
-}
-
-.fa-soundcloud:before {
- content: ""
-}
-
-.fa-database:before {
- content: ""
-}
-
-.fa-file-pdf-o:before {
- content: ""
-}
-
-.fa-file-word-o:before {
- content: ""
-}
-
-.fa-file-excel-o:before {
- content: ""
-}
-
-.fa-file-powerpoint-o:before {
- content: ""
-}
-
-.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before {
- content: ""
-}
-
-.fa-file-archive-o:before,.fa-file-zip-o:before {
- content: ""
-}
-
-.fa-file-audio-o:before,.fa-file-sound-o:before {
- content: ""
-}
-
-.fa-file-movie-o:before,.fa-file-video-o:before {
- content: ""
-}
-
-.fa-file-code-o:before {
- content: ""
-}
-
-.fa-vine:before {
- content: ""
-}
-
-.fa-codepen:before {
- content: ""
-}
-
-.fa-jsfiddle:before {
- content: ""
-}
-
-.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before {
- content: ""
-}
-
-.fa-circle-o-notch:before {
- content: ""
-}
-
-.fa-ra:before,.fa-rebel:before,.fa-resistance:before {
- content: ""
-}
-
-.fa-empire:before,.fa-ge:before {
- content: ""
-}
-
-.fa-git-square:before {
- content: ""
-}
-
-.fa-git:before {
- content: ""
-}
-
-.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before {
- content: ""
-}
-
-.fa-tencent-weibo:before {
- content: ""
-}
-
-.fa-qq:before {
- content: ""
-}
-
-.fa-wechat:before,.fa-weixin:before {
- content: ""
-}
-
-.fa-paper-plane:before,.fa-send:before {
- content: ""
-}
-
-.fa-paper-plane-o:before,.fa-send-o:before {
- content: ""
-}
-
-.fa-history:before {
- content: ""
-}
-
-.fa-circle-thin:before {
- content: ""
-}
-
-.fa-header:before {
- content: ""
-}
-
-.fa-paragraph:before {
- content: ""
-}
-
-.fa-sliders:before {
- content: ""
-}
-
-.fa-share-alt:before {
- content: ""
-}
-
-.fa-share-alt-square:before {
- content: ""
-}
-
-.fa-bomb:before {
- content: ""
-}
-
-.fa-futbol-o:before,.fa-soccer-ball-o:before {
- content: ""
-}
-
-.fa-tty:before {
- content: ""
-}
-
-.fa-binoculars:before {
- content: ""
-}
-
-.fa-plug:before {
- content: ""
-}
-
-.fa-slideshare:before {
- content: ""
-}
-
-.fa-twitch:before {
- content: ""
-}
-
-.fa-yelp:before {
- content: ""
-}
-
-.fa-newspaper-o:before {
- content: ""
-}
-
-.fa-wifi:before {
- content: ""
-}
-
-.fa-calculator:before {
- content: ""
-}
-
-.fa-paypal:before {
- content: ""
-}
-
-.fa-google-wallet:before {
- content: ""
-}
-
-.fa-cc-visa:before {
- content: ""
-}
-
-.fa-cc-mastercard:before {
- content: ""
-}
-
-.fa-cc-discover:before {
- content: ""
-}
-
-.fa-cc-amex:before {
- content: ""
-}
-
-.fa-cc-paypal:before {
- content: ""
-}
-
-.fa-cc-stripe:before {
- content: ""
-}
-
-.fa-bell-slash:before {
- content: ""
-}
-
-.fa-bell-slash-o:before {
- content: ""
-}
-
-.fa-trash:before {
- content: ""
-}
-
-.fa-copyright:before {
- content: ""
-}
-
-.fa-at:before {
- content: ""
-}
-
-.fa-eyedropper:before {
- content: ""
-}
-
-.fa-paint-brush:before {
- content: ""
-}
-
-.fa-birthday-cake:before {
- content: ""
-}
-
-.fa-area-chart:before {
- content: ""
-}
-
-.fa-pie-chart:before {
- content: ""
-}
-
-.fa-line-chart:before {
- content: ""
-}
-
-.fa-lastfm:before {
- content: ""
-}
-
-.fa-lastfm-square:before {
- content: ""
-}
-
-.fa-toggle-off:before {
- content: ""
-}
-
-.fa-toggle-on:before {
- content: ""
-}
-
-.fa-bicycle:before {
- content: ""
-}
-
-.fa-bus:before {
- content: ""
-}
-
-.fa-ioxhost:before {
- content: ""
-}
-
-.fa-angellist:before {
- content: ""
-}
-
-.fa-cc:before {
- content: ""
-}
-
-.fa-ils:before,.fa-shekel:before,.fa-sheqel:before {
- content: ""
-}
-
-.fa-meanpath:before {
- content: ""
-}
-
-.fa-buysellads:before {
- content: ""
-}
-
-.fa-connectdevelop:before {
- content: ""
-}
-
-.fa-dashcube:before {
- content: ""
-}
-
-.fa-forumbee:before {
- content: ""
-}
-
-.fa-leanpub:before {
- content: ""
-}
-
-.fa-sellsy:before {
- content: ""
-}
-
-.fa-shirtsinbulk:before {
- content: ""
-}
-
-.fa-simplybuilt:before {
- content: ""
-}
-
-.fa-skyatlas:before {
- content: ""
-}
-
-.fa-cart-plus:before {
- content: ""
-}
-
-.fa-cart-arrow-down:before {
- content: ""
-}
-
-.fa-diamond:before {
- content: ""
-}
-
-.fa-ship:before {
- content: ""
-}
-
-.fa-user-secret:before {
- content: ""
-}
-
-.fa-motorcycle:before {
- content: ""
-}
-
-.fa-street-view:before {
- content: ""
-}
-
-.fa-heartbeat:before {
- content: ""
-}
-
-.fa-venus:before {
- content: ""
-}
-
-.fa-mars:before {
- content: ""
-}
-
-.fa-mercury:before {
- content: ""
-}
-
-.fa-intersex:before,.fa-transgender:before {
- content: ""
-}
-
-.fa-transgender-alt:before {
- content: ""
-}
-
-.fa-venus-double:before {
- content: ""
-}
-
-.fa-mars-double:before {
- content: ""
-}
-
-.fa-venus-mars:before {
- content: ""
-}
-
-.fa-mars-stroke:before {
- content: ""
-}
-
-.fa-mars-stroke-v:before {
- content: ""
-}
-
-.fa-mars-stroke-h:before {
- content: ""
-}
-
-.fa-neuter:before {
- content: ""
-}
-
-.fa-genderless:before {
- content: ""
-}
-
-.fa-facebook-official:before {
- content: ""
-}
-
-.fa-pinterest-p:before {
- content: ""
-}
-
-.fa-whatsapp:before {
- content: ""
-}
-
-.fa-server:before {
- content: ""
-}
-
-.fa-user-plus:before {
- content: ""
-}
-
-.fa-user-times:before {
- content: ""
-}
-
-.fa-bed:before,.fa-hotel:before {
- content: ""
-}
-
-.fa-viacoin:before {
- content: ""
-}
-
-.fa-train:before {
- content: ""
-}
-
-.fa-subway:before {
- content: ""
-}
-
-.fa-medium:before {
- content: ""
-}
-
-.fa-y-combinator:before,.fa-yc:before {
- content: ""
-}
-
-.fa-optin-monster:before {
- content: ""
-}
-
-.fa-opencart:before {
- content: ""
-}
-
-.fa-expeditedssl:before {
- content: ""
-}
-
-.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before {
- content: ""
-}
-
-.fa-battery-3:before,.fa-battery-three-quarters:before {
- content: ""
-}
-
-.fa-battery-2:before,.fa-battery-half:before {
- content: ""
-}
-
-.fa-battery-1:before,.fa-battery-quarter:before {
- content: ""
-}
-
-.fa-battery-0:before,.fa-battery-empty:before {
- content: ""
-}
-
-.fa-mouse-pointer:before {
- content: ""
-}
-
-.fa-i-cursor:before {
- content: ""
-}
-
-.fa-object-group:before {
- content: ""
-}
-
-.fa-object-ungroup:before {
- content: ""
-}
-
-.fa-sticky-note:before {
- content: ""
-}
-
-.fa-sticky-note-o:before {
- content: ""
-}
-
-.fa-cc-jcb:before {
- content: ""
-}
-
-.fa-cc-diners-club:before {
- content: ""
-}
-
-.fa-clone:before {
- content: ""
-}
-
-.fa-balance-scale:before {
- content: ""
-}
-
-.fa-hourglass-o:before {
- content: ""
-}
-
-.fa-hourglass-1:before,.fa-hourglass-start:before {
- content: ""
-}
-
-.fa-hourglass-2:before,.fa-hourglass-half:before {
- content: ""
-}
-
-.fa-hourglass-3:before,.fa-hourglass-end:before {
- content: ""
-}
-
-.fa-hourglass:before {
- content: ""
-}
-
-.fa-hand-grab-o:before,.fa-hand-rock-o:before {
- content: ""
-}
-
-.fa-hand-paper-o:before,.fa-hand-stop-o:before {
- content: ""
-}
-
-.fa-hand-scissors-o:before {
- content: ""
-}
-
-.fa-hand-lizard-o:before {
- content: ""
-}
-
-.fa-hand-spock-o:before {
- content: ""
-}
-
-.fa-hand-pointer-o:before {
- content: ""
-}
-
-.fa-hand-peace-o:before {
- content: ""
-}
-
-.fa-trademark:before {
- content: ""
-}
-
-.fa-registered:before {
- content: ""
-}
-
-.fa-creative-commons:before {
- content: ""
-}
-
-.fa-gg:before {
- content: ""
-}
-
-.fa-gg-circle:before {
- content: ""
-}
-
-.fa-tripadvisor:before {
- content: ""
-}
-
-.fa-odnoklassniki:before {
- content: ""
-}
-
-.fa-odnoklassniki-square:before {
- content: ""
-}
-
-.fa-get-pocket:before {
- content: ""
-}
-
-.fa-wikipedia-w:before {
- content: ""
-}
-
-.fa-safari:before {
- content: ""
-}
-
-.fa-chrome:before {
- content: ""
-}
-
-.fa-firefox:before {
- content: ""
-}
-
-.fa-opera:before {
- content: ""
-}
-
-.fa-internet-explorer:before {
- content: ""
-}
-
-.fa-television:before,.fa-tv:before {
- content: ""
-}
-
-.fa-contao:before {
- content: ""
-}
-
-.fa-500px:before {
- content: ""
-}
-
-.fa-amazon:before {
- content: ""
-}
-
-.fa-calendar-plus-o:before {
- content: ""
-}
-
-.fa-calendar-minus-o:before {
- content: ""
-}
-
-.fa-calendar-times-o:before {
- content: ""
-}
-
-.fa-calendar-check-o:before {
- content: ""
-}
-
-.fa-industry:before {
- content: ""
-}
-
-.fa-map-pin:before {
- content: ""
-}
-
-.fa-map-signs:before {
- content: ""
-}
-
-.fa-map-o:before {
- content: ""
-}
-
-.fa-map:before {
- content: ""
-}
-
-.fa-commenting:before {
- content: ""
-}
-
-.fa-commenting-o:before {
- content: ""
-}
-
-.fa-houzz:before {
- content: ""
-}
-
-.fa-vimeo:before {
- content: ""
-}
-
-.fa-black-tie:before {
- content: ""
-}
-
-.fa-fonticons:before {
- content: ""
-}
-
-.fa-reddit-alien:before {
- content: ""
-}
-
-.fa-edge:before {
- content: ""
-}
-
-.fa-credit-card-alt:before {
- content: ""
-}
-
-.fa-codiepie:before {
- content: ""
-}
-
-.fa-modx:before {
- content: ""
-}
-
-.fa-fort-awesome:before {
- content: ""
-}
-
-.fa-usb:before {
- content: ""
-}
-
-.fa-product-hunt:before {
- content: ""
-}
-
-.fa-mixcloud:before {
- content: ""
-}
-
-.fa-scribd:before {
- content: ""
-}
-
-.fa-pause-circle:before {
- content: ""
-}
-
-.fa-pause-circle-o:before {
- content: ""
-}
-
-.fa-stop-circle:before {
- content: ""
-}
-
-.fa-stop-circle-o:before {
- content: ""
-}
-
-.fa-shopping-bag:before {
- content: ""
-}
-
-.fa-shopping-basket:before {
- content: ""
-}
-
-.fa-hashtag:before {
- content: ""
-}
-
-.fa-bluetooth:before {
- content: ""
-}
-
-.fa-bluetooth-b:before {
- content: ""
-}
-
-.fa-percent:before {
- content: ""
-}
-
-.fa-gitlab:before,.icon-gitlab:before {
- content: ""
-}
-
-.fa-wpbeginner:before {
- content: ""
-}
-
-.fa-wpforms:before {
- content: ""
-}
-
-.fa-envira:before {
- content: ""
-}
-
-.fa-universal-access:before {
- content: ""
-}
-
-.fa-wheelchair-alt:before {
- content: ""
-}
-
-.fa-question-circle-o:before {
- content: ""
-}
-
-.fa-blind:before {
- content: ""
-}
-
-.fa-audio-description:before {
- content: ""
-}
-
-.fa-volume-control-phone:before {
- content: ""
-}
-
-.fa-braille:before {
- content: ""
-}
-
-.fa-assistive-listening-systems:before {
- content: ""
-}
-
-.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before {
- content: ""
-}
-
-.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before {
- content: ""
-}
-
-.fa-glide:before {
- content: ""
-}
-
-.fa-glide-g:before {
- content: ""
-}
-
-.fa-sign-language:before,.fa-signing:before {
- content: ""
-}
-
-.fa-low-vision:before {
- content: ""
-}
-
-.fa-viadeo:before {
- content: ""
-}
-
-.fa-viadeo-square:before {
- content: ""
-}
-
-.fa-snapchat:before {
- content: ""
-}
-
-.fa-snapchat-ghost:before {
- content: ""
-}
-
-.fa-snapchat-square:before {
- content: ""
-}
-
-.fa-pied-piper:before {
- content: ""
-}
-
-.fa-first-order:before {
- content: ""
-}
-
-.fa-yoast:before {
- content: ""
-}
-
-.fa-themeisle:before {
- content: ""
-}
-
-.fa-google-plus-circle:before,.fa-google-plus-official:before {
- content: ""
-}
-
-.fa-fa:before,.fa-font-awesome:before {
- content: ""
-}
-
-.fa-handshake-o:before {
- content: ""
-}
-
-.fa-envelope-open:before {
- content: ""
-}
-
-.fa-envelope-open-o:before {
- content: ""
-}
-
-.fa-linode:before {
- content: ""
-}
-
-.fa-address-book:before {
- content: ""
-}
-
-.fa-address-book-o:before {
- content: ""
-}
-
-.fa-address-card:before,.fa-vcard:before {
- content: ""
-}
-
-.fa-address-card-o:before,.fa-vcard-o:before {
- content: ""
-}
-
-.fa-user-circle:before {
- content: ""
-}
-
-.fa-user-circle-o:before {
- content: ""
-}
-
-.fa-user-o:before {
- content: ""
-}
-
-.fa-id-badge:before {
- content: ""
-}
-
-.fa-drivers-license:before,.fa-id-card:before {
- content: ""
-}
-
-.fa-drivers-license-o:before,.fa-id-card-o:before {
- content: ""
-}
-
-.fa-quora:before {
- content: ""
-}
-
-.fa-free-code-camp:before {
- content: ""
-}
-
-.fa-telegram:before {
- content: ""
-}
-
-.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before {
- content: ""
-}
-
-.fa-thermometer-3:before,.fa-thermometer-three-quarters:before {
- content: ""
-}
-
-.fa-thermometer-2:before,.fa-thermometer-half:before {
- content: ""
-}
-
-.fa-thermometer-1:before,.fa-thermometer-quarter:before {
- content: ""
-}
-
-.fa-thermometer-0:before,.fa-thermometer-empty:before {
- content: ""
-}
-
-.fa-shower:before {
- content: ""
-}
-
-.fa-bath:before,.fa-bathtub:before,.fa-s15:before {
- content: ""
-}
-
-.fa-podcast:before {
- content: ""
-}
-
-.fa-window-maximize:before {
- content: ""
-}
-
-.fa-window-minimize:before {
- content: ""
-}
-
-.fa-window-restore:before {
- content: ""
-}
-
-.fa-times-rectangle:before,.fa-window-close:before {
- content: ""
-}
-
-.fa-times-rectangle-o:before,.fa-window-close-o:before {
- content: ""
-}
-
-.fa-bandcamp:before {
- content: ""
-}
-
-.fa-grav:before {
- content: ""
-}
-
-.fa-etsy:before {
- content: ""
-}
-
-.fa-imdb:before {
- content: ""
-}
-
-.fa-ravelry:before {
- content: ""
-}
-
-.fa-eercast:before {
- content: ""
-}
-
-.fa-microchip:before {
- content: ""
-}
-
-.fa-snowflake-o:before {
- content: ""
-}
-
-.fa-superpowers:before {
- content: ""
-}
-
-.fa-wpexplorer:before {
- content: ""
-}
-
-.fa-meetup:before {
- content: ""
-}
-
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0,0,0,0);
- border: 0
-}
-
-.sr-only-focusable:active,.sr-only-focusable:focus {
- position: static;
- width: auto;
- height: auto;
- margin: 0;
- overflow: visible;
- clip: auto
-}
-
-.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand {
- font-family: inherit
-}
-
-.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before {
- font-family: FontAwesome;
- display: inline-block;
- font-style: normal;
- font-weight: 400;
- line-height: 1;
- text-decoration: inherit
-}
-
-.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand {
- display: inline-block;
- text-decoration: inherit
-}
-
-.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand {
- display: inline
-}
-
-.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand {
- line-height: .9em
-}
-
-.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand {
- display: inline-block
-}
-
-.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before {
- opacity: .5;
- -webkit-transition: opacity .05s ease-in;
- -moz-transition: opacity .05s ease-in;
- transition: opacity .05s ease-in
-}
-
-.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before {
- opacity: 1
-}
-
-.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before {
- font-size: 14px;
- vertical-align: -15%
-}
-
-.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert {
- padding: 12px;
- line-height: 24px;
- margin-bottom: 24px;
- background: #e7f2fa
-}
-
-.rst-content .admonition-title,.wy-alert-title {
- font-weight: 700;
- display: block;
- color: #fff;
- background: #6ab0de;
- padding: 6px 12px;
- margin: -12px -12px 12px
-}
-
-.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger {
- background: #fdf3f2
-}
-
-.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title {
- background: #f29f97
-}
-
-.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning {
- background: #ffedcc
-}
-
-.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title {
- background: #f0b37e
-}
-
-.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info {
- background: #e7f2fa
-}
-
-.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title {
- background: #6ab0de
-}
-
-.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success {
- background: #dbfaf4
-}
-
-.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title {
- background: #1abc9c
-}
-
-.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral {
- background: #f3f6f6
-}
-
-.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title {
- color: #404040;
- background: #e1e4e5
-}
-
-.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a {
- color: #2980b9
-}
-
-.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child {
- margin-bottom: 0
-}
-
-.wy-tray-container {
- position: fixed;
- bottom: 0;
- left: 0;
- z-index: 600
-}
-
-.wy-tray-container li {
- display: block;
- width: 300px;
- background: transparent;
- color: #fff;
- text-align: center;
- box-shadow: 0 5px 5px 0 rgba(0,0,0,.1);
- padding: 0 24px;
- min-width: 20%;
- opacity: 0;
- height: 0;
- line-height: 56px;
- overflow: hidden;
- -webkit-transition: all .3s ease-in;
- -moz-transition: all .3s ease-in;
- transition: all .3s ease-in
-}
-
-.wy-tray-container li.wy-tray-item-success {
- background: #27ae60
-}
-
-.wy-tray-container li.wy-tray-item-info {
- background: #2980b9
-}
-
-.wy-tray-container li.wy-tray-item-warning {
- background: #e67e22
-}
-
-.wy-tray-container li.wy-tray-item-danger {
- background: #e74c3c
-}
-
-.wy-tray-container li.on {
- opacity: 1;
- height: 56px
-}
-
-@media screen and (max-width: 768px) {
- .wy-tray-container {
- bottom:auto;
- top: 0;
- width: 100%
- }
-
- .wy-tray-container li {
- width: 100%
- }
-}
-
-button {
- font-size: 100%;
- margin: 0;
- vertical-align: baseline;
- *vertical-align: middle;
- cursor: pointer;
- line-height: normal;
- -webkit-appearance: button;
- *overflow: visible
-}
-
-button::-moz-focus-inner,input::-moz-focus-inner {
- border: 0;
- padding: 0
-}
-
-button[disabled] {
- cursor: default
-}
-
-.btn {
- display: inline-block;
- border-radius: 2px;
- line-height: normal;
- white-space: nowrap;
- text-align: center;
- cursor: pointer;
- font-size: 100%;
- padding: 6px 12px 8px;
- color: #fff;
- border: 1px solid rgba(0,0,0,.1);
- background-color: #27ae60;
- text-decoration: none;
- font-weight: 400;
- font-family: Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;
- box-shadow: inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);
- outline-none: false;
- vertical-align: middle;
- *display: inline;
- zoom:1;-webkit-user-drag: none;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- -webkit-transition: all .1s linear;
- -moz-transition: all .1s linear;
- transition: all .1s linear
-}
-
-.btn-hover {
- background: #2e8ece;
- color: #fff
-}
-
-.btn:hover {
- background: #2cc36b;
- color: #fff
-}
-
-.btn:focus {
- background: #2cc36b;
- outline: 0
-}
-
-.btn:active {
- box-shadow: inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);
- padding: 8px 12px 6px
-}
-
-.btn:visited {
- color: #fff
-}
-
-.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled {
- background-image: none;
- filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
- filter: alpha(opacity=40);
- opacity: .4;
- cursor: not-allowed;
- box-shadow: none
-}
-
-.btn::-moz-focus-inner {
- padding: 0;
- border: 0
-}
-
-.btn-small {
- font-size: 80%
-}
-
-.btn-info {
- background-color: #2980b9!important
-}
-
-.btn-info:hover {
- background-color: #2e8ece!important
-}
-
-.btn-neutral {
- background-color: #f3f6f6!important;
- color: #404040!important
-}
-
-.btn-neutral:hover {
- background-color: #e5ebeb!important;
- color: #404040
-}
-
-.btn-neutral:visited {
- color: #404040!important
-}
-
-.btn-success {
- background-color: #27ae60!important
-}
-
-.btn-success:hover {
- background-color: #295!important
-}
-
-.btn-danger {
- background-color: #e74c3c!important
-}
-
-.btn-danger:hover {
- background-color: #ea6153!important
-}
-
-.btn-warning {
- background-color: #e67e22!important
-}
-
-.btn-warning:hover {
- background-color: #e98b39!important
-}
-
-.btn-invert {
- background-color: #222
-}
-
-.btn-invert:hover {
- background-color: #2f2f2f!important
-}
-
-.btn-link {
- background-color: transparent!important;
- color: #2980b9;
- box-shadow: none;
- border-color: transparent!important
-}
-
-.btn-link:active,.btn-link:hover {
- background-color: transparent!important;
- color: #409ad5!important;
- box-shadow: none
-}
-
-.btn-link:visited {
- color: #9b59b6
-}
-
-.wy-btn-group .btn,.wy-control .btn {
- vertical-align: middle
-}
-
-.wy-btn-group {
- margin-bottom: 24px;
- *zoom:1}
-
-.wy-btn-group:after,.wy-btn-group:before {
- display: table;
- content: ""
-}
-
-.wy-btn-group:after {
- clear: both
-}
-
-.wy-dropdown {
- position: relative;
- display: inline-block
-}
-
-.wy-dropdown-active .wy-dropdown-menu {
- display: block
-}
-
-.wy-dropdown-menu {
- position: absolute;
- left: 0;
- display: none;
- float: left;
- top: 100%;
- min-width: 100%;
- background: #fcfcfc;
- z-index: 100;
- border: 1px solid #cfd7dd;
- box-shadow: 0 2px 2px 0 rgba(0,0,0,.1);
- padding: 12px
-}
-
-.wy-dropdown-menu>dd>a {
- display: block;
- clear: both;
- color: #404040;
- white-space: nowrap;
- font-size: 90%;
- padding: 0 12px;
- cursor: pointer
-}
-
-.wy-dropdown-menu>dd>a:hover {
- background: #2980b9;
- color: #fff
-}
-
-.wy-dropdown-menu>dd.divider {
- border-top: 1px solid #cfd7dd;
- margin: 6px 0
-}
-
-.wy-dropdown-menu>dd.search {
- padding-bottom: 12px
-}
-
-.wy-dropdown-menu>dd.search input[type=search] {
- width: 100%
-}
-
-.wy-dropdown-menu>dd.call-to-action {
- background: #e3e3e3;
- text-transform: uppercase;
- font-weight: 500;
- font-size: 80%
-}
-
-.wy-dropdown-menu>dd.call-to-action:hover {
- background: #e3e3e3
-}
-
-.wy-dropdown-menu>dd.call-to-action .btn {
- color: #fff
-}
-
-.wy-dropdown.wy-dropdown-up .wy-dropdown-menu {
- bottom: 100%;
- top: auto;
- left: auto;
- right: 0
-}
-
-.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu {
- background: #fcfcfc;
- margin-top: 2px
-}
-
-.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a {
- padding: 6px 12px
-}
-
-.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover {
- background: #2980b9;
- color: #fff
-}
-
-.wy-dropdown.wy-dropdown-left .wy-dropdown-menu {
- right: 0;
- left: auto;
- text-align: right
-}
-
-.wy-dropdown-arrow:before {
- content: " ";
- border-bottom: 5px solid #f5f5f5;
- border-left: 5px solid transparent;
- border-right: 5px solid transparent;
- position: absolute;
- display: block;
- top: -4px;
- left: 50%;
- margin-left: -3px
-}
-
-.wy-dropdown-arrow.wy-dropdown-arrow-left:before {
- left: 11px
-}
-
-.wy-form-stacked select {
- display: block
-}
-
-.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea {
- display: inline-block;
- *display: inline;
- *zoom:1;vertical-align: middle
-}
-
-.wy-form-aligned .wy-control-group>label {
- display: inline-block;
- vertical-align: middle;
- width: 10em;
- margin: 6px 12px 0 0;
- float: left
-}
-
-.wy-form-aligned .wy-control {
- float: left
-}
-
-.wy-form-aligned .wy-control label {
- display: block
-}
-
-.wy-form-aligned .wy-control select {
- margin-top: 6px
-}
-
-fieldset {
- margin: 0
-}
-
-fieldset,legend {
- border: 0;
- padding: 0
-}
-
-legend {
- width: 100%;
- white-space: normal;
- margin-bottom: 24px;
- font-size: 150%;
- *margin-left: -7px
-}
-
-label,legend {
- display: block
-}
-
-label {
- margin: 0 0 .3125em;
- color: #333;
- font-size: 90%
-}
-
-input,select,textarea {
- font-size: 100%;
- margin: 0;
- vertical-align: baseline;
- *vertical-align: middle
-}
-
-.wy-control-group {
- margin-bottom: 24px;
- max-width: 1200px;
- margin-left: auto;
- margin-right: auto;
- *zoom:1}
-
-.wy-control-group:after,.wy-control-group:before {
- display: table;
- content: ""
-}
-
-.wy-control-group:after {
- clear: both
-}
-
-.wy-control-group.wy-control-group-required>label:after {
- content: " *";
- color: #e74c3c
-}
-
-.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds {
- padding-bottom: 12px
-}
-
-.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select {
- width: 100%
-}
-
-.wy-control-group .wy-form-full {
- float: left;
- display: block;
- width: 100%;
- margin-right: 0
-}
-
-.wy-control-group .wy-form-full:last-child {
- margin-right: 0
-}
-
-.wy-control-group .wy-form-halves {
- float: left;
- display: block;
- margin-right: 2.35765%;
- width: 48.82117%
-}
-
-.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n) {
- margin-right: 0
-}
-
-.wy-control-group .wy-form-halves:nth-of-type(odd) {
- clear: left
-}
-
-.wy-control-group .wy-form-thirds {
- float: left;
- display: block;
- margin-right: 2.35765%;
- width: 31.76157%
-}
-
-.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n) {
- margin-right: 0
-}
-
-.wy-control-group .wy-form-thirds:nth-of-type(3n+1) {
- clear: left
-}
-
-.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input {
- margin: 6px 0 0;
- font-size: 90%
-}
-
-.wy-control-no-input {
- display: inline-block
-}
-
-.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week] {
- width: 100%
-}
-
-.wy-form-message-inline {
- padding-left: .3em;
- color: #666;
- font-size: 90%
-}
-
-.wy-form-message {
- display: block;
- color: #999;
- font-size: 70%;
- margin-top: .3125em;
- font-style: italic
-}
-
-.wy-form-message p {
- font-size: inherit;
- font-style: italic;
- margin-bottom: 6px
-}
-
-.wy-form-message p:last-child {
- margin-bottom: 0
-}
-
-input {
- line-height: normal
-}
-
-input[type=button],input[type=reset],input[type=submit] {
- -webkit-appearance: button;
- cursor: pointer;
- font-family: Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;
- *overflow: visible
-}
-
-input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week] {
- -webkit-appearance: none;
- padding: 6px;
- display: inline-block;
- border: 1px solid #ccc;
- font-size: 80%;
- font-family: Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;
- box-shadow: inset 0 1px 3px #ddd;
- border-radius: 0;
- -webkit-transition: border .3s linear;
- -moz-transition: border .3s linear;
- transition: border .3s linear
-}
-
-input[type=datetime-local] {
- padding: .34375em .625em
-}
-
-input[disabled] {
- cursor: default
-}
-
-input[type=checkbox],input[type=radio] {
- padding: 0;
- margin-right: .3125em;
- *height: 13px;
- *width: 13px
-}
-
-input[type=checkbox],input[type=radio],input[type=search] {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box
-}
-
-input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration {
- -webkit-appearance: none
-}
-
-input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus {
- outline: 0;
- outline: thin dotted\9;
- border-color: #333
-}
-
-input.no-focus:focus {
- border-color: #ccc!important
-}
-
-input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus {
- outline: thin dotted #333;
- outline: 1px auto #129fea
-}
-
-input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled] {
- cursor: not-allowed;
- background-color: #fafafa
-}
-
-input:focus:invalid,select:focus:invalid,textarea:focus:invalid {
- color: #e74c3c;
- border: 1px solid #e74c3c
-}
-
-input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus {
- border-color: #e74c3c
-}
-
-input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus {
- outline-color: #e74c3c
-}
-
-input.wy-input-large {
- padding: 12px;
- font-size: 100%
-}
-
-textarea {
- overflow: auto;
- vertical-align: top;
- width: 100%;
- font-family: Lato,proxima-nova,Helvetica Neue,Arial,sans-serif
-}
-
-select,textarea {
- padding: .5em .625em;
- display: inline-block;
- border: 1px solid #ccc;
- font-size: 80%;
- box-shadow: inset 0 1px 3px #ddd;
- -webkit-transition: border .3s linear;
- -moz-transition: border .3s linear;
- transition: border .3s linear
-}
-
-select {
- border: 1px solid #ccc;
- background-color: #fff
-}
-
-select[multiple] {
- height: auto
-}
-
-select:focus,textarea:focus {
- outline: 0
-}
-
-input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly] {
- cursor: not-allowed;
- background-color: #fafafa
-}
-
-input[type=checkbox][disabled],input[type=radio][disabled] {
- cursor: not-allowed
-}
-
-.wy-checkbox,.wy-radio {
- margin: 6px 0;
- color: #404040;
- display: block
-}
-
-.wy-checkbox input,.wy-radio input {
- vertical-align: baseline
-}
-
-.wy-form-message-inline {
- display: inline-block;
- *display: inline;
- *zoom:1;vertical-align: middle
-}
-
-.wy-input-prefix,.wy-input-suffix {
- white-space: nowrap;
- padding: 6px
-}
-
-.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context {
- line-height: 27px;
- padding: 0 8px;
- display: inline-block;
- font-size: 80%;
- background-color: #f3f6f6;
- border: 1px solid #ccc;
- color: #999
-}
-
-.wy-input-suffix .wy-input-context {
- border-left: 0
-}
-
-.wy-input-prefix .wy-input-context {
- border-right: 0
-}
-
-.wy-switch {
- position: relative;
- display: block;
- height: 24px;
- margin-top: 12px;
- cursor: pointer
-}
-
-.wy-switch:before {
- left: 0;
- top: 0;
- width: 36px;
- height: 12px;
- background: #ccc
-}
-
-.wy-switch:after,.wy-switch:before {
- position: absolute;
- content: "";
- display: block;
- border-radius: 4px;
- -webkit-transition: all .2s ease-in-out;
- -moz-transition: all .2s ease-in-out;
- transition: all .2s ease-in-out
-}
-
-.wy-switch:after {
- width: 18px;
- height: 18px;
- background: #999;
- left: -3px;
- top: -3px
-}
-
-.wy-switch span {
- position: absolute;
- left: 48px;
- display: block;
- font-size: 12px;
- color: #ccc;
- line-height: 1
-}
-
-.wy-switch.active:before {
- background: #1e8449
-}
-
-.wy-switch.active:after {
- left: 24px;
- background: #27ae60
-}
-
-.wy-switch.disabled {
- cursor: not-allowed;
- opacity: .8
-}
-
-.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label {
- color: #e74c3c
-}
-
-.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea {
- border: 1px solid #e74c3c
-}
-
-.wy-inline-validate {
- white-space: nowrap
-}
-
-.wy-inline-validate .wy-input-context {
- padding: .5em .625em;
- display: inline-block;
- font-size: 80%
-}
-
-.wy-inline-validate.wy-inline-validate-success .wy-input-context {
- color: #27ae60
-}
-
-.wy-inline-validate.wy-inline-validate-danger .wy-input-context {
- color: #e74c3c
-}
-
-.wy-inline-validate.wy-inline-validate-warning .wy-input-context {
- color: #e67e22
-}
-
-.wy-inline-validate.wy-inline-validate-info .wy-input-context {
- color: #2980b9
-}
-
-.rotate-90 {
- -webkit-transform: rotate(90deg);
- -moz-transform: rotate(90deg);
- -ms-transform: rotate(90deg);
- -o-transform: rotate(90deg);
- transform: rotate(90deg)
-}
-
-.rotate-180 {
- -webkit-transform: rotate(180deg);
- -moz-transform: rotate(180deg);
- -ms-transform: rotate(180deg);
- -o-transform: rotate(180deg);
- transform: rotate(180deg)
-}
-
-.rotate-270 {
- -webkit-transform: rotate(270deg);
- -moz-transform: rotate(270deg);
- -ms-transform: rotate(270deg);
- -o-transform: rotate(270deg);
- transform: rotate(270deg)
-}
-
-.mirror {
- -webkit-transform: scaleX(-1);
- -moz-transform: scaleX(-1);
- -ms-transform: scaleX(-1);
- -o-transform: scaleX(-1);
- transform: scaleX(-1)
-}
-
-.mirror.rotate-90 {
- -webkit-transform: scaleX(-1) rotate(90deg);
- -moz-transform: scaleX(-1) rotate(90deg);
- -ms-transform: scaleX(-1) rotate(90deg);
- -o-transform: scaleX(-1) rotate(90deg);
- transform: scaleX(-1) rotate(90deg)
-}
-
-.mirror.rotate-180 {
- -webkit-transform: scaleX(-1) rotate(180deg);
- -moz-transform: scaleX(-1) rotate(180deg);
- -ms-transform: scaleX(-1) rotate(180deg);
- -o-transform: scaleX(-1) rotate(180deg);
- transform: scaleX(-1) rotate(180deg)
-}
-
-.mirror.rotate-270 {
- -webkit-transform: scaleX(-1) rotate(270deg);
- -moz-transform: scaleX(-1) rotate(270deg);
- -ms-transform: scaleX(-1) rotate(270deg);
- -o-transform: scaleX(-1) rotate(270deg);
- transform: scaleX(-1) rotate(270deg)
-}
-
-@media only screen and (max-width: 480px) {
- .wy-form button[type=submit] {
- margin:.7em 0 0
- }
-
- .wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label {
- margin-bottom: .3em;
- display: block
- }
-
- .wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week] {
- margin-bottom: 0
- }
-
- .wy-form-aligned .wy-control-group label {
- margin-bottom: .3em;
- text-align: left;
- display: block;
- width: 100%
- }
-
- .wy-form-aligned .wy-control {
- margin: 1.5em 0 0
- }
-
- .wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline {
- display: block;
- font-size: 80%;
- padding: 6px 0
- }
-}
-
-@media screen and (max-width: 768px) {
- .tablet-hide {
- display:none
- }
-}
-
-@media screen and (max-width: 480px) {
- .mobile-hide {
- display:none
- }
-}
-
-.float-left {
- float: left
-}
-
-.float-right {
- float: right
-}
-
-.full-width {
- width: 100%
-}
-
-.rst-content table.docutils,.rst-content table.field-list,.wy-table {
- border-collapse: collapse;
- border-spacing: 0;
- empty-cells: show;
- margin-bottom: 24px
-}
-
-.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption {
- color: #000;
- font: italic 85%/1 arial,sans-serif;
- padding: 1em 0;
- text-align: center
-}
-
-.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th {
- font-size: 90%;
- margin: 0;
- overflow: visible;
- padding: 8px 16px
-}
-
-.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child {
- border-left-width: 0
-}
-
-.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead {
- color: #000;
- text-align: left;
- vertical-align: bottom;
- white-space: nowrap
-}
-
-.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th {
- font-weight: 700;
- border-bottom: 2px solid #e1e4e5
-}
-
-.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td {
- background-color: transparent;
- vertical-align: middle
-}
-
-.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p {
- line-height: 18px
-}
-
-.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child {
- margin-bottom: 0
-}
-
-.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min {
- width: 1%;
- padding-right: 0
-}
-
-.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox] {
- margin: 0
-}
-
-.wy-table-secondary {
- color: grey;
- font-size: 90%
-}
-
-.wy-table-tertiary {
- color: grey;
- font-size: 80%
-}
-
-.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td {
- background-color: #f3f6f6
-}
-
-.rst-content table.docutils,.wy-table-bordered-all {
- border: 1px solid #e1e4e5
-}
-
-.rst-content table.docutils td,.wy-table-bordered-all td {
- border-bottom: 1px solid #e1e4e5;
- border-left: 1px solid #e1e4e5
-}
-
-.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td {
- border-bottom-width: 0
-}
-
-.wy-table-bordered {
- border: 1px solid #e1e4e5
-}
-
-.wy-table-bordered-rows td {
- border-bottom: 1px solid #e1e4e5
-}
-
-.wy-table-bordered-rows tbody>tr:last-child td {
- border-bottom-width: 0
-}
-
-.wy-table-horizontal td,.wy-table-horizontal th {
- border-width: 0 0 1px;
- border-bottom: 1px solid #e1e4e5
-}
-
-.wy-table-horizontal tbody>tr:last-child td {
- border-bottom-width: 0
-}
-
-.wy-table-responsive {
- margin-bottom: 24px;
- max-width: 100%;
- overflow: auto
-}
-
-.wy-table-responsive table {
- margin-bottom: 0!important
-}
-
-.wy-table-responsive table td,.wy-table-responsive table th {
- white-space: nowrap
-}
-
-a {
- color: #2980b9;
- text-decoration: none;
- cursor: pointer
-}
-
-a:hover {
- color: #3091d1
-}
-
-a:visited {
- color: #9b59b6
-}
-
-html {
- height: 100%
-}
-
-body,html {
- overflow-x: hidden
-}
-
-body {
- font-family: Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;
- font-weight: 400;
- color: #404040;
- min-height: 100%;
- background: #edf0f2
-}
-
-.wy-text-left {
- text-align: left
-}
-
-.wy-text-center {
- text-align: center
-}
-
-.wy-text-right {
- text-align: right
-}
-
-.wy-text-large {
- font-size: 120%
-}
-
-.wy-text-normal {
- font-size: 100%
-}
-
-.wy-text-small,small {
- font-size: 80%
-}
-
-.wy-text-strike {
- text-decoration: line-through
-}
-
-.wy-text-warning {
- color: #e67e22!important
-}
-
-a.wy-text-warning:hover {
- color: #eb9950!important
-}
-
-.wy-text-info {
- color: #2980b9!important
-}
-
-a.wy-text-info:hover {
- color: #409ad5!important
-}
-
-.wy-text-success {
- color: #27ae60!important
-}
-
-a.wy-text-success:hover {
- color: #36d278!important
-}
-
-.wy-text-danger {
- color: #e74c3c!important
-}
-
-a.wy-text-danger:hover {
- color: #ed7669!important
-}
-
-.wy-text-neutral {
- color: #404040!important
-}
-
-a.wy-text-neutral:hover {
- color: #595959!important
-}
-
-.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend {
- margin-top: 0;
- font-weight: 700;
- font-family: Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif
-}
-
-p {
- line-height: 24px;
- font-size: 16px;
- margin: 0 0 24px
-}
-
-h1 {
- font-size: 175%
-}
-
-.rst-content .toctree-wrapper>p.caption,h2 {
- font-size: 150%
-}
-
-h3 {
- font-size: 125%
-}
-
-h4 {
- font-size: 115%
-}
-
-h5 {
- font-size: 110%
-}
-
-h6 {
- font-size: 100%
-}
-
-hr {
- display: block;
- height: 1px;
- border: 0;
- border-top: 1px solid #e1e4e5;
- margin: 24px 0;
- padding: 0
-}
-
-.rst-content code,.rst-content tt,code {
- white-space: nowrap;
- max-width: 100%;
- background: #fff;
- border: 1px solid #e1e4e5;
- font-size: 75%;
- padding: 0 5px;
- font-family: SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;
- color: #e74c3c;
- overflow-x: auto
-}
-
-.rst-content tt.code-large,code.code-large {
- font-size: 90%
-}
-
-.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul {
- list-style: disc;
- line-height: 24px;
- margin-bottom: 24px
-}
-
-.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li {
- list-style: disc;
- margin-left: 24px
-}
-
-.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul {
- margin-bottom: 0
-}
-
-.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li {
- list-style: circle
-}
-
-.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li {
- list-style: square
-}
-
-.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li {
- list-style: decimal
-}
-
-.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol {
- list-style: decimal;
- line-height: 24px;
- margin-bottom: 24px
-}
-
-.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li {
- list-style: decimal;
- margin-left: 24px
-}
-
-.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul {
- margin-bottom: 0
-}
-
-.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li {
- list-style: disc
-}
-
-.wy-breadcrumbs {
- *zoom:1}
-
-.wy-breadcrumbs:after,.wy-breadcrumbs:before {
- display: table;
- content: ""
-}
-
-.wy-breadcrumbs:after {
- clear: both
-}
-
-.wy-breadcrumbs>li {
- display: inline-block;
- padding-top: 5px
-}
-
-.wy-breadcrumbs>li.wy-breadcrumbs-aside {
- float: right
-}
-
-.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code {
- all: inherit;
- color: inherit
-}
-
-.breadcrumb-item:before {
- content: "/";
- color: #bbb;
- font-size: 13px;
- padding: 0 6px 0 3px
-}
-
-.wy-breadcrumbs-extra {
- margin-bottom: 0;
- color: #b3b3b3;
- font-size: 80%;
- display: inline-block
-}
-
-@media screen and (max-width: 480px) {
- .wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside {
- display:none
- }
-}
-
-@media print {
- .wy-breadcrumbs li.wy-breadcrumbs-aside {
- display: none
- }
-}
-
-html {
- font-size: 16px
-}
-
-.wy-affix {
- position: fixed;
- top: 1.618em
-}
-
-.wy-menu a:hover {
- text-decoration: none
-}
-
-.wy-menu-horiz {
- *zoom:1}
-
-.wy-menu-horiz:after,.wy-menu-horiz:before {
- display: table;
- content: ""
-}
-
-.wy-menu-horiz:after {
- clear: both
-}
-
-.wy-menu-horiz li,.wy-menu-horiz ul {
- display: inline-block
-}
-
-.wy-menu-horiz li:hover {
- background: hsla(0,0%,100%,.1)
-}
-
-.wy-menu-horiz li.divide-left {
- border-left: 1px solid #404040
-}
-
-.wy-menu-horiz li.divide-right {
- border-right: 1px solid #404040
-}
-
-.wy-menu-horiz a {
- height: 32px;
- display: inline-block;
- line-height: 32px;
- padding: 0 16px
-}
-
-.wy-menu-vertical {
- width: 300px
-}
-
-.wy-menu-vertical header,.wy-menu-vertical p.caption {
- color: #55a5d9;
- height: 32px;
- line-height: 32px;
- padding: 0 1.618em;
- margin: 12px 0 0;
- display: block;
- font-weight: 700;
- text-transform: uppercase;
- font-size: 85%;
- white-space: nowrap
-}
-
-.wy-menu-vertical ul {
- margin-bottom: 0
-}
-
-.wy-menu-vertical li.divide-top {
- border-top: 1px solid #404040
-}
-
-.wy-menu-vertical li.divide-bottom {
- border-bottom: 1px solid #404040
-}
-
-.wy-menu-vertical li.current {
- background: #e3e3e3
-}
-
-.wy-menu-vertical li.current a {
- color: grey;
- border-right: 1px solid #c9c9c9;
- padding: .4045em 2.427em
-}
-
-.wy-menu-vertical li.current a:hover {
- background: #d6d6d6
-}
-
-.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code {
- border: none;
- background: inherit;
- color: inherit;
- padding-left: 0;
- padding-right: 0
-}
-
-.wy-menu-vertical li button.toctree-expand {
- display: block;
- float: left;
- margin-left: -1.2em;
- line-height: 18px;
- color: #4d4d4d;
- border: none;
- background: none;
- padding: 0
-}
-
-.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a {
- color: #404040;
- font-weight: 700;
- position: relative;
- background: #fcfcfc;
- border: none;
- padding: .4045em 1.618em
-}
-
-.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover {
- background: #fcfcfc
-}
-
-.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand {
- color: grey
-}
-
-.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand {
- display: block;
- line-height: 18px;
- color: #333
-}
-
-.wy-menu-vertical li.toctree-l1.current>a {
- border-bottom: 1px solid #c9c9c9;
- border-top: 1px solid #c9c9c9
-}
-
-.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul {
- display: none
-}
-
-.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul {
- display: block
-}
-
-.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4 {
- font-size: .9em
-}
-
-.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a {
- color: #404040
-}
-
-.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand {
- color: grey
-}
-
-.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a {
- display: block
-}
-
-.wy-menu-vertical li.toctree-l2.current>a {
- padding: .4045em 2.427em
-}
-
-.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a {
- padding: .4045em 1.618em .4045em 4.045em
-}
-
-.wy-menu-vertical li.toctree-l3.current>a {
- padding: .4045em 4.045em
-}
-
-.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a {
- padding: .4045em 1.618em .4045em 5.663em
-}
-
-.wy-menu-vertical li.toctree-l4.current>a {
- padding: .4045em 5.663em
-}
-
-.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a {
- padding: .4045em 1.618em .4045em 7.281em
-}
-
-.wy-menu-vertical li.toctree-l5.current>a {
- padding: .4045em 7.281em
-}
-
-.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a {
- padding: .4045em 1.618em .4045em 8.899em
-}
-
-.wy-menu-vertical li.toctree-l6.current>a {
- padding: .4045em 8.899em
-}
-
-.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a {
- padding: .4045em 1.618em .4045em 10.517em
-}
-
-.wy-menu-vertical li.toctree-l7.current>a {
- padding: .4045em 10.517em
-}
-
-.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a {
- padding: .4045em 1.618em .4045em 12.135em
-}
-
-.wy-menu-vertical li.toctree-l8.current>a {
- padding: .4045em 12.135em
-}
-
-.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a {
- padding: .4045em 1.618em .4045em 13.753em
-}
-
-.wy-menu-vertical li.toctree-l9.current>a {
- padding: .4045em 13.753em
-}
-
-.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a {
- padding: .4045em 1.618em .4045em 15.371em
-}
-
-.wy-menu-vertical li.toctree-l10.current>a {
- padding: .4045em 15.371em
-}
-
-.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a {
- padding: .4045em 1.618em .4045em 16.989em
-}
-
-.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a {
- background: #c9c9c9
-}
-
-.wy-menu-vertical li.toctree-l2 button.toctree-expand {
- color: #a3a3a3
-}
-
-.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a {
- background: #bdbdbd
-}
-
-.wy-menu-vertical li.toctree-l3 button.toctree-expand {
- color: #969696
-}
-
-.wy-menu-vertical li.current ul {
- display: block
-}
-
-.wy-menu-vertical li ul {
- margin-bottom: 0;
- display: none
-}
-
-.wy-menu-vertical li ul li a {
- margin-bottom: 0;
- color: #d9d9d9;
- font-weight: 400
-}
-
-.wy-menu-vertical a {
- line-height: 18px;
- padding: .4045em 1.618em;
- display: block;
- position: relative;
- font-size: 90%;
- color: #d9d9d9
-}
-
-.wy-menu-vertical a:hover {
- background-color: #4e4a4a;
- cursor: pointer
-}
-
-.wy-menu-vertical a:hover button.toctree-expand {
- color: #d9d9d9
-}
-
-.wy-menu-vertical a:active {
- background-color: #2980b9;
- cursor: pointer;
- color: #fff
-}
-
-.wy-menu-vertical a:active button.toctree-expand {
- color: #fff
-}
-
-.wy-side-nav-search {
- display: block;
- width: 300px;
- padding: .809em;
- margin-bottom: .809em;
- z-index: 200;
- background-color: #2980b9;
- text-align: center;
- color: #fcfcfc
-}
-
-.wy-side-nav-search input[type=text] {
- width: 100%;
- border-radius: 50px;
- padding: 6px 12px;
- border-color: #2472a4
-}
-
-.wy-side-nav-search img {
- display: block;
- margin: auto auto .809em;
- height: 45px;
- width: 45px;
- background-color: #2980b9;
- padding: 5px;
- border-radius: 100%
-}
-
-.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a {
- color: #fcfcfc;
- font-size: 100%;
- font-weight: 700;
- display: inline-block;
- padding: 4px 6px;
- margin-bottom: .809em;
- max-width: 100%
-}
-
-.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover {
- background: hsla(0,0%,100%,.1)
-}
-
-.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo {
- display: block;
- margin: 0 auto;
- height: auto;
- width: auto;
- border-radius: 0;
- max-width: 100%;
- background: transparent
-}
-
-.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo {
- margin-top: .85em
-}
-
-.wy-side-nav-search>div.version {
- margin-top: -.4045em;
- margin-bottom: .809em;
- font-weight: 400;
- color: hsla(0,0%,100%,.3)
-}
-
-.wy-nav .wy-menu-vertical header {
- color: #2980b9
-}
-
-.wy-nav .wy-menu-vertical a {
- color: #b3b3b3
-}
-
-.wy-nav .wy-menu-vertical a:hover {
- background-color: #2980b9;
- color: #fff
-}
-
-[data-menu-wrap] {
- -webkit-transition: all .2s ease-in;
- -moz-transition: all .2s ease-in;
- transition: all .2s ease-in;
- position: absolute;
- opacity: 1;
- width: 100%;
- opacity: 0
-}
-
-[data-menu-wrap].move-center {
- left: 0;
- right: auto;
- opacity: 1
-}
-
-[data-menu-wrap].move-left {
- right: auto;
- left: -100%;
- opacity: 0
-}
-
-[data-menu-wrap].move-right {
- right: -100%;
- left: auto;
- opacity: 0
-}
-
-.wy-body-for-nav {
- background: #fcfcfc
-}
-
-.wy-grid-for-nav {
- position: absolute;
- width: 100%;
- height: 100%
-}
-
-.wy-nav-side {
- position: fixed;
- top: 0;
- bottom: 0;
- left: 0;
- padding-bottom: 2em;
- width: 300px;
- overflow-x: hidden;
- overflow-y: hidden;
- min-height: 100%;
- color: #9b9b9b;
- background: #343131;
- z-index: 200
-}
-
-.wy-side-scroll {
- width: 320px;
- position: relative;
- overflow-x: hidden;
- overflow-y: scroll;
- height: 100%
-}
-
-.wy-nav-top {
- display: none;
- background: #2980b9;
- color: #fff;
- padding: .4045em .809em;
- position: relative;
- line-height: 50px;
- text-align: center;
- font-size: 100%;
- *zoom:1}
-
-.wy-nav-top:after,.wy-nav-top:before {
- display: table;
- content: ""
-}
-
-.wy-nav-top:after {
- clear: both
-}
-
-.wy-nav-top a {
- color: #fff;
- font-weight: 700
-}
-
-.wy-nav-top img {
- margin-right: 12px;
- height: 45px;
- width: 45px;
- background-color: #2980b9;
- padding: 5px;
- border-radius: 100%
-}
-
-.wy-nav-top i {
- font-size: 30px;
- float: left;
- cursor: pointer;
- padding-top: inherit
-}
-
-.wy-nav-content-wrap {
- margin-left: 300px;
- background: #fcfcfc;
- min-height: 100%
-}
-
-.wy-nav-content {
- padding: 1.618em 3.236em;
- height: 100%;
- max-width: 800px;
- margin: auto
-}
-
-.wy-body-mask {
- position: fixed;
- width: 100%;
- height: 100%;
- background: rgba(0,0,0,.2);
- display: none;
- z-index: 499
-}
-
-.wy-body-mask.on {
- display: block
-}
-
-footer {
- color: grey
-}
-
-footer p {
- margin-bottom: 12px
-}
-
-.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code {
- padding: 0;
- font-family: SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;
- font-size: 1em;
- background: none;
- border: none;
- color: grey
-}
-
-.rst-footer-buttons {
- *zoom:1}
-
-.rst-footer-buttons:after,.rst-footer-buttons:before {
- width: 100%;
- display: table;
- content: ""
-}
-
-.rst-footer-buttons:after {
- clear: both
-}
-
-.rst-breadcrumbs-buttons {
- margin-top: 12px;
- *zoom:1}
-
-.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before {
- display: table;
- content: ""
-}
-
-.rst-breadcrumbs-buttons:after {
- clear: both
-}
-
-#search-results .search li {
- margin-bottom: 24px;
- border-bottom: 1px solid #e1e4e5;
- padding-bottom: 24px
-}
-
-#search-results .search li:first-child {
- border-top: 1px solid #e1e4e5;
- padding-top: 24px
-}
-
-#search-results .search li a {
- font-size: 120%;
- margin-bottom: 12px;
- display: inline-block
-}
-
-#search-results .context {
- color: grey;
- font-size: 90%
-}
-
-.genindextable li>ul {
- margin-left: 24px
-}
-
-@media screen and (max-width: 768px) {
- .wy-body-for-nav {
- background:#fcfcfc
- }
-
- .wy-nav-top {
- display: block
- }
-
- .wy-nav-side {
- left: -300px
- }
-
- .wy-nav-side.shift {
- width: 85%;
- left: 0
- }
-
- .wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll {
- width: auto
- }
-
- .wy-nav-content-wrap {
- margin-left: 0
- }
-
- .wy-nav-content-wrap .wy-nav-content {
- padding: 1.618em
- }
-
- .wy-nav-content-wrap.shift {
- position: fixed;
- min-width: 100%;
- left: 85%;
- top: 0;
- height: 100%;
- overflow: hidden
- }
-}
-
-@media screen and (min-width: 1100px) {
- .wy-nav-content-wrap {
- background:rgba(0,0,0,.05)
- }
-
- .wy-nav-content {
- margin: 0;
- background: #fcfcfc
- }
-}
-
-@media print {
- .rst-versions,.wy-nav-side,footer {
- display: none
- }
-
- .wy-nav-content-wrap {
- margin-left: 0
- }
-}
-
-.rst-versions {
- position: fixed;
- bottom: 0;
- left: 0;
- width: 300px;
- color: #fcfcfc;
- background: #1f1d1d;
- font-family: Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;
- z-index: 400
-}
-
-.rst-versions a {
- color: #2980b9;
- text-decoration: none
-}
-
-.rst-versions .rst-badge-small {
- display: none
-}
-
-.rst-versions .rst-current-version {
- padding: 12px;
- background-color: #272525;
- display: block;
- text-align: right;
- font-size: 90%;
- cursor: pointer;
- color: #27ae60;
- *zoom:1}
-
-.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before {
- display: table;
- content: ""
-}
-
-.rst-versions .rst-current-version:after {
- clear: both
-}
-
-.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand {
- color: #fcfcfc
-}
-
-.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book {
- float: left
-}
-
-.rst-versions .rst-current-version.rst-out-of-date {
- background-color: #e74c3c;
- color: #fff
-}
-
-.rst-versions .rst-current-version.rst-active-old-version {
- background-color: #f1c40f;
- color: #000
-}
-
-.rst-versions.shift-up {
- height: auto;
- max-height: 100%;
- overflow-y: scroll
-}
-
-.rst-versions.shift-up .rst-other-versions {
- display: block
-}
-
-.rst-versions .rst-other-versions {
- font-size: 90%;
- padding: 12px;
- color: grey;
- display: none
-}
-
-.rst-versions .rst-other-versions hr {
- display: block;
- height: 1px;
- border: 0;
- margin: 20px 0;
- padding: 0;
- border-top: 1px solid #413d3d
-}
-
-.rst-versions .rst-other-versions dd {
- display: inline-block;
- margin: 0
-}
-
-.rst-versions .rst-other-versions dd a {
- display: inline-block;
- padding: 6px;
- color: #fcfcfc
-}
-
-.rst-versions.rst-badge {
- width: auto;
- bottom: 20px;
- right: 20px;
- left: auto;
- border: none;
- max-width: 300px;
- max-height: 90%
-}
-
-.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book {
- float: none;
- line-height: 30px
-}
-
-.rst-versions.rst-badge.shift-up .rst-current-version {
- text-align: right
-}
-
-.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book {
- float: left
-}
-
-.rst-versions.rst-badge>.rst-current-version {
- width: auto;
- height: 30px;
- line-height: 30px;
- padding: 0 6px;
- display: block;
- text-align: center
-}
-
-@media screen and (max-width: 768px) {
- .rst-versions {
- width:85%;
- display: none
- }
-
- .rst-versions.shift {
- display: block
- }
-}
-
-.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6 {
- margin-bottom: 24px
-}
-
-.rst-content img {
- max-width: 100%;
- /* height:auto; */
-}
-
-.rst-content div.figure,.rst-content figure {
- margin-bottom: 24px
-}
-
-.rst-content div.figure .caption-text,.rst-content figure .caption-text {
- font-style: italic
-}
-
-.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption {
- margin-bottom: 0
-}
-
-.rst-content div.figure.align-center,.rst-content figure.align-center {
- text-align: center
-}
-
-.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img {
- margin-bottom: 24px
-}
-
-.rst-content abbr[title] {
- text-decoration: none
-}
-
-.rst-content.style-external-links a.reference.external:after {
- font-family: FontAwesome;
- content: "\f08e";
- color: #b3b3b3;
- vertical-align: super;
- font-size: 60%;
- margin: 0 .2em
-}
-
-.rst-content blockquote {
- margin-left: 24px;
- line-height: 24px;
- margin-bottom: 24px
-}
-
-.rst-content pre.literal-block {
- white-space: pre;
- margin: 0;
- padding: 12px;
- font-family: SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;
- display: block;
- overflow: auto
-}
-
-.rst-content div[class^=highlight],.rst-content pre.literal-block {
- border: 1px solid #e1e4e5;
- overflow-x: auto;
- margin: 1px 0 24px
-}
-
-.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight] {
- padding: 0;
- border: none;
- margin: 0
-}
-
-.rst-content div[class^=highlight] td.code {
- width: 100%
-}
-
-.rst-content .linenodiv pre {
- border-right: 1px solid #e6e9ea;
- margin: 0;
- padding: 12px;
- font-family: SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;
- user-select: none;
- pointer-events: none
-}
-
-.rst-content div[class^=highlight] pre {
- white-space: pre;
- margin: 0;
- padding: 12px;
- display: block;
- overflow: auto
-}
-
-.rst-content div[class^=highlight] pre .hll {
- display: block;
- margin: 0 -12px;
- padding: 0 12px
-}
-
-.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block {
- font-family: SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;
- font-size: 12px;
- line-height: 1.4
-}
-
-.rst-content div.highlight .gp,.rst-content div.highlight span.linenos {
- user-select: none;
- pointer-events: none
-}
-
-.rst-content div.highlight span.linenos {
- display: inline-block;
- padding-left: 0;
- padding-right: 12px;
- margin-right: 12px;
- border-right: 1px solid #e6e9ea
-}
-
-.rst-content .code-block-caption {
- font-style: italic;
- font-size: 85%;
- line-height: 1;
- padding: 1em 0;
- text-align: center
-}
-
-@media print {
- .rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre {
- white-space: pre-wrap
- }
-}
-
-.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning {
- clear: both
-}
-
-.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child {
- margin-bottom: 0
-}
-
-.rst-content .admonition-title:before {
- margin-right: 4px
-}
-
-.rst-content .admonition table {
- border-color: rgba(0,0,0,.1)
-}
-
-.rst-content .admonition table td,.rst-content .admonition table th {
- background: transparent!important;
- border-color: rgba(0,0,0,.1)!important
-}
-
-.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li {
- list-style: lower-alpha
-}
-
-.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li {
- list-style: upper-alpha
-}
-
-.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>* {
- margin-top: 12px;
- margin-bottom: 12px
-}
-
-.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child {
- margin-top: 0
-}
-
-.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child {
- margin-bottom: 12px
-}
-
-.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child {
- margin-bottom: 0
-}
-
-.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul {
- margin-bottom: 12px
-}
-
-.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul {
- margin-top: 0;
- margin-bottom: 0
-}
-
-.rst-content .line-block {
- margin-left: 0;
- margin-bottom: 24px;
- line-height: 24px
-}
-
-.rst-content .line-block .line-block {
- margin-left: 24px;
- margin-bottom: 0
-}
-
-.rst-content .topic-title {
- font-weight: 700;
- margin-bottom: 12px
-}
-
-.rst-content .toc-backref {
- color: #404040
-}
-
-.rst-content .align-right {
- float: right;
- margin: 0 0 24px 24px
-}
-
-.rst-content .align-left {
- float: left;
- margin: 0 24px 24px 0
-}
-
-.rst-content .align-center {
- margin: auto
-}
-
-.rst-content .align-center:not(table) {
- display: block
-}
-
-.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink {
- opacity: 0;
- font-size: 14px;
- font-family: FontAwesome;
- margin-left: .5em
-}
-
-.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink {
- opacity: 1
-}
-
-.rst-content p a {
- overflow-wrap: anywhere
-}
-
-.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul {
- font-size: inherit
-}
-
-.rst-content .btn:focus {
- outline: 2px solid
-}
-
-.rst-content table>caption .headerlink:after {
- font-size: 12px
-}
-
-.rst-content .centered {
- text-align: center
-}
-
-.rst-content .sidebar {
- float: right;
- width: 40%;
- display: block;
- margin: 0 0 24px 24px;
- padding: 24px;
- background: #f3f6f6;
- border: 1px solid #e1e4e5
-}
-
-.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul {
- font-size: 90%
-}
-
-.rst-content .sidebar .last,.rst-content .sidebar>:last-child {
- margin-bottom: 0
-}
-
-.rst-content .sidebar .sidebar-title {
- display: block;
- font-family: Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;
- font-weight: 700;
- background: #e1e4e5;
- padding: 6px 12px;
- margin: -24px -24px 24px;
- font-size: 100%
-}
-
-.rst-content .highlighted {
- background: #f1c40f;
- box-shadow: 0 0 0 2px #f1c40f;
- display: inline;
- font-weight: 700
-}
-
-.rst-content .citation-reference,.rst-content .footnote-reference {
- vertical-align: baseline;
- position: relative;
- top: -.4em;
- line-height: 0;
- font-size: 90%
-}
-
-.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket {
- display: none
-}
-
-.rst-content .hlist {
- width: 100%
-}
-
-.rst-content dl dt span.classifier:before {
- content: " : "
-}
-
-.rst-content dl dt span.classifier-delimiter {
- display: none!important
-}
-
-html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote {
- background: none;
- border: none
-}
-
-html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr {
- border: none;
- background-color: transparent!important;
- white-space: normal
-}
-
-html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label {
- padding-left: 0;
- padding-right: 0;
- vertical-align: top
-}
-
-html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote {
- display: grid;
- grid-template-columns: auto minmax(80%,95%)
-}
-
-html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt {
- display: inline-grid;
- grid-template-columns: max-content auto
-}
-
-html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation {
- display: grid;
- grid-template-columns: auto auto minmax(.65rem,auto) minmax(40%,95%)
-}
-
-html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label {
- grid-column-start: 1;
- grid-column-end: 2
-}
-
-html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs {
- grid-column-start: 2;
- grid-column-end: 3;
- grid-row-start: 1;
- grid-row-end: 3
-}
-
-html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p {
- grid-column-start: 4;
- grid-column-end: 5
-}
-
-html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote {
- margin-bottom: 24px
-}
-
-html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt {
- padding-left: 1rem
-}
-
-html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt {
- margin-bottom: 0
-}
-
-html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote {
- font-size: .9rem
-}
-
-html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt {
- margin: 0 .5rem .5rem 0;
- line-height: 1.2rem;
- word-break: break-all;
- font-weight: 400
-}
-
-html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before {
- content: "["
-}
-
-html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after {
- content: "]"
-}
-
-html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref {
- text-align: left;
- font-style: italic;
- margin-left: .65rem;
- word-break: break-word;
- word-spacing: -.1rem;
- max-width: 5rem
-}
-
-html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a {
- word-break: keep-all
-}
-
-html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before {
- content: " "
-}
-
-html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd {
- margin: 0 0 .5rem;
- line-height: 1.2rem
-}
-
-html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p {
- font-size: .9rem
-}
-
-html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation {
- padding-left: 1rem;
- padding-right: 1rem;
- font-size: .9rem;
- line-height: 1.2rem
-}
-
-html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p {
- font-size: .9rem;
- line-height: 1.2rem;
- margin-bottom: 12px
-}
-
-html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs {
- text-align: left;
- font-style: italic;
- margin-left: .65rem;
- word-break: break-word;
- word-spacing: -.1rem;
- max-width: 5rem
-}
-
-html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a {
- word-break: keep-all
-}
-
-html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before {
- content: " "
-}
-
-html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label {
- line-height: 1.2rem
-}
-
-html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list {
- margin-bottom: 24px
-}
-
-html.writer-html5 .rst-content dl.option-list kbd {
- font-size: .9rem
-}
-
-.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote {
- color: grey
-}
-
-.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt {
- color: #555
-}
-
-.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote {
- margin-bottom: 0
-}
-
-.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote) {
- margin-top: 24px
-}
-
-.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child {
- margin-bottom: 24px
-}
-
-.rst-content table.docutils th {
- border-color: #e1e4e5
-}
-
-html.writer-html5 .rst-content table.docutils th {
- border: 1px solid #e1e4e5
-}
-
-html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p {
- line-height: 1rem;
- margin-bottom: 0;
- font-size: .9rem
-}
-
-.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child {
- margin-bottom: 0
-}
-
-.rst-content table.field-list,.rst-content table.field-list td {
- border: none
-}
-
-.rst-content table.field-list td p {
- line-height: inherit
-}
-
-.rst-content table.field-list td>strong {
- display: inline-block
-}
-
-.rst-content table.field-list .field-name {
- padding-right: 10px;
- text-align: left;
- white-space: nowrap
-}
-
-.rst-content table.field-list .field-body {
- text-align: left
-}
-
-.rst-content code,.rst-content tt {
- color: #000;
- font-family: SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;
- padding: 2px 5px
-}
-
-.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em {
- font-size: 100%!important;
- line-height: normal
-}
-
-.rst-content code.literal,.rst-content tt.literal {
- color: #e74c3c;
- white-space: normal
-}
-
-.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt {
- font-weight: 700;
- color: #404040;
- overflow-wrap: normal
-}
-
-.rst-content kbd,.rst-content pre,.rst-content samp {
- font-family: SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace
-}
-
-.rst-content a code,.rst-content a tt {
- color: #2980b9
-}
-
-.rst-content dl {
- margin-bottom: 24px
-}
-
-.rst-content dl dt {
- font-weight: 700;
- margin-bottom: 12px
-}
-
-.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul {
- margin-bottom: 12px
-}
-
-.rst-content dl dd {
- margin: 0 0 12px 24px;
- line-height: 24px
-}
-
-.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child {
- margin-bottom: 0
-}
-
-html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) {
- margin-bottom: 24px
-}
-
-html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt {
- display: table;
- margin: 6px 0;
- font-size: 90%;
- line-height: normal;
- background: #e7f2fa;
- color: #2980b9;
- border-top: 3px solid #6ab0de;
- padding: 6px;
- position: relative
-}
-
-html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before {
- color: #6ab0de
-}
-
-html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink {
- color: #404040;
- font-size: 100%!important
-}
-
-html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt {
- margin-bottom: 6px;
- border: none;
- border-left: 3px solid #ccc;
- background: #f0f0f0;
- color: #555
-}
-
-html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink {
- color: #404040;
- font-size: 100%!important
-}
-
-html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child {
- margin-top: 0
-}
-
-html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname {
- background-color: transparent;
- border: none;
- padding: 0;
- font-size: 100%!important
-}
-
-html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname {
- font-weight: 700
-}
-
-html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional {
- display: inline-block;
- padding: 0 4px;
- color: #000;
- font-weight: 700
-}
-
-html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property {
- display: inline-block;
- padding-right: 8px;
- max-width: 100%
-}
-
-html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k {
- font-style: italic
-}
-
-html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name {
- font-family: SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;
- color: #000
-}
-
-.rst-content .viewcode-back,.rst-content .viewcode-link {
- display: inline-block;
- color: #27ae60;
- font-size: 80%;
- padding-left: 24px
-}
-
-.rst-content .viewcode-back {
- display: block;
- float: right
-}
-
-.rst-content p.rubric {
- margin-bottom: 12px;
- font-weight: 700
-}
-
-.rst-content code.download,.rst-content tt.download {
- background: inherit;
- padding: inherit;
- font-weight: 400;
- font-family: inherit;
- font-size: inherit;
- color: inherit;
- border: inherit;
- white-space: inherit
-}
-
-.rst-content code.download span:first-child,.rst-content tt.download span:first-child {
- -webkit-font-smoothing: subpixel-antialiased
-}
-
-.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before {
- margin-right: 4px
-}
-
-.rst-content .guilabel,.rst-content .menuselection {
- font-size: 80%;
- font-weight: 700;
- border-radius: 4px;
- padding: 2.4px 6px;
- margin: auto 2px
-}
-
-.rst-content .guilabel,.rst-content .menuselection {
- border: 1px solid #7fbbe3;
- background: #e7f2fa
-}
-
-.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd {
- color: inherit;
- font-size: 80%;
- background-color: #fff;
- border: 1px solid #a6a6a6;
- border-radius: 4px;
- box-shadow: 0 2px grey;
- padding: 2.4px 6px;
- margin: auto 0
-}
-
-.rst-content .versionmodified {
- font-style: italic
-}
-
-@media screen and (max-width: 480px) {
- .rst-content .sidebar {
- width:100%
- }
-}
-
-span[id*=MathJax-Span] {
- color: #404040
-}
-
-.math {
- text-align: center
-}
-
-@font-face {
- font-family: Lato;
- src: url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");
- font-weight: 400;
- font-style: normal;
- font-display: block
-}
-
-@font-face {
- font-family: Lato;
- src: url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");
- font-weight: 700;
- font-style: normal;
- font-display: block
-}
-
-@font-face {
- font-family: Lato;
- src: url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");
- font-weight: 700;
- font-style: italic;
- font-display: block
-}
-
-@font-face {
- font-family: Lato;
- src: url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");
- font-weight: 400;
- font-style: italic;
- font-display: block
-}
-
-@font-face {
- font-family: Roboto Slab;
- font-style: normal;
- font-weight: 400;
- src: url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");
- font-display: block
-}
-
-@font-face {
- font-family: Roboto Slab;
- font-style: normal;
- font-weight: 700;
- src: url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");
- font-display: block
-}
diff --git a/docs/_static/icon.png b/docs/_static/icon.png
deleted file mode 100644
index 04462b21..00000000
Binary files a/docs/_static/icon.png and /dev/null differ
diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html
deleted file mode 100644
index d57ad550..00000000
--- a/docs/_templates/layout.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends "!layout.html" %}
-
-{% block body %}
-{% if READTHEDOCS and current_version != "stable" %}
-
-
Development Docs
-
You are reading docs for ArchiveBox {{ version }} (pre-release).
- These docs may include unreleased features and breaking changes.
- For the latest stable release, see the stable docs .
-
-{% endif %}
-{{ super() }}
-{% endblock %}
diff --git a/docs/apidocs/archivebox/archivebox.__main__.md b/docs/apidocs/archivebox/archivebox.__main__.md
deleted file mode 100644
index 6375eb50..00000000
--- a/docs/apidocs/archivebox/archivebox.__main__.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# {py:mod}`archivebox.__main__`
-
-```{py:module} archivebox.__main__
-```
-
-```{autodoc2-docstring} archivebox.__main__
-:allowtitles:
-```
-
-## Module Contents
-
-### Data
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`ASCII_LOGO_MINI `
- - ```{autodoc2-docstring} archivebox.__main__.ASCII_LOGO_MINI
- :summary:
- ```
-````
-
-### API
-
-````{py:data} ASCII_LOGO_MINI
-:canonical: archivebox.__main__.ASCII_LOGO_MINI
-:value:
-
-```{autodoc2-docstring} archivebox.__main__.ASCII_LOGO_MINI
-```
-
-````
diff --git a/docs/apidocs/archivebox/archivebox.api.admin.md b/docs/apidocs/archivebox/archivebox.api.admin.md
deleted file mode 100644
index 2b62166d..00000000
--- a/docs/apidocs/archivebox/archivebox.api.admin.md
+++ /dev/null
@@ -1,215 +0,0 @@
-# {py:mod}`archivebox.api.admin`
-
-```{py:module} archivebox.api.admin
-```
-
-```{autodoc2-docstring} archivebox.api.admin
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`APITokenAdmin `
- -
-* - {py:obj}`OutboundWebhookAdminForm `
- -
-* - {py:obj}`CustomWebhookAdmin `
- -
-````
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`_webhook_fields `
- - ```{autodoc2-docstring} archivebox.api.admin._webhook_fields
- :summary:
- ```
-* - {py:obj}`register_admin `
- - ```{autodoc2-docstring} archivebox.api.admin.register_admin
- :summary:
- ```
-````
-
-### API
-
-````{py:function} _webhook_fields(*names: str) -> tuple[str, ...]
-:canonical: archivebox.api.admin._webhook_fields
-
-```{autodoc2-docstring} archivebox.api.admin._webhook_fields
-```
-````
-
-`````{py:class} APITokenAdmin(model, admin_site)
-:canonical: archivebox.api.admin.APITokenAdmin
-
-Bases: {py:obj}`archivebox.base_models.admin.BaseModelAdmin`
-
-````{py:attribute} list_display
-:canonical: archivebox.api.admin.APITokenAdmin.list_display
-:value: >
- ('created_at', 'id', 'created_by', 'token_redacted', 'expires')
-
-```{autodoc2-docstring} archivebox.api.admin.APITokenAdmin.list_display
-```
-
-````
-
-````{py:attribute} sort_fields
-:canonical: archivebox.api.admin.APITokenAdmin.sort_fields
-:value: >
- ('id', 'created_at', 'created_by', 'expires')
-
-```{autodoc2-docstring} archivebox.api.admin.APITokenAdmin.sort_fields
-```
-
-````
-
-````{py:attribute} readonly_fields
-:canonical: archivebox.api.admin.APITokenAdmin.readonly_fields
-:value: >
- ('created_at', 'modified_at')
-
-```{autodoc2-docstring} archivebox.api.admin.APITokenAdmin.readonly_fields
-```
-
-````
-
-````{py:attribute} search_fields
-:canonical: archivebox.api.admin.APITokenAdmin.search_fields
-:value: >
- ('id', 'created_by__username', 'token')
-
-```{autodoc2-docstring} archivebox.api.admin.APITokenAdmin.search_fields
-```
-
-````
-
-````{py:attribute} fieldsets
-:canonical: archivebox.api.admin.APITokenAdmin.fieldsets
-:value: >
- (('Token',), ('Owner',), ('Timestamps',))
-
-```{autodoc2-docstring} archivebox.api.admin.APITokenAdmin.fieldsets
-```
-
-````
-
-````{py:attribute} list_filter
-:canonical: archivebox.api.admin.APITokenAdmin.list_filter
-:value: >
- ('created_by',)
-
-```{autodoc2-docstring} archivebox.api.admin.APITokenAdmin.list_filter
-```
-
-````
-
-````{py:attribute} ordering
-:canonical: archivebox.api.admin.APITokenAdmin.ordering
-:value: >
- ['-created_at']
-
-```{autodoc2-docstring} archivebox.api.admin.APITokenAdmin.ordering
-```
-
-````
-
-````{py:attribute} list_per_page
-:canonical: archivebox.api.admin.APITokenAdmin.list_per_page
-:value: >
- 100
-
-```{autodoc2-docstring} archivebox.api.admin.APITokenAdmin.list_per_page
-```
-
-````
-
-`````
-
-```{py:class} OutboundWebhookAdminForm(*args, **kwargs)
-:canonical: archivebox.api.admin.OutboundWebhookAdminForm
-
-Bases: {py:obj}`signal_webhooks.admin.WebhookModelForm`
-
-```
-
-`````{py:class} CustomWebhookAdmin(model, admin_site)
-:canonical: archivebox.api.admin.CustomWebhookAdmin
-
-Bases: {py:obj}`signal_webhooks.admin.WebhookAdmin`, {py:obj}`archivebox.base_models.admin.BaseModelAdmin`
-
-````{py:attribute} form
-:canonical: archivebox.api.admin.CustomWebhookAdmin.form
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.admin.CustomWebhookAdmin.form
-```
-
-````
-
-````{py:attribute} list_display
-:canonical: archivebox.api.admin.CustomWebhookAdmin.list_display
-:value: >
- ('created_at', 'created_by', 'id')
-
-```{autodoc2-docstring} archivebox.api.admin.CustomWebhookAdmin.list_display
-```
-
-````
-
-````{py:attribute} sort_fields
-:canonical: archivebox.api.admin.CustomWebhookAdmin.sort_fields
-:value: >
- '_webhook_fields(...)'
-
-```{autodoc2-docstring} archivebox.api.admin.CustomWebhookAdmin.sort_fields
-```
-
-````
-
-````{py:attribute} readonly_fields
-:canonical: archivebox.api.admin.CustomWebhookAdmin.readonly_fields
-:value: >
- '_webhook_fields(...)'
-
-```{autodoc2-docstring} archivebox.api.admin.CustomWebhookAdmin.readonly_fields
-```
-
-````
-
-````{py:attribute} fieldsets
-:canonical: archivebox.api.admin.CustomWebhookAdmin.fieldsets
-:value: >
- (('Webhook',), ('Authentication',), ('Status',), ('Owner',), ('Timestamps',))
-
-```{autodoc2-docstring} archivebox.api.admin.CustomWebhookAdmin.fieldsets
-```
-
-````
-
-````{py:method} lookup_allowed(lookup: str, value: str, request: django.http.HttpRequest | None = None) -> bool
-:canonical: archivebox.api.admin.CustomWebhookAdmin.lookup_allowed
-
-```{autodoc2-docstring} archivebox.api.admin.CustomWebhookAdmin.lookup_allowed
-```
-
-````
-
-`````
-
-````{py:function} register_admin(admin_site: django.contrib.admin.AdminSite) -> None
-:canonical: archivebox.api.admin.register_admin
-
-```{autodoc2-docstring} archivebox.api.admin.register_admin
-```
-````
diff --git a/docs/apidocs/archivebox/archivebox.api.apps.md b/docs/apidocs/archivebox/archivebox.api.apps.md
deleted file mode 100644
index f218c0b4..00000000
--- a/docs/apidocs/archivebox/archivebox.api.apps.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# {py:mod}`archivebox.api.apps`
-
-```{py:module} archivebox.api.apps
-```
-
-```{autodoc2-docstring} archivebox.api.apps
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`APIConfig `
- -
-````
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`register_admin `
- - ```{autodoc2-docstring} archivebox.api.apps.register_admin
- :summary:
- ```
-````
-
-### API
-
-`````{py:class} APIConfig(app_name, app_module)
-:canonical: archivebox.api.apps.APIConfig
-
-Bases: {py:obj}`django.apps.AppConfig`
-
-````{py:attribute} name
-:canonical: archivebox.api.apps.APIConfig.name
-:value: >
- 'archivebox.api'
-
-```{autodoc2-docstring} archivebox.api.apps.APIConfig.name
-```
-
-````
-
-````{py:attribute} label
-:canonical: archivebox.api.apps.APIConfig.label
-:value: >
- 'api'
-
-```{autodoc2-docstring} archivebox.api.apps.APIConfig.label
-```
-
-````
-
-`````
-
-````{py:function} register_admin(admin_site)
-:canonical: archivebox.api.apps.register_admin
-
-```{autodoc2-docstring} archivebox.api.apps.register_admin
-```
-````
diff --git a/docs/apidocs/archivebox/archivebox.api.auth.md b/docs/apidocs/archivebox/archivebox.api.auth.md
deleted file mode 100644
index 1bf22651..00000000
--- a/docs/apidocs/archivebox/archivebox.api.auth.md
+++ /dev/null
@@ -1,198 +0,0 @@
-# {py:mod}`archivebox.api.auth`
-
-```{py:module} archivebox.api.auth
-```
-
-```{autodoc2-docstring} archivebox.api.auth
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`HeaderTokenAuth `
- - ```{autodoc2-docstring} archivebox.api.auth.HeaderTokenAuth
- :summary:
- ```
-* - {py:obj}`BearerTokenAuth `
- - ```{autodoc2-docstring} archivebox.api.auth.BearerTokenAuth
- :summary:
- ```
-* - {py:obj}`QueryParamTokenAuth `
- - ```{autodoc2-docstring} archivebox.api.auth.QueryParamTokenAuth
- :summary:
- ```
-````
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`get_or_create_api_token `
- - ```{autodoc2-docstring} archivebox.api.auth.get_or_create_api_token
- :summary:
- ```
-* - {py:obj}`auth_using_token `
- - ```{autodoc2-docstring} archivebox.api.auth.auth_using_token
- :summary:
- ```
-* - {py:obj}`auth_using_password `
- - ```{autodoc2-docstring} archivebox.api.auth.auth_using_password
- :summary:
- ```
-* - {py:obj}`_require_superuser `
- - ```{autodoc2-docstring} archivebox.api.auth._require_superuser
- :summary:
- ```
-````
-
-### Data
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`API_AUTH_METHODS `
- - ```{autodoc2-docstring} archivebox.api.auth.API_AUTH_METHODS
- :summary:
- ```
-````
-
-### API
-
-````{py:function} get_or_create_api_token(user: django.contrib.auth.models.User | None)
-:canonical: archivebox.api.auth.get_or_create_api_token
-
-```{autodoc2-docstring} archivebox.api.auth.get_or_create_api_token
-```
-````
-
-````{py:function} auth_using_token(token: str | None, request: django.http.HttpRequest | None = None) -> django.contrib.auth.models.User | None
-:canonical: archivebox.api.auth.auth_using_token
-
-```{autodoc2-docstring} archivebox.api.auth.auth_using_token
-```
-````
-
-````{py:function} auth_using_password(username: str | None, password: str | None, request: django.http.HttpRequest | None = None) -> django.contrib.auth.models.User | None
-:canonical: archivebox.api.auth.auth_using_password
-
-```{autodoc2-docstring} archivebox.api.auth.auth_using_password
-```
-````
-
-````{py:function} _require_superuser(user: django.contrib.auth.models.User | None, request: django.http.HttpRequest, auth_method: str) -> django.contrib.auth.models.User | None
-:canonical: archivebox.api.auth._require_superuser
-
-```{autodoc2-docstring} archivebox.api.auth._require_superuser
-```
-````
-
-`````{py:class} HeaderTokenAuth()
-:canonical: archivebox.api.auth.HeaderTokenAuth
-
-Bases: {py:obj}`ninja.security.APIKeyHeader`
-
-```{autodoc2-docstring} archivebox.api.auth.HeaderTokenAuth
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.api.auth.HeaderTokenAuth.__init__
-```
-
-````{py:attribute} param_name
-:canonical: archivebox.api.auth.HeaderTokenAuth.param_name
-:value: >
- 'X-ArchiveBox-API-Key'
-
-```{autodoc2-docstring} archivebox.api.auth.HeaderTokenAuth.param_name
-```
-
-````
-
-````{py:method} authenticate(request: django.http.HttpRequest, key: str | None) -> django.contrib.auth.models.User | None
-:canonical: archivebox.api.auth.HeaderTokenAuth.authenticate
-
-```{autodoc2-docstring} archivebox.api.auth.HeaderTokenAuth.authenticate
-```
-
-````
-
-`````
-
-`````{py:class} BearerTokenAuth()
-:canonical: archivebox.api.auth.BearerTokenAuth
-
-Bases: {py:obj}`ninja.security.HttpBearer`
-
-```{autodoc2-docstring} archivebox.api.auth.BearerTokenAuth
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.api.auth.BearerTokenAuth.__init__
-```
-
-````{py:method} authenticate(request: django.http.HttpRequest, token: str) -> django.contrib.auth.models.User | None
-:canonical: archivebox.api.auth.BearerTokenAuth.authenticate
-
-```{autodoc2-docstring} archivebox.api.auth.BearerTokenAuth.authenticate
-```
-
-````
-
-`````
-
-`````{py:class} QueryParamTokenAuth()
-:canonical: archivebox.api.auth.QueryParamTokenAuth
-
-Bases: {py:obj}`ninja.security.APIKeyQuery`
-
-```{autodoc2-docstring} archivebox.api.auth.QueryParamTokenAuth
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.api.auth.QueryParamTokenAuth.__init__
-```
-
-````{py:attribute} param_name
-:canonical: archivebox.api.auth.QueryParamTokenAuth.param_name
-:value: >
- 'api_key'
-
-```{autodoc2-docstring} archivebox.api.auth.QueryParamTokenAuth.param_name
-```
-
-````
-
-````{py:method} authenticate(request: django.http.HttpRequest, key: str | None) -> django.contrib.auth.models.User | None
-:canonical: archivebox.api.auth.QueryParamTokenAuth.authenticate
-
-```{autodoc2-docstring} archivebox.api.auth.QueryParamTokenAuth.authenticate
-```
-
-````
-
-`````
-
-````{py:data} API_AUTH_METHODS
-:canonical: archivebox.api.auth.API_AUTH_METHODS
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.auth.API_AUTH_METHODS
-```
-
-````
diff --git a/docs/apidocs/archivebox/archivebox.api.md b/docs/apidocs/archivebox/archivebox.api.md
deleted file mode 100644
index bbe586b2..00000000
--- a/docs/apidocs/archivebox/archivebox.api.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# {py:mod}`archivebox.api`
-
-```{py:module} archivebox.api
-```
-
-```{autodoc2-docstring} archivebox.api
-:allowtitles:
-```
-
-## Submodules
-
-```{toctree}
-:titlesonly:
-:maxdepth: 1
-
-archivebox.api.auth
-archivebox.api.v1_auth
-archivebox.api.v1_api
-archivebox.api.models
-archivebox.api.v1_cli
-archivebox.api.v1_core
-archivebox.api.apps
-archivebox.api.admin
-archivebox.api.v1_personas
-archivebox.api.webhooks
-archivebox.api.urls
-archivebox.api.v1_machine
-archivebox.api.middleware
-archivebox.api.v1_crawls
-```
diff --git a/docs/apidocs/archivebox/archivebox.api.middleware.md b/docs/apidocs/archivebox/archivebox.api.middleware.md
deleted file mode 100644
index 477b1b79..00000000
--- a/docs/apidocs/archivebox/archivebox.api.middleware.md
+++ /dev/null
@@ -1,54 +0,0 @@
-# {py:mod}`archivebox.api.middleware`
-
-```{py:module} archivebox.api.middleware
-```
-
-```{autodoc2-docstring} archivebox.api.middleware
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`ApiCorsMiddleware `
- - ```{autodoc2-docstring} archivebox.api.middleware.ApiCorsMiddleware
- :summary:
- ```
-````
-
-### API
-
-`````{py:class} ApiCorsMiddleware(get_response)
-:canonical: archivebox.api.middleware.ApiCorsMiddleware
-
-```{autodoc2-docstring} archivebox.api.middleware.ApiCorsMiddleware
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.api.middleware.ApiCorsMiddleware.__init__
-```
-
-````{py:method} __call__(request)
-:canonical: archivebox.api.middleware.ApiCorsMiddleware.__call__
-
-```{autodoc2-docstring} archivebox.api.middleware.ApiCorsMiddleware.__call__
-```
-
-````
-
-````{py:method} _add_cors_headers(request, response)
-:canonical: archivebox.api.middleware.ApiCorsMiddleware._add_cors_headers
-
-```{autodoc2-docstring} archivebox.api.middleware.ApiCorsMiddleware._add_cors_headers
-```
-
-````
-
-`````
diff --git a/docs/apidocs/archivebox/archivebox.api.models.md b/docs/apidocs/archivebox/archivebox.api.models.md
deleted file mode 100644
index b4b6ac13..00000000
--- a/docs/apidocs/archivebox/archivebox.api.models.md
+++ /dev/null
@@ -1,250 +0,0 @@
-# {py:mod}`archivebox.api.models`
-
-```{py:module} archivebox.api.models
-```
-
-```{autodoc2-docstring} archivebox.api.models
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`APIToken `
- -
-* - {py:obj}`OutboundWebhook `
- -
-````
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`generate_secret_token `
- - ```{autodoc2-docstring} archivebox.api.models.generate_secret_token
- :summary:
- ```
-````
-
-### API
-
-````{py:function} generate_secret_token() -> str
-:canonical: archivebox.api.models.generate_secret_token
-
-```{autodoc2-docstring} archivebox.api.models.generate_secret_token
-```
-````
-
-``````{py:class} APIToken(*args, **kwargs)
-:canonical: archivebox.api.models.APIToken
-
-Bases: {py:obj}`django.db.models.Model`
-
-````{py:attribute} id
-:canonical: archivebox.api.models.APIToken.id
-:value: >
- 'UUIDField(...)'
-
-```{autodoc2-docstring} archivebox.api.models.APIToken.id
-```
-
-````
-
-````{py:attribute} created_by
-:canonical: archivebox.api.models.APIToken.created_by
-:value: >
- 'ForeignKey(...)'
-
-```{autodoc2-docstring} archivebox.api.models.APIToken.created_by
-```
-
-````
-
-````{py:attribute} created_at
-:canonical: archivebox.api.models.APIToken.created_at
-:value: >
- 'DateTimeField(...)'
-
-```{autodoc2-docstring} archivebox.api.models.APIToken.created_at
-```
-
-````
-
-````{py:attribute} modified_at
-:canonical: archivebox.api.models.APIToken.modified_at
-:value: >
- 'DateTimeField(...)'
-
-```{autodoc2-docstring} archivebox.api.models.APIToken.modified_at
-```
-
-````
-
-````{py:attribute} token
-:canonical: archivebox.api.models.APIToken.token
-:value: >
- 'CharField(...)'
-
-```{autodoc2-docstring} archivebox.api.models.APIToken.token
-```
-
-````
-
-````{py:attribute} expires
-:canonical: archivebox.api.models.APIToken.expires
-:value: >
- 'DateTimeField(...)'
-
-```{autodoc2-docstring} archivebox.api.models.APIToken.expires
-```
-
-````
-
-`````{py:class} Meta
-:canonical: archivebox.api.models.APIToken.Meta
-
-Bases: {py:obj}`django_stubs_ext.db.models.TypedModelMeta`
-
-````{py:attribute} app_label
-:canonical: archivebox.api.models.APIToken.Meta.app_label
-:value: >
- 'api'
-
-```{autodoc2-docstring} archivebox.api.models.APIToken.Meta.app_label
-```
-
-````
-
-````{py:attribute} verbose_name
-:canonical: archivebox.api.models.APIToken.Meta.verbose_name
-:value: >
- 'API Key'
-
-```{autodoc2-docstring} archivebox.api.models.APIToken.Meta.verbose_name
-```
-
-````
-
-````{py:attribute} verbose_name_plural
-:canonical: archivebox.api.models.APIToken.Meta.verbose_name_plural
-:value: >
- 'API Keys'
-
-```{autodoc2-docstring} archivebox.api.models.APIToken.Meta.verbose_name_plural
-```
-
-````
-
-`````
-
-````{py:method} __str__() -> str
-:canonical: archivebox.api.models.APIToken.__str__
-
-````
-
-````{py:property} token_redacted
-:canonical: archivebox.api.models.APIToken.token_redacted
-
-```{autodoc2-docstring} archivebox.api.models.APIToken.token_redacted
-```
-
-````
-
-````{py:method} is_valid(for_date=None)
-:canonical: archivebox.api.models.APIToken.is_valid
-
-```{autodoc2-docstring} archivebox.api.models.APIToken.is_valid
-```
-
-````
-
-``````
-
-``````{py:class} OutboundWebhook(*args, **kwargs)
-:canonical: archivebox.api.models.OutboundWebhook
-
-Bases: {py:obj}`signal_webhooks.models.WebhookBase`
-
-````{py:attribute} id
-:canonical: archivebox.api.models.OutboundWebhook.id
-:value: >
- 'UUIDField(...)'
-
-```{autodoc2-docstring} archivebox.api.models.OutboundWebhook.id
-```
-
-````
-
-````{py:attribute} created_by
-:canonical: archivebox.api.models.OutboundWebhook.created_by
-:value: >
- 'ForeignKey(...)'
-
-```{autodoc2-docstring} archivebox.api.models.OutboundWebhook.created_by
-```
-
-````
-
-````{py:attribute} created_at
-:canonical: archivebox.api.models.OutboundWebhook.created_at
-:value: >
- 'DateTimeField(...)'
-
-```{autodoc2-docstring} archivebox.api.models.OutboundWebhook.created_at
-```
-
-````
-
-````{py:attribute} modified_at
-:canonical: archivebox.api.models.OutboundWebhook.modified_at
-:value: >
- 'DateTimeField(...)'
-
-```{autodoc2-docstring} archivebox.api.models.OutboundWebhook.modified_at
-```
-
-````
-
-`````{py:class} Meta
-:canonical: archivebox.api.models.OutboundWebhook.Meta
-
-Bases: {py:obj}`signal_webhooks.models.WebhookBase.Meta`
-
-```{autodoc2-docstring} archivebox.api.models.OutboundWebhook.Meta
-```
-
-````{py:attribute} app_label
-:canonical: archivebox.api.models.OutboundWebhook.Meta.app_label
-:value: >
- 'api'
-
-```{autodoc2-docstring} archivebox.api.models.OutboundWebhook.Meta.app_label
-```
-
-````
-
-````{py:attribute} verbose_name
-:canonical: archivebox.api.models.OutboundWebhook.Meta.verbose_name
-:value: >
- 'API Outbound Webhook'
-
-```{autodoc2-docstring} archivebox.api.models.OutboundWebhook.Meta.verbose_name
-```
-
-````
-
-`````
-
-````{py:method} __str__() -> str
-:canonical: archivebox.api.models.OutboundWebhook.__str__
-
-````
-
-``````
diff --git a/docs/apidocs/archivebox/archivebox.api.urls.md b/docs/apidocs/archivebox/archivebox.api.urls.md
deleted file mode 100644
index c7503fd0..00000000
--- a/docs/apidocs/archivebox/archivebox.api.urls.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# {py:mod}`archivebox.api.urls`
-
-```{py:module} archivebox.api.urls
-```
-
-```{autodoc2-docstring} archivebox.api.urls
-:allowtitles:
-```
-
-## Module Contents
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`archive_redirect_view `
- - ```{autodoc2-docstring} archivebox.api.urls.archive_redirect_view
- :summary:
- ```
-````
-
-### Data
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`urlpatterns `
- - ```{autodoc2-docstring} archivebox.api.urls.urlpatterns
- :summary:
- ```
-````
-
-### API
-
-````{py:function} archive_redirect_view(request: django.http.HttpRequest, url: str) -> django.http.HttpResponseRedirect
-:canonical: archivebox.api.urls.archive_redirect_view
-
-```{autodoc2-docstring} archivebox.api.urls.archive_redirect_view
-```
-````
-
-````{py:data} urlpatterns
-:canonical: archivebox.api.urls.urlpatterns
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.urls.urlpatterns
-```
-
-````
diff --git a/docs/apidocs/archivebox/archivebox.api.v1_api.md b/docs/apidocs/archivebox/archivebox.api.v1_api.md
deleted file mode 100644
index 9d6d573b..00000000
--- a/docs/apidocs/archivebox/archivebox.api.v1_api.md
+++ /dev/null
@@ -1,131 +0,0 @@
-# {py:mod}`archivebox.api.v1_api`
-
-```{py:module} archivebox.api.v1_api
-```
-
-```{autodoc2-docstring} archivebox.api.v1_api
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`NinjaAPIWithIOCapture `
- -
-````
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`register_urls `
- - ```{autodoc2-docstring} archivebox.api.v1_api.register_urls
- :summary:
- ```
-* - {py:obj}`generic_exception_handler `
- - ```{autodoc2-docstring} archivebox.api.v1_api.generic_exception_handler
- :summary:
- ```
-````
-
-### Data
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`COMMIT_HASH `
- - ```{autodoc2-docstring} archivebox.api.v1_api.COMMIT_HASH
- :summary:
- ```
-* - {py:obj}`html_description `
- - ```{autodoc2-docstring} archivebox.api.v1_api.html_description
- :summary:
- ```
-* - {py:obj}`api `
- - ```{autodoc2-docstring} archivebox.api.v1_api.api
- :summary:
- ```
-* - {py:obj}`urls `
- - ```{autodoc2-docstring} archivebox.api.v1_api.urls
- :summary:
- ```
-````
-
-### API
-
-````{py:data} COMMIT_HASH
-:canonical: archivebox.api.v1_api.COMMIT_HASH
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_api.COMMIT_HASH
-```
-
-````
-
-````{py:data} html_description
-:canonical: archivebox.api.v1_api.html_description
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_api.html_description
-```
-
-````
-
-````{py:function} register_urls(api: ninja.NinjaAPI) -> ninja.NinjaAPI
-:canonical: archivebox.api.v1_api.register_urls
-
-```{autodoc2-docstring} archivebox.api.v1_api.register_urls
-```
-````
-
-`````{py:class} NinjaAPIWithIOCapture(*, title: str = 'NinjaAPI', version: str = '1.0.0', description: str = '', openapi_url: typing.Optional[str] = '/openapi.json', docs: ninja.openapi.docs.DocsBase = Swagger(), docs_url: typing.Optional[str] = '/docs', docs_decorator: typing.Optional[typing.Callable[[ninja.types.TCallable], ninja.types.TCallable]] = None, servers: typing.Optional[typing.List[ninja.types.DictStrAny]] = None, urls_namespace: typing.Optional[str] = None, auth: typing.Optional[typing.Union[typing.Sequence[typing.Callable], typing.Callable, ninja.constants.NOT_SET_TYPE]] = NOT_SET, throttle: typing.Union[ninja.throttling.BaseThrottle, typing.List[ninja.throttling.BaseThrottle], ninja.constants.NOT_SET_TYPE] = NOT_SET, renderer: typing.Optional[ninja.renderers.BaseRenderer] = None, parser: typing.Optional[ninja.parser.Parser] = None, default_router: typing.Optional[ninja.router.Router] = None, openapi_extra: typing.Optional[typing.Dict[str, typing.Any]] = None)
-:canonical: archivebox.api.v1_api.NinjaAPIWithIOCapture
-
-Bases: {py:obj}`ninja.NinjaAPI`
-
-````{py:method} create_temporal_response(request: django.http.HttpRequest) -> django.http.HttpResponse
-:canonical: archivebox.api.v1_api.NinjaAPIWithIOCapture.create_temporal_response
-
-```{autodoc2-docstring} archivebox.api.v1_api.NinjaAPIWithIOCapture.create_temporal_response
-```
-
-````
-
-`````
-
-````{py:data} api
-:canonical: archivebox.api.v1_api.api
-:value: >
- 'NinjaAPIWithIOCapture(...)'
-
-```{autodoc2-docstring} archivebox.api.v1_api.api
-```
-
-````
-
-````{py:data} urls
-:canonical: archivebox.api.v1_api.urls
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_api.urls
-```
-
-````
-
-````{py:function} generic_exception_handler(request, err)
-:canonical: archivebox.api.v1_api.generic_exception_handler
-
-```{autodoc2-docstring} archivebox.api.v1_api.generic_exception_handler
-```
-````
diff --git a/docs/apidocs/archivebox/archivebox.api.v1_auth.md b/docs/apidocs/archivebox/archivebox.api.v1_auth.md
deleted file mode 100644
index 1285fa26..00000000
--- a/docs/apidocs/archivebox/archivebox.api.v1_auth.md
+++ /dev/null
@@ -1,145 +0,0 @@
-# {py:mod}`archivebox.api.v1_auth`
-
-```{py:module} archivebox.api.v1_auth
-```
-
-```{autodoc2-docstring} archivebox.api.v1_auth
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`PasswordAuthSchema `
- - ```{autodoc2-docstring} archivebox.api.v1_auth.PasswordAuthSchema
- :summary:
- ```
-* - {py:obj}`TokenAuthSchema `
- - ```{autodoc2-docstring} archivebox.api.v1_auth.TokenAuthSchema
- :summary:
- ```
-````
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`get_api_token `
- - ```{autodoc2-docstring} archivebox.api.v1_auth.get_api_token
- :summary:
- ```
-* - {py:obj}`check_api_token `
- - ```{autodoc2-docstring} archivebox.api.v1_auth.check_api_token
- :summary:
- ```
-````
-
-### Data
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`router `
- - ```{autodoc2-docstring} archivebox.api.v1_auth.router
- :summary:
- ```
-````
-
-### API
-
-````{py:data} router
-:canonical: archivebox.api.v1_auth.router
-:value: >
- 'Router(...)'
-
-```{autodoc2-docstring} archivebox.api.v1_auth.router
-```
-
-````
-
-`````{py:class} PasswordAuthSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_auth.PasswordAuthSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-```{autodoc2-docstring} archivebox.api.v1_auth.PasswordAuthSchema
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.api.v1_auth.PasswordAuthSchema.__init__
-```
-
-````{py:attribute} username
-:canonical: archivebox.api.v1_auth.PasswordAuthSchema.username
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_auth.PasswordAuthSchema.username
-```
-
-````
-
-````{py:attribute} password
-:canonical: archivebox.api.v1_auth.PasswordAuthSchema.password
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_auth.PasswordAuthSchema.password
-```
-
-````
-
-`````
-
-````{py:function} get_api_token(request: django.http.HttpRequest, auth_data: archivebox.api.v1_auth.PasswordAuthSchema)
-:canonical: archivebox.api.v1_auth.get_api_token
-
-```{autodoc2-docstring} archivebox.api.v1_auth.get_api_token
-```
-````
-
-`````{py:class} TokenAuthSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_auth.TokenAuthSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-```{autodoc2-docstring} archivebox.api.v1_auth.TokenAuthSchema
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.api.v1_auth.TokenAuthSchema.__init__
-```
-
-````{py:attribute} token
-:canonical: archivebox.api.v1_auth.TokenAuthSchema.token
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_auth.TokenAuthSchema.token
-```
-
-````
-
-`````
-
-````{py:function} check_api_token(request: django.http.HttpRequest, token_data: archivebox.api.v1_auth.TokenAuthSchema)
-:canonical: archivebox.api.v1_auth.check_api_token
-
-```{autodoc2-docstring} archivebox.api.v1_auth.check_api_token
-```
-````
diff --git a/docs/apidocs/archivebox/archivebox.api.v1_cli.md b/docs/apidocs/archivebox/archivebox.api.v1_cli.md
deleted file mode 100644
index ebec6094..00000000
--- a/docs/apidocs/archivebox/archivebox.api.v1_cli.md
+++ /dev/null
@@ -1,898 +0,0 @@
-# {py:mod}`archivebox.api.v1_cli`
-
-```{py:module} archivebox.api.v1_cli
-```
-
-```{autodoc2-docstring} archivebox.api.v1_cli
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`CLICommandResponseSchema `
- -
-* - {py:obj}`FilterTypeChoices `
- -
-* - {py:obj}`StatusChoices `
- -
-* - {py:obj}`AddCommandSchema `
- -
-* - {py:obj}`UpdateCommandSchema `
- -
-* - {py:obj}`ScheduleCommandSchema `
- -
-* - {py:obj}`ListCommandSchema `
- -
-* - {py:obj}`RemoveCommandSchema `
- -
-````
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`cli_add `
- - ```{autodoc2-docstring} archivebox.api.v1_cli.cli_add
- :summary:
- ```
-* - {py:obj}`cli_update `
- - ```{autodoc2-docstring} archivebox.api.v1_cli.cli_update
- :summary:
- ```
-* - {py:obj}`cli_schedule `
- - ```{autodoc2-docstring} archivebox.api.v1_cli.cli_schedule
- :summary:
- ```
-* - {py:obj}`cli_search `
- - ```{autodoc2-docstring} archivebox.api.v1_cli.cli_search
- :summary:
- ```
-* - {py:obj}`cli_remove `
- - ```{autodoc2-docstring} archivebox.api.v1_cli.cli_remove
- :summary:
- ```
-````
-
-### Data
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`router `
- - ```{autodoc2-docstring} archivebox.api.v1_cli.router
- :summary:
- ```
-* - {py:obj}`JSONType `
- - ```{autodoc2-docstring} archivebox.api.v1_cli.JSONType
- :summary:
- ```
-````
-
-### API
-
-````{py:data} router
-:canonical: archivebox.api.v1_cli.router
-:value: >
- 'Router(...)'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.router
-```
-
-````
-
-````{py:data} JSONType
-:canonical: archivebox.api.v1_cli.JSONType
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.JSONType
-```
-
-````
-
-`````{py:class} CLICommandResponseSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_cli.CLICommandResponseSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} success
-:canonical: archivebox.api.v1_cli.CLICommandResponseSchema.success
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.CLICommandResponseSchema.success
-```
-
-````
-
-````{py:attribute} errors
-:canonical: archivebox.api.v1_cli.CLICommandResponseSchema.errors
-:type: list[str]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.CLICommandResponseSchema.errors
-```
-
-````
-
-````{py:attribute} result
-:canonical: archivebox.api.v1_cli.CLICommandResponseSchema.result
-:type: archivebox.api.v1_cli.JSONType
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.CLICommandResponseSchema.result
-```
-
-````
-
-````{py:attribute} result_format
-:canonical: archivebox.api.v1_cli.CLICommandResponseSchema.result_format
-:type: str
-:value: >
- 'str'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.CLICommandResponseSchema.result_format
-```
-
-````
-
-````{py:attribute} stdout
-:canonical: archivebox.api.v1_cli.CLICommandResponseSchema.stdout
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.CLICommandResponseSchema.stdout
-```
-
-````
-
-````{py:attribute} stderr
-:canonical: archivebox.api.v1_cli.CLICommandResponseSchema.stderr
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.CLICommandResponseSchema.stderr
-```
-
-````
-
-`````
-
-`````{py:class} FilterTypeChoices()
-:canonical: archivebox.api.v1_cli.FilterTypeChoices
-
-Bases: {py:obj}`str`, {py:obj}`enum.Enum`
-
-````{py:attribute} exact
-:canonical: archivebox.api.v1_cli.FilterTypeChoices.exact
-:value: >
- 'exact'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.FilterTypeChoices.exact
-```
-
-````
-
-````{py:attribute} substring
-:canonical: archivebox.api.v1_cli.FilterTypeChoices.substring
-:value: >
- 'substring'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.FilterTypeChoices.substring
-```
-
-````
-
-````{py:attribute} regex
-:canonical: archivebox.api.v1_cli.FilterTypeChoices.regex
-:value: >
- 'regex'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.FilterTypeChoices.regex
-```
-
-````
-
-````{py:attribute} domain
-:canonical: archivebox.api.v1_cli.FilterTypeChoices.domain
-:value: >
- 'domain'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.FilterTypeChoices.domain
-```
-
-````
-
-````{py:attribute} tag
-:canonical: archivebox.api.v1_cli.FilterTypeChoices.tag
-:value: >
- 'tag'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.FilterTypeChoices.tag
-```
-
-````
-
-````{py:attribute} timestamp
-:canonical: archivebox.api.v1_cli.FilterTypeChoices.timestamp
-:value: >
- 'timestamp'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.FilterTypeChoices.timestamp
-```
-
-````
-
-`````
-
-`````{py:class} StatusChoices()
-:canonical: archivebox.api.v1_cli.StatusChoices
-
-Bases: {py:obj}`str`, {py:obj}`enum.Enum`
-
-````{py:attribute} indexed
-:canonical: archivebox.api.v1_cli.StatusChoices.indexed
-:value: >
- 'indexed'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.StatusChoices.indexed
-```
-
-````
-
-````{py:attribute} archived
-:canonical: archivebox.api.v1_cli.StatusChoices.archived
-:value: >
- 'archived'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.StatusChoices.archived
-```
-
-````
-
-````{py:attribute} unarchived
-:canonical: archivebox.api.v1_cli.StatusChoices.unarchived
-:value: >
- 'unarchived'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.StatusChoices.unarchived
-```
-
-````
-
-````{py:attribute} present
-:canonical: archivebox.api.v1_cli.StatusChoices.present
-:value: >
- 'present'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.StatusChoices.present
-```
-
-````
-
-````{py:attribute} valid
-:canonical: archivebox.api.v1_cli.StatusChoices.valid
-:value: >
- 'valid'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.StatusChoices.valid
-```
-
-````
-
-````{py:attribute} invalid
-:canonical: archivebox.api.v1_cli.StatusChoices.invalid
-:value: >
- 'invalid'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.StatusChoices.invalid
-```
-
-````
-
-````{py:attribute} duplicate
-:canonical: archivebox.api.v1_cli.StatusChoices.duplicate
-:value: >
- 'duplicate'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.StatusChoices.duplicate
-```
-
-````
-
-````{py:attribute} orphaned
-:canonical: archivebox.api.v1_cli.StatusChoices.orphaned
-:value: >
- 'orphaned'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.StatusChoices.orphaned
-```
-
-````
-
-````{py:attribute} corrupted
-:canonical: archivebox.api.v1_cli.StatusChoices.corrupted
-:value: >
- 'corrupted'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.StatusChoices.corrupted
-```
-
-````
-
-````{py:attribute} unrecognized
-:canonical: archivebox.api.v1_cli.StatusChoices.unrecognized
-:value: >
- 'unrecognized'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.StatusChoices.unrecognized
-```
-
-````
-
-`````
-
-`````{py:class} AddCommandSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_cli.AddCommandSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} urls
-:canonical: archivebox.api.v1_cli.AddCommandSchema.urls
-:type: list[str]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.AddCommandSchema.urls
-```
-
-````
-
-````{py:attribute} snapshot_ids
-:canonical: archivebox.api.v1_cli.AddCommandSchema.snapshot_ids
-:type: list[str] | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.AddCommandSchema.snapshot_ids
-```
-
-````
-
-````{py:attribute} tag
-:canonical: archivebox.api.v1_cli.AddCommandSchema.tag
-:type: str
-:value:
-
-```{autodoc2-docstring} archivebox.api.v1_cli.AddCommandSchema.tag
-```
-
-````
-
-````{py:attribute} depth
-:canonical: archivebox.api.v1_cli.AddCommandSchema.depth
-:type: int
-:value: >
- 0
-
-```{autodoc2-docstring} archivebox.api.v1_cli.AddCommandSchema.depth
-```
-
-````
-
-````{py:attribute} max_urls
-:canonical: archivebox.api.v1_cli.AddCommandSchema.max_urls
-:type: int
-:value: >
- 0
-
-```{autodoc2-docstring} archivebox.api.v1_cli.AddCommandSchema.max_urls
-```
-
-````
-
-````{py:attribute} crawl_max_size
-:canonical: archivebox.api.v1_cli.AddCommandSchema.crawl_max_size
-:type: int
-:value: >
- 0
-
-```{autodoc2-docstring} archivebox.api.v1_cli.AddCommandSchema.crawl_max_size
-```
-
-````
-
-````{py:attribute} crawl_timeout
-:canonical: archivebox.api.v1_cli.AddCommandSchema.crawl_timeout
-:type: int
-:value: >
- 0
-
-```{autodoc2-docstring} archivebox.api.v1_cli.AddCommandSchema.crawl_timeout
-```
-
-````
-
-````{py:attribute} snapshot_max_size
-:canonical: archivebox.api.v1_cli.AddCommandSchema.snapshot_max_size
-:type: int
-:value: >
- 0
-
-```{autodoc2-docstring} archivebox.api.v1_cli.AddCommandSchema.snapshot_max_size
-```
-
-````
-
-````{py:attribute} parser
-:canonical: archivebox.api.v1_cli.AddCommandSchema.parser
-:type: str
-:value: >
- 'auto'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.AddCommandSchema.parser
-```
-
-````
-
-````{py:attribute} plugins
-:canonical: archivebox.api.v1_cli.AddCommandSchema.plugins
-:type: str
-:value:
-
-```{autodoc2-docstring} archivebox.api.v1_cli.AddCommandSchema.plugins
-```
-
-````
-
-````{py:attribute} only_new
-:canonical: archivebox.api.v1_cli.AddCommandSchema.only_new
-:type: bool | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.AddCommandSchema.only_new
-```
-
-````
-
-````{py:attribute} index_only
-:canonical: archivebox.api.v1_cli.AddCommandSchema.index_only
-:type: bool
-:value: >
- False
-
-```{autodoc2-docstring} archivebox.api.v1_cli.AddCommandSchema.index_only
-```
-
-````
-
-`````
-
-`````{py:class} UpdateCommandSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_cli.UpdateCommandSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} resume
-:canonical: archivebox.api.v1_cli.UpdateCommandSchema.resume
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.UpdateCommandSchema.resume
-```
-
-````
-
-````{py:attribute} after
-:canonical: archivebox.api.v1_cli.UpdateCommandSchema.after
-:type: float | None
-:value: >
- 0
-
-```{autodoc2-docstring} archivebox.api.v1_cli.UpdateCommandSchema.after
-```
-
-````
-
-````{py:attribute} before
-:canonical: archivebox.api.v1_cli.UpdateCommandSchema.before
-:type: float | None
-:value: >
- 999999999999999
-
-```{autodoc2-docstring} archivebox.api.v1_cli.UpdateCommandSchema.before
-```
-
-````
-
-````{py:attribute} filter_type
-:canonical: archivebox.api.v1_cli.UpdateCommandSchema.filter_type
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.UpdateCommandSchema.filter_type
-```
-
-````
-
-````{py:attribute} filter_patterns
-:canonical: archivebox.api.v1_cli.UpdateCommandSchema.filter_patterns
-:type: list[str] | None
-:value: >
- ['https://example.com']
-
-```{autodoc2-docstring} archivebox.api.v1_cli.UpdateCommandSchema.filter_patterns
-```
-
-````
-
-````{py:attribute} batch_size
-:canonical: archivebox.api.v1_cli.UpdateCommandSchema.batch_size
-:type: int
-:value: >
- 100
-
-```{autodoc2-docstring} archivebox.api.v1_cli.UpdateCommandSchema.batch_size
-```
-
-````
-
-````{py:attribute} continuous
-:canonical: archivebox.api.v1_cli.UpdateCommandSchema.continuous
-:type: bool
-:value: >
- False
-
-```{autodoc2-docstring} archivebox.api.v1_cli.UpdateCommandSchema.continuous
-```
-
-````
-
-`````
-
-`````{py:class} ScheduleCommandSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_cli.ScheduleCommandSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} import_path
-:canonical: archivebox.api.v1_cli.ScheduleCommandSchema.import_path
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ScheduleCommandSchema.import_path
-```
-
-````
-
-````{py:attribute} add
-:canonical: archivebox.api.v1_cli.ScheduleCommandSchema.add
-:type: bool
-:value: >
- False
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ScheduleCommandSchema.add
-```
-
-````
-
-````{py:attribute} show
-:canonical: archivebox.api.v1_cli.ScheduleCommandSchema.show
-:type: bool
-:value: >
- False
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ScheduleCommandSchema.show
-```
-
-````
-
-````{py:attribute} foreground
-:canonical: archivebox.api.v1_cli.ScheduleCommandSchema.foreground
-:type: bool
-:value: >
- False
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ScheduleCommandSchema.foreground
-```
-
-````
-
-````{py:attribute} run_all
-:canonical: archivebox.api.v1_cli.ScheduleCommandSchema.run_all
-:type: bool
-:value: >
- False
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ScheduleCommandSchema.run_all
-```
-
-````
-
-````{py:attribute} quiet
-:canonical: archivebox.api.v1_cli.ScheduleCommandSchema.quiet
-:type: bool
-:value: >
- False
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ScheduleCommandSchema.quiet
-```
-
-````
-
-````{py:attribute} every
-:canonical: archivebox.api.v1_cli.ScheduleCommandSchema.every
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ScheduleCommandSchema.every
-```
-
-````
-
-````{py:attribute} tag
-:canonical: archivebox.api.v1_cli.ScheduleCommandSchema.tag
-:type: str
-:value:
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ScheduleCommandSchema.tag
-```
-
-````
-
-````{py:attribute} depth
-:canonical: archivebox.api.v1_cli.ScheduleCommandSchema.depth
-:type: int
-:value: >
- 0
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ScheduleCommandSchema.depth
-```
-
-````
-
-````{py:attribute} only_new
-:canonical: archivebox.api.v1_cli.ScheduleCommandSchema.only_new
-:type: bool | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ScheduleCommandSchema.only_new
-```
-
-````
-
-````{py:attribute} clear
-:canonical: archivebox.api.v1_cli.ScheduleCommandSchema.clear
-:type: bool
-:value: >
- False
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ScheduleCommandSchema.clear
-```
-
-````
-
-`````
-
-`````{py:class} ListCommandSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_cli.ListCommandSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} filter_patterns
-:canonical: archivebox.api.v1_cli.ListCommandSchema.filter_patterns
-:type: list[str] | None
-:value: >
- ['https://example.com']
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ListCommandSchema.filter_patterns
-```
-
-````
-
-````{py:attribute} filter_type
-:canonical: archivebox.api.v1_cli.ListCommandSchema.filter_type
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ListCommandSchema.filter_type
-```
-
-````
-
-````{py:attribute} status
-:canonical: archivebox.api.v1_cli.ListCommandSchema.status
-:type: archivebox.api.v1_cli.StatusChoices
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ListCommandSchema.status
-```
-
-````
-
-````{py:attribute} after
-:canonical: archivebox.api.v1_cli.ListCommandSchema.after
-:type: float | None
-:value: >
- 0
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ListCommandSchema.after
-```
-
-````
-
-````{py:attribute} before
-:canonical: archivebox.api.v1_cli.ListCommandSchema.before
-:type: float | None
-:value: >
- 999999999999999
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ListCommandSchema.before
-```
-
-````
-
-````{py:attribute} sort
-:canonical: archivebox.api.v1_cli.ListCommandSchema.sort
-:type: str
-:value: >
- 'bookmarked_at'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ListCommandSchema.sort
-```
-
-````
-
-````{py:attribute} as_json
-:canonical: archivebox.api.v1_cli.ListCommandSchema.as_json
-:type: bool
-:value: >
- True
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ListCommandSchema.as_json
-```
-
-````
-
-````{py:attribute} as_html
-:canonical: archivebox.api.v1_cli.ListCommandSchema.as_html
-:type: bool
-:value: >
- False
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ListCommandSchema.as_html
-```
-
-````
-
-````{py:attribute} as_csv
-:canonical: archivebox.api.v1_cli.ListCommandSchema.as_csv
-:type: str | None
-:value: >
- 'timestamp,url'
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ListCommandSchema.as_csv
-```
-
-````
-
-````{py:attribute} with_headers
-:canonical: archivebox.api.v1_cli.ListCommandSchema.with_headers
-:type: bool
-:value: >
- False
-
-```{autodoc2-docstring} archivebox.api.v1_cli.ListCommandSchema.with_headers
-```
-
-````
-
-`````
-
-`````{py:class} RemoveCommandSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_cli.RemoveCommandSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} after
-:canonical: archivebox.api.v1_cli.RemoveCommandSchema.after
-:type: float | None
-:value: >
- 0
-
-```{autodoc2-docstring} archivebox.api.v1_cli.RemoveCommandSchema.after
-```
-
-````
-
-````{py:attribute} before
-:canonical: archivebox.api.v1_cli.RemoveCommandSchema.before
-:type: float | None
-:value: >
- 999999999999999
-
-```{autodoc2-docstring} archivebox.api.v1_cli.RemoveCommandSchema.before
-```
-
-````
-
-````{py:attribute} filter_type
-:canonical: archivebox.api.v1_cli.RemoveCommandSchema.filter_type
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_cli.RemoveCommandSchema.filter_type
-```
-
-````
-
-````{py:attribute} filter_patterns
-:canonical: archivebox.api.v1_cli.RemoveCommandSchema.filter_patterns
-:type: list[str] | None
-:value: >
- ['https://example.com']
-
-```{autodoc2-docstring} archivebox.api.v1_cli.RemoveCommandSchema.filter_patterns
-```
-
-````
-
-`````
-
-````{py:function} cli_add(request: django.http.HttpRequest, args: archivebox.api.v1_cli.AddCommandSchema)
-:canonical: archivebox.api.v1_cli.cli_add
-
-```{autodoc2-docstring} archivebox.api.v1_cli.cli_add
-```
-````
-
-````{py:function} cli_update(request: django.http.HttpRequest, args: archivebox.api.v1_cli.UpdateCommandSchema)
-:canonical: archivebox.api.v1_cli.cli_update
-
-```{autodoc2-docstring} archivebox.api.v1_cli.cli_update
-```
-````
-
-````{py:function} cli_schedule(request: django.http.HttpRequest, args: archivebox.api.v1_cli.ScheduleCommandSchema)
-:canonical: archivebox.api.v1_cli.cli_schedule
-
-```{autodoc2-docstring} archivebox.api.v1_cli.cli_schedule
-```
-````
-
-````{py:function} cli_search(request: django.http.HttpRequest, args: archivebox.api.v1_cli.ListCommandSchema)
-:canonical: archivebox.api.v1_cli.cli_search
-
-```{autodoc2-docstring} archivebox.api.v1_cli.cli_search
-```
-````
-
-````{py:function} cli_remove(request: django.http.HttpRequest, args: archivebox.api.v1_cli.RemoveCommandSchema)
-:canonical: archivebox.api.v1_cli.cli_remove
-
-```{autodoc2-docstring} archivebox.api.v1_cli.cli_remove
-```
-````
diff --git a/docs/apidocs/archivebox/archivebox.api.v1_core.md b/docs/apidocs/archivebox/archivebox.api.v1_core.md
deleted file mode 100644
index 1a2f5312..00000000
--- a/docs/apidocs/archivebox/archivebox.api.v1_core.md
+++ /dev/null
@@ -1,2616 +0,0 @@
-# {py:mod}`archivebox.api.v1_core`
-
-```{py:module} archivebox.api.v1_core
-```
-
-```{autodoc2-docstring} archivebox.api.v1_core
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`CustomPagination `
- -
-* - {py:obj}`MinimalArchiveResultSchema `
- -
-* - {py:obj}`ArchiveResultSchema `
- -
-* - {py:obj}`ArchiveResultFilterSchema `
- -
-* - {py:obj}`SnapshotSchema `
- -
-* - {py:obj}`SnapshotUpdateSchema `
- -
-* - {py:obj}`SnapshotCreateSchema `
- -
-* - {py:obj}`SnapshotDeleteResponseSchema `
- -
-* - {py:obj}`SnapshotFilterSchema `
- -
-* - {py:obj}`TagSchema `
- -
-* - {py:obj}`TagAutocompleteSchema `
- -
-* - {py:obj}`TagCreateSchema `
- -
-* - {py:obj}`TagCreateResponseSchema `
- -
-* - {py:obj}`TagSearchSnapshotSchema `
- -
-* - {py:obj}`TagSearchCardSchema `
- -
-* - {py:obj}`TagSearchResponseSchema `
- -
-* - {py:obj}`TagUpdateSchema `
- -
-* - {py:obj}`TagUpdateResponseSchema `
- -
-* - {py:obj}`TagDeleteResponseSchema `
- -
-* - {py:obj}`TagSnapshotRequestSchema `
- -
-* - {py:obj}`TagSnapshotResponseSchema `
- -
-````
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`get_archiveresults `
- - ```{autodoc2-docstring} archivebox.api.v1_core.get_archiveresults
- :summary:
- ```
-* - {py:obj}`_uuid_ref_query `
- - ```{autodoc2-docstring} archivebox.api.v1_core._uuid_ref_query
- :summary:
- ```
-* - {py:obj}`get_archiveresult `
- - ```{autodoc2-docstring} archivebox.api.v1_core.get_archiveresult
- :summary:
- ```
-* - {py:obj}`_normalize_uploaded_archiveresult_plugin `
- - ```{autodoc2-docstring} archivebox.api.v1_core._normalize_uploaded_archiveresult_plugin
- :summary:
- ```
-* - {py:obj}`_normalize_uploaded_archiveresult_output_path `
- - ```{autodoc2-docstring} archivebox.api.v1_core._normalize_uploaded_archiveresult_output_path
- :summary:
- ```
-* - {py:obj}`_parse_archiveresult_output_json `
- - ```{autodoc2-docstring} archivebox.api.v1_core._parse_archiveresult_output_json
- :summary:
- ```
-* - {py:obj}`_get_archiveresult_upload_data `
- - ```{autodoc2-docstring} archivebox.api.v1_core._get_archiveresult_upload_data
- :summary:
- ```
-* - {py:obj}`_get_archiveresult_upload_files `
- - ```{autodoc2-docstring} archivebox.api.v1_core._get_archiveresult_upload_files
- :summary:
- ```
-* - {py:obj}`_get_archiveresult_upload_form_values `
- - ```{autodoc2-docstring} archivebox.api.v1_core._get_archiveresult_upload_form_values
- :summary:
- ```
-* - {py:obj}`_get_archiveresult_upload_form_value `
- - ```{autodoc2-docstring} archivebox.api.v1_core._get_archiveresult_upload_form_value
- :summary:
- ```
-* - {py:obj}`_parse_archiveresult_upload_int `
- - ```{autodoc2-docstring} archivebox.api.v1_core._parse_archiveresult_upload_int
- :summary:
- ```
-* - {py:obj}`_summarize_archiveresult_output_files `
- - ```{autodoc2-docstring} archivebox.api.v1_core._summarize_archiveresult_output_files
- :summary:
- ```
-* - {py:obj}`_get_snapshot_by_ref `
- - ```{autodoc2-docstring} archivebox.api.v1_core._get_snapshot_by_ref
- :summary:
- ```
-* - {py:obj}`_queue_archiveresult_snapshot_maintenance `
- - ```{autodoc2-docstring} archivebox.api.v1_core._queue_archiveresult_snapshot_maintenance
- :summary:
- ```
-* - {py:obj}`_merge_archiveresult_output_file_maps `
- - ```{autodoc2-docstring} archivebox.api.v1_core._merge_archiveresult_output_file_maps
- :summary:
- ```
-* - {py:obj}`_write_archiveresult_files `
- - ```{autodoc2-docstring} archivebox.api.v1_core._write_archiveresult_files
- :summary:
- ```
-* - {py:obj}`create_archiveresult `
- - ```{autodoc2-docstring} archivebox.api.v1_core.create_archiveresult
- :summary:
- ```
-* - {py:obj}`patch_archiveresult `
- - ```{autodoc2-docstring} archivebox.api.v1_core.patch_archiveresult
- :summary:
- ```
-* - {py:obj}`normalize_tag_list `
- - ```{autodoc2-docstring} archivebox.api.v1_core.normalize_tag_list
- :summary:
- ```
-* - {py:obj}`_parse_rss_before `
- - ```{autodoc2-docstring} archivebox.api.v1_core._parse_rss_before
- :summary:
- ```
-* - {py:obj}`_filter_snapshots_for_rss `
- - ```{autodoc2-docstring} archivebox.api.v1_core._filter_snapshots_for_rss
- :summary:
- ```
-* - {py:obj}`_snapshots_rss_response `
- - ```{autodoc2-docstring} archivebox.api.v1_core._snapshots_rss_response
- :summary:
- ```
-* - {py:obj}`get_snapshots `
- - ```{autodoc2-docstring} archivebox.api.v1_core.get_snapshots
- :summary:
- ```
-* - {py:obj}`get_snapshots_rss `
- - ```{autodoc2-docstring} archivebox.api.v1_core.get_snapshots_rss
- :summary:
- ```
-* - {py:obj}`get_snapshot `
- - ```{autodoc2-docstring} archivebox.api.v1_core.get_snapshot
- :summary:
- ```
-* - {py:obj}`create_snapshot `
- - ```{autodoc2-docstring} archivebox.api.v1_core.create_snapshot
- :summary:
- ```
-* - {py:obj}`patch_snapshot `
- - ```{autodoc2-docstring} archivebox.api.v1_core.patch_snapshot
- :summary:
- ```
-* - {py:obj}`delete_snapshot `
- - ```{autodoc2-docstring} archivebox.api.v1_core.delete_snapshot
- :summary:
- ```
-* - {py:obj}`get_tags `
- - ```{autodoc2-docstring} archivebox.api.v1_core.get_tags
- :summary:
- ```
-* - {py:obj}`get_tag `
- - ```{autodoc2-docstring} archivebox.api.v1_core.get_tag
- :summary:
- ```
-* - {py:obj}`get_any `
- - ```{autodoc2-docstring} archivebox.api.v1_core.get_any
- :summary:
- ```
-* - {py:obj}`_get_snapshot_for_tag_edit `
- - ```{autodoc2-docstring} archivebox.api.v1_core._get_snapshot_for_tag_edit
- :summary:
- ```
-* - {py:obj}`search_tags `
- - ```{autodoc2-docstring} archivebox.api.v1_core.search_tags
- :summary:
- ```
-* - {py:obj}`_public_tag_listing_enabled `
- - ```{autodoc2-docstring} archivebox.api.v1_core._public_tag_listing_enabled
- :summary:
- ```
-* - {py:obj}`_request_has_tag_autocomplete_access `
- - ```{autodoc2-docstring} archivebox.api.v1_core._request_has_tag_autocomplete_access
- :summary:
- ```
-* - {py:obj}`tags_autocomplete `
- - ```{autodoc2-docstring} archivebox.api.v1_core.tags_autocomplete
- :summary:
- ```
-* - {py:obj}`tags_create `
- - ```{autodoc2-docstring} archivebox.api.v1_core.tags_create
- :summary:
- ```
-* - {py:obj}`rename_tag `
- - ```{autodoc2-docstring} archivebox.api.v1_core.rename_tag
- :summary:
- ```
-* - {py:obj}`delete_tag `
- - ```{autodoc2-docstring} archivebox.api.v1_core.delete_tag
- :summary:
- ```
-* - {py:obj}`tag_urls_export `
- - ```{autodoc2-docstring} archivebox.api.v1_core.tag_urls_export
- :summary:
- ```
-* - {py:obj}`tag_snapshots_export `
- - ```{autodoc2-docstring} archivebox.api.v1_core.tag_snapshots_export
- :summary:
- ```
-* - {py:obj}`tags_add_to_snapshot `
- - ```{autodoc2-docstring} archivebox.api.v1_core.tags_add_to_snapshot
- :summary:
- ```
-* - {py:obj}`tags_remove_from_snapshot `
- - ```{autodoc2-docstring} archivebox.api.v1_core.tags_remove_from_snapshot
- :summary:
- ```
-````
-
-### Data
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`router `
- - ```{autodoc2-docstring} archivebox.api.v1_core.router
- :summary:
- ```
-* - {py:obj}`ARCHIVERESULT_UPLOAD_HOOK_NAME `
- - ```{autodoc2-docstring} archivebox.api.v1_core.ARCHIVERESULT_UPLOAD_HOOK_NAME
- :summary:
- ```
-* - {py:obj}`ARCHIVERESULT_UPLOAD_PLUGIN_RE `
- - ```{autodoc2-docstring} archivebox.api.v1_core.ARCHIVERESULT_UPLOAD_PLUGIN_RE
- :summary:
- ```
-````
-
-### API
-
-````{py:data} router
-:canonical: archivebox.api.v1_core.router
-:value: >
- 'Router(...)'
-
-```{autodoc2-docstring} archivebox.api.v1_core.router
-```
-
-````
-
-````{py:data} ARCHIVERESULT_UPLOAD_HOOK_NAME
-:canonical: archivebox.api.v1_core.ARCHIVERESULT_UPLOAD_HOOK_NAME
-:value: >
- 'on_Snapshot__archivebox_browser_extension_upload'
-
-```{autodoc2-docstring} archivebox.api.v1_core.ARCHIVERESULT_UPLOAD_HOOK_NAME
-```
-
-````
-
-````{py:data} ARCHIVERESULT_UPLOAD_PLUGIN_RE
-:canonical: archivebox.api.v1_core.ARCHIVERESULT_UPLOAD_PLUGIN_RE
-:value: >
- 'compile(...)'
-
-```{autodoc2-docstring} archivebox.api.v1_core.ARCHIVERESULT_UPLOAD_PLUGIN_RE
-```
-
-````
-
-``````{py:class} CustomPagination(*, pass_parameter: typing.Optional[str] = None, **kwargs: typing.Any)
-:canonical: archivebox.api.v1_core.CustomPagination
-
-Bases: {py:obj}`ninja.pagination.PaginationBase`
-
-`````{py:class} Input(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.CustomPagination.Input
-
-Bases: {py:obj}`ninja.pagination.PaginationBase.Input`
-
-````{py:attribute} limit
-:canonical: archivebox.api.v1_core.CustomPagination.Input.limit
-:type: int
-:value: >
- 200
-
-```{autodoc2-docstring} archivebox.api.v1_core.CustomPagination.Input.limit
-```
-
-````
-
-````{py:attribute} offset
-:canonical: archivebox.api.v1_core.CustomPagination.Input.offset
-:type: int
-:value: >
- 0
-
-```{autodoc2-docstring} archivebox.api.v1_core.CustomPagination.Input.offset
-```
-
-````
-
-````{py:attribute} page
-:canonical: archivebox.api.v1_core.CustomPagination.Input.page
-:type: int
-:value: >
- 0
-
-```{autodoc2-docstring} archivebox.api.v1_core.CustomPagination.Input.page
-```
-
-````
-
-`````
-
-`````{py:class} Output(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.CustomPagination.Output
-
-Bases: {py:obj}`ninja.pagination.PaginationBase.Output`
-
-````{py:attribute} count
-:canonical: archivebox.api.v1_core.CustomPagination.Output.count
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.CustomPagination.Output.count
-```
-
-````
-
-````{py:attribute} total_items
-:canonical: archivebox.api.v1_core.CustomPagination.Output.total_items
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.CustomPagination.Output.total_items
-```
-
-````
-
-````{py:attribute} total_pages
-:canonical: archivebox.api.v1_core.CustomPagination.Output.total_pages
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.CustomPagination.Output.total_pages
-```
-
-````
-
-````{py:attribute} page
-:canonical: archivebox.api.v1_core.CustomPagination.Output.page
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.CustomPagination.Output.page
-```
-
-````
-
-````{py:attribute} limit
-:canonical: archivebox.api.v1_core.CustomPagination.Output.limit
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.CustomPagination.Output.limit
-```
-
-````
-
-````{py:attribute} offset
-:canonical: archivebox.api.v1_core.CustomPagination.Output.offset
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.CustomPagination.Output.offset
-```
-
-````
-
-````{py:attribute} num_items
-:canonical: archivebox.api.v1_core.CustomPagination.Output.num_items
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.CustomPagination.Output.num_items
-```
-
-````
-
-````{py:attribute} items
-:canonical: archivebox.api.v1_core.CustomPagination.Output.items
-:type: list[typing.Any]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.CustomPagination.Output.items
-```
-
-````
-
-`````
-
-````{py:method} paginate_queryset(queryset, pagination: Input, request: django.http.HttpRequest, **params)
-:canonical: archivebox.api.v1_core.CustomPagination.paginate_queryset
-
-```{autodoc2-docstring} archivebox.api.v1_core.CustomPagination.paginate_queryset
-```
-
-````
-
-``````
-
-`````{py:class} MinimalArchiveResultSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} TYPE
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.TYPE
-:type: str
-:value: >
- 'core.models.ArchiveResult'
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.TYPE
-```
-
-````
-
-````{py:attribute} id
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.id
-:type: uuid.UUID
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.id
-```
-
-````
-
-````{py:attribute} created_at
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.created_at
-:type: datetime.datetime | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.created_at
-```
-
-````
-
-````{py:attribute} modified_at
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.modified_at
-:type: datetime.datetime | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.modified_at
-```
-
-````
-
-````{py:attribute} created_by_id
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.created_by_id
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.created_by_id
-```
-
-````
-
-````{py:attribute} created_by_username
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.created_by_username
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.created_by_username
-```
-
-````
-
-````{py:attribute} status
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.status
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.status
-```
-
-````
-
-````{py:attribute} retry_at
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.retry_at
-:type: datetime.datetime | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.retry_at
-```
-
-````
-
-````{py:attribute} plugin
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.plugin
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.plugin
-```
-
-````
-
-````{py:attribute} hook_name
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.hook_name
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.hook_name
-```
-
-````
-
-````{py:attribute} process_id
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.process_id
-:type: uuid.UUID | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.process_id
-```
-
-````
-
-````{py:attribute} cmd_version
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.cmd_version
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.cmd_version
-```
-
-````
-
-````{py:attribute} cmd
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.cmd
-:type: list[str] | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.cmd
-```
-
-````
-
-````{py:attribute} pwd
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.pwd
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.pwd
-```
-
-````
-
-````{py:attribute} output_str
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.output_str
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.output_str
-```
-
-````
-
-````{py:attribute} output_json
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.output_json
-:type: dict[str, typing.Any] | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.output_json
-```
-
-````
-
-````{py:attribute} output_files
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.output_files
-:type: dict[str, dict[str, typing.Any]] | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.output_files
-```
-
-````
-
-````{py:attribute} output_size
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.output_size
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.output_size
-```
-
-````
-
-````{py:attribute} output_mimetypes
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.output_mimetypes
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.output_mimetypes
-```
-
-````
-
-````{py:attribute} start_ts
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.start_ts
-:type: datetime.datetime | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.start_ts
-```
-
-````
-
-````{py:attribute} end_ts
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.end_ts
-:type: datetime.datetime | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.end_ts
-```
-
-````
-
-````{py:method} resolve_created_by_id(obj)
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.resolve_created_by_id
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.resolve_created_by_id
-```
-
-````
-
-````{py:method} resolve_created_by_username(obj) -> str
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.resolve_created_by_username
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.resolve_created_by_username
-```
-
-````
-
-````{py:method} resolve_output_files(obj)
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.resolve_output_files
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.resolve_output_files
-```
-
-````
-
-````{py:method} resolve_output_mimetypes(obj) -> str
-:canonical: archivebox.api.v1_core.MinimalArchiveResultSchema.resolve_output_mimetypes
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.MinimalArchiveResultSchema.resolve_output_mimetypes
-```
-
-````
-
-`````
-
-`````{py:class} ArchiveResultSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.ArchiveResultSchema
-
-Bases: {py:obj}`archivebox.api.v1_core.MinimalArchiveResultSchema`
-
-````{py:attribute} TYPE
-:canonical: archivebox.api.v1_core.ArchiveResultSchema.TYPE
-:type: str
-:value: >
- 'core.models.ArchiveResult'
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultSchema.TYPE
-```
-
-````
-
-````{py:attribute} snapshot_id
-:canonical: archivebox.api.v1_core.ArchiveResultSchema.snapshot_id
-:type: uuid.UUID
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultSchema.snapshot_id
-```
-
-````
-
-````{py:attribute} snapshot_timestamp
-:canonical: archivebox.api.v1_core.ArchiveResultSchema.snapshot_timestamp
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultSchema.snapshot_timestamp
-```
-
-````
-
-````{py:attribute} snapshot_url
-:canonical: archivebox.api.v1_core.ArchiveResultSchema.snapshot_url
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultSchema.snapshot_url
-```
-
-````
-
-````{py:attribute} snapshot_tags
-:canonical: archivebox.api.v1_core.ArchiveResultSchema.snapshot_tags
-:type: list[str]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultSchema.snapshot_tags
-```
-
-````
-
-````{py:method} resolve_snapshot_timestamp(obj)
-:canonical: archivebox.api.v1_core.ArchiveResultSchema.resolve_snapshot_timestamp
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultSchema.resolve_snapshot_timestamp
-```
-
-````
-
-````{py:method} resolve_snapshot_url(obj)
-:canonical: archivebox.api.v1_core.ArchiveResultSchema.resolve_snapshot_url
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultSchema.resolve_snapshot_url
-```
-
-````
-
-````{py:method} resolve_snapshot_id(obj)
-:canonical: archivebox.api.v1_core.ArchiveResultSchema.resolve_snapshot_id
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultSchema.resolve_snapshot_id
-```
-
-````
-
-````{py:method} resolve_snapshot_tags(obj)
-:canonical: archivebox.api.v1_core.ArchiveResultSchema.resolve_snapshot_tags
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultSchema.resolve_snapshot_tags
-```
-
-````
-
-`````
-
-`````{py:class} ArchiveResultFilterSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema
-
-Bases: {py:obj}`ninja.FilterSchema`
-
-````{py:attribute} id
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.id
-:type: typing.Annotated[str | None, FilterLookup(['id__startswith', 'snapshot__id__startswith', 'snapshot__timestamp__startswith'])]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.id
-```
-
-````
-
-````{py:attribute} search
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.search
-:type: typing.Annotated[str | None, FilterLookup(['snapshot__url__icontains', 'snapshot__title__icontains', 'snapshot__tags__name__icontains', 'plugin', 'output_str__icontains', 'id__startswith', 'snapshot__id__startswith', 'snapshot__timestamp__startswith'])]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.search
-```
-
-````
-
-````{py:attribute} snapshot_id
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.snapshot_id
-:type: typing.Annotated[str | None, FilterLookup(['snapshot__id__startswith', 'snapshot__timestamp__startswith'])]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.snapshot_id
-```
-
-````
-
-````{py:attribute} snapshot_url
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.snapshot_url
-:type: typing.Annotated[str | None, FilterLookup('snapshot__url__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.snapshot_url
-```
-
-````
-
-````{py:attribute} snapshot_tag
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.snapshot_tag
-:type: typing.Annotated[str | None, FilterLookup('snapshot__tags__name__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.snapshot_tag
-```
-
-````
-
-````{py:attribute} status
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.status
-:type: typing.Annotated[str | None, FilterLookup('status')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.status
-```
-
-````
-
-````{py:attribute} output_str
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.output_str
-:type: typing.Annotated[str | None, FilterLookup('output_str__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.output_str
-```
-
-````
-
-````{py:attribute} plugin
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.plugin
-:type: typing.Annotated[str | None, FilterLookup('plugin__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.plugin
-```
-
-````
-
-````{py:attribute} hook_name
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.hook_name
-:type: typing.Annotated[str | None, FilterLookup('hook_name__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.hook_name
-```
-
-````
-
-````{py:attribute} process_id
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.process_id
-:type: typing.Annotated[str | None, FilterLookup('process__id__startswith')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.process_id
-```
-
-````
-
-````{py:attribute} cmd
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.cmd
-:type: typing.Annotated[str | None, FilterLookup('cmd__0__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.cmd
-```
-
-````
-
-````{py:attribute} pwd
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.pwd
-:type: typing.Annotated[str | None, FilterLookup('pwd__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.pwd
-```
-
-````
-
-````{py:attribute} cmd_version
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.cmd_version
-:type: typing.Annotated[str | None, FilterLookup('cmd_version')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.cmd_version
-```
-
-````
-
-````{py:attribute} created_at
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.created_at
-:type: typing.Annotated[datetime.datetime | None, FilterLookup('created_at')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.created_at
-```
-
-````
-
-````{py:attribute} created_at__gte
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.created_at__gte
-:type: typing.Annotated[datetime.datetime | None, FilterLookup('created_at__gte')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.created_at__gte
-```
-
-````
-
-````{py:attribute} created_at__lt
-:canonical: archivebox.api.v1_core.ArchiveResultFilterSchema.created_at__lt
-:type: typing.Annotated[datetime.datetime | None, FilterLookup('created_at__lt')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.ArchiveResultFilterSchema.created_at__lt
-```
-
-````
-
-`````
-
-````{py:function} get_archiveresults(request: django.http.HttpRequest, filters: ninja.Query[archivebox.api.v1_core.ArchiveResultFilterSchema])
-:canonical: archivebox.api.v1_core.get_archiveresults
-
-```{autodoc2-docstring} archivebox.api.v1_core.get_archiveresults
-```
-````
-
-````{py:function} _uuid_ref_query(field_name: str, ref: str) -> django.db.models.Q
-:canonical: archivebox.api.v1_core._uuid_ref_query
-
-```{autodoc2-docstring} archivebox.api.v1_core._uuid_ref_query
-```
-````
-
-````{py:function} get_archiveresult(request: django.http.HttpRequest, archiveresult_id: str)
-:canonical: archivebox.api.v1_core.get_archiveresult
-
-```{autodoc2-docstring} archivebox.api.v1_core.get_archiveresult
-```
-````
-
-````{py:function} _normalize_uploaded_archiveresult_plugin(plugin: str) -> str
-:canonical: archivebox.api.v1_core._normalize_uploaded_archiveresult_plugin
-
-```{autodoc2-docstring} archivebox.api.v1_core._normalize_uploaded_archiveresult_plugin
-```
-````
-
-````{py:function} _normalize_uploaded_archiveresult_output_path(output_path: str, *, filename: str) -> str
-:canonical: archivebox.api.v1_core._normalize_uploaded_archiveresult_output_path
-
-```{autodoc2-docstring} archivebox.api.v1_core._normalize_uploaded_archiveresult_output_path
-```
-````
-
-````{py:function} _parse_archiveresult_output_json(output_json: str | None) -> dict[str, typing.Any] | None
-:canonical: archivebox.api.v1_core._parse_archiveresult_output_json
-
-```{autodoc2-docstring} archivebox.api.v1_core._parse_archiveresult_output_json
-```
-````
-
-````{py:function} _get_archiveresult_upload_data(request: django.http.HttpRequest)
-:canonical: archivebox.api.v1_core._get_archiveresult_upload_data
-
-```{autodoc2-docstring} archivebox.api.v1_core._get_archiveresult_upload_data
-```
-````
-
-````{py:function} _get_archiveresult_upload_files(request: django.http.HttpRequest, *, allow_empty: bool = False) -> list[ninja.UploadedFile]
-:canonical: archivebox.api.v1_core._get_archiveresult_upload_files
-
-```{autodoc2-docstring} archivebox.api.v1_core._get_archiveresult_upload_files
-```
-````
-
-````{py:function} _get_archiveresult_upload_form_values(request: django.http.HttpRequest, *field_names: str) -> list[str]
-:canonical: archivebox.api.v1_core._get_archiveresult_upload_form_values
-
-```{autodoc2-docstring} archivebox.api.v1_core._get_archiveresult_upload_form_values
-```
-````
-
-````{py:function} _get_archiveresult_upload_form_value(request: django.http.HttpRequest, *field_names: str) -> str
-:canonical: archivebox.api.v1_core._get_archiveresult_upload_form_value
-
-```{autodoc2-docstring} archivebox.api.v1_core._get_archiveresult_upload_form_value
-```
-````
-
-````{py:function} _parse_archiveresult_upload_int(value: str, field_name: str, *, default: int | None = None) -> int
-:canonical: archivebox.api.v1_core._parse_archiveresult_upload_int
-
-```{autodoc2-docstring} archivebox.api.v1_core._parse_archiveresult_upload_int
-```
-````
-
-````{py:function} _summarize_archiveresult_output_files(output_files: dict[str, dict[str, typing.Any]]) -> tuple[int, str]
-:canonical: archivebox.api.v1_core._summarize_archiveresult_output_files
-
-```{autodoc2-docstring} archivebox.api.v1_core._summarize_archiveresult_output_files
-```
-````
-
-````{py:function} _get_snapshot_by_ref(snapshot_id: str)
-:canonical: archivebox.api.v1_core._get_snapshot_by_ref
-
-```{autodoc2-docstring} archivebox.api.v1_core._get_snapshot_by_ref
-```
-````
-
-````{py:function} _queue_archiveresult_snapshot_maintenance(snapshot: archivebox.core.models.Snapshot) -> None
-:canonical: archivebox.api.v1_core._queue_archiveresult_snapshot_maintenance
-
-```{autodoc2-docstring} archivebox.api.v1_core._queue_archiveresult_snapshot_maintenance
-```
-````
-
-````{py:function} _merge_archiveresult_output_file_maps(results: list[archivebox.core.models.ArchiveResult]) -> dict[str, dict[str, typing.Any]]
-:canonical: archivebox.api.v1_core._merge_archiveresult_output_file_maps
-
-```{autodoc2-docstring} archivebox.api.v1_core._merge_archiveresult_output_file_maps
-```
-````
-
-````{py:function} _write_archiveresult_files(request: django.http.HttpRequest, snapshot: archivebox.core.models.Snapshot, plugin_name: str, *, existing_output_files: dict[str, dict[str, typing.Any]] | None = None, allow_empty: bool = False) -> dict[str, dict[str, typing.Any]]
-:canonical: archivebox.api.v1_core._write_archiveresult_files
-
-```{autodoc2-docstring} archivebox.api.v1_core._write_archiveresult_files
-```
-````
-
-````{py:function} create_archiveresult(request: django.http.HttpRequest, snapshot_id: str = Form(...), plugin: str = Form(...), output_str: str = Form(''), hook_name: str = Form(ARCHIVERESULT_UPLOAD_HOOK_NAME), status: str = Form(str(ArchiveResult.StatusChoices.SUCCEEDED)), output_json: str = Form(''))
-:canonical: archivebox.api.v1_core.create_archiveresult
-
-```{autodoc2-docstring} archivebox.api.v1_core.create_archiveresult
-```
-````
-
-````{py:function} patch_archiveresult(request: django.http.HttpRequest, archiveresult_id: str)
-:canonical: archivebox.api.v1_core.patch_archiveresult
-
-```{autodoc2-docstring} archivebox.api.v1_core.patch_archiveresult
-```
-````
-
-`````{py:class} SnapshotSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.SnapshotSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} TYPE
-:canonical: archivebox.api.v1_core.SnapshotSchema.TYPE
-:type: str
-:value: >
- 'core.models.Snapshot'
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.TYPE
-```
-
-````
-
-````{py:attribute} id
-:canonical: archivebox.api.v1_core.SnapshotSchema.id
-:type: uuid.UUID
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.id
-```
-
-````
-
-````{py:attribute} created_by_id
-:canonical: archivebox.api.v1_core.SnapshotSchema.created_by_id
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.created_by_id
-```
-
-````
-
-````{py:attribute} created_by_username
-:canonical: archivebox.api.v1_core.SnapshotSchema.created_by_username
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.created_by_username
-```
-
-````
-
-````{py:attribute} created_at
-:canonical: archivebox.api.v1_core.SnapshotSchema.created_at
-:type: datetime.datetime
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.created_at
-```
-
-````
-
-````{py:attribute} modified_at
-:canonical: archivebox.api.v1_core.SnapshotSchema.modified_at
-:type: datetime.datetime
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.modified_at
-```
-
-````
-
-````{py:attribute} status
-:canonical: archivebox.api.v1_core.SnapshotSchema.status
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.status
-```
-
-````
-
-````{py:attribute} retry_at
-:canonical: archivebox.api.v1_core.SnapshotSchema.retry_at
-:type: datetime.datetime | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.retry_at
-```
-
-````
-
-````{py:attribute} bookmarked_at
-:canonical: archivebox.api.v1_core.SnapshotSchema.bookmarked_at
-:type: datetime.datetime
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.bookmarked_at
-```
-
-````
-
-````{py:attribute} downloaded_at
-:canonical: archivebox.api.v1_core.SnapshotSchema.downloaded_at
-:type: datetime.datetime | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.downloaded_at
-```
-
-````
-
-````{py:attribute} url
-:canonical: archivebox.api.v1_core.SnapshotSchema.url
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.url
-```
-
-````
-
-````{py:attribute} tags
-:canonical: archivebox.api.v1_core.SnapshotSchema.tags
-:type: list[str]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.tags
-```
-
-````
-
-````{py:attribute} title
-:canonical: archivebox.api.v1_core.SnapshotSchema.title
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.title
-```
-
-````
-
-````{py:attribute} timestamp
-:canonical: archivebox.api.v1_core.SnapshotSchema.timestamp
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.timestamp
-```
-
-````
-
-````{py:attribute} archive_path
-:canonical: archivebox.api.v1_core.SnapshotSchema.archive_path
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.archive_path
-```
-
-````
-
-````{py:attribute} archive_size
-:canonical: archivebox.api.v1_core.SnapshotSchema.archive_size
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.archive_size
-```
-
-````
-
-````{py:attribute} output_size
-:canonical: archivebox.api.v1_core.SnapshotSchema.output_size
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.output_size
-```
-
-````
-
-````{py:attribute} num_archiveresults
-:canonical: archivebox.api.v1_core.SnapshotSchema.num_archiveresults
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.num_archiveresults
-```
-
-````
-
-````{py:attribute} archiveresults
-:canonical: archivebox.api.v1_core.SnapshotSchema.archiveresults
-:type: list[archivebox.api.v1_core.MinimalArchiveResultSchema]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.archiveresults
-```
-
-````
-
-````{py:method} resolve_created_by_id(obj)
-:canonical: archivebox.api.v1_core.SnapshotSchema.resolve_created_by_id
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.resolve_created_by_id
-```
-
-````
-
-````{py:method} resolve_created_by_username(obj)
-:canonical: archivebox.api.v1_core.SnapshotSchema.resolve_created_by_username
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.resolve_created_by_username
-```
-
-````
-
-````{py:method} resolve_tags(obj)
-:canonical: archivebox.api.v1_core.SnapshotSchema.resolve_tags
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.resolve_tags
-```
-
-````
-
-````{py:method} resolve_archive_size(obj)
-:canonical: archivebox.api.v1_core.SnapshotSchema.resolve_archive_size
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.resolve_archive_size
-```
-
-````
-
-````{py:method} resolve_output_size(obj)
-:canonical: archivebox.api.v1_core.SnapshotSchema.resolve_output_size
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.resolve_output_size
-```
-
-````
-
-````{py:method} resolve_num_archiveresults(obj, context)
-:canonical: archivebox.api.v1_core.SnapshotSchema.resolve_num_archiveresults
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.resolve_num_archiveresults
-```
-
-````
-
-````{py:method} resolve_archiveresults(obj, context)
-:canonical: archivebox.api.v1_core.SnapshotSchema.resolve_archiveresults
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotSchema.resolve_archiveresults
-```
-
-````
-
-`````
-
-`````{py:class} SnapshotUpdateSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.SnapshotUpdateSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} action
-:canonical: archivebox.api.v1_core.SnapshotUpdateSchema.action
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotUpdateSchema.action
-```
-
-````
-
-````{py:attribute} status
-:canonical: archivebox.api.v1_core.SnapshotUpdateSchema.status
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotUpdateSchema.status
-```
-
-````
-
-````{py:attribute} retry_at
-:canonical: archivebox.api.v1_core.SnapshotUpdateSchema.retry_at
-:type: datetime.datetime | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotUpdateSchema.retry_at
-```
-
-````
-
-````{py:attribute} tags
-:canonical: archivebox.api.v1_core.SnapshotUpdateSchema.tags
-:type: list[str] | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotUpdateSchema.tags
-```
-
-````
-
-`````
-
-`````{py:class} SnapshotCreateSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.SnapshotCreateSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} url
-:canonical: archivebox.api.v1_core.SnapshotCreateSchema.url
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotCreateSchema.url
-```
-
-````
-
-````{py:attribute} crawl_id
-:canonical: archivebox.api.v1_core.SnapshotCreateSchema.crawl_id
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotCreateSchema.crawl_id
-```
-
-````
-
-````{py:attribute} depth
-:canonical: archivebox.api.v1_core.SnapshotCreateSchema.depth
-:type: int
-:value: >
- 0
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotCreateSchema.depth
-```
-
-````
-
-````{py:attribute} title
-:canonical: archivebox.api.v1_core.SnapshotCreateSchema.title
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotCreateSchema.title
-```
-
-````
-
-````{py:attribute} tags
-:canonical: archivebox.api.v1_core.SnapshotCreateSchema.tags
-:type: list[str] | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotCreateSchema.tags
-```
-
-````
-
-````{py:attribute} status
-:canonical: archivebox.api.v1_core.SnapshotCreateSchema.status
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotCreateSchema.status
-```
-
-````
-
-`````
-
-`````{py:class} SnapshotDeleteResponseSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.SnapshotDeleteResponseSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} success
-:canonical: archivebox.api.v1_core.SnapshotDeleteResponseSchema.success
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotDeleteResponseSchema.success
-```
-
-````
-
-````{py:attribute} snapshot_id
-:canonical: archivebox.api.v1_core.SnapshotDeleteResponseSchema.snapshot_id
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotDeleteResponseSchema.snapshot_id
-```
-
-````
-
-````{py:attribute} crawl_id
-:canonical: archivebox.api.v1_core.SnapshotDeleteResponseSchema.crawl_id
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotDeleteResponseSchema.crawl_id
-```
-
-````
-
-````{py:attribute} deleted_count
-:canonical: archivebox.api.v1_core.SnapshotDeleteResponseSchema.deleted_count
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotDeleteResponseSchema.deleted_count
-```
-
-````
-
-`````
-
-````{py:function} normalize_tag_list(tags: list[str] | None = None) -> list[str]
-:canonical: archivebox.api.v1_core.normalize_tag_list
-
-```{autodoc2-docstring} archivebox.api.v1_core.normalize_tag_list
-```
-````
-
-````{py:function} _parse_rss_before(before: str | None) -> datetime.datetime
-:canonical: archivebox.api.v1_core._parse_rss_before
-
-```{autodoc2-docstring} archivebox.api.v1_core._parse_rss_before
-```
-````
-
-````{py:function} _filter_snapshots_for_rss(*, crawl_id: str = '', created_by: str = '', before: str | None = None, limit: int = 50)
-:canonical: archivebox.api.v1_core._filter_snapshots_for_rss
-
-```{autodoc2-docstring} archivebox.api.v1_core._filter_snapshots_for_rss
-```
-````
-
-````{py:function} _snapshots_rss_response(request: django.http.HttpRequest, *, snapshots, title: str = 'ArchiveBox Snapshots') -> django.http.HttpResponse
-:canonical: archivebox.api.v1_core._snapshots_rss_response
-
-```{autodoc2-docstring} archivebox.api.v1_core._snapshots_rss_response
-```
-````
-
-`````{py:class} SnapshotFilterSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema
-
-Bases: {py:obj}`ninja.FilterSchema`
-
-````{py:attribute} id
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.id
-:type: typing.Annotated[str | None, FilterLookup(['id__istartswith', 'id__iendswith', 'timestamp__startswith'])]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.id
-```
-
-````
-
-````{py:attribute} created_by_id
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.created_by_id
-:type: typing.Annotated[str | None, FilterLookup('crawl__created_by_id')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.created_by_id
-```
-
-````
-
-````{py:attribute} created_by_username
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.created_by_username
-:type: typing.Annotated[str | None, FilterLookup('crawl__created_by__username__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.created_by_username
-```
-
-````
-
-````{py:attribute} created_at__gte
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.created_at__gte
-:type: typing.Annotated[datetime.datetime | None, FilterLookup('created_at__gte')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.created_at__gte
-```
-
-````
-
-````{py:attribute} created_at__lt
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.created_at__lt
-:type: typing.Annotated[datetime.datetime | None, FilterLookup('created_at__lt')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.created_at__lt
-```
-
-````
-
-````{py:attribute} created_at
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.created_at
-:type: typing.Annotated[datetime.datetime | None, FilterLookup('created_at')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.created_at
-```
-
-````
-
-````{py:attribute} modified_at
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.modified_at
-:type: typing.Annotated[datetime.datetime | None, FilterLookup('modified_at')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.modified_at
-```
-
-````
-
-````{py:attribute} modified_at__gte
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.modified_at__gte
-:type: typing.Annotated[datetime.datetime | None, FilterLookup('modified_at__gte')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.modified_at__gte
-```
-
-````
-
-````{py:attribute} modified_at__lt
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.modified_at__lt
-:type: typing.Annotated[datetime.datetime | None, FilterLookup('modified_at__lt')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.modified_at__lt
-```
-
-````
-
-````{py:attribute} search
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.search
-:type: typing.Annotated[str | None, FilterLookup(['url__icontains', 'title__icontains', 'tags__name__icontains', 'id__istartswith', 'id__iendswith', 'timestamp__startswith'])]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.search
-```
-
-````
-
-````{py:attribute} url
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.url
-:type: typing.Annotated[str | None, FilterLookup('url')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.url
-```
-
-````
-
-````{py:attribute} tag
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.tag
-:type: typing.Annotated[str | None, FilterLookup('tags__name')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.tag
-```
-
-````
-
-````{py:attribute} title
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.title
-:type: typing.Annotated[str | None, FilterLookup('title__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.title
-```
-
-````
-
-````{py:attribute} timestamp
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.timestamp
-:type: typing.Annotated[str | None, FilterLookup('timestamp__startswith')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.timestamp
-```
-
-````
-
-````{py:attribute} bookmarked_at__gte
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.bookmarked_at__gte
-:type: typing.Annotated[datetime.datetime | None, FilterLookup('bookmarked_at__gte')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.bookmarked_at__gte
-```
-
-````
-
-````{py:attribute} bookmarked_at__lt
-:canonical: archivebox.api.v1_core.SnapshotFilterSchema.bookmarked_at__lt
-:type: typing.Annotated[datetime.datetime | None, FilterLookup('bookmarked_at__lt')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.SnapshotFilterSchema.bookmarked_at__lt
-```
-
-````
-
-`````
-
-````{py:function} get_snapshots(request: django.http.HttpRequest, filters: ninja.Query[archivebox.api.v1_core.SnapshotFilterSchema], with_archiveresults: bool = False)
-:canonical: archivebox.api.v1_core.get_snapshots
-
-```{autodoc2-docstring} archivebox.api.v1_core.get_snapshots
-```
-````
-
-````{py:function} get_snapshots_rss(request: django.http.HttpRequest, crawl_id: str = '', created_by: str = '', limit: int = 50, before: str | None = None)
-:canonical: archivebox.api.v1_core.get_snapshots_rss
-
-```{autodoc2-docstring} archivebox.api.v1_core.get_snapshots_rss
-```
-````
-
-````{py:function} get_snapshot(request: django.http.HttpRequest, snapshot_id: str, with_archiveresults: bool = True)
-:canonical: archivebox.api.v1_core.get_snapshot
-
-```{autodoc2-docstring} archivebox.api.v1_core.get_snapshot
-```
-````
-
-````{py:function} create_snapshot(request: django.http.HttpRequest, data: archivebox.api.v1_core.SnapshotCreateSchema)
-:canonical: archivebox.api.v1_core.create_snapshot
-
-```{autodoc2-docstring} archivebox.api.v1_core.create_snapshot
-```
-````
-
-````{py:function} patch_snapshot(request: django.http.HttpRequest, snapshot_id: str, data: archivebox.api.v1_core.SnapshotUpdateSchema)
-:canonical: archivebox.api.v1_core.patch_snapshot
-
-```{autodoc2-docstring} archivebox.api.v1_core.patch_snapshot
-```
-````
-
-````{py:function} delete_snapshot(request: django.http.HttpRequest, snapshot_id: str)
-:canonical: archivebox.api.v1_core.delete_snapshot
-
-```{autodoc2-docstring} archivebox.api.v1_core.delete_snapshot
-```
-````
-
-`````{py:class} TagSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.TagSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} TYPE
-:canonical: archivebox.api.v1_core.TagSchema.TYPE
-:type: str
-:value: >
- 'core.models.Tag'
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSchema.TYPE
-```
-
-````
-
-````{py:attribute} id
-:canonical: archivebox.api.v1_core.TagSchema.id
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSchema.id
-```
-
-````
-
-````{py:attribute} modified_at
-:canonical: archivebox.api.v1_core.TagSchema.modified_at
-:type: datetime.datetime
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSchema.modified_at
-```
-
-````
-
-````{py:attribute} created_at
-:canonical: archivebox.api.v1_core.TagSchema.created_at
-:type: datetime.datetime
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSchema.created_at
-```
-
-````
-
-````{py:attribute} created_by_id
-:canonical: archivebox.api.v1_core.TagSchema.created_by_id
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSchema.created_by_id
-```
-
-````
-
-````{py:attribute} created_by_username
-:canonical: archivebox.api.v1_core.TagSchema.created_by_username
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSchema.created_by_username
-```
-
-````
-
-````{py:attribute} name
-:canonical: archivebox.api.v1_core.TagSchema.name
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSchema.name
-```
-
-````
-
-````{py:attribute} num_snapshots
-:canonical: archivebox.api.v1_core.TagSchema.num_snapshots
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSchema.num_snapshots
-```
-
-````
-
-````{py:attribute} snapshots
-:canonical: archivebox.api.v1_core.TagSchema.snapshots
-:type: list[archivebox.api.v1_core.SnapshotSchema]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSchema.snapshots
-```
-
-````
-
-````{py:method} resolve_created_by_id(obj)
-:canonical: archivebox.api.v1_core.TagSchema.resolve_created_by_id
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSchema.resolve_created_by_id
-```
-
-````
-
-````{py:method} resolve_created_by_username(obj)
-:canonical: archivebox.api.v1_core.TagSchema.resolve_created_by_username
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSchema.resolve_created_by_username
-```
-
-````
-
-````{py:method} resolve_num_snapshots(obj, context)
-:canonical: archivebox.api.v1_core.TagSchema.resolve_num_snapshots
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSchema.resolve_num_snapshots
-```
-
-````
-
-````{py:method} resolve_snapshots(obj, context)
-:canonical: archivebox.api.v1_core.TagSchema.resolve_snapshots
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSchema.resolve_snapshots
-```
-
-````
-
-`````
-
-````{py:function} get_tags(request: django.http.HttpRequest)
-:canonical: archivebox.api.v1_core.get_tags
-
-```{autodoc2-docstring} archivebox.api.v1_core.get_tags
-```
-````
-
-````{py:function} get_tag(request: django.http.HttpRequest, tag_id: str, with_snapshots: bool = True)
-:canonical: archivebox.api.v1_core.get_tag
-
-```{autodoc2-docstring} archivebox.api.v1_core.get_tag
-```
-````
-
-````{py:function} get_any(request: django.http.HttpRequest, id: str)
-:canonical: archivebox.api.v1_core.get_any
-
-```{autodoc2-docstring} archivebox.api.v1_core.get_any
-```
-````
-
-`````{py:class} TagAutocompleteSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.TagAutocompleteSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} tags
-:canonical: archivebox.api.v1_core.TagAutocompleteSchema.tags
-:type: list[dict]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagAutocompleteSchema.tags
-```
-
-````
-
-`````
-
-`````{py:class} TagCreateSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.TagCreateSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} name
-:canonical: archivebox.api.v1_core.TagCreateSchema.name
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagCreateSchema.name
-```
-
-````
-
-`````
-
-`````{py:class} TagCreateResponseSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.TagCreateResponseSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} success
-:canonical: archivebox.api.v1_core.TagCreateResponseSchema.success
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagCreateResponseSchema.success
-```
-
-````
-
-````{py:attribute} tag_id
-:canonical: archivebox.api.v1_core.TagCreateResponseSchema.tag_id
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagCreateResponseSchema.tag_id
-```
-
-````
-
-````{py:attribute} tag_name
-:canonical: archivebox.api.v1_core.TagCreateResponseSchema.tag_name
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagCreateResponseSchema.tag_name
-```
-
-````
-
-````{py:attribute} created
-:canonical: archivebox.api.v1_core.TagCreateResponseSchema.created
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagCreateResponseSchema.created
-```
-
-````
-
-`````
-
-`````{py:class} TagSearchSnapshotSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.TagSearchSnapshotSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} id
-:canonical: archivebox.api.v1_core.TagSearchSnapshotSchema.id
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchSnapshotSchema.id
-```
-
-````
-
-````{py:attribute} title
-:canonical: archivebox.api.v1_core.TagSearchSnapshotSchema.title
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchSnapshotSchema.title
-```
-
-````
-
-````{py:attribute} url
-:canonical: archivebox.api.v1_core.TagSearchSnapshotSchema.url
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchSnapshotSchema.url
-```
-
-````
-
-````{py:attribute} favicon_url
-:canonical: archivebox.api.v1_core.TagSearchSnapshotSchema.favicon_url
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchSnapshotSchema.favicon_url
-```
-
-````
-
-````{py:attribute} admin_url
-:canonical: archivebox.api.v1_core.TagSearchSnapshotSchema.admin_url
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchSnapshotSchema.admin_url
-```
-
-````
-
-````{py:attribute} archive_url
-:canonical: archivebox.api.v1_core.TagSearchSnapshotSchema.archive_url
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchSnapshotSchema.archive_url
-```
-
-````
-
-````{py:attribute} downloaded_at
-:canonical: archivebox.api.v1_core.TagSearchSnapshotSchema.downloaded_at
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchSnapshotSchema.downloaded_at
-```
-
-````
-
-`````
-
-`````{py:class} TagSearchCardSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.TagSearchCardSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} id
-:canonical: archivebox.api.v1_core.TagSearchCardSchema.id
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchCardSchema.id
-```
-
-````
-
-````{py:attribute} name
-:canonical: archivebox.api.v1_core.TagSearchCardSchema.name
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchCardSchema.name
-```
-
-````
-
-````{py:attribute} slug
-:canonical: archivebox.api.v1_core.TagSearchCardSchema.slug
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchCardSchema.slug
-```
-
-````
-
-````{py:attribute} num_snapshots
-:canonical: archivebox.api.v1_core.TagSearchCardSchema.num_snapshots
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchCardSchema.num_snapshots
-```
-
-````
-
-````{py:attribute} filter_url
-:canonical: archivebox.api.v1_core.TagSearchCardSchema.filter_url
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchCardSchema.filter_url
-```
-
-````
-
-````{py:attribute} edit_url
-:canonical: archivebox.api.v1_core.TagSearchCardSchema.edit_url
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchCardSchema.edit_url
-```
-
-````
-
-````{py:attribute} export_urls_url
-:canonical: archivebox.api.v1_core.TagSearchCardSchema.export_urls_url
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchCardSchema.export_urls_url
-```
-
-````
-
-````{py:attribute} export_jsonl_url
-:canonical: archivebox.api.v1_core.TagSearchCardSchema.export_jsonl_url
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchCardSchema.export_jsonl_url
-```
-
-````
-
-````{py:attribute} rename_url
-:canonical: archivebox.api.v1_core.TagSearchCardSchema.rename_url
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchCardSchema.rename_url
-```
-
-````
-
-````{py:attribute} delete_url
-:canonical: archivebox.api.v1_core.TagSearchCardSchema.delete_url
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchCardSchema.delete_url
-```
-
-````
-
-````{py:attribute} snapshots
-:canonical: archivebox.api.v1_core.TagSearchCardSchema.snapshots
-:type: list[archivebox.api.v1_core.TagSearchSnapshotSchema]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchCardSchema.snapshots
-```
-
-````
-
-`````
-
-`````{py:class} TagSearchResponseSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.TagSearchResponseSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} tags
-:canonical: archivebox.api.v1_core.TagSearchResponseSchema.tags
-:type: list[archivebox.api.v1_core.TagSearchCardSchema]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchResponseSchema.tags
-```
-
-````
-
-````{py:attribute} sort
-:canonical: archivebox.api.v1_core.TagSearchResponseSchema.sort
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchResponseSchema.sort
-```
-
-````
-
-````{py:attribute} created_by
-:canonical: archivebox.api.v1_core.TagSearchResponseSchema.created_by
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchResponseSchema.created_by
-```
-
-````
-
-````{py:attribute} year
-:canonical: archivebox.api.v1_core.TagSearchResponseSchema.year
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchResponseSchema.year
-```
-
-````
-
-````{py:attribute} has_snapshots
-:canonical: archivebox.api.v1_core.TagSearchResponseSchema.has_snapshots
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSearchResponseSchema.has_snapshots
-```
-
-````
-
-`````
-
-`````{py:class} TagUpdateSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.TagUpdateSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} name
-:canonical: archivebox.api.v1_core.TagUpdateSchema.name
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagUpdateSchema.name
-```
-
-````
-
-`````
-
-`````{py:class} TagUpdateResponseSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.TagUpdateResponseSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} success
-:canonical: archivebox.api.v1_core.TagUpdateResponseSchema.success
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagUpdateResponseSchema.success
-```
-
-````
-
-````{py:attribute} tag_id
-:canonical: archivebox.api.v1_core.TagUpdateResponseSchema.tag_id
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagUpdateResponseSchema.tag_id
-```
-
-````
-
-````{py:attribute} tag_name
-:canonical: archivebox.api.v1_core.TagUpdateResponseSchema.tag_name
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagUpdateResponseSchema.tag_name
-```
-
-````
-
-`````
-
-`````{py:class} TagDeleteResponseSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.TagDeleteResponseSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} success
-:canonical: archivebox.api.v1_core.TagDeleteResponseSchema.success
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagDeleteResponseSchema.success
-```
-
-````
-
-````{py:attribute} tag_id
-:canonical: archivebox.api.v1_core.TagDeleteResponseSchema.tag_id
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagDeleteResponseSchema.tag_id
-```
-
-````
-
-````{py:attribute} deleted_count
-:canonical: archivebox.api.v1_core.TagDeleteResponseSchema.deleted_count
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagDeleteResponseSchema.deleted_count
-```
-
-````
-
-`````
-
-`````{py:class} TagSnapshotRequestSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.TagSnapshotRequestSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} snapshot_id
-:canonical: archivebox.api.v1_core.TagSnapshotRequestSchema.snapshot_id
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSnapshotRequestSchema.snapshot_id
-```
-
-````
-
-````{py:attribute} tag_name
-:canonical: archivebox.api.v1_core.TagSnapshotRequestSchema.tag_name
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSnapshotRequestSchema.tag_name
-```
-
-````
-
-````{py:attribute} tag_id
-:canonical: archivebox.api.v1_core.TagSnapshotRequestSchema.tag_id
-:type: int | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSnapshotRequestSchema.tag_id
-```
-
-````
-
-`````
-
-`````{py:class} TagSnapshotResponseSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_core.TagSnapshotResponseSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} success
-:canonical: archivebox.api.v1_core.TagSnapshotResponseSchema.success
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSnapshotResponseSchema.success
-```
-
-````
-
-````{py:attribute} tag_id
-:canonical: archivebox.api.v1_core.TagSnapshotResponseSchema.tag_id
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSnapshotResponseSchema.tag_id
-```
-
-````
-
-````{py:attribute} tag_name
-:canonical: archivebox.api.v1_core.TagSnapshotResponseSchema.tag_name
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_core.TagSnapshotResponseSchema.tag_name
-```
-
-````
-
-`````
-
-````{py:function} _get_snapshot_for_tag_edit(snapshot_ref: str) -> archivebox.core.models.Snapshot
-:canonical: archivebox.api.v1_core._get_snapshot_for_tag_edit
-
-```{autodoc2-docstring} archivebox.api.v1_core._get_snapshot_for_tag_edit
-```
-````
-
-````{py:function} search_tags(request: django.http.HttpRequest, q: str = '', sort: str = 'created_desc', created_by: str = '', year: str = '', has_snapshots: str = 'all')
-:canonical: archivebox.api.v1_core.search_tags
-
-```{autodoc2-docstring} archivebox.api.v1_core.search_tags
-```
-````
-
-````{py:function} _public_tag_listing_enabled() -> bool
-:canonical: archivebox.api.v1_core._public_tag_listing_enabled
-
-```{autodoc2-docstring} archivebox.api.v1_core._public_tag_listing_enabled
-```
-````
-
-````{py:function} _request_has_tag_autocomplete_access(request: django.http.HttpRequest) -> bool
-:canonical: archivebox.api.v1_core._request_has_tag_autocomplete_access
-
-```{autodoc2-docstring} archivebox.api.v1_core._request_has_tag_autocomplete_access
-```
-````
-
-````{py:function} tags_autocomplete(request: django.http.HttpRequest, q: str = '')
-:canonical: archivebox.api.v1_core.tags_autocomplete
-
-```{autodoc2-docstring} archivebox.api.v1_core.tags_autocomplete
-```
-````
-
-````{py:function} tags_create(request: django.http.HttpRequest, data: archivebox.api.v1_core.TagCreateSchema)
-:canonical: archivebox.api.v1_core.tags_create
-
-```{autodoc2-docstring} archivebox.api.v1_core.tags_create
-```
-````
-
-````{py:function} rename_tag(request: django.http.HttpRequest, tag_id: int, data: archivebox.api.v1_core.TagUpdateSchema)
-:canonical: archivebox.api.v1_core.rename_tag
-
-```{autodoc2-docstring} archivebox.api.v1_core.rename_tag
-```
-````
-
-````{py:function} delete_tag(request: django.http.HttpRequest, tag_id: int)
-:canonical: archivebox.api.v1_core.delete_tag
-
-```{autodoc2-docstring} archivebox.api.v1_core.delete_tag
-```
-````
-
-````{py:function} tag_urls_export(request: django.http.HttpRequest, tag_id: int)
-:canonical: archivebox.api.v1_core.tag_urls_export
-
-```{autodoc2-docstring} archivebox.api.v1_core.tag_urls_export
-```
-````
-
-````{py:function} tag_snapshots_export(request: django.http.HttpRequest, tag_id: int)
-:canonical: archivebox.api.v1_core.tag_snapshots_export
-
-```{autodoc2-docstring} archivebox.api.v1_core.tag_snapshots_export
-```
-````
-
-````{py:function} tags_add_to_snapshot(request: django.http.HttpRequest, data: archivebox.api.v1_core.TagSnapshotRequestSchema)
-:canonical: archivebox.api.v1_core.tags_add_to_snapshot
-
-```{autodoc2-docstring} archivebox.api.v1_core.tags_add_to_snapshot
-```
-````
-
-````{py:function} tags_remove_from_snapshot(request: django.http.HttpRequest, data: archivebox.api.v1_core.TagSnapshotRequestSchema)
-:canonical: archivebox.api.v1_core.tags_remove_from_snapshot
-
-```{autodoc2-docstring} archivebox.api.v1_core.tags_remove_from_snapshot
-```
-````
diff --git a/docs/apidocs/archivebox/archivebox.api.v1_crawls.md b/docs/apidocs/archivebox/archivebox.api.v1_crawls.md
deleted file mode 100644
index 0f72db86..00000000
--- a/docs/apidocs/archivebox/archivebox.api.v1_crawls.md
+++ /dev/null
@@ -1,548 +0,0 @@
-# {py:mod}`archivebox.api.v1_crawls`
-
-```{py:module} archivebox.api.v1_crawls
-```
-
-```{autodoc2-docstring} archivebox.api.v1_crawls
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`CrawlSchema `
- -
-* - {py:obj}`CrawlUpdateSchema `
- -
-* - {py:obj}`CrawlCreateSchema `
- -
-* - {py:obj}`CrawlDeleteResponseSchema `
- -
-````
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`normalize_tag_list `
- - ```{autodoc2-docstring} archivebox.api.v1_crawls.normalize_tag_list
- :summary:
- ```
-* - {py:obj}`get_crawls `
- - ```{autodoc2-docstring} archivebox.api.v1_crawls.get_crawls
- :summary:
- ```
-* - {py:obj}`create_crawl `
- - ```{autodoc2-docstring} archivebox.api.v1_crawls.create_crawl
- :summary:
- ```
-* - {py:obj}`get_crawl `
- - ```{autodoc2-docstring} archivebox.api.v1_crawls.get_crawl
- :summary:
- ```
-* - {py:obj}`crawl_file `
- - ```{autodoc2-docstring} archivebox.api.v1_crawls.crawl_file
- :summary:
- ```
-* - {py:obj}`crawl_file_root `
- - ```{autodoc2-docstring} archivebox.api.v1_crawls.crawl_file_root
- :summary:
- ```
-* - {py:obj}`crawl_file_nested_1 `
- - ```{autodoc2-docstring} archivebox.api.v1_crawls.crawl_file_nested_1
- :summary:
- ```
-* - {py:obj}`crawl_file_nested_2 `
- - ```{autodoc2-docstring} archivebox.api.v1_crawls.crawl_file_nested_2
- :summary:
- ```
-* - {py:obj}`patch_crawl `
- - ```{autodoc2-docstring} archivebox.api.v1_crawls.patch_crawl
- :summary:
- ```
-* - {py:obj}`delete_crawl `
- - ```{autodoc2-docstring} archivebox.api.v1_crawls.delete_crawl
- :summary:
- ```
-````
-
-### Data
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`router `
- - ```{autodoc2-docstring} archivebox.api.v1_crawls.router
- :summary:
- ```
-````
-
-### API
-
-````{py:data} router
-:canonical: archivebox.api.v1_crawls.router
-:value: >
- 'Router(...)'
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.router
-```
-
-````
-
-`````{py:class} CrawlSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_crawls.CrawlSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} TYPE
-:canonical: archivebox.api.v1_crawls.CrawlSchema.TYPE
-:type: str
-:value: >
- 'crawls.models.Crawl'
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.TYPE
-```
-
-````
-
-````{py:attribute} id
-:canonical: archivebox.api.v1_crawls.CrawlSchema.id
-:type: uuid.UUID
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.id
-```
-
-````
-
-````{py:attribute} modified_at
-:canonical: archivebox.api.v1_crawls.CrawlSchema.modified_at
-:type: datetime.datetime
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.modified_at
-```
-
-````
-
-````{py:attribute} created_at
-:canonical: archivebox.api.v1_crawls.CrawlSchema.created_at
-:type: datetime.datetime
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.created_at
-```
-
-````
-
-````{py:attribute} created_by_id
-:canonical: archivebox.api.v1_crawls.CrawlSchema.created_by_id
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.created_by_id
-```
-
-````
-
-````{py:attribute} created_by_username
-:canonical: archivebox.api.v1_crawls.CrawlSchema.created_by_username
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.created_by_username
-```
-
-````
-
-````{py:attribute} status
-:canonical: archivebox.api.v1_crawls.CrawlSchema.status
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.status
-```
-
-````
-
-````{py:attribute} retry_at
-:canonical: archivebox.api.v1_crawls.CrawlSchema.retry_at
-:type: datetime.datetime | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.retry_at
-```
-
-````
-
-````{py:attribute} is_paused
-:canonical: archivebox.api.v1_crawls.CrawlSchema.is_paused
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.is_paused
-```
-
-````
-
-````{py:attribute} urls
-:canonical: archivebox.api.v1_crawls.CrawlSchema.urls
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.urls
-```
-
-````
-
-````{py:attribute} max_depth
-:canonical: archivebox.api.v1_crawls.CrawlSchema.max_depth
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.max_depth
-```
-
-````
-
-````{py:attribute} tags_str
-:canonical: archivebox.api.v1_crawls.CrawlSchema.tags_str
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.tags_str
-```
-
-````
-
-````{py:attribute} config
-:canonical: archivebox.api.v1_crawls.CrawlSchema.config
-:type: dict
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.config
-```
-
-````
-
-````{py:method} resolve_created_by_id(obj)
-:canonical: archivebox.api.v1_crawls.CrawlSchema.resolve_created_by_id
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.resolve_created_by_id
-```
-
-````
-
-````{py:method} resolve_created_by_username(obj)
-:canonical: archivebox.api.v1_crawls.CrawlSchema.resolve_created_by_username
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.resolve_created_by_username
-```
-
-````
-
-````{py:method} resolve_config(obj)
-:canonical: archivebox.api.v1_crawls.CrawlSchema.resolve_config
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.resolve_config
-```
-
-````
-
-````{py:method} resolve_snapshots(obj, context)
-:canonical: archivebox.api.v1_crawls.CrawlSchema.resolve_snapshots
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlSchema.resolve_snapshots
-```
-
-````
-
-`````
-
-`````{py:class} CrawlUpdateSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_crawls.CrawlUpdateSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} action
-:canonical: archivebox.api.v1_crawls.CrawlUpdateSchema.action
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlUpdateSchema.action
-```
-
-````
-
-````{py:attribute} status
-:canonical: archivebox.api.v1_crawls.CrawlUpdateSchema.status
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlUpdateSchema.status
-```
-
-````
-
-````{py:attribute} retry_at
-:canonical: archivebox.api.v1_crawls.CrawlUpdateSchema.retry_at
-:type: datetime.datetime | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlUpdateSchema.retry_at
-```
-
-````
-
-````{py:attribute} tags
-:canonical: archivebox.api.v1_crawls.CrawlUpdateSchema.tags
-:type: list[str] | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlUpdateSchema.tags
-```
-
-````
-
-````{py:attribute} tags_str
-:canonical: archivebox.api.v1_crawls.CrawlUpdateSchema.tags_str
-:type: str | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlUpdateSchema.tags_str
-```
-
-````
-
-`````
-
-`````{py:class} CrawlCreateSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_crawls.CrawlCreateSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} urls
-:canonical: archivebox.api.v1_crawls.CrawlCreateSchema.urls
-:type: list[str]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlCreateSchema.urls
-```
-
-````
-
-````{py:attribute} max_depth
-:canonical: archivebox.api.v1_crawls.CrawlCreateSchema.max_depth
-:type: int
-:value: >
- 0
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlCreateSchema.max_depth
-```
-
-````
-
-````{py:attribute} tags
-:canonical: archivebox.api.v1_crawls.CrawlCreateSchema.tags
-:type: list[str] | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlCreateSchema.tags
-```
-
-````
-
-````{py:attribute} tags_str
-:canonical: archivebox.api.v1_crawls.CrawlCreateSchema.tags_str
-:type: str
-:value:
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlCreateSchema.tags_str
-```
-
-````
-
-````{py:attribute} label
-:canonical: archivebox.api.v1_crawls.CrawlCreateSchema.label
-:type: str
-:value:
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlCreateSchema.label
-```
-
-````
-
-````{py:attribute} notes
-:canonical: archivebox.api.v1_crawls.CrawlCreateSchema.notes
-:type: str
-:value:
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlCreateSchema.notes
-```
-
-````
-
-````{py:attribute} config
-:canonical: archivebox.api.v1_crawls.CrawlCreateSchema.config
-:type: dict
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlCreateSchema.config
-```
-
-````
-
-`````
-
-`````{py:class} CrawlDeleteResponseSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_crawls.CrawlDeleteResponseSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} success
-:canonical: archivebox.api.v1_crawls.CrawlDeleteResponseSchema.success
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlDeleteResponseSchema.success
-```
-
-````
-
-````{py:attribute} crawl_id
-:canonical: archivebox.api.v1_crawls.CrawlDeleteResponseSchema.crawl_id
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlDeleteResponseSchema.crawl_id
-```
-
-````
-
-````{py:attribute} deleted_count
-:canonical: archivebox.api.v1_crawls.CrawlDeleteResponseSchema.deleted_count
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlDeleteResponseSchema.deleted_count
-```
-
-````
-
-````{py:attribute} deleted_snapshots
-:canonical: archivebox.api.v1_crawls.CrawlDeleteResponseSchema.deleted_snapshots
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.CrawlDeleteResponseSchema.deleted_snapshots
-```
-
-````
-
-`````
-
-````{py:function} normalize_tag_list(tags: list[str] | None = None, tags_str: str = '') -> list[str]
-:canonical: archivebox.api.v1_crawls.normalize_tag_list
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.normalize_tag_list
-```
-````
-
-````{py:function} get_crawls(request: django.http.HttpRequest)
-:canonical: archivebox.api.v1_crawls.get_crawls
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.get_crawls
-```
-````
-
-````{py:function} create_crawl(request: django.http.HttpRequest, data: archivebox.api.v1_crawls.CrawlCreateSchema)
-:canonical: archivebox.api.v1_crawls.create_crawl
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.create_crawl
-```
-````
-
-````{py:function} get_crawl(request: django.http.HttpRequest, crawl_id: str, as_rss: bool = False, with_snapshots: bool = False, with_archiveresults: bool = False)
-:canonical: archivebox.api.v1_crawls.get_crawl
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.get_crawl
-```
-````
-
-````{py:function} crawl_file(request: django.http.HttpRequest, crawl_id: str, path: str)
-:canonical: archivebox.api.v1_crawls.crawl_file
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.crawl_file
-```
-````
-
-````{py:function} crawl_file_root(request: django.http.HttpRequest, crawl_id: str, filename: str)
-:canonical: archivebox.api.v1_crawls.crawl_file_root
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.crawl_file_root
-```
-````
-
-````{py:function} crawl_file_nested_1(request: django.http.HttpRequest, crawl_id: str, folder: str, filename: str)
-:canonical: archivebox.api.v1_crawls.crawl_file_nested_1
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.crawl_file_nested_1
-```
-````
-
-````{py:function} crawl_file_nested_2(request: django.http.HttpRequest, crawl_id: str, folder: str, subfolder: str, filename: str)
-:canonical: archivebox.api.v1_crawls.crawl_file_nested_2
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.crawl_file_nested_2
-```
-````
-
-````{py:function} patch_crawl(request: django.http.HttpRequest, crawl_id: str, data: archivebox.api.v1_crawls.CrawlUpdateSchema)
-:canonical: archivebox.api.v1_crawls.patch_crawl
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.patch_crawl
-```
-````
-
-````{py:function} delete_crawl(request: django.http.HttpRequest, crawl_id: str)
-:canonical: archivebox.api.v1_crawls.delete_crawl
-
-```{autodoc2-docstring} archivebox.api.v1_crawls.delete_crawl
-```
-````
diff --git a/docs/apidocs/archivebox/archivebox.api.v1_machine.md b/docs/apidocs/archivebox/archivebox.api.v1_machine.md
deleted file mode 100644
index 6a5df1c7..00000000
--- a/docs/apidocs/archivebox/archivebox.api.v1_machine.md
+++ /dev/null
@@ -1,720 +0,0 @@
-# {py:mod}`archivebox.api.v1_machine`
-
-```{py:module} archivebox.api.v1_machine
-```
-
-```{autodoc2-docstring} archivebox.api.v1_machine
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`MachineSchema `
- - ```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema
- :summary:
- ```
-* - {py:obj}`MachineFilterSchema `
- -
-* - {py:obj}`BinarySchema `
- - ```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema
- :summary:
- ```
-* - {py:obj}`BinaryFilterSchema `
- -
-````
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`get_machines `
- - ```{autodoc2-docstring} archivebox.api.v1_machine.get_machines
- :summary:
- ```
-* - {py:obj}`get_current_machine `
- - ```{autodoc2-docstring} archivebox.api.v1_machine.get_current_machine
- :summary:
- ```
-* - {py:obj}`get_machine `
- - ```{autodoc2-docstring} archivebox.api.v1_machine.get_machine
- :summary:
- ```
-* - {py:obj}`get_binaries `
- - ```{autodoc2-docstring} archivebox.api.v1_machine.get_binaries
- :summary:
- ```
-* - {py:obj}`get_binary `
- - ```{autodoc2-docstring} archivebox.api.v1_machine.get_binary
- :summary:
- ```
-* - {py:obj}`get_binaries_by_name `
- - ```{autodoc2-docstring} archivebox.api.v1_machine.get_binaries_by_name
- :summary:
- ```
-````
-
-### Data
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`router `
- - ```{autodoc2-docstring} archivebox.api.v1_machine.router
- :summary:
- ```
-````
-
-### API
-
-````{py:data} router
-:canonical: archivebox.api.v1_machine.router
-:value: >
- 'Router(...)'
-
-```{autodoc2-docstring} archivebox.api.v1_machine.router
-```
-
-````
-
-`````{py:class} MachineSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_machine.MachineSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.__init__
-```
-
-````{py:attribute} TYPE
-:canonical: archivebox.api.v1_machine.MachineSchema.TYPE
-:type: str
-:value: >
- 'machine.Machine'
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.TYPE
-```
-
-````
-
-````{py:attribute} id
-:canonical: archivebox.api.v1_machine.MachineSchema.id
-:type: uuid.UUID
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.id
-```
-
-````
-
-````{py:attribute} created_at
-:canonical: archivebox.api.v1_machine.MachineSchema.created_at
-:type: datetime.datetime
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.created_at
-```
-
-````
-
-````{py:attribute} modified_at
-:canonical: archivebox.api.v1_machine.MachineSchema.modified_at
-:type: datetime.datetime
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.modified_at
-```
-
-````
-
-````{py:attribute} guid
-:canonical: archivebox.api.v1_machine.MachineSchema.guid
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.guid
-```
-
-````
-
-````{py:attribute} hostname
-:canonical: archivebox.api.v1_machine.MachineSchema.hostname
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.hostname
-```
-
-````
-
-````{py:attribute} hw_in_docker
-:canonical: archivebox.api.v1_machine.MachineSchema.hw_in_docker
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.hw_in_docker
-```
-
-````
-
-````{py:attribute} hw_in_vm
-:canonical: archivebox.api.v1_machine.MachineSchema.hw_in_vm
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.hw_in_vm
-```
-
-````
-
-````{py:attribute} hw_manufacturer
-:canonical: archivebox.api.v1_machine.MachineSchema.hw_manufacturer
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.hw_manufacturer
-```
-
-````
-
-````{py:attribute} hw_product
-:canonical: archivebox.api.v1_machine.MachineSchema.hw_product
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.hw_product
-```
-
-````
-
-````{py:attribute} hw_uuid
-:canonical: archivebox.api.v1_machine.MachineSchema.hw_uuid
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.hw_uuid
-```
-
-````
-
-````{py:attribute} os_arch
-:canonical: archivebox.api.v1_machine.MachineSchema.os_arch
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.os_arch
-```
-
-````
-
-````{py:attribute} os_family
-:canonical: archivebox.api.v1_machine.MachineSchema.os_family
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.os_family
-```
-
-````
-
-````{py:attribute} os_platform
-:canonical: archivebox.api.v1_machine.MachineSchema.os_platform
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.os_platform
-```
-
-````
-
-````{py:attribute} os_release
-:canonical: archivebox.api.v1_machine.MachineSchema.os_release
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.os_release
-```
-
-````
-
-````{py:attribute} os_kernel
-:canonical: archivebox.api.v1_machine.MachineSchema.os_kernel
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.os_kernel
-```
-
-````
-
-````{py:attribute} stats
-:canonical: archivebox.api.v1_machine.MachineSchema.stats
-:type: dict
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.stats
-```
-
-````
-
-````{py:attribute} num_uses_succeeded
-:canonical: archivebox.api.v1_machine.MachineSchema.num_uses_succeeded
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.num_uses_succeeded
-```
-
-````
-
-````{py:attribute} num_uses_failed
-:canonical: archivebox.api.v1_machine.MachineSchema.num_uses_failed
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineSchema.num_uses_failed
-```
-
-````
-
-`````
-
-`````{py:class} MachineFilterSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_machine.MachineFilterSchema
-
-Bases: {py:obj}`ninja.FilterSchema`
-
-````{py:attribute} id
-:canonical: archivebox.api.v1_machine.MachineFilterSchema.id
-:type: typing.Annotated[str | None, FilterLookup('id__startswith')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineFilterSchema.id
-```
-
-````
-
-````{py:attribute} hostname
-:canonical: archivebox.api.v1_machine.MachineFilterSchema.hostname
-:type: typing.Annotated[str | None, FilterLookup('hostname__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineFilterSchema.hostname
-```
-
-````
-
-````{py:attribute} os_platform
-:canonical: archivebox.api.v1_machine.MachineFilterSchema.os_platform
-:type: typing.Annotated[str | None, FilterLookup('os_platform__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineFilterSchema.os_platform
-```
-
-````
-
-````{py:attribute} os_arch
-:canonical: archivebox.api.v1_machine.MachineFilterSchema.os_arch
-:type: typing.Annotated[str | None, FilterLookup('os_arch')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineFilterSchema.os_arch
-```
-
-````
-
-````{py:attribute} hw_in_docker
-:canonical: archivebox.api.v1_machine.MachineFilterSchema.hw_in_docker
-:type: typing.Annotated[bool | None, FilterLookup('hw_in_docker')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineFilterSchema.hw_in_docker
-```
-
-````
-
-````{py:attribute} hw_in_vm
-:canonical: archivebox.api.v1_machine.MachineFilterSchema.hw_in_vm
-:type: typing.Annotated[bool | None, FilterLookup('hw_in_vm')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineFilterSchema.hw_in_vm
-```
-
-````
-
-````{py:attribute} bin_providers
-:canonical: archivebox.api.v1_machine.MachineFilterSchema.bin_providers
-:type: typing.Annotated[str | None, FilterLookup('bin_providers__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.MachineFilterSchema.bin_providers
-```
-
-````
-
-`````
-
-`````{py:class} BinarySchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_machine.BinarySchema
-
-Bases: {py:obj}`ninja.Schema`
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.__init__
-```
-
-````{py:attribute} TYPE
-:canonical: archivebox.api.v1_machine.BinarySchema.TYPE
-:type: str
-:value: >
- 'machine.Binary'
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.TYPE
-```
-
-````
-
-````{py:attribute} id
-:canonical: archivebox.api.v1_machine.BinarySchema.id
-:type: uuid.UUID
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.id
-```
-
-````
-
-````{py:attribute} created_at
-:canonical: archivebox.api.v1_machine.BinarySchema.created_at
-:type: datetime.datetime
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.created_at
-```
-
-````
-
-````{py:attribute} modified_at
-:canonical: archivebox.api.v1_machine.BinarySchema.modified_at
-:type: datetime.datetime
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.modified_at
-```
-
-````
-
-````{py:attribute} machine_id
-:canonical: archivebox.api.v1_machine.BinarySchema.machine_id
-:type: uuid.UUID
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.machine_id
-```
-
-````
-
-````{py:attribute} machine_hostname
-:canonical: archivebox.api.v1_machine.BinarySchema.machine_hostname
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.machine_hostname
-```
-
-````
-
-````{py:attribute} name
-:canonical: archivebox.api.v1_machine.BinarySchema.name
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.name
-```
-
-````
-
-````{py:attribute} binproviders
-:canonical: archivebox.api.v1_machine.BinarySchema.binproviders
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.binproviders
-```
-
-````
-
-````{py:attribute} binprovider
-:canonical: archivebox.api.v1_machine.BinarySchema.binprovider
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.binprovider
-```
-
-````
-
-````{py:attribute} abspath
-:canonical: archivebox.api.v1_machine.BinarySchema.abspath
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.abspath
-```
-
-````
-
-````{py:attribute} version
-:canonical: archivebox.api.v1_machine.BinarySchema.version
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.version
-```
-
-````
-
-````{py:attribute} sha256
-:canonical: archivebox.api.v1_machine.BinarySchema.sha256
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.sha256
-```
-
-````
-
-````{py:attribute} status
-:canonical: archivebox.api.v1_machine.BinarySchema.status
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.status
-```
-
-````
-
-````{py:attribute} is_valid
-:canonical: archivebox.api.v1_machine.BinarySchema.is_valid
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.is_valid
-```
-
-````
-
-````{py:attribute} num_uses_succeeded
-:canonical: archivebox.api.v1_machine.BinarySchema.num_uses_succeeded
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.num_uses_succeeded
-```
-
-````
-
-````{py:attribute} num_uses_failed
-:canonical: archivebox.api.v1_machine.BinarySchema.num_uses_failed
-:type: int
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.num_uses_failed
-```
-
-````
-
-````{py:method} resolve_machine_hostname(obj) -> str
-:canonical: archivebox.api.v1_machine.BinarySchema.resolve_machine_hostname
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.resolve_machine_hostname
-```
-
-````
-
-````{py:method} resolve_is_valid(obj) -> bool
-:canonical: archivebox.api.v1_machine.BinarySchema.resolve_is_valid
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinarySchema.resolve_is_valid
-```
-
-````
-
-`````
-
-`````{py:class} BinaryFilterSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_machine.BinaryFilterSchema
-
-Bases: {py:obj}`ninja.FilterSchema`
-
-````{py:attribute} id
-:canonical: archivebox.api.v1_machine.BinaryFilterSchema.id
-:type: typing.Annotated[str | None, FilterLookup('id__startswith')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinaryFilterSchema.id
-```
-
-````
-
-````{py:attribute} name
-:canonical: archivebox.api.v1_machine.BinaryFilterSchema.name
-:type: typing.Annotated[str | None, FilterLookup('name__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinaryFilterSchema.name
-```
-
-````
-
-````{py:attribute} binprovider
-:canonical: archivebox.api.v1_machine.BinaryFilterSchema.binprovider
-:type: typing.Annotated[str | None, FilterLookup('binprovider')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinaryFilterSchema.binprovider
-```
-
-````
-
-````{py:attribute} status
-:canonical: archivebox.api.v1_machine.BinaryFilterSchema.status
-:type: typing.Annotated[str | None, FilterLookup('status')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinaryFilterSchema.status
-```
-
-````
-
-````{py:attribute} machine_id
-:canonical: archivebox.api.v1_machine.BinaryFilterSchema.machine_id
-:type: typing.Annotated[str | None, FilterLookup('machine_id__startswith')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinaryFilterSchema.machine_id
-```
-
-````
-
-````{py:attribute} version
-:canonical: archivebox.api.v1_machine.BinaryFilterSchema.version
-:type: typing.Annotated[str | None, FilterLookup('version__icontains')]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_machine.BinaryFilterSchema.version
-```
-
-````
-
-`````
-
-````{py:function} get_machines(request: django.http.HttpRequest, filters: ninja.Query[archivebox.api.v1_machine.MachineFilterSchema])
-:canonical: archivebox.api.v1_machine.get_machines
-
-```{autodoc2-docstring} archivebox.api.v1_machine.get_machines
-```
-````
-
-````{py:function} get_current_machine(request: django.http.HttpRequest)
-:canonical: archivebox.api.v1_machine.get_current_machine
-
-```{autodoc2-docstring} archivebox.api.v1_machine.get_current_machine
-```
-````
-
-````{py:function} get_machine(request: django.http.HttpRequest, machine_id: str)
-:canonical: archivebox.api.v1_machine.get_machine
-
-```{autodoc2-docstring} archivebox.api.v1_machine.get_machine
-```
-````
-
-````{py:function} get_binaries(request: django.http.HttpRequest, filters: ninja.Query[archivebox.api.v1_machine.BinaryFilterSchema])
-:canonical: archivebox.api.v1_machine.get_binaries
-
-```{autodoc2-docstring} archivebox.api.v1_machine.get_binaries
-```
-````
-
-````{py:function} get_binary(request: django.http.HttpRequest, binary_id: str)
-:canonical: archivebox.api.v1_machine.get_binary
-
-```{autodoc2-docstring} archivebox.api.v1_machine.get_binary
-```
-````
-
-````{py:function} get_binaries_by_name(request: django.http.HttpRequest, name: str)
-:canonical: archivebox.api.v1_machine.get_binaries_by_name
-
-```{autodoc2-docstring} archivebox.api.v1_machine.get_binaries_by_name
-```
-````
diff --git a/docs/apidocs/archivebox/archivebox.api.v1_personas.md b/docs/apidocs/archivebox/archivebox.api.v1_personas.md
deleted file mode 100644
index d35a4883..00000000
--- a/docs/apidocs/archivebox/archivebox.api.v1_personas.md
+++ /dev/null
@@ -1,405 +0,0 @@
-# {py:mod}`archivebox.api.v1_personas`
-
-```{py:module} archivebox.api.v1_personas
-```
-
-```{autodoc2-docstring} archivebox.api.v1_personas
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`PersonaBrowserSettingsSchema `
- -
-* - {py:obj}`PersonaSyncSchema `
- -
-* - {py:obj}`PersonaSchema `
- -
-* - {py:obj}`PersonaSyncResponseSchema `
- -
-````
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`browser_settings_to_config `
- - ```{autodoc2-docstring} archivebox.api.v1_personas.browser_settings_to_config
- :summary:
- ```
-* - {py:obj}`find_persona `
- - ```{autodoc2-docstring} archivebox.api.v1_personas.find_persona
- :summary:
- ```
-* - {py:obj}`get_personas `
- - ```{autodoc2-docstring} archivebox.api.v1_personas.get_personas
- :summary:
- ```
-* - {py:obj}`sync_persona `
- - ```{autodoc2-docstring} archivebox.api.v1_personas.sync_persona
- :summary:
- ```
-````
-
-### Data
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`router `
- - ```{autodoc2-docstring} archivebox.api.v1_personas.router
- :summary:
- ```
-````
-
-### API
-
-````{py:data} router
-:canonical: archivebox.api.v1_personas.router
-:value: >
- 'Router(...)'
-
-```{autodoc2-docstring} archivebox.api.v1_personas.router
-```
-
-````
-
-`````{py:class} PersonaBrowserSettingsSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_personas.PersonaBrowserSettingsSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} user_agent
-:canonical: archivebox.api.v1_personas.PersonaBrowserSettingsSchema.user_agent
-:type: str
-:value:
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaBrowserSettingsSchema.user_agent
-```
-
-````
-
-````{py:attribute} viewport_size
-:canonical: archivebox.api.v1_personas.PersonaBrowserSettingsSchema.viewport_size
-:type: str
-:value:
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaBrowserSettingsSchema.viewport_size
-```
-
-````
-
-````{py:attribute} viewport_device_scale_factor
-:canonical: archivebox.api.v1_personas.PersonaBrowserSettingsSchema.viewport_device_scale_factor
-:type: float | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaBrowserSettingsSchema.viewport_device_scale_factor
-```
-
-````
-
-````{py:attribute} language
-:canonical: archivebox.api.v1_personas.PersonaBrowserSettingsSchema.language
-:type: str
-:value:
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaBrowserSettingsSchema.language
-```
-
-````
-
-````{py:attribute} timezone
-:canonical: archivebox.api.v1_personas.PersonaBrowserSettingsSchema.timezone
-:type: str
-:value:
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaBrowserSettingsSchema.timezone
-```
-
-````
-
-````{py:attribute} geolocation
-:canonical: archivebox.api.v1_personas.PersonaBrowserSettingsSchema.geolocation
-:type: dict[str, typing.Any] | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaBrowserSettingsSchema.geolocation
-```
-
-````
-
-`````
-
-`````{py:class} PersonaSyncSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_personas.PersonaSyncSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} extension_persona_id
-:canonical: archivebox.api.v1_personas.PersonaSyncSchema.extension_persona_id
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSyncSchema.extension_persona_id
-```
-
-````
-
-````{py:attribute} name
-:canonical: archivebox.api.v1_personas.PersonaSyncSchema.name
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSyncSchema.name
-```
-
-````
-
-````{py:attribute} settings
-:canonical: archivebox.api.v1_personas.PersonaSyncSchema.settings
-:type: archivebox.api.v1_personas.PersonaBrowserSettingsSchema
-:value: >
- 'Field(...)'
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSyncSchema.settings
-```
-
-````
-
-````{py:attribute} cookies_txt
-:canonical: archivebox.api.v1_personas.PersonaSyncSchema.cookies_txt
-:type: str
-:value:
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSyncSchema.cookies_txt
-```
-
-````
-
-````{py:attribute} auth_json
-:canonical: archivebox.api.v1_personas.PersonaSyncSchema.auth_json
-:type: dict[str, typing.Any]
-:value: >
- 'Field(...)'
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSyncSchema.auth_json
-```
-
-````
-
-`````
-
-`````{py:class} PersonaSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_personas.PersonaSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} TYPE
-:canonical: archivebox.api.v1_personas.PersonaSchema.TYPE
-:type: str
-:value: >
- 'personas.models.Persona'
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSchema.TYPE
-```
-
-````
-
-````{py:attribute} id
-:canonical: archivebox.api.v1_personas.PersonaSchema.id
-:type: uuid.UUID
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSchema.id
-```
-
-````
-
-````{py:attribute} name
-:canonical: archivebox.api.v1_personas.PersonaSchema.name
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSchema.name
-```
-
-````
-
-````{py:attribute} created_at
-:canonical: archivebox.api.v1_personas.PersonaSchema.created_at
-:type: datetime.datetime
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSchema.created_at
-```
-
-````
-
-````{py:attribute} created_by_id
-:canonical: archivebox.api.v1_personas.PersonaSchema.created_by_id
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSchema.created_by_id
-```
-
-````
-
-````{py:attribute} created_by_username
-:canonical: archivebox.api.v1_personas.PersonaSchema.created_by_username
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSchema.created_by_username
-```
-
-````
-
-````{py:attribute} config
-:canonical: archivebox.api.v1_personas.PersonaSchema.config
-:type: dict[str, typing.Any] | None
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSchema.config
-```
-
-````
-
-````{py:method} resolve_created_by_id(obj)
-:canonical: archivebox.api.v1_personas.PersonaSchema.resolve_created_by_id
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSchema.resolve_created_by_id
-```
-
-````
-
-````{py:method} resolve_created_by_username(obj) -> str
-:canonical: archivebox.api.v1_personas.PersonaSchema.resolve_created_by_username
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSchema.resolve_created_by_username
-```
-
-````
-
-````{py:method} resolve_config(obj)
-:canonical: archivebox.api.v1_personas.PersonaSchema.resolve_config
-:staticmethod:
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSchema.resolve_config
-```
-
-````
-
-`````
-
-`````{py:class} PersonaSyncResponseSchema(/, **data: typing.Any)
-:canonical: archivebox.api.v1_personas.PersonaSyncResponseSchema
-
-Bases: {py:obj}`ninja.Schema`
-
-````{py:attribute} success
-:canonical: archivebox.api.v1_personas.PersonaSyncResponseSchema.success
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSyncResponseSchema.success
-```
-
-````
-
-````{py:attribute} created
-:canonical: archivebox.api.v1_personas.PersonaSyncResponseSchema.created
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSyncResponseSchema.created
-```
-
-````
-
-````{py:attribute} persona
-:canonical: archivebox.api.v1_personas.PersonaSyncResponseSchema.persona
-:type: archivebox.api.v1_personas.PersonaSchema
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSyncResponseSchema.persona
-```
-
-````
-
-````{py:attribute} cookies_file_written
-:canonical: archivebox.api.v1_personas.PersonaSyncResponseSchema.cookies_file_written
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSyncResponseSchema.cookies_file_written
-```
-
-````
-
-````{py:attribute} auth_file_written
-:canonical: archivebox.api.v1_personas.PersonaSyncResponseSchema.auth_file_written
-:type: bool
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.api.v1_personas.PersonaSyncResponseSchema.auth_file_written
-```
-
-````
-
-`````
-
-````{py:function} browser_settings_to_config(extension_persona_id: str, settings: archivebox.api.v1_personas.PersonaBrowserSettingsSchema) -> dict[str, typing.Any]
-:canonical: archivebox.api.v1_personas.browser_settings_to_config
-
-```{autodoc2-docstring} archivebox.api.v1_personas.browser_settings_to_config
-```
-````
-
-````{py:function} find_persona(extension_persona_id: str, name: str) -> archivebox.personas.models.Persona | None
-:canonical: archivebox.api.v1_personas.find_persona
-
-```{autodoc2-docstring} archivebox.api.v1_personas.find_persona
-```
-````
-
-````{py:function} get_personas(request: django.http.HttpRequest)
-:canonical: archivebox.api.v1_personas.get_personas
-
-```{autodoc2-docstring} archivebox.api.v1_personas.get_personas
-```
-````
-
-````{py:function} sync_persona(request: django.http.HttpRequest, payload: archivebox.api.v1_personas.PersonaSyncSchema)
-:canonical: archivebox.api.v1_personas.sync_persona
-
-```{autodoc2-docstring} archivebox.api.v1_personas.sync_persona
-```
-````
diff --git a/docs/apidocs/archivebox/archivebox.api.webhooks.md b/docs/apidocs/archivebox/archivebox.api.webhooks.md
deleted file mode 100644
index 96802163..00000000
--- a/docs/apidocs/archivebox/archivebox.api.webhooks.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# {py:mod}`archivebox.api.webhooks`
-
-```{py:module} archivebox.api.webhooks
-```
-
-```{autodoc2-docstring} archivebox.api.webhooks
-:allowtitles:
-```
-
-## Module Contents
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`warning_error_handler `
- - ```{autodoc2-docstring} archivebox.api.webhooks.warning_error_handler
- :summary:
- ```
-* - {py:obj}`transaction_on_commit_task_handler `
- - ```{autodoc2-docstring} archivebox.api.webhooks.transaction_on_commit_task_handler
- :summary:
- ```
-````
-
-### Data
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`logger `
- - ```{autodoc2-docstring} archivebox.api.webhooks.logger
- :summary:
- ```
-````
-
-### API
-
-````{py:data} logger
-:canonical: archivebox.api.webhooks.logger
-:value: >
- 'getLogger(...)'
-
-```{autodoc2-docstring} archivebox.api.webhooks.logger
-```
-
-````
-
-````{py:function} warning_error_handler(hook: typing.Any, error: Exception | None) -> None
-:canonical: archivebox.api.webhooks.warning_error_handler
-
-```{autodoc2-docstring} archivebox.api.webhooks.warning_error_handler
-```
-````
-
-````{py:function} transaction_on_commit_task_handler(hook: collections.abc.Callable[..., None], **kwargs: typing.Any) -> None
-:canonical: archivebox.api.webhooks.transaction_on_commit_task_handler
-
-```{autodoc2-docstring} archivebox.api.webhooks.transaction_on_commit_task_handler
-```
-````
diff --git a/docs/apidocs/archivebox/archivebox.base_models.admin.md b/docs/apidocs/archivebox/archivebox.base_models.admin.md
deleted file mode 100644
index 86a3ab40..00000000
--- a/docs/apidocs/archivebox/archivebox.base_models.admin.md
+++ /dev/null
@@ -1,350 +0,0 @@
-# {py:mod}`archivebox.base_models.admin`
-
-```{py:module} archivebox.base_models.admin
-```
-
-```{autodoc2-docstring} archivebox.base_models.admin
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`HexUUIDConverter `
- - ```{autodoc2-docstring} archivebox.base_models.admin.HexUUIDConverter
- :summary:
- ```
-* - {py:obj}`ConfigOption `
- -
-* - {py:obj}`KeyValueWidget `
- - ```{autodoc2-docstring} archivebox.base_models.admin.KeyValueWidget
- :summary:
- ```
-* - {py:obj}`ConfigEditorMixin `
- - ```{autodoc2-docstring} archivebox.base_models.admin.ConfigEditorMixin
- :summary:
- ```
-* - {py:obj}`BaseModelAdmin `
- -
-````
-
-### API
-
-`````{py:class} HexUUIDConverter
-:canonical: archivebox.base_models.admin.HexUUIDConverter
-
-```{autodoc2-docstring} archivebox.base_models.admin.HexUUIDConverter
-```
-
-````{py:attribute} regex
-:canonical: archivebox.base_models.admin.HexUUIDConverter.regex
-:value: >
- '[0-9a-fA-F]{32}|[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}'
-
-```{autodoc2-docstring} archivebox.base_models.admin.HexUUIDConverter.regex
-```
-
-````
-
-````{py:method} to_python(value: str) -> str
-:canonical: archivebox.base_models.admin.HexUUIDConverter.to_python
-
-```{autodoc2-docstring} archivebox.base_models.admin.HexUUIDConverter.to_python
-```
-
-````
-
-````{py:method} to_url(value) -> str
-:canonical: archivebox.base_models.admin.HexUUIDConverter.to_url
-
-```{autodoc2-docstring} archivebox.base_models.admin.HexUUIDConverter.to_url
-```
-
-````
-
-`````
-
-`````{py:class} ConfigOption()
-:canonical: archivebox.base_models.admin.ConfigOption
-
-Bases: {py:obj}`typing.TypedDict`
-
-````{py:attribute} plugin
-:canonical: archivebox.base_models.admin.ConfigOption.plugin
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.base_models.admin.ConfigOption.plugin
-```
-
-````
-
-````{py:attribute} type
-:canonical: archivebox.base_models.admin.ConfigOption.type
-:type: str | list[str]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.base_models.admin.ConfigOption.type
-```
-
-````
-
-````{py:attribute} default
-:canonical: archivebox.base_models.admin.ConfigOption.default
-:type: object
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.base_models.admin.ConfigOption.default
-```
-
-````
-
-````{py:attribute} description
-:canonical: archivebox.base_models.admin.ConfigOption.description
-:type: str
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.base_models.admin.ConfigOption.description
-```
-
-````
-
-````{py:attribute} enum
-:canonical: archivebox.base_models.admin.ConfigOption.enum
-:type: typing.NotRequired[list[object]]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.base_models.admin.ConfigOption.enum
-```
-
-````
-
-````{py:attribute} pattern
-:canonical: archivebox.base_models.admin.ConfigOption.pattern
-:type: typing.NotRequired[str]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.base_models.admin.ConfigOption.pattern
-```
-
-````
-
-````{py:attribute} minimum
-:canonical: archivebox.base_models.admin.ConfigOption.minimum
-:type: typing.NotRequired[int | float]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.base_models.admin.ConfigOption.minimum
-```
-
-````
-
-````{py:attribute} maximum
-:canonical: archivebox.base_models.admin.ConfigOption.maximum
-:type: typing.NotRequired[int | float]
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.base_models.admin.ConfigOption.maximum
-```
-
-````
-
-`````
-
-``````{py:class} KeyValueWidget(attrs=None)
-:canonical: archivebox.base_models.admin.KeyValueWidget
-
-Bases: {py:obj}`django.forms.Widget`
-
-```{autodoc2-docstring} archivebox.base_models.admin.KeyValueWidget
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.base_models.admin.KeyValueWidget.__init__
-```
-
-````{py:attribute} template_name
-:canonical: archivebox.base_models.admin.KeyValueWidget.template_name
-:value:
-
-```{autodoc2-docstring} archivebox.base_models.admin.KeyValueWidget.template_name
-```
-
-````
-
-`````{py:class} Media
-:canonical: archivebox.base_models.admin.KeyValueWidget.Media
-
-```{autodoc2-docstring} archivebox.base_models.admin.KeyValueWidget.Media
-```
-
-````{py:attribute} css
-:canonical: archivebox.base_models.admin.KeyValueWidget.Media.css
-:value: >
- None
-
-```{autodoc2-docstring} archivebox.base_models.admin.KeyValueWidget.Media.css
-```
-
-````
-
-````{py:attribute} js
-:canonical: archivebox.base_models.admin.KeyValueWidget.Media.js
-:value: >
- []
-
-```{autodoc2-docstring} archivebox.base_models.admin.KeyValueWidget.Media.js
-```
-
-````
-
-`````
-
-````{py:method} _get_config_options() -> dict[str, archivebox.base_models.admin.ConfigOption]
-:canonical: archivebox.base_models.admin.KeyValueWidget._get_config_options
-
-```{autodoc2-docstring} archivebox.base_models.admin.KeyValueWidget._get_config_options
-```
-
-````
-
-````{py:method} _parse_value(value: object) -> dict[str, object]
-:canonical: archivebox.base_models.admin.KeyValueWidget._parse_value
-
-```{autodoc2-docstring} archivebox.base_models.admin.KeyValueWidget._parse_value
-```
-
-````
-
-````{py:method} render(name: str, value: object, attrs: collections.abc.Mapping[str, str] | None = None, renderer: django.forms.renderers.BaseRenderer | None = None) -> django.utils.safestring.SafeString
-:canonical: archivebox.base_models.admin.KeyValueWidget.render
-
-````
-
-````{py:method} _render_row(widget_id: str, key: str, value: str) -> str
-:canonical: archivebox.base_models.admin.KeyValueWidget._render_row
-
-```{autodoc2-docstring} archivebox.base_models.admin.KeyValueWidget._render_row
-```
-
-````
-
-````{py:method} _escape(s: object) -> str
-:canonical: archivebox.base_models.admin.KeyValueWidget._escape
-
-```{autodoc2-docstring} archivebox.base_models.admin.KeyValueWidget._escape
-```
-
-````
-
-````{py:method} value_from_datadict(data: django.http.QueryDict | collections.abc.Mapping[str, object], files: object, name: str) -> str
-:canonical: archivebox.base_models.admin.KeyValueWidget.value_from_datadict
-
-````
-
-``````
-
-`````{py:class} ConfigEditorMixin(model, admin_site)
-:canonical: archivebox.base_models.admin.ConfigEditorMixin
-
-Bases: {py:obj}`django.contrib.admin.ModelAdmin`
-
-```{autodoc2-docstring} archivebox.base_models.admin.ConfigEditorMixin
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.base_models.admin.ConfigEditorMixin.__init__
-```
-
-````{py:method} formfield_for_dbfield(db_field: django.db.models.Field, request: django.http.HttpRequest, **kwargs: object) -> django.forms.Field | None
-:canonical: archivebox.base_models.admin.ConfigEditorMixin.formfield_for_dbfield
-
-```{autodoc2-docstring} archivebox.base_models.admin.ConfigEditorMixin.formfield_for_dbfield
-```
-
-````
-
-````{py:method} save_model(request: django.http.HttpRequest, obj, form, change)
-:canonical: archivebox.base_models.admin.ConfigEditorMixin.save_model
-
-```{autodoc2-docstring} archivebox.base_models.admin.ConfigEditorMixin.save_model
-```
-
-````
-
-`````
-
-`````{py:class} BaseModelAdmin(model, admin_site)
-:canonical: archivebox.base_models.admin.BaseModelAdmin
-
-Bases: {py:obj}`django_object_actions.DjangoObjectActions`, {py:obj}`django.contrib.admin.ModelAdmin`
-
-````{py:attribute} list_display
-:canonical: archivebox.base_models.admin.BaseModelAdmin.list_display
-:value: >
- ('id', 'created_at', 'created_by')
-
-```{autodoc2-docstring} archivebox.base_models.admin.BaseModelAdmin.list_display
-```
-
-````
-
-````{py:attribute} readonly_fields
-:canonical: archivebox.base_models.admin.BaseModelAdmin.readonly_fields
-:value: >
- ('id', 'created_at', 'modified_at')
-
-```{autodoc2-docstring} archivebox.base_models.admin.BaseModelAdmin.readonly_fields
-```
-
-````
-
-````{py:attribute} show_search_mode_selector
-:canonical: archivebox.base_models.admin.BaseModelAdmin.show_search_mode_selector
-:value: >
- False
-
-```{autodoc2-docstring} archivebox.base_models.admin.BaseModelAdmin.show_search_mode_selector
-```
-
-````
-
-````{py:method} get_default_search_mode() -> str
-:canonical: archivebox.base_models.admin.BaseModelAdmin.get_default_search_mode
-
-```{autodoc2-docstring} archivebox.base_models.admin.BaseModelAdmin.get_default_search_mode
-```
-
-````
-
-````{py:method} get_form(request: django.http.HttpRequest, obj: django.db.models.Model | None = None, change: bool = False, **kwargs: object)
-:canonical: archivebox.base_models.admin.BaseModelAdmin.get_form
-
-````
-
-````{py:method} get_urls()
-:canonical: archivebox.base_models.admin.BaseModelAdmin.get_urls
-
-```{autodoc2-docstring} archivebox.base_models.admin.BaseModelAdmin.get_urls
-```
-
-````
-
-`````
diff --git a/docs/apidocs/archivebox/archivebox.base_models.apps.md b/docs/apidocs/archivebox/archivebox.base_models.apps.md
deleted file mode 100644
index fe05cf19..00000000
--- a/docs/apidocs/archivebox/archivebox.base_models.apps.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# {py:mod}`archivebox.base_models.apps`
-
-```{py:module} archivebox.base_models.apps
-```
-
-```{autodoc2-docstring} archivebox.base_models.apps
-:allowtitles:
-```
diff --git a/docs/apidocs/archivebox/archivebox.base_models.md b/docs/apidocs/archivebox/archivebox.base_models.md
deleted file mode 100644
index 25e6a7fe..00000000
--- a/docs/apidocs/archivebox/archivebox.base_models.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# {py:mod}`archivebox.base_models`
-
-```{py:module} archivebox.base_models
-```
-
-```{autodoc2-docstring} archivebox.base_models
-:allowtitles:
-```
-
-## Submodules
-
-```{toctree}
-:titlesonly:
-:maxdepth: 1
-
-archivebox.base_models.models
-archivebox.base_models.apps
-archivebox.base_models.admin
-```
diff --git a/docs/apidocs/archivebox/archivebox.base_models.models.md b/docs/apidocs/archivebox/archivebox.base_models.models.md
deleted file mode 100644
index 3d7cedc3..00000000
--- a/docs/apidocs/archivebox/archivebox.base_models.models.md
+++ /dev/null
@@ -1,529 +0,0 @@
-# {py:mod}`archivebox.base_models.models`
-
-```{py:module} archivebox.base_models.models
-```
-
-```{autodoc2-docstring} archivebox.base_models.models
-:allowtitles:
-```
-
-## Module Contents
-
-### Classes
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`AutoDateTimeField `
- - ```{autodoc2-docstring} archivebox.base_models.models.AutoDateTimeField
- :summary:
- ```
-* - {py:obj}`ModelWithUUID `
- -
-* - {py:obj}`ModelWithNotes `
- - ```{autodoc2-docstring} archivebox.base_models.models.ModelWithNotes
- :summary:
- ```
-* - {py:obj}`ModelWithHealthStats `
- - ```{autodoc2-docstring} archivebox.base_models.models.ModelWithHealthStats
- :summary:
- ```
-* - {py:obj}`ModelWithConfig `
- - ```{autodoc2-docstring} archivebox.base_models.models.ModelWithConfig
- :summary:
- ```
-* - {py:obj}`ModelWithDeleteAfter `
- -
-* - {py:obj}`ModelWithOutputDir `
- -
-````
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`get_or_create_system_user_pk `
- - ```{autodoc2-docstring} archivebox.base_models.models.get_or_create_system_user_pk
- :summary:
- ```
-````
-
-### API
-
-````{py:function} get_or_create_system_user_pk(username='system')
-:canonical: archivebox.base_models.models.get_or_create_system_user_pk
-
-```{autodoc2-docstring} archivebox.base_models.models.get_or_create_system_user_pk
-```
-````
-
-`````{py:class} AutoDateTimeField(verbose_name=None, name=None, auto_now=False, auto_now_add=False, **kwargs)
-:canonical: archivebox.base_models.models.AutoDateTimeField
-
-Bases: {py:obj}`django.db.models.DateTimeField`
-
-```{autodoc2-docstring} archivebox.base_models.models.AutoDateTimeField
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.base_models.models.AutoDateTimeField.__init__
-```
-
-````{py:method} pre_save(model_instance, add)
-:canonical: archivebox.base_models.models.AutoDateTimeField.pre_save
-
-````
-
-`````
-
-``````{py:class} ModelWithUUID(*args, **kwargs)
-:canonical: archivebox.base_models.models.ModelWithUUID
-
-Bases: {py:obj}`django.db.models.Model`
-
-````{py:attribute} id
-:canonical: archivebox.base_models.models.ModelWithUUID.id
-:value: >
- 'UUIDField(...)'
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithUUID.id
-```
-
-````
-
-````{py:attribute} created_at
-:canonical: archivebox.base_models.models.ModelWithUUID.created_at
-:value: >
- 'DateTimeField(...)'
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithUUID.created_at
-```
-
-````
-
-````{py:attribute} modified_at
-:canonical: archivebox.base_models.models.ModelWithUUID.modified_at
-:value: >
- 'DateTimeField(...)'
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithUUID.modified_at
-```
-
-````
-
-````{py:attribute} created_by
-:canonical: archivebox.base_models.models.ModelWithUUID.created_by
-:value: >
- 'ForeignKey(...)'
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithUUID.created_by
-```
-
-````
-
-`````{py:class} Meta
-:canonical: archivebox.base_models.models.ModelWithUUID.Meta
-
-Bases: {py:obj}`django_stubs_ext.db.models.TypedModelMeta`
-
-````{py:attribute} abstract
-:canonical: archivebox.base_models.models.ModelWithUUID.Meta.abstract
-:value: >
- True
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithUUID.Meta.abstract
-```
-
-````
-
-`````
-
-````{py:method} __str__() -> str
-:canonical: archivebox.base_models.models.ModelWithUUID.__str__
-
-````
-
-````{py:property} admin_change_url
-:canonical: archivebox.base_models.models.ModelWithUUID.admin_change_url
-:type: str
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithUUID.admin_change_url
-```
-
-````
-
-````{py:property} api_url
-:canonical: archivebox.base_models.models.ModelWithUUID.api_url
-:type: str
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithUUID.api_url
-```
-
-````
-
-````{py:property} api_docs_url
-:canonical: archivebox.base_models.models.ModelWithUUID.api_docs_url
-:type: str
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithUUID.api_docs_url
-```
-
-````
-
-``````
-
-``````{py:class} ModelWithNotes(*args, **kwargs)
-:canonical: archivebox.base_models.models.ModelWithNotes
-
-Bases: {py:obj}`django.db.models.Model`
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithNotes
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithNotes.__init__
-```
-
-````{py:attribute} notes
-:canonical: archivebox.base_models.models.ModelWithNotes.notes
-:value: >
- 'TextField(...)'
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithNotes.notes
-```
-
-````
-
-`````{py:class} Meta
-:canonical: archivebox.base_models.models.ModelWithNotes.Meta
-
-Bases: {py:obj}`django_stubs_ext.db.models.TypedModelMeta`
-
-````{py:attribute} abstract
-:canonical: archivebox.base_models.models.ModelWithNotes.Meta.abstract
-:value: >
- True
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithNotes.Meta.abstract
-```
-
-````
-
-`````
-
-``````
-
-``````{py:class} ModelWithHealthStats(*args, **kwargs)
-:canonical: archivebox.base_models.models.ModelWithHealthStats
-
-Bases: {py:obj}`django.db.models.Model`
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithHealthStats
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithHealthStats.__init__
-```
-
-````{py:attribute} num_uses_failed
-:canonical: archivebox.base_models.models.ModelWithHealthStats.num_uses_failed
-:value: >
- 'PositiveIntegerField(...)'
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithHealthStats.num_uses_failed
-```
-
-````
-
-````{py:attribute} num_uses_succeeded
-:canonical: archivebox.base_models.models.ModelWithHealthStats.num_uses_succeeded
-:value: >
- 'PositiveIntegerField(...)'
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithHealthStats.num_uses_succeeded
-```
-
-````
-
-`````{py:class} Meta
-:canonical: archivebox.base_models.models.ModelWithHealthStats.Meta
-
-Bases: {py:obj}`django_stubs_ext.db.models.TypedModelMeta`
-
-````{py:attribute} abstract
-:canonical: archivebox.base_models.models.ModelWithHealthStats.Meta.abstract
-:value: >
- True
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithHealthStats.Meta.abstract
-```
-
-````
-
-`````
-
-````{py:property} health
-:canonical: archivebox.base_models.models.ModelWithHealthStats.health
-:type: int
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithHealthStats.health
-```
-
-````
-
-````{py:method} increment_health_stats(success: bool)
-:canonical: archivebox.base_models.models.ModelWithHealthStats.increment_health_stats
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithHealthStats.increment_health_stats
-```
-
-````
-
-``````
-
-``````{py:class} ModelWithConfig(*args, **kwargs)
-:canonical: archivebox.base_models.models.ModelWithConfig
-
-Bases: {py:obj}`django.db.models.Model`
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithConfig
-```
-
-```{rubric} Initialization
-```
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithConfig.__init__
-```
-
-````{py:attribute} config
-:canonical: archivebox.base_models.models.ModelWithConfig.config
-:value: >
- 'JSONField(...)'
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithConfig.config
-```
-
-````
-
-`````{py:class} Meta
-:canonical: archivebox.base_models.models.ModelWithConfig.Meta
-
-Bases: {py:obj}`django_stubs_ext.db.models.TypedModelMeta`
-
-````{py:attribute} abstract
-:canonical: archivebox.base_models.models.ModelWithConfig.Meta.abstract
-:value: >
- True
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithConfig.Meta.abstract
-```
-
-````
-
-`````
-
-``````
-
-``````{py:class} ModelWithDeleteAfter(*args, **kwargs)
-:canonical: archivebox.base_models.models.ModelWithDeleteAfter
-
-Bases: {py:obj}`django.db.models.Model`
-
-````{py:attribute} delete_after_final_statuses
-:canonical: archivebox.base_models.models.ModelWithDeleteAfter.delete_after_final_statuses
-:type: tuple[str, ...]
-:value: >
- ()
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithDeleteAfter.delete_after_final_statuses
-```
-
-````
-
-````{py:attribute} delete_at
-:canonical: archivebox.base_models.models.ModelWithDeleteAfter.delete_at
-:value: >
- 'DateTimeField(...)'
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithDeleteAfter.delete_at
-```
-
-````
-
-`````{py:class} Meta
-:canonical: archivebox.base_models.models.ModelWithDeleteAfter.Meta
-
-Bases: {py:obj}`django_stubs_ext.db.models.TypedModelMeta`
-
-````{py:attribute} abstract
-:canonical: archivebox.base_models.models.ModelWithDeleteAfter.Meta.abstract
-:value: >
- True
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithDeleteAfter.Meta.abstract
-```
-
-````
-
-`````
-
-````{py:method} save(*args, **kwargs)
-:canonical: archivebox.base_models.models.ModelWithDeleteAfter.save
-
-````
-
-````{py:method} get_delete_after_config_value()
-:canonical: archivebox.base_models.models.ModelWithDeleteAfter.get_delete_after_config_value
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithDeleteAfter.get_delete_after_config_value
-```
-
-````
-
-````{py:method} set_delete_at_from_config(config_value=None) -> bool
-:canonical: archivebox.base_models.models.ModelWithDeleteAfter.set_delete_at_from_config
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithDeleteAfter.set_delete_at_from_config
-```
-
-````
-
-````{py:method} missing_delete_at_candidates()
-:canonical: archivebox.base_models.models.ModelWithDeleteAfter.missing_delete_at_candidates
-:classmethod:
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithDeleteAfter.missing_delete_at_candidates
-```
-
-````
-
-````{py:method} delete_expired(*, batch_size: int = 100, backfill_missing: bool = True) -> int
-:canonical: archivebox.base_models.models.ModelWithDeleteAfter.delete_expired
-:classmethod:
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithDeleteAfter.delete_expired
-```
-
-````
-
-``````
-
-``````{py:class} ModelWithOutputDir(*args, **kwargs)
-:canonical: archivebox.base_models.models.ModelWithOutputDir
-
-Bases: {py:obj}`archivebox.base_models.models.ModelWithUUID`
-
-`````{py:class} Meta
-:canonical: archivebox.base_models.models.ModelWithOutputDir.Meta
-
-Bases: {py:obj}`archivebox.base_models.models.ModelWithUUID`
-
-````{py:attribute} abstract
-:canonical: archivebox.base_models.models.ModelWithOutputDir.Meta.abstract
-:value: >
- True
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithOutputDir.Meta.abstract
-```
-
-````
-
-`````
-
-````{py:attribute} _delete_signal_registered
-:canonical: archivebox.base_models.models.ModelWithOutputDir._delete_signal_registered
-:value: >
- False
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithOutputDir._delete_signal_registered
-```
-
-````
-
-````{py:method} save(*args, **kwargs)
-:canonical: archivebox.base_models.models.ModelWithOutputDir.save
-
-````
-
-````{py:property} output_dir_parent
-:canonical: archivebox.base_models.models.ModelWithOutputDir.output_dir_parent
-:type: str
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithOutputDir.output_dir_parent
-```
-
-````
-
-````{py:property} output_dir_name
-:canonical: archivebox.base_models.models.ModelWithOutputDir.output_dir_name
-:type: str
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithOutputDir.output_dir_name
-```
-
-````
-
-````{py:property} output_dir_str
-:canonical: archivebox.base_models.models.ModelWithOutputDir.output_dir_str
-:type: str
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithOutputDir.output_dir_str
-```
-
-````
-
-````{py:property} output_dir
-:canonical: archivebox.base_models.models.ModelWithOutputDir.output_dir
-:abstractmethod:
-:type: pathlib.Path
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithOutputDir.output_dir
-```
-
-````
-
-````{py:method} output_paths_for_delete() -> tuple[pathlib.Path, ...]
-:canonical: archivebox.base_models.models.ModelWithOutputDir.output_paths_for_delete
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithOutputDir.output_paths_for_delete
-```
-
-````
-
-````{py:method} validate_output_paths_for_delete(paths) -> tuple[pathlib.Path, ...]
-:canonical: archivebox.base_models.models.ModelWithOutputDir.validate_output_paths_for_delete
-:classmethod:
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithOutputDir.validate_output_paths_for_delete
-```
-
-````
-
-````{py:method} delete_output_paths(paths) -> None
-:canonical: archivebox.base_models.models.ModelWithOutputDir.delete_output_paths
-:classmethod:
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithOutputDir.delete_output_paths
-```
-
-````
-
-````{py:method} register_delete_signal() -> None
-:canonical: archivebox.base_models.models.ModelWithOutputDir.register_delete_signal
-:classmethod:
-
-```{autodoc2-docstring} archivebox.base_models.models.ModelWithOutputDir.register_delete_signal
-```
-
-````
-
-``````
diff --git a/docs/apidocs/archivebox/archivebox.cli.archivebox_add.md b/docs/apidocs/archivebox/archivebox.cli.archivebox_add.md
deleted file mode 100644
index 988bea56..00000000
--- a/docs/apidocs/archivebox/archivebox.cli.archivebox_add.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# {py:mod}`archivebox.cli.archivebox_add`
-
-```{py:module} archivebox.cli.archivebox_add
-```
-
-```{autodoc2-docstring} archivebox.cli.archivebox_add
-:allowtitles:
-```
-
-## Module Contents
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`_collect_input_urls `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_add._collect_input_urls
- :summary:
- ```
-* - {py:obj}`add `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_add.add
- :summary:
- ```
-* - {py:obj}`main `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_add.main
- :summary:
- ```
-````
-
-### Data
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`__command__ `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_add.__command__
- :summary:
- ```
-````
-
-### API
-
-````{py:data} __command__
-:canonical: archivebox.cli.archivebox_add.__command__
-:value: >
- 'archivebox add'
-
-```{autodoc2-docstring} archivebox.cli.archivebox_add.__command__
-```
-
-````
-
-````{py:function} _collect_input_urls(args: tuple[str, ...]) -> list[str]
-:canonical: archivebox.cli.archivebox_add._collect_input_urls
-
-```{autodoc2-docstring} archivebox.cli.archivebox_add._collect_input_urls
-```
-````
-
-````{py:function} add(urls: str | list[str], snapshot_ids: list[str] | None = None, depth: int | str = 0, max_urls: int = 0, crawl_max_size: int | str = 0, crawl_timeout: int = 0, snapshot_max_size: int | str = 0, crawl_max_concurrent_snapshots: int | None = None, tag: str = '', url_allowlist: str = '', url_denylist: str = '', parser: str = 'auto', plugins: str = '', persona: str = 'Default', index_only: bool = False, bg: bool = False, created_by_id: int | None = None, config: dict[str, typing.Any] | None = None) -> tuple[archivebox.crawls.models.Crawl, django.db.models.QuerySet[archivebox.core.models.Snapshot]]
-:canonical: archivebox.cli.archivebox_add.add
-
-```{autodoc2-docstring} archivebox.cli.archivebox_add.add
-```
-````
-
-````{py:function} main(**kwargs)
-:canonical: archivebox.cli.archivebox_add.main
-
-```{autodoc2-docstring} archivebox.cli.archivebox_add.main
-```
-````
diff --git a/docs/apidocs/archivebox/archivebox.cli.archivebox_archiveresult.md b/docs/apidocs/archivebox/archivebox.cli.archivebox_archiveresult.md
deleted file mode 100644
index 8b01f3da..00000000
--- a/docs/apidocs/archivebox/archivebox.cli.archivebox_archiveresult.md
+++ /dev/null
@@ -1,152 +0,0 @@
-# {py:mod}`archivebox.cli.archivebox_archiveresult`
-
-```{py:module} archivebox.cli.archivebox_archiveresult
-```
-
-```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult
-:allowtitles:
-```
-
-## Module Contents
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`build_archiveresult_request `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.build_archiveresult_request
- :summary:
- ```
-* - {py:obj}`create_archiveresults `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.create_archiveresults
- :summary:
- ```
-* - {py:obj}`list_archiveresults `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.list_archiveresults
- :summary:
- ```
-* - {py:obj}`update_archiveresults `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.update_archiveresults
- :summary:
- ```
-* - {py:obj}`delete_archiveresults `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.delete_archiveresults
- :summary:
- ```
-* - {py:obj}`main `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.main
- :summary:
- ```
-* - {py:obj}`create_cmd `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.create_cmd
- :summary:
- ```
-* - {py:obj}`list_cmd `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.list_cmd
- :summary:
- ```
-* - {py:obj}`update_cmd `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.update_cmd
- :summary:
- ```
-* - {py:obj}`delete_cmd `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.delete_cmd
- :summary:
- ```
-````
-
-### Data
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`__command__ `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.__command__
- :summary:
- ```
-````
-
-### API
-
-````{py:data} __command__
-:canonical: archivebox.cli.archivebox_archiveresult.__command__
-:value: >
- 'archivebox archiveresult'
-
-```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.__command__
-```
-
-````
-
-````{py:function} build_archiveresult_request(snapshot_id: str, plugin: str, hook_name: str = '', status: str = 'queued') -> dict
-:canonical: archivebox.cli.archivebox_archiveresult.build_archiveresult_request
-
-```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.build_archiveresult_request
-```
-````
-
-````{py:function} create_archiveresults(snapshot_id: str | None = None, plugin: str | None = None, status: str = 'queued') -> int
-:canonical: archivebox.cli.archivebox_archiveresult.create_archiveresults
-
-```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.create_archiveresults
-```
-````
-
-````{py:function} list_archiveresults(status: str | None = None, plugin: str | None = None, snapshot_id: str | None = None, limit: int | None = None) -> int
-:canonical: archivebox.cli.archivebox_archiveresult.list_archiveresults
-
-```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.list_archiveresults
-```
-````
-
-````{py:function} update_archiveresults(status: str | None = None) -> int
-:canonical: archivebox.cli.archivebox_archiveresult.update_archiveresults
-
-```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.update_archiveresults
-```
-````
-
-````{py:function} delete_archiveresults(yes: bool = False, dry_run: bool = False) -> int
-:canonical: archivebox.cli.archivebox_archiveresult.delete_archiveresults
-
-```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.delete_archiveresults
-```
-````
-
-````{py:function} main()
-:canonical: archivebox.cli.archivebox_archiveresult.main
-
-```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.main
-```
-````
-
-````{py:function} create_cmd(snapshot_id: str | None, plugin: str | None, status: str)
-:canonical: archivebox.cli.archivebox_archiveresult.create_cmd
-
-```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.create_cmd
-```
-````
-
-````{py:function} list_cmd(status: str | None, plugin: str | None, snapshot_id: str | None, limit: int | None)
-:canonical: archivebox.cli.archivebox_archiveresult.list_cmd
-
-```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.list_cmd
-```
-````
-
-````{py:function} update_cmd(status: str | None)
-:canonical: archivebox.cli.archivebox_archiveresult.update_cmd
-
-```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.update_cmd
-```
-````
-
-````{py:function} delete_cmd(yes: bool, dry_run: bool)
-:canonical: archivebox.cli.archivebox_archiveresult.delete_cmd
-
-```{autodoc2-docstring} archivebox.cli.archivebox_archiveresult.delete_cmd
-```
-````
diff --git a/docs/apidocs/archivebox/archivebox.cli.archivebox_binary.md b/docs/apidocs/archivebox/archivebox.cli.archivebox_binary.md
deleted file mode 100644
index 005a1929..00000000
--- a/docs/apidocs/archivebox/archivebox.cli.archivebox_binary.md
+++ /dev/null
@@ -1,141 +0,0 @@
-# {py:mod}`archivebox.cli.archivebox_binary`
-
-```{py:module} archivebox.cli.archivebox_binary
-```
-
-```{autodoc2-docstring} archivebox.cli.archivebox_binary
-:allowtitles:
-```
-
-## Module Contents
-
-### Functions
-
-````{list-table}
-:class: autosummary longtable
-:align: left
-
-* - {py:obj}`create_binary `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_binary.create_binary
- :summary:
- ```
-* - {py:obj}`list_binaries `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_binary.list_binaries
- :summary:
- ```
-* - {py:obj}`update_binaries `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_binary.update_binaries
- :summary:
- ```
-* - {py:obj}`delete_binaries `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_binary.delete_binaries
- :summary:
- ```
-* - {py:obj}`main `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_binary.main
- :summary:
- ```
-* - {py:obj}`create_cmd `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_binary.create_cmd
- :summary:
- ```
-* - {py:obj}`list_cmd `
- - ```{autodoc2-docstring} archivebox.cli.archivebox_binary.list_cmd
- :summary:
- ```
-* - {py:obj}`update_cmd