diff --git a/.gitignore b/.gitignore index 265a4a5..eea7407 100644 --- a/.gitignore +++ b/.gitignore @@ -100,3 +100,13 @@ ENV/ # mypy .mypy_cache/ .idea + +great-docs/ +.ruff_cache/ +.pytest_cache/ +docs/build-timings.json +uv.lock + +# Great Docs "Changelog" section, staged from CHANGELOG.md by scripts/build_docs.py +/changelog/ +.DS_Store diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..3d036b0 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,33 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Build Docs", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/scripts/build_docs.py", + "console": "integratedTerminal", + "python": "${workspaceFolder}/venv/bin/python", + "cwd": "${workspaceFolder}" + }, + { + "name": "Preview Docs", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/venv/bin/great-docs", + "args": ["preview"], + "console": "integratedTerminal", + "python": "${workspaceFolder}/venv/bin/python", + "cwd": "${workspaceFolder}" + }, + { + "name": "Preview Docs (subpath)", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/scripts/serve_docs.py", + "console": "integratedTerminal", + "python": "${workspaceFolder}/venv/bin/python", + "cwd": "${workspaceFolder}" + } + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..1e0791b --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,16 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Build Docs", + "type": "shell", + "command": "${workspaceFolder}/venv/bin/python", + "args": ["${workspaceFolder}/scripts/build_docs.py"], + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + } + ] +} diff --git a/AGENTS.md b/AGENTS.md new file mode 120000 index 0000000..681311e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1 @@ +CLAUDE.md \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..88d68fa --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,113 @@ +# Changelog + +All notable changes to **switchlang** are documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.1.3] - 2026-06-11 + +### Fixed + +- **An exception raised inside the `with` block now always aborts the switch, + even when the exception object is falsy.** `__exit__` guarded its re-raise with + `if exc_val:`, a truthiness test that invokes the exception's `__bool__`/`__len__`. + An exception whose `__bool__` returned `False` slipped past the guard, so the + matched case action ran before the exception propagated. The guard now tests + `exc_val is not None`, restoring the documented "no case actions run on + exception" guarantee for every exception type. + ([#15](https://github.com/mikeckennedy/python-switch/issues/15)) + +## [0.1.2] - 2026-06-11 + +This release brings switchlang's whole public-facing surface up to date — a +documentation site, a shipped type-hint contract, refreshed docs — and fixes +two correctness bugs in the public API +([#13](https://github.com/mikeckennedy/python-switch/issues/13), +[#14](https://github.com/mikeckennedy/python-switch/issues/14)). + +### Added + +- **Type information now ships with the package.** A `py.typed` marker makes the + hints public API, so switchlang's signatures type-check and autocomplete in + IDEs and type checkers. Every public signature is annotated — + `case() -> bool`, `__enter__() -> switch`, `__exit__(...)`, `result -> Any`, + and `closed_range(...) -> range` — using modern, Python 3.9-safe syntax + (`from __future__ import annotations`). ([#13](https://github.com/mikeckennedy/python-switch/issues/13)) +- **Documentation site** at + [mkennedy.codes/docs/python-switch](https://mkennedy.codes/docs/python-switch/), + built with [Great Docs](https://github.com/posit-dev/great-docs) (Quarto): a + landing page plus an API reference for `switch` and `closed_range`. Includes + `scripts/build_docs.py` and `scripts/serve_docs.py`. ([#13](https://github.com/mikeckennedy/python-switch/issues/13)) +- **`closed_range()` now validates its step.** A `step` less than 1 raises a + clear `ValueError` instead of surfacing a raw `range` error (for `step=0`) or + silently producing an empty range (for a negative step). ([#14](https://github.com/mikeckennedy/python-switch/issues/14)) +- `uv add switchlang` installation instructions alongside pip. ([#13](https://github.com/mikeckennedy/python-switch/issues/13)) + +### Changed + +- **Packaging modernized** to `pyproject.toml` + hatchling: the version is read + from package metadata, a `[dev]` extra is provided, Python 3.9–3.15 + classifiers and a `Typing :: Typed` classifier are declared, and full project + URLs (docs, repository, issues, PyPI, funding) are published. ([#13](https://github.com/mikeckennedy/python-switch/issues/13)) +- **`case()` now always returns `bool`.** It previously returned `None` on a + scalar no-match but `False` on a list no-match; the return value is now a + consistent `bool`. ([#13](https://github.com/mikeckennedy/python-switch/issues/13)) +- Tooling: ruff pinned to `target-version = "py39"` to match + `requires-python = ">=3.9"`. ([#13](https://github.com/mikeckennedy/python-switch/issues/13)) + +### Fixed + +- **`closed_range(start, stop, step)` no longer overshoots `stop` when + `step > 1`.** The inclusive bound was built as `range(start, stop + step, step)`, + which added a full extra step — e.g. `closed_range(1, 6, 2)` yielded + `[1, 3, 5, 7]`, letting `7` (a value outside the stated range) silently match + the case. The bound is now computed as `stop + 1`, so values never pass `stop` + while `stop` is still included when a step lands on it exactly + (`closed_range(1, 7, 2)` -> `1, 3, 5, 7`). ([#14](https://github.com/mikeckennedy/python-switch/issues/14)) +- **`.result` no longer breaks for matched cases that return an always-equal + object.** The "no result" sentinel was compared with `==`, so a returned + object with a permissive `__eq__` (a NumPy array is the real-world case) made + `.result` raise *"No result has been computed"* even though a result existed. + The sentinel is now compared by identity (`is`). ([#14](https://github.com/mikeckennedy/python-switch/issues/14)) + +### Documentation + +- **README refreshed:** version and docs badges, a prominent link to the + documentation site, an honest feature list ("Validates that case actions are + callable", replacing an inaccurate signature-verification claim), a new + `s.result` bullet, a new "Fall-through and results" section, a new "Why not + just `match`?" section, a `closed_range` usage example, and f-strings + throughout. ([#13](https://github.com/mikeckennedy/python-switch/issues/13)) +- **Docstrings rewritten to render as the API reference:** `switch` is described + as a context manager; `default()` documents that ordering is not enforced + (register it last); `case()` documents its return contract, the `ValueError`s + it raises, and the internal no-match sentinel; `result` documents that the + last function executed wins under fall-through; and `closed_range` is + documented as returning a `range` object (not a "generator") with its step + semantics and `ValueError`. ([#13](https://github.com/mikeckennedy/python-switch/issues/13)) + +## [0.1.1] - 2025-09-11 + +### Changed + +- Standardized string literals on double quotes across the codebase and added + an initial round of type annotations, including a fix for a potential type + warning on `s.result`. + +## [0.1.0] - 2020-12-10 + +### Added + +- Initial public release of switchlang on PyPI: an explicit `switch` block for + Python built on the `with` statement, with default cases, duplicate-case + detection, list/range cases, opt-in fall-through, and the `closed_range` + helper. + +[Unreleased]: https://github.com/mikeckennedy/python-switch/compare/v0.1.3...HEAD +[0.1.3]: https://github.com/mikeckennedy/python-switch/compare/v0.1.2...v0.1.3 +[0.1.2]: https://github.com/mikeckennedy/python-switch/compare/v0.1.1...v0.1.2 +[0.1.1]: https://github.com/mikeckennedy/python-switch/releases/tag/v0.1.1 +[0.1.0]: https://pypi.org/project/switchlang/0.1.0/ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..33ae259 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,210 @@ +# Agent guide: switchlang (python-switch) + +Guidance for AI agents working in this repository. `GEMINI.md` and `AGENTS.md` +are symlinks to this file — edit this one. + +## What this is + +`switchlang` adds an explicit **switch statement to Python without changing the +language**. It is implemented as a context manager: you open a `with switch(value)` +block, register cases as method calls, and read the matched case's return value +from `s.result`. The whole library is ~200 lines with **zero runtime dependencies**. + +- **Repo name** is `python-switch`; the **PyPI / import name** is `switchlang`. + Don't confuse the two — `import switchlang`, `pip install switchlang`. +- The package ships type hints and a `py.typed` marker (PEP 561). It is + `Typing :: Typed`. +- **The default git branch is `master`, not `main`.** Several tools (and + `great-docs.yml`) hard-code this. + +## Repository layout + +| Path | What it is | +|------|------------| +| [switchlang/__init__.py](switchlang/__init__.py) | Public package: re-exports `switch` and `closed_range`, sets `__version__`/`__author__`/`__all__`. | +| [switchlang/__switchlang_impl.py](switchlang/__switchlang_impl.py) | **The entire implementation** — `switch` class and `closed_range()`. Make code changes here. | +| [switchlang/py.typed](switchlang/py.typed) | PEP 561 marker so type checkers read our hints. | +| [tests/test_core.py](tests/test_core.py) | The whole test suite (29 `unittest`-style tests). | +| [pyproject.toml](pyproject.toml) | Packaging (hatchling), metadata, version, `[dev]` extra. | +| [ruff.toml](ruff.toml) | Lint + format config. | +| [great-docs.yml](great-docs.yml) | Docs site config (Great Docs / Quarto). | +| [scripts/build_docs.py](scripts/build_docs.py) | Builds docs and mirrors them into `docs/`. | +| [scripts/serve_docs.py](scripts/serve_docs.py) | Local preview that mimics the nginx subpath. | +| [docs/](docs/) | **Generated** static site (committed, served at `mkennedy.codes/docs/python-switch`). Do not hand-edit. | +| [README.md](README.md) | The narrative/marketing docs and rationale. Keep in sync with behavior. | + +Generated / ignored artifacts you should not edit or commit by hand: `docs/` +(regenerate it), `great-docs/` (ephemeral build dir, gitignored), `dist/`, +`*.egg-info/`, `venv/`. + +## The public API and its semantics + +Only two names are public (`switchlang.__all__`): **`switch`** and **`closed_range`**. + +```python +from switchlang import switch, closed_range + +with switch(value) as s: + s.case('a', process_a) # key == value -> run process_a + s.case(['v', 'b'], view_bookings) # list key: each item is a case + s.case(range(1, 6), handler) # range key: each item is a case + s.case(closed_range(1, 5), handler) # inclusive range: 1,2,3,4,5 + s.case(2, do_two, fallthrough=True) # opt into running the next case too + s.default(unknown_command) # runs if nothing else matched +print(s.result) # return value of the executed case +``` + +Behaviors that are easy to get wrong — preserve all of these (they are pinned by tests): + +- **Cases run on block exit, not at registration.** `case()`/`default()` only + *register*; the matched function(s) execute in `__exit__`. So `s.result` is only + valid *after* the `with` block. Reading it inside the block raises. +- **Matching is equality-based** (`key == value`). Keys are also stored in a `set`, + so case keys must be **hashable**. Any hashable value works as a key, including + `None` and arbitrary objects. +- **`default()` is just a case** keyed on a private sentinel, and **ordering is not + enforced**: a default registered *before* a matching case will also run. **Always + register `default()` last.** +- **`result` uses identity, not equality, against its "no result" sentinel.** A + computed result with a permissive `__eq__` (e.g. a NumPy array) must not be + mistaken for "nothing computed." `None` is a valid computed result and is + distinct from "not computed." +- **`case()` returns `bool`** — `True` if the case (or any item of a list/range + key) matched. +- **Fall-through is opt-in** per case via `fallthrough=True`; the next registered + case then runs whether or not its key matches, and so on until a case without + fall-through. When falling through, `result` is the **last** function executed. + The `fallthrough=None` value is **reserved for internal recursion** (list/range + expansion) and must not be used by callers. +- **`closed_range(start, stop, step=1)`** is inclusive on **both** ends and never + overshoots `stop`: `closed_range(1, 5)` -> `1,2,3,4,5`; `closed_range(1, 6, 2)` + -> `1,3,5`; `closed_range(1, 7, 2)` -> `1,3,5,7`. Note adjacent closed ranges + **overlap** (`closed_range(1,5)` and `closed_range(5,9)` both contain 5) and will + raise a duplicate-case error. + +Validation (all raise on registration/exit): + +- Duplicate case key -> `ValueError`. +- `func` that is `None` or not callable -> `ValueError`. +- Empty list/range key (`[]`) -> `ValueError` (it could never match). +- `closed_range` with `start >= stop` or `step < 1` -> `ValueError`. +- No case matched **and** no `default()` registered -> `Exception` on block exit. +- An **exception raised inside the `with` block** propagates and aborts the switch: + `__exit__` re-raises it before any case actions run, so **no case actions run**. + This holds for any exception (the guard is `if exc_val is not None:`, so an + exception whose `__bool__` is falsy still aborts — see *Implementation notes*). + +## Implementation notes (don't refactor naively) + +- The implementation lives in a deliberately **private module**, + `__switchlang_impl.py` (leading dunder); `__init__.py` re-exports `switch` and + `closed_range`. Import via the package (`from switchlang import ...`), never the + impl module directly. +- The `switch` class's `__no_result` and `__default` are **name-mangled class + attributes** assigned `uuid.uuid4()` at class-load time (mangled to + `_switch__no_result` / `_switch__default`) — unique, opaque sentinels. Don't + rename the class or hoist these to module level, and **keep the `result` check + identity-based** (`is`, not `==`); that identity check is what stops a result with + a permissive `__eq__` (e.g. a NumPy array) from being read as "no result." +- `__exit__` guards exception re-raise with `if exc_val is not None:` — an identity + check, **not** truthiness. This is deliberate (fixed in #15): testing + `if exc_val:` would invoke the exception's `__bool__`/`__len__`, so a falsy + exception would slip past and let the matched case run. Keep it `is not None`. + +## Development workflow + +There is a **local, gitignored** uv-managed `venv/` — it is **not** in the repo, so +on a fresh checkout it is absent (and even on the maintainer's machine its symlinks may +be broken). **Never rely on `venv/bin/python` existing**; use `uv run`, which provisions +the environment on demand. Note that the tracked [.vscode/tasks.json](.vscode/tasks.json) +and [.vscode/launch.json](.vscode/launch.json) (Build / Preview Docs) hard-code +`venv/bin/python` and `venv/bin/great-docs`, so those IDE configs only work once such a +venv exists at that path — prefer `uv run` from the CLI. + +```bash +# Run the test suite — fast path, no extra deps (tests are unittest-based): +uv run python -m unittest discover -s tests + +# Or with pytest + the full dev environment (pulls in great-docs and its deps): +uv run --extra dev pytest -q + +# Lint and format (config in ruff.toml): +uvx ruff check . +uvx ruff format . +``` + +Coding constraints — match the existing style: + +- **Python 3.9+** is supported (classifiers go through 3.15). **Do not use syntax + that breaks 3.9.** The impl uses `from __future__ import annotations` so it can + write modern annotation syntax (`set[Any]`, `X | None`) while still importing on + 3.9. Ruff's `target-version` is pinned to `py39` to enforce this. +- Ruff config: **line length 120**, **single-quoted** strings, import sorting on + (`I`), error/pyflakes rules (`E`, `F`), McCabe max complexity **10**. +- Keep the public API fully type-hinted (the package is `py.typed`). Note **no static + type checker is wired into the project** — ruff only does lint/format/import-sort + (`E`/`F`/`I`). Validate hints ad hoc if you want, e.g. `uvx mypy switchlang` or + `uvx ty check switchlang`; there is no CI gate for types. +- When you change behavior, update **all three** places that document it: + the **docstrings** in `__switchlang_impl.py` (source of the API reference), + the **README**, and the **tests**. Then rebuild the docs. + +## Versioning and release + +- The version of record is `[project].version` in [pyproject.toml](pyproject.toml) + (currently `0.1.3`). `__version__` is read at runtime from installed package + metadata via `importlib.metadata`, falling back to `'0.0.0'` when not installed. + Because it reflects *installed* metadata, after a bump you must reinstall + (`uv pip install -e .`) before `__version__` or the introspected docs show the new + number. `uv.lock` is gitignored, so there is no committed lockfile. + - **Gotcha:** a stale `switchlang.egg-info/` in the repo root (left by an old + `setup.py`-era build) shadows the venv's `*.dist-info` on `sys.path` and makes + `importlib.metadata` report an old version no matter what you reinstall. If + `__version__` looks wrong, `rm -rf switchlang.egg-info` (it's gitignored). +- To cut a release: bump `[project].version`, rename `## [Unreleased]` in + `CHANGELOG.md` to `## [X.Y.Z] - ` (add a fresh empty `[Unreleased]` and a + new compare-link line in the footer), reinstall, then rebuild docs. The docs + **version badge** comes from PyPI (`pypi: true`), so it shows the latest + *published* release and only updates to the new version after you publish to PyPI + and rebuild — it legitimately lags during a release. +- Build backend is **hatchling**; the wheel packages the `switchlang/` directory. +- The changelog is **hand-maintained** in the repo-root [CHANGELOG.md](CHANGELOG.md) + ([Keep a Changelog](https://keepachangelog.com/) format). Record every + user-facing change there under the `## [Unreleased]` heading; on release, rename + that heading to the new version. The docs site renders this file — + `scripts/build_docs.py` stages `CHANGELOG.md` into `changelog/index.qmd` before + each build (configured in `great-docs.yml`), so the generated `docs/changelog/` + output is **not** a source you edit. + +## Documentation pipeline + +Docs are built with **Great Docs** (Quarto) and **dynamically introspect** the +installed package, so the docstrings in `__switchlang_impl.py` are the real source +of the API reference. The flow: + +1. `scripts/build_docs.py` runs `great-docs build` (output -> `great-docs/_site`, + which is ephemeral/gitignored) and **mirrors it into the committed `docs/` + folder** (full replace, so deleted pages don't linger). +2. `scripts/serve_docs.py` serves `docs/` locally on port **8099** under the + `/docs/python-switch` subpath to mirror production nginx and catch + absolute-path asset bugs. +3. Production serves the committed `docs/` at `https://mkennedy.codes/docs/python-switch/`. + +`great-docs.yml` has documented gotchas (subpath `site_url` needs a trailing +slash; SEO `canonical.base_url` must be set explicitly or the sitemap points at +the wrong domain; `mcp.enabled` is disabled; `source.branch` is `master`). The +generated site also includes agent-skill descriptors under +[docs/.well-known/](docs/.well-known/) and `llms.txt`/`llms-full.txt` — these are +**build output** (produced from the docstrings and `great-docs.yml`), so edit the +sources and rebuild rather than hand-editing them. + +## Quick checklist for a typical change + +1. Edit [switchlang/__switchlang_impl.py](switchlang/__switchlang_impl.py). +2. Update/extend [tests/test_core.py](tests/test_core.py) and run + `uv run python -m unittest discover -s tests`. +3. Keep docstrings + [README.md](README.md) in sync with the new behavior. +4. Add a `## [Unreleased]` entry to [CHANGELOG.md](CHANGELOG.md) for any user-facing change. +5. `uvx ruff format . && uvx ruff check .` +6. If docs-visible, rebuild: `uv run --extra dev python scripts/build_docs.py`. +7. Bump `[project].version` in [pyproject.toml](pyproject.toml) if releasing. diff --git a/GEMINI.md b/GEMINI.md new file mode 120000 index 0000000..681311e --- /dev/null +++ b/GEMINI.md @@ -0,0 +1 @@ +CLAUDE.md \ No newline at end of file diff --git a/README.md b/README.md index c74f30f..602dc92 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,65 @@ -# python-switch +# switchlang +[![](https://img.shields.io/pypi/v/switchlang.svg)](https://pypi.org/project/switchlang/) +[![](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/) +[![](https://img.shields.io/badge/docs-mkennedy.codes-brightgreen.svg)](https://mkennedy.codes/docs/python-switch/) +[![](https://img.shields.io/pypi/l/switchlang.svg)](https://github.com/mikeckennedy/python-switch/blob/master/LICENSE) +[![](https://img.shields.io/pypi/dm/switchlang.svg)](https://pypi.org/project/switchlang/) -Adds switch blocks to Python. -This module adds explicit switch functionality to Python +Adds switch blocks to the Python language. + +This module adds explicit switch functionality to Python without changing the language. It builds upon a standard way to define execution blocks: the `with` statement. +Full documentation, including the API reference, lives at +**[mkennedy.codes/docs/python-switch](https://mkennedy.codes/docs/python-switch/)**. + ## Example ```python from switchlang import switch -num = 7 -val = input("Enter a key. a, b, c or any other: ") +def main(): + num = 7 + val = input("Enter a character, a, b, c or any other: ") + + with switch(val) as s: + s.case('a', process_a) + s.case('b', lambda: process_with_data(val, num, 'other values still')) + s.default(process_any) -with switch(val) as s: - s.case('a', process_a) - s.case('b', lambda: process_with_data(val, num, 'other values still')) - s.default(process_any) - def process_a(): print("Found A!") - + def process_any(): print("Found Default!") - + def process_with_data(*value): - print("Found with data: {}".format(value)) -``` + print(f"Found with data: {value}") + +main() +``` + +## Installation + +Simply install via pip or uv: + +```bash +pip install switchlang +# or +uv add switchlang +``` ## Features * More explicit than using dictionaries with functions as values. -* Verifies the signatures of the methods +* Validates that case actions are callable * Supports default case * Checks for duplicate keys / cases * Keys can be anything hashable (numbers, strings, objects, etc.) -* Could be extended for "fall-through" cases (doesn't yet) +* Capture the return value of the matched case with `s.result` +* Supports "fall-through" cases (opt-in with `fallthrough=True`) * Use range and list for multiple cases mapped to a single action ## Multiple cases, one action @@ -65,12 +88,41 @@ with switch(value) as s: ## Closed vs. Open ranges -Looking at the above code it's a bit weird that 6 appears +Looking at the above code it's a bit weird that 6 appears at the end of one case, beginning of the next. But `range()` is -half open/closed. +half open/closed. To handle the inclusive case, I've added `closed_range(start, stop)`. -For example, `closed_range(1,5)` -> `[1,2,3,4,5]` +For example, `closed_range(1, 5)` -> `[1, 2, 3, 4, 5]`: + +```python +from switchlang import switch, closed_range + +with switch(value) as s: + s.case(closed_range(1, 5), lambda: 'one to five') # matches 1, 2, 3, 4, 5 + s.case(closed_range(6, 9), lambda: 'six to nine') # matches 6, 7, 8, 9 + s.default(lambda: 'something else') +``` + +## Fall-through and results + +Cases don't fall through by default. Opt in per case with `fallthrough=True` +and the next case runs too, whether or not its key matches: + +```python +value = 2 + +with switch(value) as s: + s.case(1, lambda: 'one') + s.case(2, lambda: 'two', fallthrough=True) + s.case(3, lambda: 'three') # runs as well, then stops here + s.default(lambda: 'other') + +print(s.result) # 'three' +``` + +Whatever the executed case's function returns is available after the block +as `s.result`. When cases fall through, the last function executed wins. ## Why not just raw `dict`? @@ -84,10 +136,10 @@ switch = { 3: method_three } -result = switch.get(value, defult_method_to_run)() +result = switch.get(value, default_method_to_run)() ``` -This works but is very low on the functionality level. We have a better solution here +This works but is very low on the functionality level. We have a better solution here I believe. Let's take this example and see how it looks in python-switch vs raw dicts: ```python @@ -104,13 +156,13 @@ while True: s.case(['v', 'b'], view_bookings) s.case('x', exit_app) s.case('', lambda: None) - s.case(range(1,6), lambda: set_level(action)) + s.case(range(1, 6), lambda: set_level(action)) s.default(unknown_command) - - result = s.result + + print(f'Result is {s.result}') ``` -Now compare that to they espoused *pythonic* way: +Now compare that to the espoused *pythonic* way: ```python # with raw dicts @@ -135,7 +187,93 @@ while True: '': lambda: None, } result = switch.get(action, unknown_command)() + print(f'Result is {result}') ``` Personally, I much prefer to read and write the one above. That's why I wrote this module. -It seems to convey the intent of switch way more than the dict. But either are options. +It seems to convey the intent of switch way more than the dict. But both are options. + +## Why not just `if / elif / else`? + +Another push back on this idea is that we already have this problem solved. +Switch statements are really if / elif / else blocks. So you write the following code. + +```python +# with if / elif / else + +while True: + action = get_action(action) + + if action == 'c' or action == 'a': + result = create_account() + elif action == 'l': + result = log_into_account() + elif action == 'r': + result = register_cage() + elif action == 'a': + result = update_availability() + elif action == 'v' or action == 'b': + result = view_bookings() + elif action == 'x': + result = exit_app() + elif action in {1, 2, 3, 4, 5}: + result = set_level(action) + else: + unknown_command() + + print(f'Result is {result}') +``` + +I actually believe this is a little better than the +[raw dict option](https://github.com/mikeckennedy/python-switch#why-not-just-raw-dict). +But there are still things that are harder. + +* How would you deal with fall-through cleanly? +* Did you notice the bug? We forgot to set result in default case (`else`) and will result in a runtime error (but only if that case hits). +* There is another bug. `update_availability` will never run because its command (`a`) is bound to two cases. +This is guarded against in switch and you would receive a duplicate case error the first time it runs at all. +* While it's pretty clear, it's much more verbose and less declarative than the switch version. + +Again, compare the if / elif / else to what you have with switch. This code is identical except +doesn't have the default case bug. + +```python +while True: + action = get_action(action) + + with switch(action) as s: + s.case(['c', 'a'], create_account) + s.case('l', log_into_account) + s.case('r', register_cage) + s.case('u', update_availability) + s.case(['v', 'b'], view_bookings) + s.case('x', exit_app) + s.case('', lambda: None) + s.case(range(1, 6), lambda: set_level(action)) + s.default(unknown_command) + + print(f'Result is {s.result}') +``` + +## Why not just `match`? + +Python 3.10 added structural pattern matching, and it's genuinely great at what +it was built for: destructuring data by shape (tuples, dataclasses, nested +structures, and so on). But it covers different ground than a classic switch +statement: + +* **No fall-through.** `match` arms are exclusive. With switchlang, fall-through +is opt-in per case with `fallthrough=True`. +* **Cases are fixed syntax.** You can't build `match` arms from data at runtime, +while `s.case(some_list, action)` and `s.case(closed_range(1, 5), action)` are +plain method calls. Also watch out: a bare name in a `case` pattern *captures* +the value rather than comparing against a constant — a classic `match` gotcha +that can't happen here. +* **No result capture.** `match` arms are blocks of statements. switchlang +dispatches to callables and hands back the chosen case's return value as +`s.result`. +* **Python version.** `match` needs Python 3.10+, while switchlang supports 3.9+. + +If you're pattern-matching on the shape of objects, use `match` — that's what +it's for. If you want explicit value-based dispatch with fall-through, ranges, +and a captured result, that's switchlang. diff --git a/docs/.well-known/agent-skills/index.json b/docs/.well-known/agent-skills/index.json new file mode 100644 index 0000000..7b1de61 --- /dev/null +++ b/docs/.well-known/agent-skills/index.json @@ -0,0 +1,11 @@ +{ + "skills": [ + { + "name": "switchlang", + "description": "Adds switch blocks to the Python language. Use when writing Python code that uses the switchlang package.", + "files": [ + "SKILL.md" + ] + } + ] +} diff --git a/docs/.well-known/agent-skills/switchlang/SKILL.md b/docs/.well-known/agent-skills/switchlang/SKILL.md new file mode 100644 index 0000000..107bf8b --- /dev/null +++ b/docs/.well-known/agent-skills/switchlang/SKILL.md @@ -0,0 +1,126 @@ +--- +name: switchlang +description: > + Adds switch blocks to the Python language. Use when writing Python code that uses the switchlang package. +license: MIT +compatibility: Requires Python >=3.9. +--- + +# switchlang + +Adds switch blocks to the Python language. + +## Installation + +```bash +pip install switchlang +``` + +## When to use what + +| Need | Use | +|------|-----| +| Map several discrete values to one action | `s.case(['c', 'a'], func) — list keys expand to one case per item` | +| Match an inclusive numeric span | `s.case(closed_range(1, 5), func)` | +| Run the next case too (fall-through) | `s.case(key, func, fallthrough=True)` | +| Get the matched case's return value | `s.result, after the with block exits` | +| Handle 'nothing matched' | `s.default(func), registered last` | +| Match a key but do nothing | `s.case(key, lambda: None)` | + +## API overview + +### The switch block + +The context manager that gives Python an explicit switch statement. Use it in a `with` block, register cases, then read `result`. + + +- `switch`: An explicit switch statement for Python, implemented as a context manager + +### Range helpers + +Helpers for mapping ranges of values to a single case. + + +- `closed_range`: Create a closed range for a case: both `start` and `stop` are included + +## Gotchas + +1. Cases execute on block exit, not at registration: case()/default() only register; the matched function runs in __exit__, and s.result is only readable after the with block (reading it inside raises). +2. Case functions take no parameters — bind arguments with a lambda: s.case('b', lambda: process(val)). Passing process(val) calls it immediately and registers its return value. +3. default() ordering is not enforced: a default registered before a matching case runs as well. Always register default() last. +4. Adjacent closed_range cases overlap (closed_range(1, 5) and closed_range(5, 9) both contain 5) and raise a duplicate-case ValueError — follow closed_range(1, 5) with closed_range(6, 9). +5. Keys are matched with == and stored in a set: they must be hashable, and equal-comparing keys (1 and True, 1 and 1.0) are duplicates. +6. If no case matches and no default() is registered, the block raises Exception on exit. +7. An exception raised inside the with block aborts the switch — it is re-raised and no case actions run. +8. fallthrough=None is reserved for internal use — pass only True or False. + +## Best practices + +- Register default() as the last statement in every switch block. +- Read s.result only after the with block exits; capture per-case data via lambdas or closures. +- Use closed_range(start, stop) for inclusive numeric spans and plain range() for half-open ones. +- Import from the package — from switchlang import switch, closed_range — never from the private __switchlang_impl module. + +## End-to-end wiring + +A complete, minimal switch — registration inside the `with` block, execution at block exit, result read after: + +```python +from switchlang import switch, closed_range + +action = get_action() + +with switch(action) as s: + s.case(['c', 'a'], create_account) # several keys -> one action + s.case('l', log_into_account) + s.case('', lambda: None) # explicit "do nothing" case + s.case(closed_range(1, 5), lambda: set_level(action)) # inclusive 1..5 + s.default(unknown_command) # ALWAYS register last + +print(s.result) # return value of whichever case ran — only valid here, after the block +``` + +## The execution model (this is what code generators get wrong) + +`case()` and `default()` only **register** cases — nothing executes at those lines. The matched function (and any fall-through functions) run inside `__exit__` as the `with` block closes. Three consequences: + +- Case functions take **zero parameters**. Bind data with a lambda or closure: `s.case('b', lambda: process(val, num))` — never `s.case('b', process(val, num))`, which would call the function immediately and register its return value. +- `s.result` is only readable **after** the block; reading it inside raises even when the case has already been registered and matched. +- Registration errors (duplicate key, non-callable action, empty list/range) raise at the `s.case(...)` line, but the "no case matched and no default" error raises at the block's closing line. + +## Fall-through, from the usage side + +Fall-through is opt-in per case. The next registered case then runs **whether or not its key matches**, continuing until a case without `fallthrough=True`. The last function executed supplies `result`: + +```python +value = 2 +with switch(value) as s: + s.case(1, lambda: 'one') + s.case(2, lambda: 'two', fallthrough=True) + s.case(3, lambda: 'three') # runs too (its key is never compared), then the chain stops + s.default(lambda: 'other') + +s.result # 'three' +``` + +Pass only `True` or `False` — `fallthrough=None` is reserved for the library's internal list/range expansion. + +## Keys: equality, hashability, ranges + +Matching is plain `key == value`, and keys are stored in a `set`, so every key must be hashable and keys that compare equal are duplicates (`1` and `True`, `1` and `1.0` collide). A `list` or `range` key is expanded so each item becomes its own case for the same function. `closed_range(start, stop)` is inclusive on **both** ends — and because of that, adjacent closed ranges share their endpoint and raise the duplicate-case error: use `closed_range(1, 5)` with `closed_range(6, 9)`, not `closed_range(5, 9)`. + +## When to reach for this vs `match` + +`match` (3.10+) destructures by *shape*; `switchlang` dispatches on *values*. Prefer `switchlang` when you need opt-in fall-through, case lists built at runtime (`s.case(some_list, action)`), a captured return value (`s.result`), or Python 3.9 support. Prefer `match` for structural pattern matching on tuples/dataclasses/nested data. Remember: `import switchlang`, `pip install switchlang` — the repo name `python-switch` is not the import name. + +## Fetching the docs as Markdown + +Every page on the documentation site has a plain-Markdown twin: swap the `.html` extension for `.md` to get token-efficient source without the site chrome. For example https://mkennedy.codes/docs/python-switch/reference/switch.html is also available at https://mkennedy.codes/docs/python-switch/reference/switch.md. Prefer the `.md` form when reading these docs programmatically. + + +## Resources + +- [Full documentation](https://mkennedy.codes/docs/python-switch/) +- [llms.txt](llms.txt) — Indexed API reference for LLMs +- [llms-full.txt](llms-full.txt) — Comprehensive documentation for LLMs +- [Source code](https://github.com/mikeckennedy/python-switch) diff --git a/docs/.well-known/skills/default/SKILL.md b/docs/.well-known/skills/default/SKILL.md new file mode 100644 index 0000000..107bf8b --- /dev/null +++ b/docs/.well-known/skills/default/SKILL.md @@ -0,0 +1,126 @@ +--- +name: switchlang +description: > + Adds switch blocks to the Python language. Use when writing Python code that uses the switchlang package. +license: MIT +compatibility: Requires Python >=3.9. +--- + +# switchlang + +Adds switch blocks to the Python language. + +## Installation + +```bash +pip install switchlang +``` + +## When to use what + +| Need | Use | +|------|-----| +| Map several discrete values to one action | `s.case(['c', 'a'], func) — list keys expand to one case per item` | +| Match an inclusive numeric span | `s.case(closed_range(1, 5), func)` | +| Run the next case too (fall-through) | `s.case(key, func, fallthrough=True)` | +| Get the matched case's return value | `s.result, after the with block exits` | +| Handle 'nothing matched' | `s.default(func), registered last` | +| Match a key but do nothing | `s.case(key, lambda: None)` | + +## API overview + +### The switch block + +The context manager that gives Python an explicit switch statement. Use it in a `with` block, register cases, then read `result`. + + +- `switch`: An explicit switch statement for Python, implemented as a context manager + +### Range helpers + +Helpers for mapping ranges of values to a single case. + + +- `closed_range`: Create a closed range for a case: both `start` and `stop` are included + +## Gotchas + +1. Cases execute on block exit, not at registration: case()/default() only register; the matched function runs in __exit__, and s.result is only readable after the with block (reading it inside raises). +2. Case functions take no parameters — bind arguments with a lambda: s.case('b', lambda: process(val)). Passing process(val) calls it immediately and registers its return value. +3. default() ordering is not enforced: a default registered before a matching case runs as well. Always register default() last. +4. Adjacent closed_range cases overlap (closed_range(1, 5) and closed_range(5, 9) both contain 5) and raise a duplicate-case ValueError — follow closed_range(1, 5) with closed_range(6, 9). +5. Keys are matched with == and stored in a set: they must be hashable, and equal-comparing keys (1 and True, 1 and 1.0) are duplicates. +6. If no case matches and no default() is registered, the block raises Exception on exit. +7. An exception raised inside the with block aborts the switch — it is re-raised and no case actions run. +8. fallthrough=None is reserved for internal use — pass only True or False. + +## Best practices + +- Register default() as the last statement in every switch block. +- Read s.result only after the with block exits; capture per-case data via lambdas or closures. +- Use closed_range(start, stop) for inclusive numeric spans and plain range() for half-open ones. +- Import from the package — from switchlang import switch, closed_range — never from the private __switchlang_impl module. + +## End-to-end wiring + +A complete, minimal switch — registration inside the `with` block, execution at block exit, result read after: + +```python +from switchlang import switch, closed_range + +action = get_action() + +with switch(action) as s: + s.case(['c', 'a'], create_account) # several keys -> one action + s.case('l', log_into_account) + s.case('', lambda: None) # explicit "do nothing" case + s.case(closed_range(1, 5), lambda: set_level(action)) # inclusive 1..5 + s.default(unknown_command) # ALWAYS register last + +print(s.result) # return value of whichever case ran — only valid here, after the block +``` + +## The execution model (this is what code generators get wrong) + +`case()` and `default()` only **register** cases — nothing executes at those lines. The matched function (and any fall-through functions) run inside `__exit__` as the `with` block closes. Three consequences: + +- Case functions take **zero parameters**. Bind data with a lambda or closure: `s.case('b', lambda: process(val, num))` — never `s.case('b', process(val, num))`, which would call the function immediately and register its return value. +- `s.result` is only readable **after** the block; reading it inside raises even when the case has already been registered and matched. +- Registration errors (duplicate key, non-callable action, empty list/range) raise at the `s.case(...)` line, but the "no case matched and no default" error raises at the block's closing line. + +## Fall-through, from the usage side + +Fall-through is opt-in per case. The next registered case then runs **whether or not its key matches**, continuing until a case without `fallthrough=True`. The last function executed supplies `result`: + +```python +value = 2 +with switch(value) as s: + s.case(1, lambda: 'one') + s.case(2, lambda: 'two', fallthrough=True) + s.case(3, lambda: 'three') # runs too (its key is never compared), then the chain stops + s.default(lambda: 'other') + +s.result # 'three' +``` + +Pass only `True` or `False` — `fallthrough=None` is reserved for the library's internal list/range expansion. + +## Keys: equality, hashability, ranges + +Matching is plain `key == value`, and keys are stored in a `set`, so every key must be hashable and keys that compare equal are duplicates (`1` and `True`, `1` and `1.0` collide). A `list` or `range` key is expanded so each item becomes its own case for the same function. `closed_range(start, stop)` is inclusive on **both** ends — and because of that, adjacent closed ranges share their endpoint and raise the duplicate-case error: use `closed_range(1, 5)` with `closed_range(6, 9)`, not `closed_range(5, 9)`. + +## When to reach for this vs `match` + +`match` (3.10+) destructures by *shape*; `switchlang` dispatches on *values*. Prefer `switchlang` when you need opt-in fall-through, case lists built at runtime (`s.case(some_list, action)`), a captured return value (`s.result`), or Python 3.9 support. Prefer `match` for structural pattern matching on tuples/dataclasses/nested data. Remember: `import switchlang`, `pip install switchlang` — the repo name `python-switch` is not the import name. + +## Fetching the docs as Markdown + +Every page on the documentation site has a plain-Markdown twin: swap the `.html` extension for `.md` to get token-efficient source without the site chrome. For example https://mkennedy.codes/docs/python-switch/reference/switch.html is also available at https://mkennedy.codes/docs/python-switch/reference/switch.md. Prefer the `.md` form when reading these docs programmatically. + + +## Resources + +- [Full documentation](https://mkennedy.codes/docs/python-switch/) +- [llms.txt](llms.txt) — Indexed API reference for LLMs +- [llms-full.txt](llms-full.txt) — Comprehensive documentation for LLMs +- [Source code](https://github.com/mikeckennedy/python-switch) diff --git a/docs/JetBrainsMono-Bold.subset.woff2 b/docs/JetBrainsMono-Bold.subset.woff2 new file mode 100644 index 0000000..aa9ad55 Binary files /dev/null and b/docs/JetBrainsMono-Bold.subset.woff2 differ diff --git a/docs/JetBrainsMono-Regular.subset.woff2 b/docs/JetBrainsMono-Regular.subset.woff2 new file mode 100644 index 0000000..901b8bb Binary files /dev/null and b/docs/JetBrainsMono-Regular.subset.woff2 differ diff --git a/docs/_extensions/gd-lightbox/gd-lightbox-annotate.css b/docs/_extensions/gd-lightbox/gd-lightbox-annotate.css new file mode 100644 index 0000000..99c5c0a --- /dev/null +++ b/docs/_extensions/gd-lightbox/gd-lightbox-annotate.css @@ -0,0 +1,180 @@ +/* GD Lightbox Annotate — Marker & Tooltip Styles */ + +.gd-annotate-overlay { + position: absolute; + inset: 0; + pointer-events: none; + z-index: 5; +} + +/* ── Marker ─────────────────────────────────────────────────────────────── */ + +.gd-annotate-marker { + --gd-annotate-marker-bg: var(--bs-primary, #0d6efd); + --gd-annotate-marker-size: 28px; + + position: absolute; + transform: translate(-50%, -50%); + width: var(--gd-annotate-marker-size); + height: var(--gd-annotate-marker-size); + border-radius: 50%; + background: var(--gd-annotate-marker-bg); + border: 2px solid #fff; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); + cursor: pointer; + pointer-events: auto; + display: flex; + align-items: center; + justify-content: center; + padding: 0; + transition: transform 0.15s ease, box-shadow 0.15s ease; + z-index: 6; +} + +.gd-annotate-marker:hover { + transform: translate(-50%, -50%) scale(1.15); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); +} + +/* Lift the active/hovered marker's whole stacking context above the other + markers so its tooltip is never painted behind a neighbouring marker. + (The tooltip is a child of the marker, so raising the marker raises it.) */ +.gd-annotate-marker:hover, +.gd-annotate-marker.gd-annotate-active { + z-index: 30; +} + +.gd-annotate-marker:focus-visible { + outline: 3px solid var(--bs-primary, #0d6efd); + outline-offset: 3px; +} + +.gd-annotate-marker-label { + color: #fff; + font-size: 12px; + font-weight: 700; + font-family: system-ui, -apple-system, sans-serif; + line-height: 1; + user-select: none; +} + +/* ── Pulse animation (shown on first view) ──────────────────────────────── */ + +.gd-annotate-pulse::after { + content: ""; + position: absolute; + inset: -4px; + border-radius: 50%; + border: 2px solid var(--gd-annotate-marker-bg); + animation: gd-annotate-pulse 2s ease-out infinite; + pointer-events: none; +} + +@keyframes gd-annotate-pulse { + 0% { + transform: scale(1); + opacity: 0.8; + } + 70% { + transform: scale(1.6); + opacity: 0; + } + 100% { + transform: scale(1.6); + opacity: 0; + } +} + +/* ── Tooltip ────────────────────────────────────────────────────────────── */ + +.gd-annotate-tooltip { + position: absolute; + left: 50%; + transform: translateX(-50%); + width: max-content; + max-width: 240px; + padding: 8px 12px; + background: var(--bs-body-bg, #fff); + color: var(--bs-body-color, #212529); + border: 1px solid var(--bs-border-color, #dee2e6); + border-radius: 6px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); + font-size: 13px; + line-height: 1.4; + font-family: system-ui, -apple-system, sans-serif; + pointer-events: none; + opacity: 0; + visibility: hidden; + transition: opacity 0.15s ease, visibility 0.15s ease; + z-index: 10; + white-space: normal; +} + +/* Position variants */ +.gd-annotate-tooltip--above { + bottom: calc(100% + 10px); + top: auto; +} + +.gd-annotate-tooltip--below { + top: calc(100% + 10px); + bottom: auto; +} + +.gd-annotate-tooltip--left { + left: auto; + right: 0; + transform: none; +} + +.gd-annotate-tooltip--right { + left: 0; + right: auto; + transform: none; +} + +/* Show tooltip states */ +.gd-annotate-active .gd-annotate-tooltip, +.gd-annotate-tooltip--hover { + opacity: 1; + visibility: visible; + pointer-events: auto; +} + +.gd-annotate-tooltip-label { + display: block; + margin-bottom: 2px; + color: var(--bs-primary, #0d6efd); +} + +.gd-annotate-tooltip-text { + display: block; +} + +/* ── Dark mode ──────────────────────────────────────────────────────────── */ + +[data-bs-theme="dark"] .gd-annotate-marker { + border-color: rgba(255, 255, 255, 0.8); +} + +[data-bs-theme="dark"] .gd-annotate-tooltip { + background: var(--bs-body-bg, #212529); + border-color: var(--bs-border-color, #495057); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4); +} + +/* ── Reduced motion ─────────────────────────────────────────────────────── */ + +@media (prefers-reduced-motion: reduce) { + .gd-annotate-pulse::after { + animation: none; + } + + .gd-annotate-marker { + transition: none; + } + + .gd-annotate-tooltip { + transition: none; + } +} diff --git a/docs/_extensions/gd-lightbox/gd-lightbox-annotate.js b/docs/_extensions/gd-lightbox/gd-lightbox-annotate.js new file mode 100644 index 0000000..ee6bb4d --- /dev/null +++ b/docs/_extensions/gd-lightbox/gd-lightbox-annotate.js @@ -0,0 +1,225 @@ +/** + * GD Lightbox Annotate — Image Annotation Markers & Tooltips + * + * Reads JSON annotations from data-gd-lightbox-annotations attributes and + * renders numbered markers over the image with hover/click tooltips. + * + * Annotation JSON schema: + * [{ "x": 20, "y": 15, "label": "1", "text": "Description" }, ...] + * - x, y: percentage position (0-100) relative to image bounds + * - label: short text shown inside the marker circle (e.g., "1", "A") + * - text: tooltip description shown on hover/click + * - color (optional): marker color override + * + * No dependencies. ~4KB minified+gzipped target. + */ +(function () { + "use strict"; + + var PREFIX = "gd-annotate"; + var ATTR = "data-gd-lightbox-annotations"; + + function initAll() { + var wrappers = document.querySelectorAll("[" + ATTR + "]"); + for (var i = 0; i < wrappers.length; i++) { + initWrapper(wrappers[i]); + } + } + + /** + * Parse a raw annotations attribute value into an array, or null if it is + * absent / invalid / empty. + */ + function parse(raw) { + if (!raw) return null; + try { + var annotations = JSON.parse(raw); + return Array.isArray(annotations) && annotations.length ? annotations : null; + } catch (e) { + // Not valid JSON — could be a file path (future: fetch) + return null; + } + } + + function initWrapper(wrapper) { + if (wrapper.dataset.gdAnnotateInit) return; + wrapper.dataset.gdAnnotateInit = "true"; + + var annotations = parse(wrapper.getAttribute(ATTR)); + if (!annotations) return; + + wrapper.style.position = "relative"; + var overlay = buildOverlay(annotations); + wrapper.appendChild(overlay); + + // Close tooltips when clicking outside the wrapper + document.addEventListener("click", function (e) { + if (!wrapper.contains(e.target)) { + closeAll(overlay); + } + }); + } + + /** + * Build a `.gd-annotate-overlay` element populated with markers and tooltips + * for the given annotations array, with all interactions wired up. The + * overlay is `position:absolute; inset:0`, so the caller is responsible for + * sizing/positioning its container to match the target image. Edge-aware + * tooltip placement uses the overlay's own bounds. + * + * Reused by both the in-page annotator and the lightbox view. + * @param {Array} annotations + * @returns {HTMLElement} the overlay element + */ + function buildOverlay(annotations) { + var overlay = document.createElement("div"); + overlay.className = PREFIX + "-overlay"; + + annotations.forEach(function (ann, idx) { + var x = parseFloat(ann.x) || 0; + var y = parseFloat(ann.y) || 0; + var label = ann.label || String(idx + 1); + var text = ann.text || ""; + var color = ann.color || null; + + // Marker element + var marker = document.createElement("button"); + marker.className = PREFIX + "-marker"; + marker.setAttribute("aria-label", "Annotation " + label + ": " + text); + marker.setAttribute("aria-expanded", "false"); + marker.setAttribute("type", "button"); + marker.style.left = x + "%"; + marker.style.top = y + "%"; + if (color) { + marker.style.setProperty("--gd-annotate-marker-bg", color); + } + + // Label inside marker + var labelSpan = document.createElement("span"); + labelSpan.className = PREFIX + "-marker-label"; + labelSpan.textContent = label; + marker.appendChild(labelSpan); + + // Pulse animation class (removed after first interaction) + marker.classList.add(PREFIX + "-pulse"); + + // Tooltip + var tooltip = document.createElement("div"); + tooltip.className = PREFIX + "-tooltip"; + tooltip.setAttribute("role", "tooltip"); + tooltip.setAttribute("id", PREFIX + "-tip-" + idx + "-" + Date.now()); + marker.setAttribute("aria-describedby", tooltip.id); + + var tipLabel = document.createElement("strong"); + tipLabel.className = PREFIX + "-tooltip-label"; + tipLabel.textContent = label; + tooltip.appendChild(tipLabel); + + if (text) { + var tipText = document.createElement("span"); + tipText.className = PREFIX + "-tooltip-text"; + tipText.textContent = text; + tooltip.appendChild(tipText); + } + + marker.appendChild(tooltip); + overlay.appendChild(marker); + + // Interaction: toggle tooltip on click/Enter + marker.addEventListener("click", function (e) { + e.stopPropagation(); + var isActive = marker.classList.contains(PREFIX + "-active"); + closeAll(overlay); + if (!isActive) { + marker.classList.add(PREFIX + "-active"); + marker.setAttribute("aria-expanded", "true"); + marker.classList.remove(PREFIX + "-pulse"); + positionTooltip(marker, tooltip, overlay); + } + }); + + // Show on hover (desktop) + marker.addEventListener("mouseenter", function () { + marker.classList.remove(PREFIX + "-pulse"); + if (!marker.classList.contains(PREFIX + "-active")) { + tooltip.classList.add(PREFIX + "-tooltip--hover"); + positionTooltip(marker, tooltip, overlay); + } + }); + + marker.addEventListener("mouseleave", function () { + tooltip.classList.remove(PREFIX + "-tooltip--hover"); + }); + + // Keyboard: Enter/Space toggles, Escape closes + marker.addEventListener("keydown", function (e) { + if (e.key === "Escape") { + closeAll(overlay); + e.preventDefault(); + } + }); + }); + + return overlay; + } + + function closeAll(overlay) { + var active = overlay.querySelectorAll("." + PREFIX + "-active"); + for (var i = 0; i < active.length; i++) { + active[i].classList.remove(PREFIX + "-active"); + active[i].setAttribute("aria-expanded", "false"); + } + } + + /** + * Position tooltip so it doesn't overflow the bounds element. + * Prefers showing above the marker; falls back to below. + */ + function positionTooltip(marker, tooltip, bounds) { + // Reset positioning classes + tooltip.classList.remove( + PREFIX + "-tooltip--above", + PREFIX + "-tooltip--below", + PREFIX + "-tooltip--left", + PREFIX + "-tooltip--right" + ); + + var boundsRect = bounds.getBoundingClientRect(); + var markerRect = marker.getBoundingClientRect(); + var markerCenterX = markerRect.left + markerRect.width / 2 - boundsRect.left; + var markerTop = markerRect.top - boundsRect.top; + + // Default: above + if (markerTop > 80) { + tooltip.classList.add(PREFIX + "-tooltip--above"); + } else { + tooltip.classList.add(PREFIX + "-tooltip--below"); + } + + // Horizontal: center, but shift if near edges + var boundsWidth = boundsRect.width; + if (markerCenterX < boundsWidth * 0.25) { + tooltip.classList.add(PREFIX + "-tooltip--right"); + } else if (markerCenterX > boundsWidth * 0.75) { + tooltip.classList.add(PREFIX + "-tooltip--left"); + } + } + + // Init on DOM ready + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", initAll); + } else { + initAll(); + } + + // Re-init after Quarto navigation (for SPA-like navigation) + document.addEventListener("quarto-nav", initAll); + + // Public API — consumed by the lightbox to render the same annotation + // markers/tooltips over the enlarged image. + window.GDAnnotate = { + parse: parse, + buildOverlay: buildOverlay, + closeAll: closeAll, + }; +})(); diff --git a/docs/_extensions/gd-lightbox/gd-lightbox-compare.css b/docs/_extensions/gd-lightbox/gd-lightbox-compare.css new file mode 100644 index 0000000..c8d5a05 --- /dev/null +++ b/docs/_extensions/gd-lightbox/gd-lightbox-compare.css @@ -0,0 +1,170 @@ +/* GD Lightbox Compare — Before/After Slider Styles */ + +.gd-compare { + --gd-compare-divider-width: 3px; + --gd-compare-divider-color: #fff; + --gd-compare-handle-size: 40px; + --gd-compare-label-bg: rgba(0, 0, 0, 0.6); + --gd-compare-label-color: #fff; + --gd-compare-radius: 8px; + + position: relative; + overflow: hidden; + border-radius: var(--gd-compare-radius); + cursor: ew-resize; + user-select: none; + -webkit-user-select: none; + line-height: 0; + max-width: 100%; +} + +.gd-compare--vertical { + cursor: ns-resize; +} + +/* Both layers fill the container */ +.gd-compare__before, +.gd-compare__after { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.gd-compare__after { + z-index: 1; +} + +.gd-compare__before { + z-index: 2; +} + +.gd-compare__before img, +.gd-compare__after img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; +} + +/* Make container size from the after (bottom) image */ +.gd-compare__after { + position: relative; +} + +/* Divider line */ +.gd-compare__divider { + position: absolute; + z-index: 3; + display: flex; + align-items: center; + justify-content: center; +} + +.gd-compare--horizontal .gd-compare__divider { + top: 0; + bottom: 0; + width: var(--gd-compare-divider-width); + background: var(--gd-compare-divider-color); + transform: translateX(-50%); + box-shadow: 0 0 6px rgba(0, 0, 0, 0.3); +} + +.gd-compare--vertical .gd-compare__divider { + left: 0; + right: 0; + height: var(--gd-compare-divider-width); + background: var(--gd-compare-divider-color); + transform: translateY(-50%); + box-shadow: 0 0 6px rgba(0, 0, 0, 0.3); +} + +/* Handle (grab circle) */ +.gd-compare__handle { + width: var(--gd-compare-handle-size); + height: var(--gd-compare-handle-size); + border-radius: 50%; + background: var(--gd-compare-divider-color); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); + display: flex; + align-items: center; + justify-content: center; + color: #333; + transition: transform 0.15s ease, box-shadow 0.15s ease; +} + +.gd-compare--active .gd-compare__handle { + transform: scale(1.15); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4); +} + +.gd-compare__handle svg { + width: 20px; + height: 20px; +} + +/* Labels */ +.gd-compare__label { + position: absolute; + z-index: 4; + padding: 4px 10px; + font-size: 12px; + font-weight: 600; + font-family: system-ui, -apple-system, sans-serif; + line-height: 1.4; + letter-spacing: 0.02em; + text-transform: uppercase; + color: var(--gd-compare-label-color); + background: var(--gd-compare-label-bg); + border-radius: 4px; + pointer-events: none; +} + +.gd-compare--horizontal .gd-compare__label--before { + top: 12px; + left: 12px; +} + +.gd-compare--horizontal .gd-compare__label--after { + top: 12px; + right: 12px; +} + +.gd-compare--vertical .gd-compare__label--before { + top: 12px; + left: 12px; +} + +.gd-compare--vertical .gd-compare__label--after { + bottom: 12px; + left: 12px; +} + +/* Focus ring for keyboard navigation */ +.gd-compare:focus { + outline: 3px solid var(--bs-primary, #0d6efd); + outline-offset: 2px; +} + +.gd-compare:focus:not(:focus-visible) { + outline: none; +} + +.gd-compare:focus-visible { + outline: 3px solid var(--bs-primary, #0d6efd); + outline-offset: 2px; +} + +/* Dark mode adjustments */ +[data-bs-theme="dark"] .gd-compare { + --gd-compare-divider-color: #e0e0e0; + --gd-compare-label-bg: rgba(255, 255, 255, 0.15); +} + +/* Reduced motion */ +@media (prefers-reduced-motion: reduce) { + .gd-compare__handle { + transition: none; + } +} diff --git a/docs/_extensions/gd-lightbox/gd-lightbox-compare.js b/docs/_extensions/gd-lightbox/gd-lightbox-compare.js new file mode 100644 index 0000000..236476d --- /dev/null +++ b/docs/_extensions/gd-lightbox/gd-lightbox-compare.js @@ -0,0 +1,201 @@ +/** + * GD Lightbox Compare — Before/After Image Comparison Slider + * + * Renders a draggable divider between two overlaid images. Supports: + * - Mouse and touch drag + * - Keyboard control (arrow keys move divider in 5% increments) + * - Horizontal (default) and vertical split + * - Customizable labels + * - Works inline and can be opened in the main lightbox + * + * No dependencies. ~3KB minified+gzipped target. + */ +(function () { + "use strict"; + + var PREFIX = "gd-compare"; + var STEP = 5; // Keyboard step in percent + + function initAll() { + var containers = document.querySelectorAll("." + PREFIX); + for (var i = 0; i < containers.length; i++) { + initSlider(containers[i]); + } + } + + function initSlider(container) { + if (container.dataset.gdCompareInit) return; + container.dataset.gdCompareInit = "true"; + + var direction = container.dataset.direction || "horizontal"; + var startPos = parseFloat(container.dataset.startPosition) || 50; + var labelBefore = container.dataset.labelBefore || "Before"; + var labelAfter = container.dataset.labelAfter || "After"; + + // Get the two images + var images = container.querySelectorAll("img"); + if (images.length < 2) return; + + var beforeImg = images[0]; + var afterImg = images[1]; + + // Build the comparison structure + container.innerHTML = ""; + container.classList.add(PREFIX + "--" + direction); + container.setAttribute("role", "slider"); + container.setAttribute("aria-label", "Image comparison slider"); + container.setAttribute("aria-valuemin", "0"); + container.setAttribute("aria-valuemax", "100"); + container.setAttribute("aria-valuenow", String(Math.round(startPos))); + container.setAttribute("aria-valuetext", Math.round(startPos) + "% " + labelBefore); + container.setAttribute("tabindex", "0"); + + // Before layer (clipped) + var beforeLayer = document.createElement("div"); + beforeLayer.className = PREFIX + "__before"; + beforeLayer.appendChild(beforeImg.cloneNode(true)); + container.appendChild(beforeLayer); + + // After layer (full, behind) + var afterLayer = document.createElement("div"); + afterLayer.className = PREFIX + "__after"; + afterLayer.appendChild(afterImg.cloneNode(true)); + container.appendChild(afterLayer); + + // Divider + var divider = document.createElement("div"); + divider.className = PREFIX + "__divider"; + var handle = document.createElement("div"); + handle.className = PREFIX + "__handle"; + handle.innerHTML = + '' + + '' + + '' + + ''; + divider.appendChild(handle); + container.appendChild(divider); + + // Labels + var bLabel = document.createElement("span"); + bLabel.className = PREFIX + "__label " + PREFIX + "__label--before"; + bLabel.textContent = labelBefore; + container.appendChild(bLabel); + + var aLabel = document.createElement("span"); + aLabel.className = PREFIX + "__label " + PREFIX + "__label--after"; + aLabel.textContent = labelAfter; + container.appendChild(aLabel); + + // State + var position = startPos; + var isDragging = false; + + function setPosition(pct) { + pct = Math.max(0, Math.min(100, pct)); + position = pct; + + if (direction === "vertical") { + beforeLayer.style.clipPath = "inset(0 0 " + (100 - pct) + "% 0)"; + divider.style.top = pct + "%"; + divider.style.left = ""; + } else { + beforeLayer.style.clipPath = "inset(0 " + (100 - pct) + "% 0 0)"; + divider.style.left = pct + "%"; + divider.style.top = ""; + } + + container.setAttribute("aria-valuenow", String(Math.round(pct))); + container.setAttribute( + "aria-valuetext", + Math.round(pct) + "% " + labelBefore + ); + } + + function getPosition(e) { + var rect = container.getBoundingClientRect(); + var clientX, clientY; + + if (e.touches && e.touches.length > 0) { + clientX = e.touches[0].clientX; + clientY = e.touches[0].clientY; + } else { + clientX = e.clientX; + clientY = e.clientY; + } + + if (direction === "vertical") { + return ((clientY - rect.top) / rect.height) * 100; + } + return ((clientX - rect.left) / rect.width) * 100; + } + + // Pointer events + function onPointerDown(e) { + isDragging = true; + setPosition(getPosition(e)); + e.preventDefault(); + container.classList.add(PREFIX + "--active"); + } + + function onPointerMove(e) { + if (!isDragging) return; + setPosition(getPosition(e)); + e.preventDefault(); + } + + function onPointerUp() { + if (!isDragging) return; + isDragging = false; + container.classList.remove(PREFIX + "--active"); + } + + // Mouse + container.addEventListener("mousedown", onPointerDown); + document.addEventListener("mousemove", onPointerMove); + document.addEventListener("mouseup", onPointerUp); + + // Touch + container.addEventListener("touchstart", onPointerDown, { passive: false }); + document.addEventListener("touchmove", function (e) { + if (isDragging) onPointerMove(e); + }, { passive: false }); + document.addEventListener("touchend", onPointerUp); + + // Keyboard + container.addEventListener("keydown", function (e) { + var moved = false; + switch (e.key) { + case "ArrowLeft": + case "ArrowUp": + setPosition(position - STEP); + moved = true; + break; + case "ArrowRight": + case "ArrowDown": + setPosition(position + STEP); + moved = true; + break; + case "Home": + setPosition(0); + moved = true; + break; + case "End": + setPosition(100); + moved = true; + break; + } + if (moved) e.preventDefault(); + }); + + // Set initial position + setPosition(startPos); + } + + // Init on DOM ready + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", initAll); + } else { + initAll(); + } +})(); diff --git a/docs/_extensions/gd-lightbox/gd-lightbox.css b/docs/_extensions/gd-lightbox/gd-lightbox.css new file mode 100644 index 0000000..d5b7566 --- /dev/null +++ b/docs/_extensions/gd-lightbox/gd-lightbox.css @@ -0,0 +1,658 @@ +/** + * GD Lightbox — Styles + * + * Uses CSS custom properties for theming integration with Great Docs. + * Supports dark mode via [data-bs-theme="dark"] and .quarto-dark selectors. + */ + +/* --------------------------------------------------------------------------- + Custom Properties + --------------------------------------------------------------------------- */ + +:root { + --gd-lightbox-backdrop: rgba(0, 0, 0, 0.85); + --gd-lightbox-backdrop-blur: 8px; + --gd-lightbox-radius: 12px; + --gd-lightbox-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); + --gd-lightbox-toolbar-bg: rgba(255, 255, 255, 0.95); + --gd-lightbox-toolbar-color: #1a1a2e; + --gd-lightbox-caption-bg: rgba(255, 255, 255, 0.95); + --gd-lightbox-caption-color: #374151; + --gd-lightbox-accent: #6366f1; + --gd-lightbox-transition: 300ms; + --gd-lightbox-filmstrip-height: 64px; + --gd-lightbox-btn-hover: rgba(0, 0, 0, 0.08); + --gd-lightbox-nav-bg: rgba(255, 255, 255, 0.9); + --gd-lightbox-nav-color: #1a1a2e; + --gd-lightbox-toast-bg: #1a1a2e; + --gd-lightbox-toast-color: #ffffff; +} + +[data-bs-theme="dark"], +.quarto-dark { + --gd-lightbox-backdrop: rgba(0, 0, 0, 0.92); + --gd-lightbox-backdrop-blur: 12px; + --gd-lightbox-toolbar-bg: rgba(30, 30, 46, 0.95); + --gd-lightbox-toolbar-color: #e2e8f0; + --gd-lightbox-caption-bg: rgba(30, 30, 46, 0.95); + --gd-lightbox-caption-color: #cbd5e1; + --gd-lightbox-btn-hover: rgba(255, 255, 255, 0.1); + --gd-lightbox-nav-bg: rgba(30, 30, 46, 0.9); + --gd-lightbox-nav-color: #e2e8f0; + --gd-lightbox-toast-bg: #e2e8f0; + --gd-lightbox-toast-color: #1a1a2e; +} + +/* --------------------------------------------------------------------------- + Body Lock (prevent scroll when lightbox open) + --------------------------------------------------------------------------- */ + +body.gd-lightbox-open { + overflow: hidden; +} + +/* --------------------------------------------------------------------------- + Thumbnail Wrapper (in-page) + --------------------------------------------------------------------------- */ + +.gd-lightbox-wrapper { + position: relative; + display: inline-block; + /* Breathing room so body text above/below isn't tight against the image. + Margin (not padding) keeps the space outside the rounded image box. */ + margin: 1.5rem 0; + cursor: zoom-in; + border-radius: 8px; + /* No overflow clipping: annotation tooltips must be free to extend past the + image edge onto the page. The rounded corners live on the image instead. */ + transition: transform 200ms ease, box-shadow 200ms ease; +} + +/* Keep a set of stacked images close together while preserving the 1.5rem + gap to surrounding body text. Each consecutive image is pulled up to offset + the previous one's bottom margin, leaving a small 0.5rem gap between images. + The first and last images in a run keep their full margin against text. */ +.gd-lightbox-wrapper + .gd-lightbox-wrapper { + margin-top: -1rem; +} + +/* --------------------------------------------------------------------------- + Gallery Stack (in-page cover that opens a gallery in the lightbox) + --------------------------------------------------------------------------- */ + +.gd-gallery { + position: relative; + /* Block sized to its content so margin auto can center it in the body. */ + display: block; + width: fit-content; + max-width: 480px; + margin: 1.5rem auto; +} + +/* The cover is a normal lightbox wrapper; drop its standalone margin. */ +.gd-gallery .gd-lightbox-wrapper { + margin: 0; +} + +/* Matte frame around the cover photo. */ +.gd-gallery .gd-gallery-cover { + padding: 6px; + background: var(--gd-lightbox-caption-bg, #fff); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.22); +} + +/* Offset "photos" peeking out behind the cover to suggest a stack. */ +.gd-gallery .gd-gallery-cover::before, +.gd-gallery .gd-gallery-cover::after { + content: ""; + position: absolute; + inset: 0; + border-radius: 8px; + background: var(--gd-lightbox-caption-bg, #fff); + border: 1px solid rgba(0, 0, 0, 0.1); + box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18); + z-index: -1; + transition: transform 220ms ease; +} + +.gd-gallery .gd-gallery-cover::before { + transform: rotate(-3deg) translate(-7px, 5px); +} + +.gd-gallery .gd-gallery-cover::after { + transform: rotate(3deg) translate(7px, 5px); + z-index: -2; +} + +/* Fan the stack out a little on hover. */ +.gd-gallery:hover .gd-gallery-cover::before { + transform: rotate(-6deg) translate(-14px, 7px); +} + +.gd-gallery:hover .gd-gallery-cover::after { + transform: rotate(6deg) translate(14px, 7px); +} + +/* Image count badge. */ +.gd-gallery-badge { + position: absolute; + bottom: 14px; + right: 14px; + z-index: 3; + display: inline-flex; + align-items: center; + gap: 4px; + padding: 3px 9px; + font-size: 12px; + font-weight: 600; + line-height: 1; + color: #fff; + background: rgba(0, 0, 0, 0.65); + border-radius: 20px; + pointer-events: none; +} + +.gd-gallery-badge svg { + display: block; +} + +/* Hidden gallery members stay in the DOM for the engine but take no space. */ +.gd-gallery-rest { + display: none; +} + +@media (prefers-reduced-motion: reduce) { + .gd-gallery .gd-gallery-cover::before, + .gd-gallery .gd-gallery-cover::after { + transition: none; + } +} + +.gd-lightbox-wrapper:hover, +.gd-lightbox-wrapper:focus-visible { + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); +} + +.gd-lightbox-wrapper:focus-visible { + outline: 2px solid var(--gd-lightbox-accent); + outline-offset: 2px; +} + +.gd-lightbox-wrapper .gd-lightbox-img { + display: block; + max-width: 100%; + height: auto; + border-radius: inherit; +} + +/* Expand button overlay */ +.gd-lightbox-expand { + position: absolute; + top: 8px; + right: 8px; + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + background: rgba(0, 0, 0, 0.6); + color: #fff; + border: none; + border-radius: 6px; + cursor: pointer; + opacity: 0; + transition: opacity 200ms ease; + pointer-events: none; +} + +.gd-lightbox-wrapper:hover .gd-lightbox-expand, +.gd-lightbox-wrapper:focus-within .gd-lightbox-expand { + opacity: 1; + pointer-events: auto; +} + +/* --------------------------------------------------------------------------- + Overlay + --------------------------------------------------------------------------- */ + +.gd-lightbox-overlay { + position: fixed; + inset: 0; + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + opacity: 0; + visibility: hidden; + transition: opacity var(--gd-lightbox-transition) ease, + visibility 0s linear var(--gd-lightbox-transition); +} + +.gd-lightbox-overlay.gd-lightbox-visible { + opacity: 1; + visibility: visible; + transition: opacity var(--gd-lightbox-transition) ease, visibility 0s linear 0s; +} + +.gd-lightbox-overlay.gd-lightbox-closing { + opacity: 0; + visibility: visible; +} + +/* Backdrop with blur */ +.gd-lightbox-backdrop { + position: absolute; + inset: 0; + background: var(--gd-lightbox-backdrop); + backdrop-filter: blur(var(--gd-lightbox-backdrop-blur)); + -webkit-backdrop-filter: blur(var(--gd-lightbox-backdrop-blur)); +} + +/* --------------------------------------------------------------------------- + Content Area + --------------------------------------------------------------------------- */ + +.gd-lightbox-content { + position: relative; + z-index: 1; + display: flex; + flex-direction: column; + align-items: center; + max-width: 90vw; + max-height: calc(100vh - 160px); +} + +.gd-lightbox-image-wrap { + position: relative; + display: flex; + align-items: center; + justify-content: center; + max-width: 90vw; + max-height: calc(100vh - 200px); +} + +/* Annotation layer — sized/positioned by JS to cover the displayed image. + Holds a .gd-annotate-overlay (inset:0), so markers position by % of this + box. Fades in once positioned to avoid a flash at the wrong location. */ +.gd-lightbox-annotations { + position: absolute; + opacity: 0; + transition: opacity 200ms ease; + pointer-events: none; + z-index: 6; +} + +.gd-lightbox-annotations.visible { + opacity: 1; +} + +/* The markers themselves re-enable pointer events (see annotate CSS). */ +.gd-lightbox-annotations .gd-annotate-marker { + pointer-events: auto; +} + +.gd-lightbox-main-img { + max-width: 90vw; + max-height: calc(100vh - 200px); + object-fit: contain; + border-radius: var(--gd-lightbox-radius); + box-shadow: var(--gd-lightbox-shadow); + user-select: none; + -webkit-user-drag: none; + /* Smooth zoom from the toolbar buttons. The open animation overrides this + with its own inline transition, so it isn't affected. */ + transition: transform 200ms ease; +} + +/* Zoomed: image is draggable to pan. */ +.gd-lightbox-overlay.gd-lightbox-zoomed .gd-lightbox-main-img { + cursor: grab; + touch-action: none; /* let pointer-pan own the gesture on touch devices */ +} + +/* Actively dragging: grabbing cursor, and no transition so pan tracks 1:1. */ +.gd-lightbox-overlay.gd-lightbox-panning .gd-lightbox-main-img { + cursor: grabbing; + transition: none; +} + +/* Gallery mode reserves extra bottom space so the centered image and its + caption clear the filmstrip dock (which is absolutely positioned at the + bottom and would otherwise overlap a caption under a large image). The + content stays centered, so the toolbar at the top is cleared too. */ +.gd-lightbox-overlay.gd-lightbox-has-filmstrip .gd-lightbox-content { + max-height: calc(100vh - 220px); +} + +.gd-lightbox-overlay.gd-lightbox-has-filmstrip .gd-lightbox-image-wrap, +.gd-lightbox-overlay.gd-lightbox-has-filmstrip .gd-lightbox-main-img { + max-height: calc(100vh - 300px); +} + +/* --------------------------------------------------------------------------- + Caption + --------------------------------------------------------------------------- */ + +.gd-lightbox-caption { + margin-top: 12px; + padding: 8px 16px; + background: var(--gd-lightbox-caption-bg); + border-radius: 8px; + text-align: center; + max-width: 600px; +} + +.gd-lightbox-caption-text { + margin: 0; + font-size: 0.9rem; + color: var(--gd-lightbox-caption-color); + line-height: 1.4; +} + +.gd-lightbox-credit-text { + margin: 4px 0 0; + font-size: 0.75rem; + color: var(--gd-lightbox-caption-color); + opacity: 0.7; +} + +/* --------------------------------------------------------------------------- + Toolbar + --------------------------------------------------------------------------- */ + +.gd-lightbox-toolbar { + position: absolute; + top: 0; + left: 0; + right: 0; + z-index: 10; + display: flex; + align-items: center; + padding: 12px 16px; + background: linear-gradient( + to bottom, + var(--gd-lightbox-toolbar-bg), + transparent + ); + transition: opacity 300ms ease, transform 300ms ease; +} + +.gd-lightbox-toolbar.hidden { + opacity: 0; + transform: translateY(-8px); + pointer-events: none; +} + +.gd-lightbox-toolbar-spacer { + flex: 1; +} + +.gd-lightbox-counter { + font-size: 0.85rem; + font-weight: 500; + color: var(--gd-lightbox-toolbar-color); + padding: 4px 10px; + background: var(--gd-lightbox-btn-hover); + border-radius: 20px; +} + +/* Zoom level readout (e.g. "150%") */ +.gd-lightbox-zoom-level { + min-width: 3.5em; + text-align: center; + font-size: 0.8rem; + font-variant-numeric: tabular-nums; + font-weight: 500; + color: var(--gd-lightbox-toolbar-color); + user-select: none; +} + +/* Disabled toolbar buttons (e.g. zoom at min/max) */ +.gd-lightbox-btn:disabled { + opacity: 0.35; + cursor: default; + pointer-events: none; +} + +/* Toolbar buttons */ +.gd-lightbox-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + border: none; + border-radius: 8px; + background: transparent; + color: var(--gd-lightbox-toolbar-color); + cursor: pointer; + transition: background 150ms ease; + margin-left: 4px; +} + +.gd-lightbox-btn:hover { + background: var(--gd-lightbox-btn-hover); +} + +.gd-lightbox-btn:focus-visible { + outline: 2px solid var(--gd-lightbox-accent); + outline-offset: 2px; +} + +/* --------------------------------------------------------------------------- + Navigation Arrows + --------------------------------------------------------------------------- */ + +.gd-lightbox-nav { + position: absolute; + top: 50%; + transform: translateY(-50%); + z-index: 5; + display: flex; + align-items: center; + justify-content: center; + width: 44px; + height: 44px; + border: none; + border-radius: 50%; + background: var(--gd-lightbox-nav-bg); + color: var(--gd-lightbox-nav-color); + cursor: pointer; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + transition: transform 150ms ease, box-shadow 150ms ease; +} + +.gd-lightbox-nav:hover { + transform: translateY(-50%) scale(1.1); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); +} + +.gd-lightbox-nav:focus-visible { + outline: 2px solid var(--gd-lightbox-accent); + outline-offset: 2px; +} + +.gd-lightbox-nav-prev { + left: 16px; +} + +.gd-lightbox-nav-next { + right: 16px; +} + +/* --------------------------------------------------------------------------- + Filmstrip + --------------------------------------------------------------------------- */ + +.gd-lightbox-filmstrip { + position: absolute; + bottom: 16px; + left: 50%; + transform: translateX(-50%); + z-index: 5; + display: flex; + gap: 8px; + padding: 8px 12px; + background: var(--gd-lightbox-toolbar-bg); + border-radius: 12px; + max-width: 80vw; + overflow-x: auto; + scrollbar-width: thin; +} + +.gd-lightbox-filmstrip-thumb { + flex-shrink: 0; + width: var(--gd-lightbox-filmstrip-height); + height: var(--gd-lightbox-filmstrip-height); + border: 2px solid transparent; + border-radius: 8px; + overflow: hidden; + cursor: pointer; + background: none; + padding: 0; + transition: border-color 200ms ease, transform 200ms ease; +} + +.gd-lightbox-filmstrip-thumb:hover { + transform: scale(1.05); +} + +.gd-lightbox-filmstrip-thumb.active { + border-color: var(--gd-lightbox-accent); + transform: scale(1.08); +} + +.gd-lightbox-filmstrip-thumb:focus-visible { + outline: 2px solid var(--gd-lightbox-accent); + outline-offset: 2px; +} + +.gd-lightbox-filmstrip-thumb img { + width: 100%; + height: 100%; + object-fit: cover; +} + +/* --------------------------------------------------------------------------- + Toast Notification + --------------------------------------------------------------------------- */ + +.gd-lightbox-toast { + position: absolute; + bottom: 100px; + left: 50%; + transform: translateX(-50%) translateY(8px); + z-index: 20; + padding: 8px 16px; + background: var(--gd-lightbox-toast-bg); + color: var(--gd-lightbox-toast-color); + border-radius: 8px; + font-size: 0.85rem; + font-weight: 500; + opacity: 0; + transition: opacity 200ms ease, transform 200ms ease; + pointer-events: none; +} + +.gd-lightbox-toast.visible { + opacity: 1; + transform: translateX(-50%) translateY(0); +} + +/* --------------------------------------------------------------------------- + Screen Reader Only + --------------------------------------------------------------------------- */ + +.gd-lightbox-sr-announce { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +/* --------------------------------------------------------------------------- + Responsive / Mobile + --------------------------------------------------------------------------- */ + +@media (max-width: 768px) { + .gd-lightbox-content { + max-width: 100vw; + max-height: calc(100vh - 120px); + } + + .gd-lightbox-image-wrap { + max-width: 100vw; + max-height: calc(100vh - 140px); + } + + .gd-lightbox-main-img { + max-width: 100vw; + max-height: calc(100vh - 140px); + border-radius: 0; + } + + .gd-lightbox-overlay.gd-lightbox-has-filmstrip .gd-lightbox-content { + max-height: calc(100vh - 180px); + } + + .gd-lightbox-overlay.gd-lightbox-has-filmstrip .gd-lightbox-image-wrap, + .gd-lightbox-overlay.gd-lightbox-has-filmstrip .gd-lightbox-main-img { + max-height: calc(100vh - 260px); + } + + .gd-lightbox-nav { + width: 36px; + height: 36px; + } + + .gd-lightbox-nav-prev { + left: 8px; + } + + .gd-lightbox-nav-next { + right: 8px; + } + + .gd-lightbox-filmstrip { + bottom: 8px; + padding: 6px 8px; + gap: 6px; + } + + .gd-lightbox-filmstrip-thumb { + width: 48px; + height: 48px; + } + + .gd-lightbox-toolbar { + padding: 8px 12px; + } + + .gd-lightbox-expand { + opacity: 1; + pointer-events: auto; + } +} + +/* --------------------------------------------------------------------------- + Reduced Motion + --------------------------------------------------------------------------- */ + +@media (prefers-reduced-motion: reduce) { + .gd-lightbox-overlay, + .gd-lightbox-main-img, + .gd-lightbox-toolbar, + .gd-lightbox-nav, + .gd-lightbox-filmstrip-thumb, + .gd-lightbox-toast, + .gd-lightbox-wrapper { + transition: none !important; + } +} diff --git a/docs/_extensions/gd-lightbox/gd-lightbox.js b/docs/_extensions/gd-lightbox/gd-lightbox.js new file mode 100644 index 0000000..29a090d --- /dev/null +++ b/docs/_extensions/gd-lightbox/gd-lightbox.js @@ -0,0 +1,1419 @@ +/** + * GD Lightbox — Great Docs Lightbox Engine + * + * A documentation-focused lightbox built from scratch. Features: + * - Origin-aware zoom animation (image grows from thumbnail position) + * - Dark-mode image variant swapping + * - Gallery with filmstrip navigation + * - Keyboard & touch navigation + * - Copy/download/deep-link toolbar + * - Accessible: focus trap, ARIA, screen reader announcements + * + * No dependencies. ~12KB minified+gzipped target. + */ +(function () { + "use strict"; + + // --------------------------------------------------------------------------- + // Constants + // --------------------------------------------------------------------------- + + const PREFIX = "gd-lightbox"; + const ATTR_LB = "data-gd-lightbox"; + const ATTR_ID = "data-gd-lightbox-id"; + const ATTR_GROUP = "data-gd-lightbox-group"; + const ATTR_DARK = "data-gd-lightbox-dark"; + const ATTR_CAPTION = "data-gd-lightbox-caption"; + const ATTR_CREDIT = "data-gd-lightbox-credit"; + const ATTR_DESC_POS = "data-gd-lightbox-desc-position"; + const ATTR_ZOOM_TARGET = "data-gd-lightbox-zoom-target"; + const ATTR_LOOP = "data-gd-lightbox-loop"; + const ATTR_AUTOPLAY = "data-gd-lightbox-autoplay"; + const ATTR_FULL_SRC = "data-gd-lightbox-full-src"; + + const TRANSITION_MS = 300; + const TOOLBAR_HIDE_MS = 3000; + + // --------------------------------------------------------------------------- + // State + // --------------------------------------------------------------------------- + + let overlay = null; // The lightbox overlay DOM element + let isOpen = false; + let currentIndex = -1; + let currentGroup = null; // Array of items in the active gallery + let allItems = []; // All lightbox items on the page + let groups = {}; // { groupName: [items...] } + let toolbarTimer = null; + let previousFocus = null; // Element that had focus before lightbox opened + let isDarkMode = false; + let loopEnabled = true; // Whether gallery wraps around at ends + let autoplayInterval = 0; // Autoplay interval in ms (0 = disabled) + let autoplayTimer = null; // Active autoplay timer + + // Zoom state (toolbar-button controlled; zooms about the image center) + let zoomScale = 1; + const ZOOM_MIN = 1; + const ZOOM_MAX = 4; + const ZOOM_STEP = 0.5; + + // Pan state (drag the zoomed image around) + let panX = 0; + let panY = 0; + let isPanning = false; + let panPointerStartX = 0; + let panPointerStartY = 0; + let panOriginX = 0; + let panOriginY = 0; + + // Touch/gesture state + let touchStartX = 0; + let touchStartY = 0; + let touchDeltaX = 0; + let touchDeltaY = 0; + let isSwiping = false; + + // --------------------------------------------------------------------------- + // Utilities + // --------------------------------------------------------------------------- + + function qs(sel, ctx) { + return (ctx || document).querySelector(sel); + } + + function qsa(sel, ctx) { + return Array.from((ctx || document).querySelectorAll(sel)); + } + + function el(tag, attrs, children) { + const node = document.createElement(tag); + if (attrs) { + Object.keys(attrs).forEach(function (k) { + if (k === "className") { + node.className = attrs[k]; + } else if (k.startsWith("on")) { + node.addEventListener(k.slice(2).toLowerCase(), attrs[k]); + } else { + node.setAttribute(k, attrs[k]); + } + }); + } + if (children) { + children.forEach(function (c) { + if (typeof c === "string") { + node.appendChild(document.createTextNode(c)); + } else if (c) { + node.appendChild(c); + } + }); + } + return node; + } + + function detectDarkMode() { + const html = document.documentElement; + return ( + html.classList.contains("quarto-dark") || + html.getAttribute("data-bs-theme") === "dark" + ); + } + + function getImageSrc(item) { + if (isDarkMode && item.darkSrc) { + return item.darkSrc; + } + return item.src; + } + + /** + * Get the highest-resolution source for lightbox display. + * Prefers: explicit full-src > largest srcset entry > base src. + */ + function getFullResSrc(item) { + if (isDarkMode && item.darkSrc) { + return item.darkSrc; + } + if (item.fullSrc) { + return item.fullSrc; + } + if (item.srcsetMax) { + return item.srcsetMax; + } + return item.src; + } + + /** + * Parse a srcset string and return the URL of the widest/highest-res source. + * Handles both width descriptors (800w) and pixel density (2x). + */ + function parseSrcsetMax(srcset) { + if (!srcset) return null; + var best = null; + var bestVal = 0; + srcset.split(",").forEach(function (entry) { + var parts = entry.trim().split(/\s+/); + if (parts.length < 2) return; + var url = parts[0]; + var descriptor = parts[1]; + var val = parseFloat(descriptor) || 0; + if (val > bestVal) { + bestVal = val; + best = url; + } + }); + return best; + } + + function prefersReducedMotion() { + return window.matchMedia("(prefers-reduced-motion: reduce)").matches; + } + + /** Parse a lightbox annotations attribute into an array, or null. */ + function parseAnnotations(raw) { + if (window.GDAnnotate && window.GDAnnotate.parse) { + return window.GDAnnotate.parse(raw); + } + if (!raw) return null; + try { + var a = JSON.parse(raw); + return Array.isArray(a) && a.length ? a : null; + } catch (e) { + return null; + } + } + + // --------------------------------------------------------------------------- + // Collect Items + // --------------------------------------------------------------------------- + + function collectItems() { + allItems = []; + groups = {}; + + qsa("[" + ATTR_LB + "]").forEach(function (wrapper) { + var img = qs(".gd-lightbox-img", wrapper); + if (!img) return; + + var item = { + wrapper: wrapper, + img: img, + id: wrapper.getAttribute(ATTR_ID), + src: img.getAttribute("src"), + darkSrc: wrapper.getAttribute(ATTR_DARK) || null, + fullSrc: wrapper.getAttribute(ATTR_FULL_SRC) || null, + srcsetMax: parseSrcsetMax(img.getAttribute("srcset")), + group: wrapper.getAttribute(ATTR_GROUP) || null, + caption: wrapper.getAttribute(ATTR_CAPTION) || "", + credit: wrapper.getAttribute(ATTR_CREDIT) || "", + descPosition: wrapper.getAttribute(ATTR_DESC_POS) || "bottom", + zoomTarget: wrapper.getAttribute(ATTR_ZOOM_TARGET) || null, + loop: wrapper.getAttribute(ATTR_LOOP), + autoplay: wrapper.getAttribute(ATTR_AUTOPLAY), + alt: img.getAttribute("alt") || "", + annotations: parseAnnotations( + wrapper.getAttribute("data-gd-lightbox-annotations") + ), + }; + + allItems.push(item); + + if (item.group) { + if (!groups[item.group]) { + groups[item.group] = []; + } + groups[item.group].push(item); + } + }); + } + + // --------------------------------------------------------------------------- + // Overlay DOM + // --------------------------------------------------------------------------- + + function createOverlay() { + if (overlay) return; + + overlay = el("div", { + className: PREFIX + "-overlay", + role: "dialog", + "aria-modal": "true", + "aria-label": "Image lightbox", + "aria-hidden": "true", + }); + + // Backdrop + var backdrop = el("div", { + className: PREFIX + "-backdrop", + onClick: close, + }); + overlay.appendChild(backdrop); + + // Content container + var content = el("div", { className: PREFIX + "-content" }); + + // Main image + var imageWrap = el("div", { className: PREFIX + "-image-wrap" }); + var mainImg = el("img", { + className: PREFIX + "-main-img", + alt: "", + }); + // Drag-to-pan when zoomed (pointer events cover mouse + touch) + mainImg.addEventListener("pointerdown", onPanStart); + mainImg.addEventListener("pointermove", onPanMove); + mainImg.addEventListener("pointerup", onPanEnd); + mainImg.addEventListener("pointercancel", onPanEnd); + imageWrap.appendChild(mainImg); + content.appendChild(imageWrap); + + // Caption area + var captionEl = el("div", { className: PREFIX + "-caption" }); + var captionText = el("p", { className: PREFIX + "-caption-text" }); + var creditText = el("p", { className: PREFIX + "-credit-text" }); + captionEl.appendChild(captionText); + captionEl.appendChild(creditText); + content.appendChild(captionEl); + + overlay.appendChild(content); + + // Toolbar + var toolbar = el("div", { className: PREFIX + "-toolbar" }); + + // Counter (for galleries) + var counter = el("span", { className: PREFIX + "-counter" }); + toolbar.appendChild(counter); + + // Spacer + toolbar.appendChild(el("span", { className: PREFIX + "-toolbar-spacer" })); + + // Zoom controls: out / level / in / reset + var zoomOutBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-zoom-out", + "aria-label": "Zoom out", + "data-tippy-content": "Zoom out", + "data-tippy-trigger": "mouseenter", + onClick: zoomOut, + }, + [createZoomOutIcon()] + ); + toolbar.appendChild(zoomOutBtn); + + var zoomLevel = el("span", { + className: PREFIX + "-zoom-level", + "aria-live": "polite", + }); + toolbar.appendChild(zoomLevel); + + var zoomInBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-zoom-in", + "aria-label": "Zoom in", + "data-tippy-content": "Zoom in", + "data-tippy-trigger": "mouseenter", + onClick: zoomIn, + }, + [createZoomInIcon()] + ); + toolbar.appendChild(zoomInBtn); + + var zoomResetBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-zoom-reset", + "aria-label": "Reset zoom", + "data-tippy-content": "Reset zoom", + "data-tippy-trigger": "mouseenter", + onClick: zoomReset, + }, + [createZoomResetIcon()] + ); + toolbar.appendChild(zoomResetBtn); + + // Copy button + var copyBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-copy", + "aria-label": "Copy image to clipboard", + // Tooltip via Great Docs' tooltips.js (tippy). Hover-only trigger so it + // never fires on the auto-focus/focus-trap that would otherwise strand + // the tooltip when the toolbar auto-hides. No native `title` is used. + "data-tippy-content": "Copy image", + "data-tippy-trigger": "mouseenter", + onClick: handleCopy, + }, + [createCopyIcon()] + ); + toolbar.appendChild(copyBtn); + + // Download button + var downloadBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-download", + "aria-label": "Download image", + "data-tippy-content": "Download image", + "data-tippy-trigger": "mouseenter", + onClick: handleDownload, + }, + [createDownloadIcon()] + ); + toolbar.appendChild(downloadBtn); + + // Copy link button + var linkBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-link", + "aria-label": "Copy link to this image", + "data-tippy-content": "Copy link", + "data-tippy-trigger": "mouseenter", + onClick: handleCopyLink, + }, + [createLinkIcon()] + ); + toolbar.appendChild(linkBtn); + + // Close button + var closeBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-close", + "aria-label": "Close lightbox", + "data-tippy-content": "Close (Esc)", + "data-tippy-trigger": "mouseenter", + onClick: close, + }, + [createCloseIcon()] + ); + toolbar.appendChild(closeBtn); + + overlay.appendChild(toolbar); + + // Navigation arrows + var prevBtn = el( + "button", + { + className: PREFIX + "-nav " + PREFIX + "-nav-prev", + "aria-label": "Previous image", + onClick: prev, + }, + [createChevronLeft()] + ); + var nextBtn = el( + "button", + { + className: PREFIX + "-nav " + PREFIX + "-nav-next", + "aria-label": "Next image", + onClick: next, + }, + [createChevronRight()] + ); + overlay.appendChild(prevBtn); + overlay.appendChild(nextBtn); + + // Filmstrip + var filmstrip = el("div", { className: PREFIX + "-filmstrip" }); + overlay.appendChild(filmstrip); + + // Live region for screen reader announcements + var liveRegion = el("div", { + className: PREFIX + "-sr-announce", + "aria-live": "polite", + "aria-atomic": "true", + }); + overlay.appendChild(liveRegion); + + document.body.appendChild(overlay); + } + + // --------------------------------------------------------------------------- + // SVG Icons (inline, no external deps) + // --------------------------------------------------------------------------- + + function svgEl(paths, size) { + size = size || 20; + var ns = "http://www.w3.org/2000/svg"; + var svg = document.createElementNS(ns, "svg"); + svg.setAttribute("width", size); + svg.setAttribute("height", size); + svg.setAttribute("viewBox", "0 0 24 24"); + svg.setAttribute("fill", "none"); + svg.setAttribute("stroke", "currentColor"); + svg.setAttribute("stroke-width", "2"); + svg.setAttribute("stroke-linecap", "round"); + svg.setAttribute("stroke-linejoin", "round"); + paths.forEach(function (d) { + var path = document.createElementNS(ns, "path"); + path.setAttribute("d", d); + svg.appendChild(path); + }); + return svg; + } + + function createCloseIcon() { + return svgEl(["M18 6L6 18", "M6 6l12 12"]); + } + + function createChevronLeft() { + return svgEl(["M15 18l-6-6 6-6"], 24); + } + + function createChevronRight() { + return svgEl(["M9 18l6-6-6-6"], 24); + } + + function createZoomInIcon() { + return svgEl([ + "M11 4a7 7 0 100 14 7 7 0 000-14z", + "M21 21l-4.35-4.35", + "M11 8v6", + "M8 11h6", + ]); + } + + function createZoomOutIcon() { + return svgEl([ + "M11 4a7 7 0 100 14 7 7 0 000-14z", + "M21 21l-4.35-4.35", + "M8 11h6", + ]); + } + + function createZoomResetIcon() { + // "Fit to view" — inward-pointing corner arrows (feather minimize-2), + // visually distinct from the +/- magnifiers. + return svgEl([ + "M4 14h6v6", + "M20 10h-6V4", + "M14 10l7-7", + "M3 21l7-7", + ]); + } + + function createCopyIcon() { + return svgEl([ + "M16 4h2a2 2 0 012 2v14a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2h2", + "M9 2h6a1 1 0 011 1v1a1 1 0 01-1 1H9a1 1 0 01-1-1V3a1 1 0 011-1z", + ]); + } + + function createDownloadIcon() { + return svgEl(["M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4", "M7 10l5 5 5-5", "M12 15V3"]); + } + + function createLinkIcon() { + return svgEl([ + "M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71", + "M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71", + ]); + } + + // --------------------------------------------------------------------------- + // Open / Close / Navigate + // --------------------------------------------------------------------------- + + function open(item) { + if (isOpen) return; + + previousFocus = document.activeElement; + isOpen = true; + isDarkMode = detectDarkMode(); + + createOverlay(); + + // Determine the gallery group + if (item.group && groups[item.group]) { + currentGroup = groups[item.group]; + } else { + currentGroup = [item]; + } + currentIndex = currentGroup.indexOf(item); + if (currentIndex < 0) currentIndex = 0; + + // Read loop setting from the opening item (group-level attribute) + // Default: true (wraps around). Set data-gd-lightbox-loop="false" to disable. + var loopAttr = item.loop; + loopEnabled = loopAttr !== "false"; + + // Read autoplay interval (e.g., "3s", "2000ms", or "3000") + autoplayInterval = parseInterval(item.autoplay); + + showSlide(currentIndex, item); + + // Show overlay with animation + overlay.classList.add(PREFIX + "-visible"); + overlay.setAttribute("aria-hidden", "false"); + document.body.classList.add(PREFIX + "-open"); + + // Origin animation: get thumbnail rect and animate from there + if (!prefersReducedMotion()) { + animateOpen(item); + } + + // Update URL hash for deep linking + if (item.id) { + history.replaceState(null, "", "#lightbox=" + item.id); + } + + // Focus the close button + setTimeout(function () { + var closeBtn = qs("." + PREFIX + "-btn-close", overlay); + if (closeBtn) closeBtn.focus(); + }, TRANSITION_MS); + + startToolbarTimer(); + startAutoplay(); + } + + function close() { + if (!isOpen) return; + isOpen = false; + stopAutoplay(); + hideToolbarTooltips(); + + overlay.classList.remove(PREFIX + "-visible"); + overlay.classList.add(PREFIX + "-closing"); + overlay.setAttribute("aria-hidden", "true"); + document.body.classList.remove(PREFIX + "-open"); + + // Remove hash + if (window.location.hash.startsWith("#lightbox=")) { + history.replaceState(null, "", window.location.pathname + window.location.search); + } + + setTimeout(function () { + overlay.classList.remove(PREFIX + "-closing"); + // Restore focus + if (previousFocus) { + previousFocus.focus(); + } + }, TRANSITION_MS); + } + + function next() { + if (!currentGroup || currentGroup.length <= 1) return; + if (!loopEnabled && currentIndex >= currentGroup.length - 1) return; + currentIndex = (currentIndex + 1) % currentGroup.length; + showSlide(currentIndex); + announce("Image " + (currentIndex + 1) + " of " + currentGroup.length); + resetAutoplay(); + } + + function prev() { + if (!currentGroup || currentGroup.length <= 1) return; + if (!loopEnabled && currentIndex <= 0) return; + currentIndex = (currentIndex - 1 + currentGroup.length) % currentGroup.length; + showSlide(currentIndex); + announce("Image " + (currentIndex + 1) + " of " + currentGroup.length); + resetAutoplay(); + } + + // --------------------------------------------------------------------------- + // Autoplay + // --------------------------------------------------------------------------- + + /** Parse an interval string like "3s", "2000ms", or "3000" → milliseconds. */ + function parseInterval(val) { + if (!val) return 0; + val = val.trim().toLowerCase(); + if (val.endsWith("ms")) { + return parseInt(val, 10) || 0; + } + if (val.endsWith("s")) { + return (parseFloat(val) || 0) * 1000; + } + // Bare number: treat as ms if >=100, otherwise as seconds + var n = parseFloat(val); + if (!n || n <= 0) return 0; + return n >= 100 ? n : n * 1000; + } + + function startAutoplay() { + stopAutoplay(); + if (autoplayInterval <= 0 || !currentGroup || currentGroup.length <= 1) return; + autoplayTimer = setInterval(function () { + if (!loopEnabled && currentIndex >= currentGroup.length - 1) { + stopAutoplay(); + return; + } + currentIndex = (currentIndex + 1) % currentGroup.length; + showSlide(currentIndex); + announce("Image " + (currentIndex + 1) + " of " + currentGroup.length); + }, autoplayInterval); + } + + function stopAutoplay() { + if (autoplayTimer) { + clearInterval(autoplayTimer); + autoplayTimer = null; + } + } + + /** Reset autoplay timer (called on manual navigation to restart the interval). */ + function resetAutoplay() { + if (autoplayInterval > 0) { + startAutoplay(); + } + } + + // --------------------------------------------------------------------------- + // Zoom (toolbar-button controlled; zooms about the image center) + // --------------------------------------------------------------------------- + + function zoomIn() { setZoom(zoomScale + ZOOM_STEP); } + function zoomOut() { setZoom(zoomScale - ZOOM_STEP); } + function zoomReset() { setZoom(1); } + + function setZoom(scale) { + scale = Math.max(ZOOM_MIN, Math.min(ZOOM_MAX, Math.round(scale * 100) / 100)); + if (scale === zoomScale) { + updateZoomUI(); + return; + } + zoomScale = scale; + clampPan(); // pull pan back into bounds when zooming out + applyZoom(false); + announce("Zoom " + Math.round(zoomScale * 100) + " percent"); + } + + /** Reset to fit (100%). `immediate` skips the transition (slide changes). */ + function resetZoom(immediate) { + zoomScale = 1; + panX = 0; + panY = 0; + applyZoom(immediate); + } + + /** Build the transform for the current zoom + pan (empty string at fit). */ + function zoomTransform() { + if (zoomScale <= 1) return ""; + return "translate(" + panX + "px, " + panY + "px) scale(" + zoomScale + ")"; + } + + /** Apply just the transform (used during drag-pan; no transition juggling). */ + function applyTransform() { + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (mainImg) mainImg.style.transform = zoomTransform(); + } + + function applyZoom(immediate) { + if (!overlay) return; + if (zoomScale <= 1) { + panX = 0; + panY = 0; + } + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (mainImg) { + if (immediate) { + var prev = mainImg.style.transition; + mainImg.style.transition = "none"; + mainImg.style.transform = zoomTransform(); + mainImg.offsetHeight; // force reflow so future changes animate + mainImg.style.transition = prev; + } else { + mainImg.style.transform = zoomTransform(); + } + } + // Cursor affordance: grab when zoomed (grabbing handled while dragging). + overlay.classList.toggle(PREFIX + "-zoomed", zoomScale > 1); + // Annotations are hidden while zoomed (shown again at fit level). + var layer = qs("." + PREFIX + "-annotations", overlay); + if (layer) { + layer.style.display = zoomScale > 1 ? "none" : ""; + } + updateZoomUI(); + } + + /** Clamp pan so the image always covers its fit box (no gaps inside it). */ + function clampPan() { + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (!mainImg || zoomScale <= 1) { + panX = 0; + panY = 0; + return; + } + var maxX = (mainImg.offsetWidth * (zoomScale - 1)) / 2; + var maxY = (mainImg.offsetHeight * (zoomScale - 1)) / 2; + panX = Math.max(-maxX, Math.min(maxX, panX)); + panY = Math.max(-maxY, Math.min(maxY, panY)); + } + + // ── Drag-to-pan (pointer events: mouse + touch) ─────────────────────────── + + function onPanStart(e) { + if (zoomScale <= 1) return; + isPanning = true; + panPointerStartX = e.clientX; + panPointerStartY = e.clientY; + panOriginX = panX; + panOriginY = panY; + overlay.classList.add(PREFIX + "-panning"); + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (mainImg && mainImg.setPointerCapture) { + try { mainImg.setPointerCapture(e.pointerId); } catch (err) {} + } + e.preventDefault(); + } + + function onPanMove(e) { + if (!isPanning) return; + panX = panOriginX + (e.clientX - panPointerStartX); + panY = panOriginY + (e.clientY - panPointerStartY); + clampPan(); + applyTransform(); + e.preventDefault(); + } + + function onPanEnd() { + if (!isPanning) return; + isPanning = false; + overlay.classList.remove(PREFIX + "-panning"); + } + + function updateZoomUI() { + if (!overlay) return; + var level = qs("." + PREFIX + "-zoom-level", overlay); + if (level) level.textContent = Math.round(zoomScale * 100) + "%"; + var outBtn = qs("." + PREFIX + "-btn-zoom-out", overlay); + var inBtn = qs("." + PREFIX + "-btn-zoom-in", overlay); + var resetBtn = qs("." + PREFIX + "-btn-zoom-reset", overlay); + if (outBtn) outBtn.disabled = zoomScale <= ZOOM_MIN; + if (inBtn) inBtn.disabled = zoomScale >= ZOOM_MAX; + if (resetBtn) resetBtn.disabled = zoomScale === 1; + } + + function showSlide(index, originItem) { + var item = currentGroup[index]; + if (!item) return; + + // Each slide starts at fit (100%); clear any zoom from the previous image. + resetZoom(true); + + var mainImg = qs("." + PREFIX + "-main-img", overlay); + var captionText = qs("." + PREFIX + "-caption-text", overlay); + var creditText = qs("." + PREFIX + "-credit-text", overlay); + var counter = qs("." + PREFIX + "-counter", overlay); + + // Update image source — use highest-resolution source for lightbox display + var src = getFullResSrc(item); + mainImg.setAttribute("src", src); + mainImg.removeAttribute("srcset"); + mainImg.removeAttribute("sizes"); + mainImg.setAttribute("alt", item.alt); + + // Update dialog label for screen readers + overlay.setAttribute("aria-label", item.alt || item.caption || "Image lightbox"); + + // Update caption + if (item.caption) { + captionText.textContent = item.caption; + captionText.style.display = ""; + } else { + captionText.style.display = "none"; + } + + if (item.credit) { + creditText.textContent = item.credit; + creditText.style.display = ""; + } else { + creditText.style.display = "none"; + } + + // Update counter + if (currentGroup.length > 1) { + counter.textContent = (index + 1) + " / " + currentGroup.length; + counter.style.display = ""; + } else { + counter.style.display = "none"; + } + + // Update navigation visibility + var prevBtn = qs("." + PREFIX + "-nav-prev", overlay); + var nextBtn = qs("." + PREFIX + "-nav-next", overlay); + if (currentGroup.length <= 1) { + prevBtn.style.display = "none"; + nextBtn.style.display = "none"; + } else { + prevBtn.style.display = ""; + nextBtn.style.display = ""; + // Disable buttons at boundaries when loop is off + if (!loopEnabled) { + prevBtn.disabled = index <= 0; + nextBtn.disabled = index >= currentGroup.length - 1; + } else { + prevBtn.disabled = false; + nextBtn.disabled = false; + } + } + + // Update filmstrip + updateFilmstrip(); + + // Render any annotations over the enlarged image + renderAnnotations(item); + } + + // --------------------------------------------------------------------------- + // Annotations (over the enlarged image) + // --------------------------------------------------------------------------- + + /** + * Render annotation markers for the current slide using the shared + * GDAnnotate API, so they match the in-page annotations exactly. The markers + * live in a layer that is sized to the displayed image by positionAnnotations. + */ + function renderAnnotations(item) { + var imageWrap = qs("." + PREFIX + "-image-wrap", overlay); + if (!imageWrap) return; + + // Clear any layer from the previous slide + var existing = qs("." + PREFIX + "-annotations", imageWrap); + if (existing) existing.remove(); + + if (!item.annotations || !window.GDAnnotate || !window.GDAnnotate.buildOverlay) { + return; + } + + var layer = el("div", { className: PREFIX + "-annotations" }); + layer.appendChild(window.GDAnnotate.buildOverlay(item.annotations)); + imageWrap.appendChild(layer); + + // The image src was just (re)set, so its layout box may not be final yet. + // Position immediately (no reveal), then reveal once it has loaded and as a + // fallback after the open animation (covers cached images). + var mainImg = qs("." + PREFIX + "-main-img", overlay); + positionAnnotations(false); + if (mainImg) { + mainImg.addEventListener("load", function () { + positionAnnotations(true); + }, { once: true }); + } + setTimeout(function () { positionAnnotations(true); }, TRANSITION_MS + 60); + } + + /** Size/position the annotation layer to exactly cover the displayed image. */ + function positionAnnotations(reveal) { + if (!overlay) return; + var imageWrap = qs("." + PREFIX + "-image-wrap", overlay); + var mainImg = imageWrap && qs("." + PREFIX + "-main-img", overlay); + var layer = imageWrap && qs("." + PREFIX + "-annotations", imageWrap); + if (!layer || !mainImg) return; + + layer.style.left = mainImg.offsetLeft + "px"; + layer.style.top = mainImg.offsetTop + "px"; + layer.style.width = mainImg.offsetWidth + "px"; + layer.style.height = mainImg.offsetHeight + "px"; + if (reveal) layer.classList.add("visible"); + } + + // --------------------------------------------------------------------------- + // Filmstrip + // --------------------------------------------------------------------------- + + function updateFilmstrip() { + var filmstrip = qs("." + PREFIX + "-filmstrip", overlay); + if (!filmstrip) return; + + if (!currentGroup || currentGroup.length <= 1) { + filmstrip.style.display = "none"; + overlay.classList.remove(PREFIX + "-has-filmstrip"); + return; + } + + filmstrip.style.display = ""; + // Reserve bottom space so the caption clears the filmstrip (see CSS). + overlay.classList.add(PREFIX + "-has-filmstrip"); + filmstrip.innerHTML = ""; + + currentGroup.forEach(function (item, i) { + var thumb = el("button", { + className: + PREFIX + "-filmstrip-thumb" + (i === currentIndex ? " active" : ""), + "aria-label": "Go to image " + (i + 1), + onClick: function () { + currentIndex = i; + showSlide(i); + announce("Image " + (i + 1) + " of " + currentGroup.length); + }, + }); + var img = el("img", { + src: getImageSrc(item), + alt: "", + "aria-hidden": "true", + }); + thumb.appendChild(img); + filmstrip.appendChild(thumb); + }); + + // Scroll active thumb into view + var active = qs("." + PREFIX + "-filmstrip-thumb.active", filmstrip); + if (active) { + active.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" }); + } + } + + // --------------------------------------------------------------------------- + // Origin-Aware Animation + // --------------------------------------------------------------------------- + + function animateOpen(item) { + var rect = item.img.getBoundingClientRect(); + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (!mainImg) return; + + // Set starting transform to match thumbnail position + var vpW = window.innerWidth; + var vpH = window.innerHeight; + + // Calculate scale and translation + var targetW = Math.min(vpW * 0.9, mainImg.naturalWidth || vpW * 0.8); + var scaleX = rect.width / targetW; + var scaleY = rect.height / (targetW * (rect.height / rect.width)); + + mainImg.style.transition = "none"; + mainImg.style.transform = + "translate(" + + (rect.left + rect.width / 2 - vpW / 2) + + "px, " + + (rect.top + rect.height / 2 - vpH / 2) + + "px) scale(" + + scaleX + + ")"; + mainImg.style.opacity = "0.8"; + + // Force reflow + mainImg.offsetHeight; + + // Animate to center + mainImg.style.transition = + "transform " + TRANSITION_MS + "ms cubic-bezier(0.4, 0, 0.2, 1), " + + "opacity " + TRANSITION_MS + "ms ease"; + mainImg.style.transform = "translate(0, 0) scale(1)"; + mainImg.style.opacity = "1"; + + // Clean up after animation. Don't clobber an active zoom if the user + // zoomed during the open transition — only clear the open transform. + setTimeout(function () { + mainImg.style.transition = ""; + mainImg.style.transform = zoomScale > 1 ? "scale(" + zoomScale + ")" : ""; + }, TRANSITION_MS + 50); + } + + // --------------------------------------------------------------------------- + // Toolbar Actions + // --------------------------------------------------------------------------- + + function handleCopy() { + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (!mainImg || !mainImg.src) return; + var src = mainImg.src; + + // The async Clipboard API only reliably accepts image/png (SVG and other + // types are rejected), so we rasterize whatever is displayed — including + // SVG — to a PNG before copying. We hand a Promise to ClipboardItem so the + // async rasterization happens inside the user-activation window, which + // Safari requires; doing the work first and writing afterwards loses the + // gesture and the write (and any fallback) silently fails. + var canWriteImage = + window.ClipboardItem && navigator.clipboard && navigator.clipboard.write; + + if (canWriteImage) { + var item = new ClipboardItem({ "image/png": toPngBlob(src) }); + navigator.clipboard + .write([item]) + .then(function () { showToast("Image copied"); }) + .catch(function () { fallbackCopyUrl(src); }); + } else { + fallbackCopyUrl(src); + } + } + + /** + * Rasterize an image URL (raster or SVG) to a PNG Blob via canvas. + * Returns a Promise; rejects if the image can't be loaded or the + * canvas is tainted (e.g. a cross-origin source without CORS headers). + */ + function toPngBlob(src) { + return new Promise(function (resolve, reject) { + var img = new Image(); + img.crossOrigin = "anonymous"; + img.onload = function () { + var w = img.naturalWidth || img.width; + var h = img.naturalHeight || img.height; + if (!w || !h) { + reject(new Error("Image has no intrinsic size")); + return; + } + var canvas = document.createElement("canvas"); + canvas.width = w; + canvas.height = h; + try { + canvas.getContext("2d").drawImage(img, 0, 0, w, h); + canvas.toBlob(function (blob) { + blob ? resolve(blob) : reject(new Error("toBlob returned null")); + }, "image/png"); + } catch (e) { + reject(e); + } + }; + img.onerror = function () { reject(new Error("Image load failed")); }; + img.src = src; + }); + } + + /** Fallback when image copy isn't possible: copy the image URL as text. */ + function fallbackCopyUrl(src) { + if (navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard + .writeText(src) + .then(function () { showToast("Image URL copied"); }) + .catch(function () { showToast("Copy not supported"); }); + } else { + showToast("Copy not supported"); + } + } + + function handleDownload() { + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (!mainImg || !mainImg.src) return; + + var item = currentGroup[currentIndex]; + var filename = item + ? (item.alt || item.src.split("/").pop() || "image") + : "image"; + // Sanitize filename + filename = filename.replace(/[^a-zA-Z0-9_\-. ]/g, "_").slice(0, 100); + + var a = document.createElement("a"); + a.href = mainImg.src; + a.download = filename; + a.style.display = "none"; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + } + + function handleCopyLink() { + var item = currentGroup[currentIndex]; + if (!item || !item.id) { + showToast("No link available"); + return; + } + var url = window.location.origin + window.location.pathname + "#lightbox=" + item.id; + navigator.clipboard.writeText(url).then(function () { + showToast("Link copied"); + }).catch(function () { + showToast("Could not copy link"); + }); + } + + function showToast(msg) { + var existing = qs("." + PREFIX + "-toast"); + if (existing) existing.remove(); + + var toast = el("div", { className: PREFIX + "-toast" }, [msg]); + overlay.appendChild(toast); + + // Animate in + requestAnimationFrame(function () { + toast.classList.add("visible"); + }); + + setTimeout(function () { + toast.classList.remove("visible"); + setTimeout(function () { toast.remove(); }, 300); + }, 2000); + } + + // --------------------------------------------------------------------------- + // Toolbar Auto-Hide + // --------------------------------------------------------------------------- + + function startToolbarTimer() { + clearTimeout(toolbarTimer); + showToolbar(); + toolbarTimer = setTimeout(hideToolbar, TOOLBAR_HIDE_MS); + } + + function showToolbar() { + var tb = qs("." + PREFIX + "-toolbar", overlay); + if (tb) tb.classList.remove("hidden"); + } + + function hideToolbar() { + var tb = qs("." + PREFIX + "-toolbar", overlay); + if (tb) tb.classList.add("hidden"); + // The toolbar hides via opacity (it stays in the DOM), so a tippy tooltip + // attached to a button could linger visibly. Dismiss any active ones. + hideToolbarTooltips(); + } + + /** Hide any tippy tooltips currently attached to toolbar buttons. */ + function hideToolbarTooltips() { + if (!overlay) return; + qsa("." + PREFIX + "-btn", overlay).forEach(function (btn) { + if (btn._tippy) btn._tippy.hide(); + }); + } + + // --------------------------------------------------------------------------- + // Keyboard Navigation + // --------------------------------------------------------------------------- + + function handleKeydown(e) { + if (!isOpen) return; + + switch (e.key) { + case "Escape": + close(); + e.preventDefault(); + break; + case "ArrowRight": + next(); + e.preventDefault(); + break; + case "ArrowLeft": + prev(); + e.preventDefault(); + break; + case "Tab": + trapFocus(e); + break; + case "+": + case "=": // unshifted "+" key + zoomIn(); + e.preventDefault(); + break; + case "-": + case "_": + zoomOut(); + e.preventDefault(); + break; + case "0": + zoomReset(); + e.preventDefault(); + break; + } + } + + function trapFocus(e) { + var focusable = qsa( + 'button:not([disabled]), [tabindex]:not([tabindex="-1"])', + overlay + ); + if (focusable.length === 0) return; + + var first = focusable[0]; + var last = focusable[focusable.length - 1]; + + if (e.shiftKey) { + if (document.activeElement === first) { + last.focus(); + e.preventDefault(); + } + } else { + if (document.activeElement === last) { + first.focus(); + e.preventDefault(); + } + } + } + + // --------------------------------------------------------------------------- + // Touch / Swipe + // --------------------------------------------------------------------------- + + function handleTouchStart(e) { + if (!isOpen) return; + // When zoomed, touch drives pan (pointer events), not swipe-nav/close. + if (zoomScale > 1) return; + var touch = e.touches[0]; + touchStartX = touch.clientX; + touchStartY = touch.clientY; + touchDeltaX = 0; + touchDeltaY = 0; + isSwiping = false; + } + + function handleTouchMove(e) { + if (!isOpen) return; + if (zoomScale > 1) return; + var touch = e.touches[0]; + touchDeltaX = touch.clientX - touchStartX; + touchDeltaY = touch.clientY - touchStartY; + + // Determine if horizontal or vertical swipe + if (!isSwiping && (Math.abs(touchDeltaX) > 10 || Math.abs(touchDeltaY) > 10)) { + isSwiping = true; + } + + // Prevent page scroll while swiping in lightbox + if (isSwiping) { + e.preventDefault(); + } + } + + function handleTouchEnd() { + if (!isOpen || !isSwiping) return; + + var threshold = 50; + + // Horizontal swipe → gallery navigation + if (Math.abs(touchDeltaX) > Math.abs(touchDeltaY)) { + if (touchDeltaX > threshold) { + prev(); + } else if (touchDeltaX < -threshold) { + next(); + } + } else { + // Vertical swipe down → close + if (touchDeltaY > threshold) { + close(); + } + } + + isSwiping = false; + } + + // --------------------------------------------------------------------------- + // Dark Mode Observer + // --------------------------------------------------------------------------- + + function setupDarkModeObserver() { + var html = document.documentElement; + var observer = new MutationObserver(function (mutations) { + var newDarkMode = detectDarkMode(); + if (newDarkMode !== isDarkMode) { + isDarkMode = newDarkMode; + if (isOpen) { + // Swap image source + showSlide(currentIndex); + } + // Also swap thumbnails on the page + swapThumbnails(); + } + }); + observer.observe(html, { + attributes: true, + attributeFilter: ["class", "data-bs-theme"], + }); + } + + function swapThumbnails() { + allItems.forEach(function (item) { + if (item.darkSrc) { + item.img.setAttribute("src", getImageSrc(item)); + } + }); + } + + // --------------------------------------------------------------------------- + // Screen Reader Announcements + // --------------------------------------------------------------------------- + + function announce(msg) { + var region = qs("." + PREFIX + "-sr-announce", overlay); + if (region) { + region.textContent = msg; + } + } + + // --------------------------------------------------------------------------- + // Deep Linking + // --------------------------------------------------------------------------- + + function checkDeepLink() { + var hash = window.location.hash; + if (!hash.startsWith("#lightbox=")) return; + + var id = hash.slice("#lightbox=".length); + var item = allItems.find(function (it) { + return it.id === id; + }); + if (item) { + // Delay to allow page to render + setTimeout(function () { open(item); }, 100); + } + } + + // --------------------------------------------------------------------------- + // Event Binding + // --------------------------------------------------------------------------- + + function bindClick(item) { + // Click on wrapper or expand button opens lightbox + item.wrapper.addEventListener("click", function (e) { + e.preventDefault(); + e.stopPropagation(); + open(item); + }); + + // Make wrapper keyboard-accessible + item.wrapper.setAttribute("tabindex", "0"); + item.wrapper.setAttribute("role", "button"); + item.wrapper.setAttribute("aria-label", "View image: " + (item.alt || "image")); + item.wrapper.addEventListener("keydown", function (e) { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + open(item); + } + }); + } + + // --------------------------------------------------------------------------- + // Init + // --------------------------------------------------------------------------- + + function init() { + isDarkMode = detectDarkMode(); + collectItems(); + + if (allItems.length === 0) return; + + allItems.forEach(bindClick); + setupDarkModeObserver(); + + // Global keyboard handler + document.addEventListener("keydown", handleKeydown); + + // Touch handlers on overlay (after it's created) + document.addEventListener("touchstart", function (e) { + if (isOpen) handleTouchStart(e); + }, { passive: true }); + document.addEventListener("touchmove", function (e) { + if (isOpen) handleTouchMove(e); + }, { passive: false }); + document.addEventListener("touchend", function (e) { + if (isOpen) handleTouchEnd(e); + }, { passive: true }); + + // Mouse movement re-shows toolbar + document.addEventListener("mousemove", function () { + if (isOpen) startToolbarTimer(); + }); + + // Keep annotation markers aligned to the image when the viewport resizes + window.addEventListener("resize", function () { + if (!isOpen) return; + positionAnnotations(false); + if (zoomScale > 1) { + clampPan(); + applyTransform(); + } + }); + + // Deep link check + checkDeepLink(); + window.addEventListener("hashchange", checkDeepLink); + } + + // Run on DOM ready + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", init); + } else { + init(); + } +})(); diff --git a/docs/back-to-top.js b/docs/back-to-top.js new file mode 100644 index 0000000..0d938c7 --- /dev/null +++ b/docs/back-to-top.js @@ -0,0 +1,122 @@ +/** + * Back-to-Top Button for Great Docs + * + * Features: + * - Floating button that appears after scrolling down + * - Smooth scroll animation to page top + * - Respects reduced-motion preferences + * - Positioned to avoid collision with prev/next page navigation + * - Dark mode aware + * - Keyboard accessible + */ + +(function() { + 'use strict'; + + // How far (in pixels) the user must scroll before the button appears + var SCROLL_THRESHOLD = 300; + + /** + * Check if the user prefers reduced motion + */ + function prefersReducedMotion() { + return window.matchMedia('(prefers-reduced-motion: reduce)').matches; + } + + /** + * Create the back-to-top button element + */ + function createButton() { + var btn = document.createElement('button'); + btn.className = 'gd-back-to-top'; + btn.setAttribute('aria-label', 'Back to top'); + btn.setAttribute('title', 'Back to top'); + btn.setAttribute('type', 'button'); + + // Chevron-up SVG icon (Lucide-style, 24×24) + btn.innerHTML = + ''; + + return btn; + } + + /** + * Scroll to the top of the page + */ + function scrollToTop() { + if (prefersReducedMotion()) { + // Instant scroll for reduced-motion preference + window.scrollTo(0, 0); + } else { + window.scrollTo({ top: 0, behavior: 'smooth' }); + } + } + + /** + * Update button visibility based on scroll position + */ + function updateVisibility(btn) { + if (window.scrollY > SCROLL_THRESHOLD) { + btn.classList.add('gd-back-to-top-visible'); + } else { + btn.classList.remove('gd-back-to-top-visible'); + } + } + + /** + * Check if prev/next page navigation is near the viewport bottom + * and adjust button position to avoid overlap + */ + function adjustForPageNav(btn) { + var pageNav = document.querySelector('.page-navigation'); + if (!pageNav) return; + + var navRect = pageNav.getBoundingClientRect(); + var viewportHeight = window.innerHeight; + + // If the page nav is visible in the viewport, shift the button up + if (navRect.top < viewportHeight && navRect.bottom > 0) { + var overlap = viewportHeight - navRect.top + 16; // 16px extra gap + btn.style.bottom = Math.max(overlap, 32) + 'px'; + } else { + btn.style.bottom = ''; + } + } + + /** + * Initialize the back-to-top button + */ + function init() { + var btn = createButton(); + document.body.appendChild(btn); + + btn.addEventListener('click', scrollToTop); + + // Throttle scroll handler for performance + var ticking = false; + window.addEventListener('scroll', function() { + if (!ticking) { + window.requestAnimationFrame(function() { + updateVisibility(btn); + adjustForPageNav(btn); + ticking = false; + }); + ticking = true; + } + }, { passive: true }); + + // Initial state + updateVisibility(btn); + } + + // DOM ready check + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } +})(); diff --git a/docs/changelog/index.html b/docs/changelog/index.html new file mode 100644 index 0000000..90d21c7 --- /dev/null +++ b/docs/changelog/index.html @@ -0,0 +1,630 @@ + + + + + + + + + +Changelog – switchlang | switchlang + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+ + + + +
+ +
+
+

Changelog

+
+ + + +
+ + + + +
+ + + +
+ + +

All notable changes to switchlang are documented in this file.

+

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

+
+

Unreleased

+
+
+

0.1.3 - 2026-06-11

+
+

Fixed

+
    +
  • An exception raised inside the with block now always aborts the switch, even when the exception object is falsy. __exit__ guarded its re-raise with if exc_val:, a truthiness test that invokes the exception’s __bool__/__len__. An exception whose __bool__ returned False slipped past the guard, so the matched case action ran before the exception propagated. The guard now tests exc_val is not None, restoring the documented “no case actions run on exception” guarantee for every exception type. (#15)
  • +
+
+
+
+

0.1.2 - 2026-06-11

+

This release brings switchlang’s whole public-facing surface up to date — a documentation site, a shipped type-hint contract, refreshed docs — and fixes two correctness bugs in the public API (#13, #14).

+
+

Added

+
    +
  • Type information now ships with the package. A py.typed marker makes the hints public API, so switchlang’s signatures type-check and autocomplete in IDEs and type checkers. Every public signature is annotated — case() -> bool, __enter__() -> switch, __exit__(...), result -> Any, and closed_range(...) -> range — using modern, Python 3.9-safe syntax (from __future__ import annotations). (#13)
  • +
  • Documentation site at mkennedy.codes/docs/python-switch, built with Great Docs (Quarto): a landing page plus an API reference for switch and closed_range. Includes scripts/build_docs.py and scripts/serve_docs.py. (#13)
  • +
  • closed_range() now validates its step. A step less than 1 raises a clear ValueError instead of surfacing a raw range error (for step=0) or silently producing an empty range (for a negative step). (#14)
  • +
  • uv add switchlang installation instructions alongside pip. (#13)
  • +
+
+
+

Changed

+
    +
  • Packaging modernized to pyproject.toml + hatchling: the version is read from package metadata, a [dev] extra is provided, Python 3.9–3.15 classifiers and a Typing :: Typed classifier are declared, and full project URLs (docs, repository, issues, PyPI, funding) are published. (#13)
  • +
  • case() now always returns bool. It previously returned None on a scalar no-match but False on a list no-match; the return value is now a consistent bool. (#13)
  • +
  • Tooling: ruff pinned to target-version = "py39" to match requires-python = ">=3.9". (#13)
  • +
+
+
+

Fixed

+
    +
  • closed_range(start, stop, step) no longer overshoots stop when step > 1. The inclusive bound was built as range(start, stop + step, step), which added a full extra step — e.g. closed_range(1, 6, 2) yielded [1, 3, 5, 7], letting 7 (a value outside the stated range) silently match the case. The bound is now computed as stop + 1, so values never pass stop while stop is still included when a step lands on it exactly (closed_range(1, 7, 2) -> 1, 3, 5, 7). (#14)
  • +
  • .result no longer breaks for matched cases that return an always-equal object. The “no result” sentinel was compared with ==, so a returned object with a permissive __eq__ (a NumPy array is the real-world case) made .result raise “No result has been computed” even though a result existed. The sentinel is now compared by identity (is). (#14)
  • +
+
+
+

Documentation

+
    +
  • README refreshed: version and docs badges, a prominent link to the documentation site, an honest feature list (“Validates that case actions are callable”, replacing an inaccurate signature-verification claim), a new s.result bullet, a new “Fall-through and results” section, a new “Why not just match?” section, a closed_range usage example, and f-strings throughout. (#13)
  • +
  • Docstrings rewritten to render as the API reference: switch is described as a context manager; default() documents that ordering is not enforced (register it last); case() documents its return contract, the ValueErrors it raises, and the internal no-match sentinel; result documents that the last function executed wins under fall-through; and closed_range is documented as returning a range object (not a “generator”) with its step semantics and ValueError. (#13)
  • +
+
+
+
+

0.1.1 - 2025-09-11

+
+

Changed

+
    +
  • Standardized string literals on double quotes across the codebase and added an initial round of type annotations, including a fix for a potential type warning on s.result.
  • +
+
+
+
+

0.1.0 - 2020-12-10

+
+

Added

+
    +
  • Initial public release of switchlang on PyPI: an explicit switch block for Python built on the with statement, with default cases, duplicate-case detection, list/range cases, opt-in fall-through, and the closed_range helper.
  • +
+ + +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/changelog/index.md b/docs/changelog/index.md new file mode 100644 index 0000000..ba13dc3 --- /dev/null +++ b/docs/changelog/index.md @@ -0,0 +1,64 @@ +# Changelog + +All notable changes to **switchlang** are documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + +# [Unreleased](https://github.com/mikeckennedy/python-switch/compare/v0.1.3...HEAD) + + +# [0.1.3](https://github.com/mikeckennedy/python-switch/compare/v0.1.2...v0.1.3) - 2026-06-11 + + +## Fixed + +- **An exception raised inside the `with` block now always aborts the switch, even when the exception object is falsy.** [__exit__](../reference/switch.md#switchlang.switch.__exit__) guarded its re-raise with `if exc_val:`, a truthiness test that invokes the exception's `__bool__`/`__len__`. An exception whose `__bool__` returned `False` slipped past the guard, so the matched case action ran before the exception propagated. The guard now tests `exc_val is not None`, restoring the documented "no case actions run on exception" guarantee for every exception type. ([\#15](https://github.com/mikeckennedy/python-switch/issues/15)) + + +# [0.1.2](https://github.com/mikeckennedy/python-switch/compare/v0.1.1...v0.1.2) - 2026-06-11 + +This release brings switchlang's whole public-facing surface up to date -- a documentation site, a shipped type-hint contract, refreshed docs -- and fixes two correctness bugs in the public API ([\#13](https://github.com/mikeckennedy/python-switch/issues/13), [\#14](https://github.com/mikeckennedy/python-switch/issues/14)). + + +## Added + +- **Type information now ships with the package.** A `py.typed` marker makes the hints public API, so switchlang's signatures type-check and autocomplete in IDEs and type checkers. Every public signature is annotated -- `case() -> bool`, `__enter__() -> switch`, `__exit__(...)`, `result -> Any`, and `closed_range(...) -> range` -- using modern, Python 3.9-safe syntax (`from __future__ import annotations`). ([\#13](https://github.com/mikeckennedy/python-switch/issues/13)) +- **Documentation site** at [mkennedy.codes/docs/python-switch](https://mkennedy.codes/docs/python-switch/), built with [Great Docs](https://github.com/posit-dev/great-docs) (Quarto): a landing page plus an API reference for [switch](../reference/switch.md#switchlang.switch) and [closed_range](../reference/closed_range.md#switchlang.closed_range). Includes `scripts/build_docs.py` and `scripts/serve_docs.py`. ([\#13](https://github.com/mikeckennedy/python-switch/issues/13)) +- **[closed_range()](../reference/closed_range.md#switchlang.closed_range) now validates its step.** A `step` less than 1 raises a clear `ValueError` instead of surfacing a raw `range` error (for `step=0`) or silently producing an empty range (for a negative step). ([\#14](https://github.com/mikeckennedy/python-switch/issues/14)) +- `uv add switchlang` installation instructions alongside pip. ([\#13](https://github.com/mikeckennedy/python-switch/issues/13)) + + +## Changed + +- **Packaging modernized** to `pyproject.toml` + hatchling: the version is read from package metadata, a `[dev]` extra is provided, Python 3.9-3.15 classifiers and a `Typing :: Typed` classifier are declared, and full project URLs (docs, repository, issues, PyPI, funding) are published. ([\#13](https://github.com/mikeckennedy/python-switch/issues/13)) +- **[case()](../reference/switch.md#switchlang.switch.case) now always returns `bool`.** It previously returned `None` on a scalar no-match but `False` on a list no-match; the return value is now a consistent `bool`. ([\#13](https://github.com/mikeckennedy/python-switch/issues/13)) +- Tooling: ruff pinned to `target-version = "py39"` to match `requires-python = ">=3.9"`. ([\#13](https://github.com/mikeckennedy/python-switch/issues/13)) + + +## Fixed + +- **`closed_range(start, stop, step)` no longer overshoots `stop` when `step > 1`.** The inclusive bound was built as `range(start, stop + step, step)`, which added a full extra step -- e.g. `closed_range(1, 6, 2)` yielded `[1, 3, 5, 7]`, letting `7` (a value outside the stated range) silently match the case. The bound is now computed as `stop + 1`, so values never pass `stop` while `stop` is still included when a step lands on it exactly (`closed_range(1, 7, 2)` -\> `1, 3, 5, 7`). ([\#14](https://github.com/mikeckennedy/python-switch/issues/14)) +- **`.result` no longer breaks for matched cases that return an always-equal object.** The "no result" sentinel was compared with `==`, so a returned object with a permissive `__eq__` (a NumPy array is the real-world case) made `.result` raise *"No result has been computed"* even though a result existed. The sentinel is now compared by identity (`is`). ([\#14](https://github.com/mikeckennedy/python-switch/issues/14)) + + +## Documentation + +- **README refreshed:** version and docs badges, a prominent link to the documentation site, an honest feature list ("Validates that case actions are callable", replacing an inaccurate signature-verification claim), a new `s.result` bullet, a new "Fall-through and results" section, a new "Why not just `match`?" section, a [closed_range](../reference/closed_range.md#switchlang.closed_range) usage example, and f-strings throughout. ([\#13](https://github.com/mikeckennedy/python-switch/issues/13)) +- **Docstrings rewritten to render as the API reference:** [switch](../reference/switch.md#switchlang.switch) is described as a context manager; [default()](../reference/switch.md#switchlang.switch.default) documents that ordering is not enforced (register it last); [case()](../reference/switch.md#switchlang.switch.case) documents its return contract, the `ValueError`s it raises, and the internal no-match sentinel; [result](../reference/switch.md#switchlang.switch.result) documents that the last function executed wins under fall-through; and [closed_range](../reference/closed_range.md#switchlang.closed_range) is documented as returning a `range` object (not a "generator") with its step semantics and `ValueError`. ([\#13](https://github.com/mikeckennedy/python-switch/issues/13)) + + +# [0.1.1](https://github.com/mikeckennedy/python-switch/releases/tag/v0.1.1) - 2025-09-11 + + +## Changed + +- Standardized string literals on double quotes across the codebase and added an initial round of type annotations, including a fix for a potential type warning on `s.result`. + + +# [0.1.0](https://pypi.org/project/switchlang/0.1.0/) - 2020-12-10 + + +## Added + +- Initial public release of switchlang on PyPI: an explicit [switch](../reference/switch.md#switchlang.switch) block for Python built on the `with` statement, with default cases, duplicate-case detection, list/range cases, opt-in fall-through, and the [closed_range](../reference/closed_range.md#switchlang.closed_range) helper. diff --git a/docs/color-swatch.js b/docs/color-swatch.js new file mode 100644 index 0000000..a035643 --- /dev/null +++ b/docs/color-swatch.js @@ -0,0 +1,186 @@ +/** + * Color Swatch Extension for Great Docs + * + * Handles Tippy.js tooltips, click-to-copy with feedback overlay, + * and tooltip copy buttons for the color-swatch shortcode. + */ +(function () { + "use strict"; + + var containers = document.querySelectorAll(".gd-color-swatch"); + if (!containers.length) return; + + // Check icon SVG for copy feedback overlay + var checkSvg = + ''; + + /** + * Copy text to clipboard with fallback for non-HTTPS contexts. + */ + function copyToClipboard(text) { + if (navigator.clipboard && navigator.clipboard.writeText) { + return navigator.clipboard.writeText(text); + } + // Fallback: hidden textarea + execCommand + return new Promise(function (resolve, reject) { + var ta = document.createElement("textarea"); + ta.value = text; + ta.style.position = "fixed"; + ta.style.left = "-9999px"; + ta.style.opacity = "0"; + document.body.appendChild(ta); + ta.select(); + try { + document.execCommand("copy"); + resolve(); + } catch (err) { + reject(err); + } finally { + document.body.removeChild(ta); + } + }); + } + + /** + * Show a brief checkmark overlay on a swatch element after copying. + */ + function showCopyFeedback(el) { + var overlay = document.createElement("div"); + overlay.className = "gd-swatch-copy-overlay"; + overlay.innerHTML = checkSvg; + el.appendChild(overlay); + + // Announce for screen readers + var liveRegion = document.getElementById("gd-cs-live"); + if (liveRegion) { + liveRegion.textContent = "Copied"; + } + + requestAnimationFrame(function () { + overlay.style.opacity = "1"; + setTimeout(function () { + overlay.style.opacity = "0"; + setTimeout(function () { + overlay.remove(); + }, 300); + }, 700); + }); + } + + /** + * Get the hex value to copy from a swatch element. + */ + function getHexFromEl(el) { + return ( + el.getAttribute("data-hex") || + el.querySelector("[data-hex]")?.getAttribute("data-hex") || + "" + ); + } + + /** + * Handle click-to-copy on a swatch. + */ + function handleSwatchClick(e) { + var el = e.currentTarget; + var hex = getHexFromEl(el); + if (!hex) return; + + // Find the color fill element for the overlay + var colorEl = el.classList.contains("gd-swatch-color") + ? el + : el.querySelector(".gd-swatch-color") || el; + + copyToClipboard(hex).then(function () { + showCopyFeedback(colorEl); + }); + } + + /** + * Handle keyboard activation (Enter/Space). + */ + function handleSwatchKeydown(e) { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + handleSwatchClick(e); + } + } + + /** + * Initialize tooltips on elements with data-tooltip-html. + */ + function initTooltips(container) { + if (typeof tippy === "undefined") return; + + var els = container.querySelectorAll("[data-tooltip-html]"); + els.forEach(function (el) { + var content = el.getAttribute("data-tooltip-html"); + if (!content) return; + + tippy(el, { + content: content, + allowHTML: true, + placement: "top", + delay: [150, 100], + interactive: true, + appendTo: document.body, + maxWidth: 320, + onShown: function (instance) { + // Attach copy handlers to tooltip copy buttons + var btns = instance.popper.querySelectorAll(".gd-cs-tooltip-copy"); + btns.forEach(function (btn) { + btn.addEventListener("click", function (e) { + e.stopPropagation(); + var hex = btn.getAttribute("data-hex"); + if (hex) { + copyToClipboard(hex).then(function () { + btn.textContent = "\u2713"; + setTimeout(function () { + btn.innerHTML = "📋"; + }, 1000); + }); + } + }); + }); + }, + }); + }); + } + + /** + * Initialize a single color-swatch container. + */ + function initContainer(container) { + // Circle swatches — click on the wrapper (.gd-swatch) + var swatches = container.querySelectorAll(".gd-swatch"); + swatches.forEach(function (el) { + el.addEventListener("click", handleSwatchClick); + el.addEventListener("keydown", handleSwatchKeydown); + }); + + // Rectangle swatches — click on the strip (.gd-swatch-rect) + var rects = container.querySelectorAll(".gd-swatch-rect"); + rects.forEach(function (el) { + el.addEventListener("click", handleSwatchClick); + el.addEventListener("keydown", handleSwatchKeydown); + }); + + // Tooltips (attach to color fills and rects) + initTooltips(container); + } + + // Create a live region for screen reader announcements + if (!document.getElementById("gd-cs-live")) { + var live = document.createElement("div"); + live.id = "gd-cs-live"; + live.setAttribute("aria-live", "polite"); + live.setAttribute("aria-atomic", "true"); + live.className = "visually-hidden"; + document.body.appendChild(live); + } + + // Initialize all containers + containers.forEach(initContainer); +})(); diff --git a/docs/copy-code.js b/docs/copy-code.js new file mode 100644 index 0000000..d8c68fb --- /dev/null +++ b/docs/copy-code.js @@ -0,0 +1,176 @@ +/** + * Custom copy-code button for Great Docs + * + * Replaces Quarto's default code-copy with a consistent top-right button + * that floats properly and works in both light and dark modes. + * + * Handles: + * - Buttons injected by post-render.py (.gd-code-copy inside .gd-code-nav) + * - Quarto-native code blocks (pre.code-with-copy) that lack a custom button + */ +(function () { + "use strict"; + + // i18n helper — read translations from + var _i18nCache = null; + function _gdT(key, fallback) { + if (!_i18nCache) { + try { + var meta = document.querySelector('meta[name="gd-i18n"]'); + _i18nCache = meta ? JSON.parse(meta.getAttribute('content')) : {}; + } catch (e) { _i18nCache = {}; } + } + return _i18nCache[key] || fallback; + } + + // Inline SVG icons — no external dependency + var COPY_ICON = + '' + + '' + + '' + + ""; + + var CHECK_ICON = + '' + + '' + + ""; + + /** + * Walk up from the button to find the element whose text to copy. + */ + function getCodeText(button) { + var scaffold = button.closest(".code-copy-outer-scaffold"); + if (scaffold) { + var code = scaffold.querySelector("pre > code"); + if (code) return code.textContent; + } + // Fallback: walk up to the nav, then find sibling pre > code + var nav = button.closest(".gd-code-nav"); + if (nav) { + var container = nav.parentElement; + if (container) { + var code = container.querySelector("pre > code"); + if (code) return code.textContent; + } + } + return ""; + } + + /** + * Copy handler with visual feedback. + */ + function handleCopy(event) { + var button = event.currentTarget; + var text = getCodeText(button); + if (!text) return; + + navigator.clipboard.writeText(text).then(function () { + button.innerHTML = CHECK_ICON; + button.classList.add("gd-code-copied"); + button.setAttribute("title", _gdT("copied", "Copied!")); + + setTimeout(function () { + button.innerHTML = COPY_ICON; + button.classList.remove("gd-code-copied"); + button.setAttribute("title", _gdT("copy_to_clipboard", "Copy to clipboard")); + }, 2000); + }); + } + + /** + * Create a gd-code-nav + gd-code-copy button element. + */ + function createCopyButton() { + var nav = document.createElement("nav"); + nav.className = "gd-code-nav"; + var btn = document.createElement("button"); + btn.className = "gd-code-copy"; + btn.title = _gdT("copy_to_clipboard", "Copy to clipboard"); + btn.innerHTML = COPY_ICON; + btn.addEventListener("click", handleCopy); + nav.appendChild(btn); + return nav; + } + + /** + * Replace any leftover Quarto-native .code-copy-button with our component. + */ + function replaceQuartoButtons() { + document + .querySelectorAll("button.code-copy-button") + .forEach(function (oldBtn) { + var nav = createCopyButton(); + + // The Quarto button lives inside a wrapper div; insert the nav there + var parent = oldBtn.parentElement; + if (parent) { + parent.insertBefore(nav, oldBtn); + parent.removeChild(oldBtn); + // Ensure the wrapper acts as a positioning anchor + parent.style.position = "relative"; + } + }); + } + + /** + * Inject a copy button into any code block that doesn't already have one. + * Targets
wrappers and Quarto
 blocks.
+   */
+  function injectMissingButtons() {
+    // Find all 
that aren't inside a scaffold + document.querySelectorAll("div.sourceCode").forEach(function (div) { + // Skip if already inside a scaffold with a button + if (div.closest(".code-copy-outer-scaffold")) return; + // Skip if already has a gd-code-nav + if (div.querySelector(".gd-code-nav")) return; + + var code = div.querySelector("pre > code"); + if (!code) return; + + div.style.position = "relative"; + div.prepend(createCopyButton()); + }); + + // Also catch standalone
 not inside a div.sourceCode
+    document.querySelectorAll("pre.sourceCode").forEach(function (pre) {
+      var parent = pre.parentElement;
+      // Skip if already handled
+      if (parent && parent.classList.contains("sourceCode")) return;
+      if (parent && parent.querySelector(".gd-code-nav")) return;
+      if (pre.closest(".code-copy-outer-scaffold")) return;
+
+      var code = pre.querySelector("code");
+      if (!code) return;
+
+      // Wrap in a relative container
+      if (parent) {
+        parent.style.position = "relative";
+        parent.insertBefore(createCopyButton(), pre);
+      }
+    });
+  }
+
+  function init() {
+    // 1. Wire up buttons that post-render.py already injected
+    document.querySelectorAll(".gd-code-copy").forEach(function (btn) {
+      btn.innerHTML = COPY_ICON;
+      btn.addEventListener("click", handleCopy);
+    });
+
+    // 2. Convert any remaining Quarto-native copy buttons
+    replaceQuartoButtons();
+
+    // 3. Inject buttons into code blocks that have none
+    injectMissingButtons();
+  }
+
+  if (document.readyState === "loading") {
+    document.addEventListener("DOMContentLoaded", init);
+  } else {
+    init();
+  }
+})();
diff --git a/docs/copy-page.js b/docs/copy-page.js
new file mode 100644
index 0000000..8120cda
--- /dev/null
+++ b/docs/copy-page.js
@@ -0,0 +1,149 @@
+/**
+ * Copy Page Widget for Great Docs
+ *
+ * Provides two actions:
+ * - "Copy as Markdown" — copies the page's .md content to clipboard
+ * - "View as Markdown" — navigates to the .md version of the page
+ *
+ * The .md files are generated alongside .html files by the post-render script.
+ */
+
+(function() {
+    'use strict';
+
+    /**
+     * Look up a translated string from the gd-i18n meta tag.
+     */
+    var _i18nCache = null;
+    function _gdT(key, fallback) {
+        if (!_i18nCache) {
+            try {
+                var meta = document.querySelector('meta[name="gd-i18n"]');
+                _i18nCache = meta ? JSON.parse(meta.getAttribute('content')) : {};
+            } catch (e) { _i18nCache = {}; }
+        }
+        return _i18nCache[key] || fallback;
+    }
+
+    /**
+     * Derive the .md URL from the current page URL.
+     * e.g., /reference/GreatDocs.html -> /reference/GreatDocs.md
+     *       /user-guide/quickstart.html -> /user-guide/quickstart.md
+     */
+    function getMdUrl() {
+        var path = window.location.pathname;
+        // Replace .html with .md
+        if (path.endsWith('.html')) {
+            return path.slice(0, -5) + '.md';
+        }
+        // For paths ending in / (index pages), try index.md
+        if (path.endsWith('/')) {
+            return path + 'index.md';
+        }
+        return path + '.md';
+    }
+
+    /**
+     * Create and inject the copy-page widget.
+     */
+    function initCopyPage() {
+        // Find the title block header to position the button
+        var titleBlock = document.getElementById('title-block-header');
+        if (!titleBlock) return;
+
+        // Skip the Skills page (has its own layout)
+        if (document.querySelector('.gd-skills-install')) return;
+
+        // Skip the License page (has its own layout)
+        if (document.body.classList.contains('gd-license-page')) return;
+
+        // Skip the Tags index page
+        if (document.body.classList.contains('gd-tags-index')) return;
+
+        // Skip the Blog index page
+        if (document.body.classList.contains('gd-blog-index')) return;
+
+        // Create the widget container
+        var widget = document.createElement('div');
+        widget.className = 'gd-copy-page';
+        widget.setAttribute('role', 'group');
+        widget.setAttribute('aria-label', _gdT('page_actions', 'Page actions'));
+
+        // Copy as Markdown button
+        var copyBtn = document.createElement('button');
+        copyBtn.className = 'gd-copy-page-btn gd-copy-md-btn';
+        copyBtn.setAttribute('title', _gdT('copy_page_as_markdown', 'Copy page as Markdown'));
+        copyBtn.setAttribute('aria-label', _gdT('copy_page_as_markdown', 'Copy page as Markdown'));
+        copyBtn.innerHTML =
+            '' +
+            '' + _gdT('copy_page', 'Copy page') + '';
+
+        // View as Markdown link
+        var viewLink = document.createElement('a');
+        viewLink.className = 'gd-copy-page-btn gd-view-md-btn';
+        viewLink.href = getMdUrl();
+        viewLink.setAttribute('title', _gdT('view_as_markdown', 'View as Markdown'));
+        viewLink.setAttribute('aria-label', _gdT('view_page_as_markdown', 'View page as Markdown'));
+        viewLink.innerHTML =
+            '';
+
+        widget.appendChild(copyBtn);
+        widget.appendChild(viewLink);
+
+        // Insert before the title block
+        titleBlock.parentNode.insertBefore(widget, titleBlock);
+
+        // Pre-fetch the .md content so the clipboard write can happen
+        // synchronously inside the click handler (preserving user activation).
+        var mdUrl = getMdUrl();
+        var cachedMd = null;
+
+        fetch(mdUrl)
+            .then(function(response) {
+                if (!response.ok) throw new Error('not found');
+                return response.text();
+            })
+            .then(function(text) { cachedMd = text; })
+            .catch(function() { /* will show error on click */ });
+
+        // Copy handler — writes from cache so clipboard API gets user activation
+        copyBtn.addEventListener('click', function() {
+            var label = copyBtn.querySelector('.gd-copy-page-label');
+            var origText = label.textContent;
+
+            if (!cachedMd) {
+                    label.textContent = _gdT('error', 'Error');
+                setTimeout(function() { label.textContent = origText; }, 2000);
+                return;
+            }
+
+            navigator.clipboard.writeText(cachedMd)
+                .then(function() {
+                    label.textContent = _gdT('copied', 'Copied!');
+                    copyBtn.classList.add('gd-copy-success');
+                    setTimeout(function() {
+                        label.textContent = origText;
+                        copyBtn.classList.remove('gd-copy-success');
+                    }, 2000);
+                })
+                .catch(function(err) {
+                    console.warn('Copy page failed:', err);
+                    label.textContent = _gdT('error', 'Error');
+                    setTimeout(function() { label.textContent = origText; }, 2000);
+                });
+        });
+    }
+
+    // Initialize when DOM is ready
+    if (document.readyState === 'loading') {
+        document.addEventListener('DOMContentLoaded', initCopyPage);
+    } else {
+        initCopyPage();
+    }
+})();
diff --git a/docs/dark-mode-toggle.js b/docs/dark-mode-toggle.js
new file mode 100644
index 0000000..62ede84
--- /dev/null
+++ b/docs/dark-mode-toggle.js
@@ -0,0 +1,321 @@
+/**
+ * Dark Mode Toggle for Great Docs
+ *
+ * Features:
+ * - Toggle switch in the navbar
+ * - System preference detection
+ * - Persistent preference storage
+ * - Smooth transitions
+ */
+
+(function() {
+    'use strict';
+
+    // i18n helper — read translations from 
+    var _i18nCache = null;
+    function _gdT(key, fallback) {
+        if (!_i18nCache) {
+            try {
+                var meta = document.querySelector('meta[name="gd-i18n"]');
+                _i18nCache = meta ? JSON.parse(meta.getAttribute('content')) : {};
+            } catch (e) { _i18nCache = {}; }
+        }
+        return _i18nCache[key] || fallback;
+    }
+
+    const STORAGE_KEY = 'great-docs-theme';
+    const DARK_CLASS = 'quarto-dark';
+    const LIGHT_CLASS = 'quarto-light';
+
+    /**
+     * Get the user's system color scheme preference
+     */
+    function getSystemPreference() {
+        if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
+            return 'dark';
+        }
+        return 'light';
+    }
+
+    /**
+     * Get the stored theme preference
+     */
+    function getStoredPreference() {
+        try {
+            return localStorage.getItem(STORAGE_KEY);
+        } catch (e) {
+            return null;
+        }
+    }
+
+    /**
+     * Store the theme preference
+     */
+    function setStoredPreference(theme) {
+        try {
+            localStorage.setItem(STORAGE_KEY, theme);
+        } catch (e) {
+            // localStorage not available
+        }
+    }
+
+    /**
+     * Get the current effective theme
+     */
+    function getCurrentTheme() {
+        const stored = getStoredPreference();
+        if (stored === 'dark' || stored === 'light') {
+            return stored;
+        }
+        return getSystemPreference();
+    }
+
+    /**
+     * Apply the theme to the document
+     */
+    function applyTheme(theme) {
+        const html = document.documentElement;
+        const body = document.body;
+
+        if (theme === 'dark') {
+            html.classList.add(DARK_CLASS);
+            html.classList.remove(LIGHT_CLASS);
+            body.classList.add(DARK_CLASS);
+            body.classList.remove(LIGHT_CLASS);
+            html.setAttribute('data-bs-theme', 'dark');
+        } else {
+            html.classList.add(LIGHT_CLASS);
+            html.classList.remove(DARK_CLASS);
+            body.classList.add(LIGHT_CLASS);
+            body.classList.remove(DARK_CLASS);
+            html.setAttribute('data-bs-theme', 'light');
+        }
+
+        // Update toggle button state
+        updateToggleButton(theme);
+    }
+
+    /**
+     * Update the toggle button appearance
+     */
+    function updateToggleButton(theme) {
+        const toggle = document.getElementById('dark-mode-toggle');
+        if (!toggle) return;
+
+        const sunIcon = toggle.querySelector('.theme-icon-light');
+        const moonIcon = toggle.querySelector('.theme-icon-dark');
+        const newTooltip = theme === 'dark'
+            ? _gdT('switch_to_light_mode', 'Switch to light mode')
+            : _gdT('switch_to_dark_mode', 'Switch to dark mode');
+
+        if (theme === 'dark') {
+            toggle.setAttribute('aria-pressed', 'true');
+            if (sunIcon) sunIcon.style.display = 'none';
+            if (moonIcon) moonIcon.style.display = 'inline-block';
+        } else {
+            toggle.setAttribute('aria-pressed', 'false');
+            if (sunIcon) sunIcon.style.display = 'inline-block';
+            if (moonIcon) moonIcon.style.display = 'none';
+        }
+
+        // Update tooltip: use data-tippy-content to keep Tippy in sync
+        // and avoid native browser tooltips (which appear after delay)
+        toggle.setAttribute('data-tippy-content', newTooltip);
+        toggle.removeAttribute('title');
+
+        // Update existing Tippy instance content directly if present
+        if (toggle._tippy) {
+            toggle._tippy.setContent(newTooltip);
+        }
+    }
+
+    /**
+     * Toggle between light and dark themes
+     */
+    function toggleTheme() {
+        const current = getCurrentTheme();
+        const newTheme = current === 'dark' ? 'light' : 'dark';
+        setStoredPreference(newTheme);
+        applyTheme(newTheme);
+    }
+
+    /**
+     * Create the toggle button HTML
+     */
+    function createToggleButton() {
+        const container = document.createElement('div');
+        container.id = 'dark-mode-toggle-container';
+        container.innerHTML = `
+            
+        `;
+        return container;
+    }
+
+    /**
+     * Insert the toggle button into the navbar
+     */
+    function insertToggleButton() {
+        // Insert into navbarCollapse; navbar-widgets.js will collect it
+        // into the unified #gd-navbar-widgets container.
+        const collapse = document.getElementById('navbarCollapse');
+        if (!collapse) return;
+
+        const toggleContainer = createToggleButton();
+        const navItem = document.createElement('li');
+        navItem.className = 'nav-item';
+        navItem.appendChild(toggleContainer);
+
+        // Append to navbarCollapse (the collector will move it)
+        var msAuto = collapse.querySelector('.navbar-nav.ms-auto');
+        if (msAuto) {
+            msAuto.insertBefore(navItem, msAuto.firstChild);
+        } else {
+            collapse.appendChild(navItem);
+        }
+
+        // Add click handler
+        const toggle = document.getElementById('dark-mode-toggle');
+        if (toggle) {
+            toggle.addEventListener('click', toggleTheme);
+        }
+    }
+
+    /**
+     * Listen for system preference changes
+     */
+    function setupSystemPreferenceListener() {
+        if (!window.matchMedia) return;
+
+        const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
+
+        mediaQuery.addEventListener('change', (e) => {
+            // Only respond to system changes if user hasn't set a preference
+            const stored = getStoredPreference();
+            if (!stored) {
+                applyTheme(e.matches ? 'dark' : 'light');
+            }
+        });
+    }
+
+    /**
+     * Apply theme immediately to prevent flash
+     */
+    function applyInitialTheme() {
+        const theme = getCurrentTheme();
+
+        // Apply to html element immediately (before body is available)
+        const html = document.documentElement;
+        if (theme === 'dark') {
+            html.classList.add(DARK_CLASS);
+            html.classList.remove(LIGHT_CLASS);
+            html.setAttribute('data-bs-theme', 'dark');
+        } else {
+            html.classList.add(LIGHT_CLASS);
+            html.classList.remove(DARK_CLASS);
+            html.setAttribute('data-bs-theme', 'light');
+        }
+    }
+
+    /**
+     * Fix the navbar dark-logo src from a  tag.
+     * Quarto's logo-dark config is ignored without a paired dark theme,
+     * so both .light-content and .dark-content imgs point to the same file.
+     * We read the correct dark logo path from 
+     * and patch the src at runtime.
+     */
+    function fixNavbarDarkLogo() {
+        var meta = document.querySelector('meta[name="gd-logo-dark"]');
+        if (!meta) return;
+        var darkFilename = meta.getAttribute('content');
+        if (!darkFilename) return;
+
+        // Resolve the dark logo path relative to the light logo's directory,
+        // so sub-pages (e.g. user-guide/page.html) get the correct "../" prefix.
+        var lightImg = document.querySelector('.navbar-logo.light-content');
+        var darkSrc = darkFilename;
+        if (lightImg && lightImg.getAttribute('src')) {
+            var lightSrc = lightImg.getAttribute('src');
+            var lastSlash = lightSrc.lastIndexOf('/');
+            if (lastSlash >= 0) {
+                darkSrc = lightSrc.substring(0, lastSlash + 1) + darkFilename;
+            }
+        }
+
+        document.querySelectorAll('.navbar-logo.dark-content').forEach(function(img) {
+            img.src = darkSrc;
+        });
+    }
+
+    /**
+     * Initialize dark mode functionality
+     */
+    function init() {
+        // Fix navbar dark logo src before applying theme
+        fixNavbarDarkLogo();
+
+        // Apply theme to body now that DOM is ready
+        const theme = getCurrentTheme();
+        applyTheme(theme);
+
+        // Insert toggle button
+        insertToggleButton();
+
+        // Update toggle button to reflect current theme (must be after insertion)
+        updateToggleButton(theme);
+
+        // Setup system preference listener
+        setupSystemPreferenceListener();
+    }
+
+    // Apply initial theme immediately to prevent flash of wrong theme
+    applyInitialTheme();
+
+    // Initialize when DOM is ready
+    if (document.readyState === 'loading') {
+        document.addEventListener('DOMContentLoaded', init);
+    } else {
+        init();
+    }
+
+    // Expose API for external use
+    window.greatDocsDarkMode = {
+        toggle: toggleTheme,
+        setTheme: function(theme) {
+            if (theme === 'dark' || theme === 'light') {
+                setStoredPreference(theme);
+                applyTheme(theme);
+            }
+        },
+        getTheme: getCurrentTheme,
+        clearPreference: function() {
+            try {
+                localStorage.removeItem(STORAGE_KEY);
+            } catch (e) {}
+            applyTheme(getSystemPreference());
+        }
+    };
+})();
diff --git a/docs/details.js b/docs/details.js
new file mode 100644
index 0000000..6e109e3
--- /dev/null
+++ b/docs/details.js
@@ -0,0 +1,198 @@
+/**
+ * Great Docs — Collapsible Details
+ *
+ * Provides smooth expand/collapse animation and accordion-group behavior
+ * for 
elements produced by the {{< details >}} + * shortcode. + * + * Features: + * - Smooth height animation on toggle (respects prefers-reduced-motion) + * - Accordion groups: elements sharing the same data-gd-group attribute + * close siblings when one opens + * - Works with nested details elements + */ +(function () { + "use strict"; + + // ── Feature detection ────────────────────────────────────────────── + var reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"); + + // ── Animation helpers ────────────────────────────────────────────── + + /** + * Animate the opening of a
element. + * @param {HTMLDetailsElement} el + */ + function animateOpen(el) { + var body = el.querySelector(".gd-details-body"); + if (!body) return; + + // Force the element open so we can measure the target height + el.open = true; + + // Measure current (collapsed) and target (expanded) heights + var summary = el.querySelector("summary"); + var startHeight = summary ? summary.offsetHeight : 0; + var endHeight = el.scrollHeight; + + // If reduced motion is preferred, skip animation + if (reducedMotion.matches) { + el.style.height = ""; + el.style.overflow = ""; + el.classList.add("gd-details--open"); + return; + } + + el.style.height = startHeight + "px"; + el.style.overflow = "hidden"; + + // Force reflow + void el.offsetHeight; + + el.classList.add("gd-details--animating"); + el.style.height = endHeight + "px"; + + function onEnd() { + el.removeEventListener("transitionend", onEnd); + el.classList.remove("gd-details--animating"); + el.classList.add("gd-details--open"); + el.style.height = ""; + el.style.overflow = ""; + } + el.addEventListener("transitionend", onEnd); + } + + /** + * Animate the closing of a
element. + * @param {HTMLDetailsElement} el + */ + function animateClose(el) { + var body = el.querySelector(".gd-details-body"); + if (!body) return; + + // If reduced motion is preferred, just close immediately + if (reducedMotion.matches) { + el.classList.remove("gd-details--open"); + el.open = false; + return; + } + + var startHeight = el.scrollHeight; + var summary = el.querySelector("summary"); + var endHeight = summary ? summary.offsetHeight : 0; + + el.style.height = startHeight + "px"; + el.style.overflow = "hidden"; + + // Force reflow + void el.offsetHeight; + + el.classList.add("gd-details--animating"); + el.classList.remove("gd-details--open"); + el.style.height = endHeight + "px"; + + function onEnd() { + el.removeEventListener("transitionend", onEnd); + el.classList.remove("gd-details--animating"); + el.open = false; + el.style.height = ""; + el.style.overflow = ""; + } + el.addEventListener("transitionend", onEnd); + } + + // ── Accordion logic ──────────────────────────────────────────────── + + /** + * Close all other details in the same accordion group. + * @param {HTMLDetailsElement} current - The details element being opened + * @param {string} group - The accordion group name + */ + function closeGroupSiblings(current, group) { + var siblings = document.querySelectorAll( + 'details.gd-details[data-gd-group="' + group + '"]' + ); + for (var i = 0; i < siblings.length; i++) { + if (siblings[i] !== current && siblings[i].open) { + animateClose(siblings[i]); + } + } + } + + // ── Event binding ────────────────────────────────────────────────── + + /** + * Attach click handlers to all .gd-details elements. + */ + function initDetails() { + var elements = document.querySelectorAll("details.gd-details"); + + for (var i = 0; i < elements.length; i++) { + (function (el) { + // Mark initially-open elements + if (el.open) { + el.classList.add("gd-details--open"); + } + + var summary = el.querySelector("summary"); + if (!summary) return; + + summary.addEventListener("click", function (e) { + e.preventDefault(); + + if (el.open) { + // Currently open → close it + animateClose(el); + } else { + // Currently closed → open it + var group = el.getAttribute("data-gd-group"); + if (group) { + closeGroupSiblings(el, group); + } + animateOpen(el); + } + }); + })(elements[i]); + } + } + + // ── Gleam animation (JS-driven) ───────────────────────────────────── + + /** + * Animate the --gd-gleam-angle custom property via requestAnimationFrame. + * This avoids reliance on @property (inconsistent cross-browser). + */ + function initGleam() { + var gleamEls = document.querySelectorAll(".gd-details--gleam"); + if (!gleamEls.length) return; + if (reducedMotion.matches) return; + + var duration = 6000; // ms for a full 360° sweep + var start = null; + + function tick(timestamp) { + if (!start) start = timestamp; + var elapsed = (timestamp - start) % duration; + var angle = (elapsed / duration) * 360; + var value = angle + "deg"; + + for (var i = 0; i < gleamEls.length; i++) { + gleamEls[i].style.setProperty("--gd-gleam-angle", value); + } + requestAnimationFrame(tick); + } + + requestAnimationFrame(tick); + } + + // ── Initialize ───────────────────────────────────────────────────── + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", function () { + initDetails(); + initGleam(); + }); + } else { + initDetails(); + initGleam(); + } +})(); diff --git a/docs/gd-lightbox-annotate.css b/docs/gd-lightbox-annotate.css new file mode 100644 index 0000000..99c5c0a --- /dev/null +++ b/docs/gd-lightbox-annotate.css @@ -0,0 +1,180 @@ +/* GD Lightbox Annotate — Marker & Tooltip Styles */ + +.gd-annotate-overlay { + position: absolute; + inset: 0; + pointer-events: none; + z-index: 5; +} + +/* ── Marker ─────────────────────────────────────────────────────────────── */ + +.gd-annotate-marker { + --gd-annotate-marker-bg: var(--bs-primary, #0d6efd); + --gd-annotate-marker-size: 28px; + + position: absolute; + transform: translate(-50%, -50%); + width: var(--gd-annotate-marker-size); + height: var(--gd-annotate-marker-size); + border-radius: 50%; + background: var(--gd-annotate-marker-bg); + border: 2px solid #fff; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); + cursor: pointer; + pointer-events: auto; + display: flex; + align-items: center; + justify-content: center; + padding: 0; + transition: transform 0.15s ease, box-shadow 0.15s ease; + z-index: 6; +} + +.gd-annotate-marker:hover { + transform: translate(-50%, -50%) scale(1.15); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); +} + +/* Lift the active/hovered marker's whole stacking context above the other + markers so its tooltip is never painted behind a neighbouring marker. + (The tooltip is a child of the marker, so raising the marker raises it.) */ +.gd-annotate-marker:hover, +.gd-annotate-marker.gd-annotate-active { + z-index: 30; +} + +.gd-annotate-marker:focus-visible { + outline: 3px solid var(--bs-primary, #0d6efd); + outline-offset: 3px; +} + +.gd-annotate-marker-label { + color: #fff; + font-size: 12px; + font-weight: 700; + font-family: system-ui, -apple-system, sans-serif; + line-height: 1; + user-select: none; +} + +/* ── Pulse animation (shown on first view) ──────────────────────────────── */ + +.gd-annotate-pulse::after { + content: ""; + position: absolute; + inset: -4px; + border-radius: 50%; + border: 2px solid var(--gd-annotate-marker-bg); + animation: gd-annotate-pulse 2s ease-out infinite; + pointer-events: none; +} + +@keyframes gd-annotate-pulse { + 0% { + transform: scale(1); + opacity: 0.8; + } + 70% { + transform: scale(1.6); + opacity: 0; + } + 100% { + transform: scale(1.6); + opacity: 0; + } +} + +/* ── Tooltip ────────────────────────────────────────────────────────────── */ + +.gd-annotate-tooltip { + position: absolute; + left: 50%; + transform: translateX(-50%); + width: max-content; + max-width: 240px; + padding: 8px 12px; + background: var(--bs-body-bg, #fff); + color: var(--bs-body-color, #212529); + border: 1px solid var(--bs-border-color, #dee2e6); + border-radius: 6px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); + font-size: 13px; + line-height: 1.4; + font-family: system-ui, -apple-system, sans-serif; + pointer-events: none; + opacity: 0; + visibility: hidden; + transition: opacity 0.15s ease, visibility 0.15s ease; + z-index: 10; + white-space: normal; +} + +/* Position variants */ +.gd-annotate-tooltip--above { + bottom: calc(100% + 10px); + top: auto; +} + +.gd-annotate-tooltip--below { + top: calc(100% + 10px); + bottom: auto; +} + +.gd-annotate-tooltip--left { + left: auto; + right: 0; + transform: none; +} + +.gd-annotate-tooltip--right { + left: 0; + right: auto; + transform: none; +} + +/* Show tooltip states */ +.gd-annotate-active .gd-annotate-tooltip, +.gd-annotate-tooltip--hover { + opacity: 1; + visibility: visible; + pointer-events: auto; +} + +.gd-annotate-tooltip-label { + display: block; + margin-bottom: 2px; + color: var(--bs-primary, #0d6efd); +} + +.gd-annotate-tooltip-text { + display: block; +} + +/* ── Dark mode ──────────────────────────────────────────────────────────── */ + +[data-bs-theme="dark"] .gd-annotate-marker { + border-color: rgba(255, 255, 255, 0.8); +} + +[data-bs-theme="dark"] .gd-annotate-tooltip { + background: var(--bs-body-bg, #212529); + border-color: var(--bs-border-color, #495057); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4); +} + +/* ── Reduced motion ─────────────────────────────────────────────────────── */ + +@media (prefers-reduced-motion: reduce) { + .gd-annotate-pulse::after { + animation: none; + } + + .gd-annotate-marker { + transition: none; + } + + .gd-annotate-tooltip { + transition: none; + } +} diff --git a/docs/gd-lightbox-annotate.js b/docs/gd-lightbox-annotate.js new file mode 100644 index 0000000..ee6bb4d --- /dev/null +++ b/docs/gd-lightbox-annotate.js @@ -0,0 +1,225 @@ +/** + * GD Lightbox Annotate — Image Annotation Markers & Tooltips + * + * Reads JSON annotations from data-gd-lightbox-annotations attributes and + * renders numbered markers over the image with hover/click tooltips. + * + * Annotation JSON schema: + * [{ "x": 20, "y": 15, "label": "1", "text": "Description" }, ...] + * - x, y: percentage position (0-100) relative to image bounds + * - label: short text shown inside the marker circle (e.g., "1", "A") + * - text: tooltip description shown on hover/click + * - color (optional): marker color override + * + * No dependencies. ~4KB minified+gzipped target. + */ +(function () { + "use strict"; + + var PREFIX = "gd-annotate"; + var ATTR = "data-gd-lightbox-annotations"; + + function initAll() { + var wrappers = document.querySelectorAll("[" + ATTR + "]"); + for (var i = 0; i < wrappers.length; i++) { + initWrapper(wrappers[i]); + } + } + + /** + * Parse a raw annotations attribute value into an array, or null if it is + * absent / invalid / empty. + */ + function parse(raw) { + if (!raw) return null; + try { + var annotations = JSON.parse(raw); + return Array.isArray(annotations) && annotations.length ? annotations : null; + } catch (e) { + // Not valid JSON — could be a file path (future: fetch) + return null; + } + } + + function initWrapper(wrapper) { + if (wrapper.dataset.gdAnnotateInit) return; + wrapper.dataset.gdAnnotateInit = "true"; + + var annotations = parse(wrapper.getAttribute(ATTR)); + if (!annotations) return; + + wrapper.style.position = "relative"; + var overlay = buildOverlay(annotations); + wrapper.appendChild(overlay); + + // Close tooltips when clicking outside the wrapper + document.addEventListener("click", function (e) { + if (!wrapper.contains(e.target)) { + closeAll(overlay); + } + }); + } + + /** + * Build a `.gd-annotate-overlay` element populated with markers and tooltips + * for the given annotations array, with all interactions wired up. The + * overlay is `position:absolute; inset:0`, so the caller is responsible for + * sizing/positioning its container to match the target image. Edge-aware + * tooltip placement uses the overlay's own bounds. + * + * Reused by both the in-page annotator and the lightbox view. + * @param {Array} annotations + * @returns {HTMLElement} the overlay element + */ + function buildOverlay(annotations) { + var overlay = document.createElement("div"); + overlay.className = PREFIX + "-overlay"; + + annotations.forEach(function (ann, idx) { + var x = parseFloat(ann.x) || 0; + var y = parseFloat(ann.y) || 0; + var label = ann.label || String(idx + 1); + var text = ann.text || ""; + var color = ann.color || null; + + // Marker element + var marker = document.createElement("button"); + marker.className = PREFIX + "-marker"; + marker.setAttribute("aria-label", "Annotation " + label + ": " + text); + marker.setAttribute("aria-expanded", "false"); + marker.setAttribute("type", "button"); + marker.style.left = x + "%"; + marker.style.top = y + "%"; + if (color) { + marker.style.setProperty("--gd-annotate-marker-bg", color); + } + + // Label inside marker + var labelSpan = document.createElement("span"); + labelSpan.className = PREFIX + "-marker-label"; + labelSpan.textContent = label; + marker.appendChild(labelSpan); + + // Pulse animation class (removed after first interaction) + marker.classList.add(PREFIX + "-pulse"); + + // Tooltip + var tooltip = document.createElement("div"); + tooltip.className = PREFIX + "-tooltip"; + tooltip.setAttribute("role", "tooltip"); + tooltip.setAttribute("id", PREFIX + "-tip-" + idx + "-" + Date.now()); + marker.setAttribute("aria-describedby", tooltip.id); + + var tipLabel = document.createElement("strong"); + tipLabel.className = PREFIX + "-tooltip-label"; + tipLabel.textContent = label; + tooltip.appendChild(tipLabel); + + if (text) { + var tipText = document.createElement("span"); + tipText.className = PREFIX + "-tooltip-text"; + tipText.textContent = text; + tooltip.appendChild(tipText); + } + + marker.appendChild(tooltip); + overlay.appendChild(marker); + + // Interaction: toggle tooltip on click/Enter + marker.addEventListener("click", function (e) { + e.stopPropagation(); + var isActive = marker.classList.contains(PREFIX + "-active"); + closeAll(overlay); + if (!isActive) { + marker.classList.add(PREFIX + "-active"); + marker.setAttribute("aria-expanded", "true"); + marker.classList.remove(PREFIX + "-pulse"); + positionTooltip(marker, tooltip, overlay); + } + }); + + // Show on hover (desktop) + marker.addEventListener("mouseenter", function () { + marker.classList.remove(PREFIX + "-pulse"); + if (!marker.classList.contains(PREFIX + "-active")) { + tooltip.classList.add(PREFIX + "-tooltip--hover"); + positionTooltip(marker, tooltip, overlay); + } + }); + + marker.addEventListener("mouseleave", function () { + tooltip.classList.remove(PREFIX + "-tooltip--hover"); + }); + + // Keyboard: Enter/Space toggles, Escape closes + marker.addEventListener("keydown", function (e) { + if (e.key === "Escape") { + closeAll(overlay); + e.preventDefault(); + } + }); + }); + + return overlay; + } + + function closeAll(overlay) { + var active = overlay.querySelectorAll("." + PREFIX + "-active"); + for (var i = 0; i < active.length; i++) { + active[i].classList.remove(PREFIX + "-active"); + active[i].setAttribute("aria-expanded", "false"); + } + } + + /** + * Position tooltip so it doesn't overflow the bounds element. + * Prefers showing above the marker; falls back to below. + */ + function positionTooltip(marker, tooltip, bounds) { + // Reset positioning classes + tooltip.classList.remove( + PREFIX + "-tooltip--above", + PREFIX + "-tooltip--below", + PREFIX + "-tooltip--left", + PREFIX + "-tooltip--right" + ); + + var boundsRect = bounds.getBoundingClientRect(); + var markerRect = marker.getBoundingClientRect(); + var markerCenterX = markerRect.left + markerRect.width / 2 - boundsRect.left; + var markerTop = markerRect.top - boundsRect.top; + + // Default: above + if (markerTop > 80) { + tooltip.classList.add(PREFIX + "-tooltip--above"); + } else { + tooltip.classList.add(PREFIX + "-tooltip--below"); + } + + // Horizontal: center, but shift if near edges + var boundsWidth = boundsRect.width; + if (markerCenterX < boundsWidth * 0.25) { + tooltip.classList.add(PREFIX + "-tooltip--right"); + } else if (markerCenterX > boundsWidth * 0.75) { + tooltip.classList.add(PREFIX + "-tooltip--left"); + } + } + + // Init on DOM ready + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", initAll); + } else { + initAll(); + } + + // Re-init after Quarto navigation (for SPA-like navigation) + document.addEventListener("quarto-nav", initAll); + + // Public API — consumed by the lightbox to render the same annotation + // markers/tooltips over the enlarged image. + window.GDAnnotate = { + parse: parse, + buildOverlay: buildOverlay, + closeAll: closeAll, + }; +})(); diff --git a/docs/gd-lightbox-compare.css b/docs/gd-lightbox-compare.css new file mode 100644 index 0000000..c8d5a05 --- /dev/null +++ b/docs/gd-lightbox-compare.css @@ -0,0 +1,170 @@ +/* GD Lightbox Compare — Before/After Slider Styles */ + +.gd-compare { + --gd-compare-divider-width: 3px; + --gd-compare-divider-color: #fff; + --gd-compare-handle-size: 40px; + --gd-compare-label-bg: rgba(0, 0, 0, 0.6); + --gd-compare-label-color: #fff; + --gd-compare-radius: 8px; + + position: relative; + overflow: hidden; + border-radius: var(--gd-compare-radius); + cursor: ew-resize; + user-select: none; + -webkit-user-select: none; + line-height: 0; + max-width: 100%; +} + +.gd-compare--vertical { + cursor: ns-resize; +} + +/* Both layers fill the container */ +.gd-compare__before, +.gd-compare__after { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.gd-compare__after { + z-index: 1; +} + +.gd-compare__before { + z-index: 2; +} + +.gd-compare__before img, +.gd-compare__after img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; +} + +/* Make container size from the after (bottom) image */ +.gd-compare__after { + position: relative; +} + +/* Divider line */ +.gd-compare__divider { + position: absolute; + z-index: 3; + display: flex; + align-items: center; + justify-content: center; +} + +.gd-compare--horizontal .gd-compare__divider { + top: 0; + bottom: 0; + width: var(--gd-compare-divider-width); + background: var(--gd-compare-divider-color); + transform: translateX(-50%); + box-shadow: 0 0 6px rgba(0, 0, 0, 0.3); +} + +.gd-compare--vertical .gd-compare__divider { + left: 0; + right: 0; + height: var(--gd-compare-divider-width); + background: var(--gd-compare-divider-color); + transform: translateY(-50%); + box-shadow: 0 0 6px rgba(0, 0, 0, 0.3); +} + +/* Handle (grab circle) */ +.gd-compare__handle { + width: var(--gd-compare-handle-size); + height: var(--gd-compare-handle-size); + border-radius: 50%; + background: var(--gd-compare-divider-color); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); + display: flex; + align-items: center; + justify-content: center; + color: #333; + transition: transform 0.15s ease, box-shadow 0.15s ease; +} + +.gd-compare--active .gd-compare__handle { + transform: scale(1.15); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4); +} + +.gd-compare__handle svg { + width: 20px; + height: 20px; +} + +/* Labels */ +.gd-compare__label { + position: absolute; + z-index: 4; + padding: 4px 10px; + font-size: 12px; + font-weight: 600; + font-family: system-ui, -apple-system, sans-serif; + line-height: 1.4; + letter-spacing: 0.02em; + text-transform: uppercase; + color: var(--gd-compare-label-color); + background: var(--gd-compare-label-bg); + border-radius: 4px; + pointer-events: none; +} + +.gd-compare--horizontal .gd-compare__label--before { + top: 12px; + left: 12px; +} + +.gd-compare--horizontal .gd-compare__label--after { + top: 12px; + right: 12px; +} + +.gd-compare--vertical .gd-compare__label--before { + top: 12px; + left: 12px; +} + +.gd-compare--vertical .gd-compare__label--after { + bottom: 12px; + left: 12px; +} + +/* Focus ring for keyboard navigation */ +.gd-compare:focus { + outline: 3px solid var(--bs-primary, #0d6efd); + outline-offset: 2px; +} + +.gd-compare:focus:not(:focus-visible) { + outline: none; +} + +.gd-compare:focus-visible { + outline: 3px solid var(--bs-primary, #0d6efd); + outline-offset: 2px; +} + +/* Dark mode adjustments */ +[data-bs-theme="dark"] .gd-compare { + --gd-compare-divider-color: #e0e0e0; + --gd-compare-label-bg: rgba(255, 255, 255, 0.15); +} + +/* Reduced motion */ +@media (prefers-reduced-motion: reduce) { + .gd-compare__handle { + transition: none; + } +} diff --git a/docs/gd-lightbox-compare.js b/docs/gd-lightbox-compare.js new file mode 100644 index 0000000..236476d --- /dev/null +++ b/docs/gd-lightbox-compare.js @@ -0,0 +1,201 @@ +/** + * GD Lightbox Compare — Before/After Image Comparison Slider + * + * Renders a draggable divider between two overlaid images. Supports: + * - Mouse and touch drag + * - Keyboard control (arrow keys move divider in 5% increments) + * - Horizontal (default) and vertical split + * - Customizable labels + * - Works inline and can be opened in the main lightbox + * + * No dependencies. ~3KB minified+gzipped target. + */ +(function () { + "use strict"; + + var PREFIX = "gd-compare"; + var STEP = 5; // Keyboard step in percent + + function initAll() { + var containers = document.querySelectorAll("." + PREFIX); + for (var i = 0; i < containers.length; i++) { + initSlider(containers[i]); + } + } + + function initSlider(container) { + if (container.dataset.gdCompareInit) return; + container.dataset.gdCompareInit = "true"; + + var direction = container.dataset.direction || "horizontal"; + var startPos = parseFloat(container.dataset.startPosition) || 50; + var labelBefore = container.dataset.labelBefore || "Before"; + var labelAfter = container.dataset.labelAfter || "After"; + + // Get the two images + var images = container.querySelectorAll("img"); + if (images.length < 2) return; + + var beforeImg = images[0]; + var afterImg = images[1]; + + // Build the comparison structure + container.innerHTML = ""; + container.classList.add(PREFIX + "--" + direction); + container.setAttribute("role", "slider"); + container.setAttribute("aria-label", "Image comparison slider"); + container.setAttribute("aria-valuemin", "0"); + container.setAttribute("aria-valuemax", "100"); + container.setAttribute("aria-valuenow", String(Math.round(startPos))); + container.setAttribute("aria-valuetext", Math.round(startPos) + "% " + labelBefore); + container.setAttribute("tabindex", "0"); + + // Before layer (clipped) + var beforeLayer = document.createElement("div"); + beforeLayer.className = PREFIX + "__before"; + beforeLayer.appendChild(beforeImg.cloneNode(true)); + container.appendChild(beforeLayer); + + // After layer (full, behind) + var afterLayer = document.createElement("div"); + afterLayer.className = PREFIX + "__after"; + afterLayer.appendChild(afterImg.cloneNode(true)); + container.appendChild(afterLayer); + + // Divider + var divider = document.createElement("div"); + divider.className = PREFIX + "__divider"; + var handle = document.createElement("div"); + handle.className = PREFIX + "__handle"; + handle.innerHTML = + '' + + '' + + '' + + ''; + divider.appendChild(handle); + container.appendChild(divider); + + // Labels + var bLabel = document.createElement("span"); + bLabel.className = PREFIX + "__label " + PREFIX + "__label--before"; + bLabel.textContent = labelBefore; + container.appendChild(bLabel); + + var aLabel = document.createElement("span"); + aLabel.className = PREFIX + "__label " + PREFIX + "__label--after"; + aLabel.textContent = labelAfter; + container.appendChild(aLabel); + + // State + var position = startPos; + var isDragging = false; + + function setPosition(pct) { + pct = Math.max(0, Math.min(100, pct)); + position = pct; + + if (direction === "vertical") { + beforeLayer.style.clipPath = "inset(0 0 " + (100 - pct) + "% 0)"; + divider.style.top = pct + "%"; + divider.style.left = ""; + } else { + beforeLayer.style.clipPath = "inset(0 " + (100 - pct) + "% 0 0)"; + divider.style.left = pct + "%"; + divider.style.top = ""; + } + + container.setAttribute("aria-valuenow", String(Math.round(pct))); + container.setAttribute( + "aria-valuetext", + Math.round(pct) + "% " + labelBefore + ); + } + + function getPosition(e) { + var rect = container.getBoundingClientRect(); + var clientX, clientY; + + if (e.touches && e.touches.length > 0) { + clientX = e.touches[0].clientX; + clientY = e.touches[0].clientY; + } else { + clientX = e.clientX; + clientY = e.clientY; + } + + if (direction === "vertical") { + return ((clientY - rect.top) / rect.height) * 100; + } + return ((clientX - rect.left) / rect.width) * 100; + } + + // Pointer events + function onPointerDown(e) { + isDragging = true; + setPosition(getPosition(e)); + e.preventDefault(); + container.classList.add(PREFIX + "--active"); + } + + function onPointerMove(e) { + if (!isDragging) return; + setPosition(getPosition(e)); + e.preventDefault(); + } + + function onPointerUp() { + if (!isDragging) return; + isDragging = false; + container.classList.remove(PREFIX + "--active"); + } + + // Mouse + container.addEventListener("mousedown", onPointerDown); + document.addEventListener("mousemove", onPointerMove); + document.addEventListener("mouseup", onPointerUp); + + // Touch + container.addEventListener("touchstart", onPointerDown, { passive: false }); + document.addEventListener("touchmove", function (e) { + if (isDragging) onPointerMove(e); + }, { passive: false }); + document.addEventListener("touchend", onPointerUp); + + // Keyboard + container.addEventListener("keydown", function (e) { + var moved = false; + switch (e.key) { + case "ArrowLeft": + case "ArrowUp": + setPosition(position - STEP); + moved = true; + break; + case "ArrowRight": + case "ArrowDown": + setPosition(position + STEP); + moved = true; + break; + case "Home": + setPosition(0); + moved = true; + break; + case "End": + setPosition(100); + moved = true; + break; + } + if (moved) e.preventDefault(); + }); + + // Set initial position + setPosition(startPos); + } + + // Init on DOM ready + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", initAll); + } else { + initAll(); + } +})(); diff --git a/docs/gd-lightbox.css b/docs/gd-lightbox.css new file mode 100644 index 0000000..d5b7566 --- /dev/null +++ b/docs/gd-lightbox.css @@ -0,0 +1,658 @@ +/** + * GD Lightbox — Styles + * + * Uses CSS custom properties for theming integration with Great Docs. + * Supports dark mode via [data-bs-theme="dark"] and .quarto-dark selectors. + */ + +/* --------------------------------------------------------------------------- + Custom Properties + --------------------------------------------------------------------------- */ + +:root { + --gd-lightbox-backdrop: rgba(0, 0, 0, 0.85); + --gd-lightbox-backdrop-blur: 8px; + --gd-lightbox-radius: 12px; + --gd-lightbox-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); + --gd-lightbox-toolbar-bg: rgba(255, 255, 255, 0.95); + --gd-lightbox-toolbar-color: #1a1a2e; + --gd-lightbox-caption-bg: rgba(255, 255, 255, 0.95); + --gd-lightbox-caption-color: #374151; + --gd-lightbox-accent: #6366f1; + --gd-lightbox-transition: 300ms; + --gd-lightbox-filmstrip-height: 64px; + --gd-lightbox-btn-hover: rgba(0, 0, 0, 0.08); + --gd-lightbox-nav-bg: rgba(255, 255, 255, 0.9); + --gd-lightbox-nav-color: #1a1a2e; + --gd-lightbox-toast-bg: #1a1a2e; + --gd-lightbox-toast-color: #ffffff; +} + +[data-bs-theme="dark"], +.quarto-dark { + --gd-lightbox-backdrop: rgba(0, 0, 0, 0.92); + --gd-lightbox-backdrop-blur: 12px; + --gd-lightbox-toolbar-bg: rgba(30, 30, 46, 0.95); + --gd-lightbox-toolbar-color: #e2e8f0; + --gd-lightbox-caption-bg: rgba(30, 30, 46, 0.95); + --gd-lightbox-caption-color: #cbd5e1; + --gd-lightbox-btn-hover: rgba(255, 255, 255, 0.1); + --gd-lightbox-nav-bg: rgba(30, 30, 46, 0.9); + --gd-lightbox-nav-color: #e2e8f0; + --gd-lightbox-toast-bg: #e2e8f0; + --gd-lightbox-toast-color: #1a1a2e; +} + +/* --------------------------------------------------------------------------- + Body Lock (prevent scroll when lightbox open) + --------------------------------------------------------------------------- */ + +body.gd-lightbox-open { + overflow: hidden; +} + +/* --------------------------------------------------------------------------- + Thumbnail Wrapper (in-page) + --------------------------------------------------------------------------- */ + +.gd-lightbox-wrapper { + position: relative; + display: inline-block; + /* Breathing room so body text above/below isn't tight against the image. + Margin (not padding) keeps the space outside the rounded image box. */ + margin: 1.5rem 0; + cursor: zoom-in; + border-radius: 8px; + /* No overflow clipping: annotation tooltips must be free to extend past the + image edge onto the page. The rounded corners live on the image instead. */ + transition: transform 200ms ease, box-shadow 200ms ease; +} + +/* Keep a set of stacked images close together while preserving the 1.5rem + gap to surrounding body text. Each consecutive image is pulled up to offset + the previous one's bottom margin, leaving a small 0.5rem gap between images. + The first and last images in a run keep their full margin against text. */ +.gd-lightbox-wrapper + .gd-lightbox-wrapper { + margin-top: -1rem; +} + +/* --------------------------------------------------------------------------- + Gallery Stack (in-page cover that opens a gallery in the lightbox) + --------------------------------------------------------------------------- */ + +.gd-gallery { + position: relative; + /* Block sized to its content so margin auto can center it in the body. */ + display: block; + width: fit-content; + max-width: 480px; + margin: 1.5rem auto; +} + +/* The cover is a normal lightbox wrapper; drop its standalone margin. */ +.gd-gallery .gd-lightbox-wrapper { + margin: 0; +} + +/* Matte frame around the cover photo. */ +.gd-gallery .gd-gallery-cover { + padding: 6px; + background: var(--gd-lightbox-caption-bg, #fff); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.22); +} + +/* Offset "photos" peeking out behind the cover to suggest a stack. */ +.gd-gallery .gd-gallery-cover::before, +.gd-gallery .gd-gallery-cover::after { + content: ""; + position: absolute; + inset: 0; + border-radius: 8px; + background: var(--gd-lightbox-caption-bg, #fff); + border: 1px solid rgba(0, 0, 0, 0.1); + box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18); + z-index: -1; + transition: transform 220ms ease; +} + +.gd-gallery .gd-gallery-cover::before { + transform: rotate(-3deg) translate(-7px, 5px); +} + +.gd-gallery .gd-gallery-cover::after { + transform: rotate(3deg) translate(7px, 5px); + z-index: -2; +} + +/* Fan the stack out a little on hover. */ +.gd-gallery:hover .gd-gallery-cover::before { + transform: rotate(-6deg) translate(-14px, 7px); +} + +.gd-gallery:hover .gd-gallery-cover::after { + transform: rotate(6deg) translate(14px, 7px); +} + +/* Image count badge. */ +.gd-gallery-badge { + position: absolute; + bottom: 14px; + right: 14px; + z-index: 3; + display: inline-flex; + align-items: center; + gap: 4px; + padding: 3px 9px; + font-size: 12px; + font-weight: 600; + line-height: 1; + color: #fff; + background: rgba(0, 0, 0, 0.65); + border-radius: 20px; + pointer-events: none; +} + +.gd-gallery-badge svg { + display: block; +} + +/* Hidden gallery members stay in the DOM for the engine but take no space. */ +.gd-gallery-rest { + display: none; +} + +@media (prefers-reduced-motion: reduce) { + .gd-gallery .gd-gallery-cover::before, + .gd-gallery .gd-gallery-cover::after { + transition: none; + } +} + +.gd-lightbox-wrapper:hover, +.gd-lightbox-wrapper:focus-visible { + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); +} + +.gd-lightbox-wrapper:focus-visible { + outline: 2px solid var(--gd-lightbox-accent); + outline-offset: 2px; +} + +.gd-lightbox-wrapper .gd-lightbox-img { + display: block; + max-width: 100%; + height: auto; + border-radius: inherit; +} + +/* Expand button overlay */ +.gd-lightbox-expand { + position: absolute; + top: 8px; + right: 8px; + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + background: rgba(0, 0, 0, 0.6); + color: #fff; + border: none; + border-radius: 6px; + cursor: pointer; + opacity: 0; + transition: opacity 200ms ease; + pointer-events: none; +} + +.gd-lightbox-wrapper:hover .gd-lightbox-expand, +.gd-lightbox-wrapper:focus-within .gd-lightbox-expand { + opacity: 1; + pointer-events: auto; +} + +/* --------------------------------------------------------------------------- + Overlay + --------------------------------------------------------------------------- */ + +.gd-lightbox-overlay { + position: fixed; + inset: 0; + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + opacity: 0; + visibility: hidden; + transition: opacity var(--gd-lightbox-transition) ease, + visibility 0s linear var(--gd-lightbox-transition); +} + +.gd-lightbox-overlay.gd-lightbox-visible { + opacity: 1; + visibility: visible; + transition: opacity var(--gd-lightbox-transition) ease, visibility 0s linear 0s; +} + +.gd-lightbox-overlay.gd-lightbox-closing { + opacity: 0; + visibility: visible; +} + +/* Backdrop with blur */ +.gd-lightbox-backdrop { + position: absolute; + inset: 0; + background: var(--gd-lightbox-backdrop); + backdrop-filter: blur(var(--gd-lightbox-backdrop-blur)); + -webkit-backdrop-filter: blur(var(--gd-lightbox-backdrop-blur)); +} + +/* --------------------------------------------------------------------------- + Content Area + --------------------------------------------------------------------------- */ + +.gd-lightbox-content { + position: relative; + z-index: 1; + display: flex; + flex-direction: column; + align-items: center; + max-width: 90vw; + max-height: calc(100vh - 160px); +} + +.gd-lightbox-image-wrap { + position: relative; + display: flex; + align-items: center; + justify-content: center; + max-width: 90vw; + max-height: calc(100vh - 200px); +} + +/* Annotation layer — sized/positioned by JS to cover the displayed image. + Holds a .gd-annotate-overlay (inset:0), so markers position by % of this + box. Fades in once positioned to avoid a flash at the wrong location. */ +.gd-lightbox-annotations { + position: absolute; + opacity: 0; + transition: opacity 200ms ease; + pointer-events: none; + z-index: 6; +} + +.gd-lightbox-annotations.visible { + opacity: 1; +} + +/* The markers themselves re-enable pointer events (see annotate CSS). */ +.gd-lightbox-annotations .gd-annotate-marker { + pointer-events: auto; +} + +.gd-lightbox-main-img { + max-width: 90vw; + max-height: calc(100vh - 200px); + object-fit: contain; + border-radius: var(--gd-lightbox-radius); + box-shadow: var(--gd-lightbox-shadow); + user-select: none; + -webkit-user-drag: none; + /* Smooth zoom from the toolbar buttons. The open animation overrides this + with its own inline transition, so it isn't affected. */ + transition: transform 200ms ease; +} + +/* Zoomed: image is draggable to pan. */ +.gd-lightbox-overlay.gd-lightbox-zoomed .gd-lightbox-main-img { + cursor: grab; + touch-action: none; /* let pointer-pan own the gesture on touch devices */ +} + +/* Actively dragging: grabbing cursor, and no transition so pan tracks 1:1. */ +.gd-lightbox-overlay.gd-lightbox-panning .gd-lightbox-main-img { + cursor: grabbing; + transition: none; +} + +/* Gallery mode reserves extra bottom space so the centered image and its + caption clear the filmstrip dock (which is absolutely positioned at the + bottom and would otherwise overlap a caption under a large image). The + content stays centered, so the toolbar at the top is cleared too. */ +.gd-lightbox-overlay.gd-lightbox-has-filmstrip .gd-lightbox-content { + max-height: calc(100vh - 220px); +} + +.gd-lightbox-overlay.gd-lightbox-has-filmstrip .gd-lightbox-image-wrap, +.gd-lightbox-overlay.gd-lightbox-has-filmstrip .gd-lightbox-main-img { + max-height: calc(100vh - 300px); +} + +/* --------------------------------------------------------------------------- + Caption + --------------------------------------------------------------------------- */ + +.gd-lightbox-caption { + margin-top: 12px; + padding: 8px 16px; + background: var(--gd-lightbox-caption-bg); + border-radius: 8px; + text-align: center; + max-width: 600px; +} + +.gd-lightbox-caption-text { + margin: 0; + font-size: 0.9rem; + color: var(--gd-lightbox-caption-color); + line-height: 1.4; +} + +.gd-lightbox-credit-text { + margin: 4px 0 0; + font-size: 0.75rem; + color: var(--gd-lightbox-caption-color); + opacity: 0.7; +} + +/* --------------------------------------------------------------------------- + Toolbar + --------------------------------------------------------------------------- */ + +.gd-lightbox-toolbar { + position: absolute; + top: 0; + left: 0; + right: 0; + z-index: 10; + display: flex; + align-items: center; + padding: 12px 16px; + background: linear-gradient( + to bottom, + var(--gd-lightbox-toolbar-bg), + transparent + ); + transition: opacity 300ms ease, transform 300ms ease; +} + +.gd-lightbox-toolbar.hidden { + opacity: 0; + transform: translateY(-8px); + pointer-events: none; +} + +.gd-lightbox-toolbar-spacer { + flex: 1; +} + +.gd-lightbox-counter { + font-size: 0.85rem; + font-weight: 500; + color: var(--gd-lightbox-toolbar-color); + padding: 4px 10px; + background: var(--gd-lightbox-btn-hover); + border-radius: 20px; +} + +/* Zoom level readout (e.g. "150%") */ +.gd-lightbox-zoom-level { + min-width: 3.5em; + text-align: center; + font-size: 0.8rem; + font-variant-numeric: tabular-nums; + font-weight: 500; + color: var(--gd-lightbox-toolbar-color); + user-select: none; +} + +/* Disabled toolbar buttons (e.g. zoom at min/max) */ +.gd-lightbox-btn:disabled { + opacity: 0.35; + cursor: default; + pointer-events: none; +} + +/* Toolbar buttons */ +.gd-lightbox-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + border: none; + border-radius: 8px; + background: transparent; + color: var(--gd-lightbox-toolbar-color); + cursor: pointer; + transition: background 150ms ease; + margin-left: 4px; +} + +.gd-lightbox-btn:hover { + background: var(--gd-lightbox-btn-hover); +} + +.gd-lightbox-btn:focus-visible { + outline: 2px solid var(--gd-lightbox-accent); + outline-offset: 2px; +} + +/* --------------------------------------------------------------------------- + Navigation Arrows + --------------------------------------------------------------------------- */ + +.gd-lightbox-nav { + position: absolute; + top: 50%; + transform: translateY(-50%); + z-index: 5; + display: flex; + align-items: center; + justify-content: center; + width: 44px; + height: 44px; + border: none; + border-radius: 50%; + background: var(--gd-lightbox-nav-bg); + color: var(--gd-lightbox-nav-color); + cursor: pointer; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + transition: transform 150ms ease, box-shadow 150ms ease; +} + +.gd-lightbox-nav:hover { + transform: translateY(-50%) scale(1.1); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); +} + +.gd-lightbox-nav:focus-visible { + outline: 2px solid var(--gd-lightbox-accent); + outline-offset: 2px; +} + +.gd-lightbox-nav-prev { + left: 16px; +} + +.gd-lightbox-nav-next { + right: 16px; +} + +/* --------------------------------------------------------------------------- + Filmstrip + --------------------------------------------------------------------------- */ + +.gd-lightbox-filmstrip { + position: absolute; + bottom: 16px; + left: 50%; + transform: translateX(-50%); + z-index: 5; + display: flex; + gap: 8px; + padding: 8px 12px; + background: var(--gd-lightbox-toolbar-bg); + border-radius: 12px; + max-width: 80vw; + overflow-x: auto; + scrollbar-width: thin; +} + +.gd-lightbox-filmstrip-thumb { + flex-shrink: 0; + width: var(--gd-lightbox-filmstrip-height); + height: var(--gd-lightbox-filmstrip-height); + border: 2px solid transparent; + border-radius: 8px; + overflow: hidden; + cursor: pointer; + background: none; + padding: 0; + transition: border-color 200ms ease, transform 200ms ease; +} + +.gd-lightbox-filmstrip-thumb:hover { + transform: scale(1.05); +} + +.gd-lightbox-filmstrip-thumb.active { + border-color: var(--gd-lightbox-accent); + transform: scale(1.08); +} + +.gd-lightbox-filmstrip-thumb:focus-visible { + outline: 2px solid var(--gd-lightbox-accent); + outline-offset: 2px; +} + +.gd-lightbox-filmstrip-thumb img { + width: 100%; + height: 100%; + object-fit: cover; +} + +/* --------------------------------------------------------------------------- + Toast Notification + --------------------------------------------------------------------------- */ + +.gd-lightbox-toast { + position: absolute; + bottom: 100px; + left: 50%; + transform: translateX(-50%) translateY(8px); + z-index: 20; + padding: 8px 16px; + background: var(--gd-lightbox-toast-bg); + color: var(--gd-lightbox-toast-color); + border-radius: 8px; + font-size: 0.85rem; + font-weight: 500; + opacity: 0; + transition: opacity 200ms ease, transform 200ms ease; + pointer-events: none; +} + +.gd-lightbox-toast.visible { + opacity: 1; + transform: translateX(-50%) translateY(0); +} + +/* --------------------------------------------------------------------------- + Screen Reader Only + --------------------------------------------------------------------------- */ + +.gd-lightbox-sr-announce { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +/* --------------------------------------------------------------------------- + Responsive / Mobile + --------------------------------------------------------------------------- */ + +@media (max-width: 768px) { + .gd-lightbox-content { + max-width: 100vw; + max-height: calc(100vh - 120px); + } + + .gd-lightbox-image-wrap { + max-width: 100vw; + max-height: calc(100vh - 140px); + } + + .gd-lightbox-main-img { + max-width: 100vw; + max-height: calc(100vh - 140px); + border-radius: 0; + } + + .gd-lightbox-overlay.gd-lightbox-has-filmstrip .gd-lightbox-content { + max-height: calc(100vh - 180px); + } + + .gd-lightbox-overlay.gd-lightbox-has-filmstrip .gd-lightbox-image-wrap, + .gd-lightbox-overlay.gd-lightbox-has-filmstrip .gd-lightbox-main-img { + max-height: calc(100vh - 260px); + } + + .gd-lightbox-nav { + width: 36px; + height: 36px; + } + + .gd-lightbox-nav-prev { + left: 8px; + } + + .gd-lightbox-nav-next { + right: 8px; + } + + .gd-lightbox-filmstrip { + bottom: 8px; + padding: 6px 8px; + gap: 6px; + } + + .gd-lightbox-filmstrip-thumb { + width: 48px; + height: 48px; + } + + .gd-lightbox-toolbar { + padding: 8px 12px; + } + + .gd-lightbox-expand { + opacity: 1; + pointer-events: auto; + } +} + +/* --------------------------------------------------------------------------- + Reduced Motion + --------------------------------------------------------------------------- */ + +@media (prefers-reduced-motion: reduce) { + .gd-lightbox-overlay, + .gd-lightbox-main-img, + .gd-lightbox-toolbar, + .gd-lightbox-nav, + .gd-lightbox-filmstrip-thumb, + .gd-lightbox-toast, + .gd-lightbox-wrapper { + transition: none !important; + } +} diff --git a/docs/gd-lightbox.js b/docs/gd-lightbox.js new file mode 100644 index 0000000..29a090d --- /dev/null +++ b/docs/gd-lightbox.js @@ -0,0 +1,1419 @@ +/** + * GD Lightbox — Great Docs Lightbox Engine + * + * A documentation-focused lightbox built from scratch. Features: + * - Origin-aware zoom animation (image grows from thumbnail position) + * - Dark-mode image variant swapping + * - Gallery with filmstrip navigation + * - Keyboard & touch navigation + * - Copy/download/deep-link toolbar + * - Accessible: focus trap, ARIA, screen reader announcements + * + * No dependencies. ~12KB minified+gzipped target. + */ +(function () { + "use strict"; + + // --------------------------------------------------------------------------- + // Constants + // --------------------------------------------------------------------------- + + const PREFIX = "gd-lightbox"; + const ATTR_LB = "data-gd-lightbox"; + const ATTR_ID = "data-gd-lightbox-id"; + const ATTR_GROUP = "data-gd-lightbox-group"; + const ATTR_DARK = "data-gd-lightbox-dark"; + const ATTR_CAPTION = "data-gd-lightbox-caption"; + const ATTR_CREDIT = "data-gd-lightbox-credit"; + const ATTR_DESC_POS = "data-gd-lightbox-desc-position"; + const ATTR_ZOOM_TARGET = "data-gd-lightbox-zoom-target"; + const ATTR_LOOP = "data-gd-lightbox-loop"; + const ATTR_AUTOPLAY = "data-gd-lightbox-autoplay"; + const ATTR_FULL_SRC = "data-gd-lightbox-full-src"; + + const TRANSITION_MS = 300; + const TOOLBAR_HIDE_MS = 3000; + + // --------------------------------------------------------------------------- + // State + // --------------------------------------------------------------------------- + + let overlay = null; // The lightbox overlay DOM element + let isOpen = false; + let currentIndex = -1; + let currentGroup = null; // Array of items in the active gallery + let allItems = []; // All lightbox items on the page + let groups = {}; // { groupName: [items...] } + let toolbarTimer = null; + let previousFocus = null; // Element that had focus before lightbox opened + let isDarkMode = false; + let loopEnabled = true; // Whether gallery wraps around at ends + let autoplayInterval = 0; // Autoplay interval in ms (0 = disabled) + let autoplayTimer = null; // Active autoplay timer + + // Zoom state (toolbar-button controlled; zooms about the image center) + let zoomScale = 1; + const ZOOM_MIN = 1; + const ZOOM_MAX = 4; + const ZOOM_STEP = 0.5; + + // Pan state (drag the zoomed image around) + let panX = 0; + let panY = 0; + let isPanning = false; + let panPointerStartX = 0; + let panPointerStartY = 0; + let panOriginX = 0; + let panOriginY = 0; + + // Touch/gesture state + let touchStartX = 0; + let touchStartY = 0; + let touchDeltaX = 0; + let touchDeltaY = 0; + let isSwiping = false; + + // --------------------------------------------------------------------------- + // Utilities + // --------------------------------------------------------------------------- + + function qs(sel, ctx) { + return (ctx || document).querySelector(sel); + } + + function qsa(sel, ctx) { + return Array.from((ctx || document).querySelectorAll(sel)); + } + + function el(tag, attrs, children) { + const node = document.createElement(tag); + if (attrs) { + Object.keys(attrs).forEach(function (k) { + if (k === "className") { + node.className = attrs[k]; + } else if (k.startsWith("on")) { + node.addEventListener(k.slice(2).toLowerCase(), attrs[k]); + } else { + node.setAttribute(k, attrs[k]); + } + }); + } + if (children) { + children.forEach(function (c) { + if (typeof c === "string") { + node.appendChild(document.createTextNode(c)); + } else if (c) { + node.appendChild(c); + } + }); + } + return node; + } + + function detectDarkMode() { + const html = document.documentElement; + return ( + html.classList.contains("quarto-dark") || + html.getAttribute("data-bs-theme") === "dark" + ); + } + + function getImageSrc(item) { + if (isDarkMode && item.darkSrc) { + return item.darkSrc; + } + return item.src; + } + + /** + * Get the highest-resolution source for lightbox display. + * Prefers: explicit full-src > largest srcset entry > base src. + */ + function getFullResSrc(item) { + if (isDarkMode && item.darkSrc) { + return item.darkSrc; + } + if (item.fullSrc) { + return item.fullSrc; + } + if (item.srcsetMax) { + return item.srcsetMax; + } + return item.src; + } + + /** + * Parse a srcset string and return the URL of the widest/highest-res source. + * Handles both width descriptors (800w) and pixel density (2x). + */ + function parseSrcsetMax(srcset) { + if (!srcset) return null; + var best = null; + var bestVal = 0; + srcset.split(",").forEach(function (entry) { + var parts = entry.trim().split(/\s+/); + if (parts.length < 2) return; + var url = parts[0]; + var descriptor = parts[1]; + var val = parseFloat(descriptor) || 0; + if (val > bestVal) { + bestVal = val; + best = url; + } + }); + return best; + } + + function prefersReducedMotion() { + return window.matchMedia("(prefers-reduced-motion: reduce)").matches; + } + + /** Parse a lightbox annotations attribute into an array, or null. */ + function parseAnnotations(raw) { + if (window.GDAnnotate && window.GDAnnotate.parse) { + return window.GDAnnotate.parse(raw); + } + if (!raw) return null; + try { + var a = JSON.parse(raw); + return Array.isArray(a) && a.length ? a : null; + } catch (e) { + return null; + } + } + + // --------------------------------------------------------------------------- + // Collect Items + // --------------------------------------------------------------------------- + + function collectItems() { + allItems = []; + groups = {}; + + qsa("[" + ATTR_LB + "]").forEach(function (wrapper) { + var img = qs(".gd-lightbox-img", wrapper); + if (!img) return; + + var item = { + wrapper: wrapper, + img: img, + id: wrapper.getAttribute(ATTR_ID), + src: img.getAttribute("src"), + darkSrc: wrapper.getAttribute(ATTR_DARK) || null, + fullSrc: wrapper.getAttribute(ATTR_FULL_SRC) || null, + srcsetMax: parseSrcsetMax(img.getAttribute("srcset")), + group: wrapper.getAttribute(ATTR_GROUP) || null, + caption: wrapper.getAttribute(ATTR_CAPTION) || "", + credit: wrapper.getAttribute(ATTR_CREDIT) || "", + descPosition: wrapper.getAttribute(ATTR_DESC_POS) || "bottom", + zoomTarget: wrapper.getAttribute(ATTR_ZOOM_TARGET) || null, + loop: wrapper.getAttribute(ATTR_LOOP), + autoplay: wrapper.getAttribute(ATTR_AUTOPLAY), + alt: img.getAttribute("alt") || "", + annotations: parseAnnotations( + wrapper.getAttribute("data-gd-lightbox-annotations") + ), + }; + + allItems.push(item); + + if (item.group) { + if (!groups[item.group]) { + groups[item.group] = []; + } + groups[item.group].push(item); + } + }); + } + + // --------------------------------------------------------------------------- + // Overlay DOM + // --------------------------------------------------------------------------- + + function createOverlay() { + if (overlay) return; + + overlay = el("div", { + className: PREFIX + "-overlay", + role: "dialog", + "aria-modal": "true", + "aria-label": "Image lightbox", + "aria-hidden": "true", + }); + + // Backdrop + var backdrop = el("div", { + className: PREFIX + "-backdrop", + onClick: close, + }); + overlay.appendChild(backdrop); + + // Content container + var content = el("div", { className: PREFIX + "-content" }); + + // Main image + var imageWrap = el("div", { className: PREFIX + "-image-wrap" }); + var mainImg = el("img", { + className: PREFIX + "-main-img", + alt: "", + }); + // Drag-to-pan when zoomed (pointer events cover mouse + touch) + mainImg.addEventListener("pointerdown", onPanStart); + mainImg.addEventListener("pointermove", onPanMove); + mainImg.addEventListener("pointerup", onPanEnd); + mainImg.addEventListener("pointercancel", onPanEnd); + imageWrap.appendChild(mainImg); + content.appendChild(imageWrap); + + // Caption area + var captionEl = el("div", { className: PREFIX + "-caption" }); + var captionText = el("p", { className: PREFIX + "-caption-text" }); + var creditText = el("p", { className: PREFIX + "-credit-text" }); + captionEl.appendChild(captionText); + captionEl.appendChild(creditText); + content.appendChild(captionEl); + + overlay.appendChild(content); + + // Toolbar + var toolbar = el("div", { className: PREFIX + "-toolbar" }); + + // Counter (for galleries) + var counter = el("span", { className: PREFIX + "-counter" }); + toolbar.appendChild(counter); + + // Spacer + toolbar.appendChild(el("span", { className: PREFIX + "-toolbar-spacer" })); + + // Zoom controls: out / level / in / reset + var zoomOutBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-zoom-out", + "aria-label": "Zoom out", + "data-tippy-content": "Zoom out", + "data-tippy-trigger": "mouseenter", + onClick: zoomOut, + }, + [createZoomOutIcon()] + ); + toolbar.appendChild(zoomOutBtn); + + var zoomLevel = el("span", { + className: PREFIX + "-zoom-level", + "aria-live": "polite", + }); + toolbar.appendChild(zoomLevel); + + var zoomInBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-zoom-in", + "aria-label": "Zoom in", + "data-tippy-content": "Zoom in", + "data-tippy-trigger": "mouseenter", + onClick: zoomIn, + }, + [createZoomInIcon()] + ); + toolbar.appendChild(zoomInBtn); + + var zoomResetBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-zoom-reset", + "aria-label": "Reset zoom", + "data-tippy-content": "Reset zoom", + "data-tippy-trigger": "mouseenter", + onClick: zoomReset, + }, + [createZoomResetIcon()] + ); + toolbar.appendChild(zoomResetBtn); + + // Copy button + var copyBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-copy", + "aria-label": "Copy image to clipboard", + // Tooltip via Great Docs' tooltips.js (tippy). Hover-only trigger so it + // never fires on the auto-focus/focus-trap that would otherwise strand + // the tooltip when the toolbar auto-hides. No native `title` is used. + "data-tippy-content": "Copy image", + "data-tippy-trigger": "mouseenter", + onClick: handleCopy, + }, + [createCopyIcon()] + ); + toolbar.appendChild(copyBtn); + + // Download button + var downloadBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-download", + "aria-label": "Download image", + "data-tippy-content": "Download image", + "data-tippy-trigger": "mouseenter", + onClick: handleDownload, + }, + [createDownloadIcon()] + ); + toolbar.appendChild(downloadBtn); + + // Copy link button + var linkBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-link", + "aria-label": "Copy link to this image", + "data-tippy-content": "Copy link", + "data-tippy-trigger": "mouseenter", + onClick: handleCopyLink, + }, + [createLinkIcon()] + ); + toolbar.appendChild(linkBtn); + + // Close button + var closeBtn = el( + "button", + { + className: PREFIX + "-btn " + PREFIX + "-btn-close", + "aria-label": "Close lightbox", + "data-tippy-content": "Close (Esc)", + "data-tippy-trigger": "mouseenter", + onClick: close, + }, + [createCloseIcon()] + ); + toolbar.appendChild(closeBtn); + + overlay.appendChild(toolbar); + + // Navigation arrows + var prevBtn = el( + "button", + { + className: PREFIX + "-nav " + PREFIX + "-nav-prev", + "aria-label": "Previous image", + onClick: prev, + }, + [createChevronLeft()] + ); + var nextBtn = el( + "button", + { + className: PREFIX + "-nav " + PREFIX + "-nav-next", + "aria-label": "Next image", + onClick: next, + }, + [createChevronRight()] + ); + overlay.appendChild(prevBtn); + overlay.appendChild(nextBtn); + + // Filmstrip + var filmstrip = el("div", { className: PREFIX + "-filmstrip" }); + overlay.appendChild(filmstrip); + + // Live region for screen reader announcements + var liveRegion = el("div", { + className: PREFIX + "-sr-announce", + "aria-live": "polite", + "aria-atomic": "true", + }); + overlay.appendChild(liveRegion); + + document.body.appendChild(overlay); + } + + // --------------------------------------------------------------------------- + // SVG Icons (inline, no external deps) + // --------------------------------------------------------------------------- + + function svgEl(paths, size) { + size = size || 20; + var ns = "http://www.w3.org/2000/svg"; + var svg = document.createElementNS(ns, "svg"); + svg.setAttribute("width", size); + svg.setAttribute("height", size); + svg.setAttribute("viewBox", "0 0 24 24"); + svg.setAttribute("fill", "none"); + svg.setAttribute("stroke", "currentColor"); + svg.setAttribute("stroke-width", "2"); + svg.setAttribute("stroke-linecap", "round"); + svg.setAttribute("stroke-linejoin", "round"); + paths.forEach(function (d) { + var path = document.createElementNS(ns, "path"); + path.setAttribute("d", d); + svg.appendChild(path); + }); + return svg; + } + + function createCloseIcon() { + return svgEl(["M18 6L6 18", "M6 6l12 12"]); + } + + function createChevronLeft() { + return svgEl(["M15 18l-6-6 6-6"], 24); + } + + function createChevronRight() { + return svgEl(["M9 18l6-6-6-6"], 24); + } + + function createZoomInIcon() { + return svgEl([ + "M11 4a7 7 0 100 14 7 7 0 000-14z", + "M21 21l-4.35-4.35", + "M11 8v6", + "M8 11h6", + ]); + } + + function createZoomOutIcon() { + return svgEl([ + "M11 4a7 7 0 100 14 7 7 0 000-14z", + "M21 21l-4.35-4.35", + "M8 11h6", + ]); + } + + function createZoomResetIcon() { + // "Fit to view" — inward-pointing corner arrows (feather minimize-2), + // visually distinct from the +/- magnifiers. + return svgEl([ + "M4 14h6v6", + "M20 10h-6V4", + "M14 10l7-7", + "M3 21l7-7", + ]); + } + + function createCopyIcon() { + return svgEl([ + "M16 4h2a2 2 0 012 2v14a2 2 0 01-2 2H6a2 2 0 01-2-2V6a2 2 0 012-2h2", + "M9 2h6a1 1 0 011 1v1a1 1 0 01-1 1H9a1 1 0 01-1-1V3a1 1 0 011-1z", + ]); + } + + function createDownloadIcon() { + return svgEl(["M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4", "M7 10l5 5 5-5", "M12 15V3"]); + } + + function createLinkIcon() { + return svgEl([ + "M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71", + "M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71", + ]); + } + + // --------------------------------------------------------------------------- + // Open / Close / Navigate + // --------------------------------------------------------------------------- + + function open(item) { + if (isOpen) return; + + previousFocus = document.activeElement; + isOpen = true; + isDarkMode = detectDarkMode(); + + createOverlay(); + + // Determine the gallery group + if (item.group && groups[item.group]) { + currentGroup = groups[item.group]; + } else { + currentGroup = [item]; + } + currentIndex = currentGroup.indexOf(item); + if (currentIndex < 0) currentIndex = 0; + + // Read loop setting from the opening item (group-level attribute) + // Default: true (wraps around). Set data-gd-lightbox-loop="false" to disable. + var loopAttr = item.loop; + loopEnabled = loopAttr !== "false"; + + // Read autoplay interval (e.g., "3s", "2000ms", or "3000") + autoplayInterval = parseInterval(item.autoplay); + + showSlide(currentIndex, item); + + // Show overlay with animation + overlay.classList.add(PREFIX + "-visible"); + overlay.setAttribute("aria-hidden", "false"); + document.body.classList.add(PREFIX + "-open"); + + // Origin animation: get thumbnail rect and animate from there + if (!prefersReducedMotion()) { + animateOpen(item); + } + + // Update URL hash for deep linking + if (item.id) { + history.replaceState(null, "", "#lightbox=" + item.id); + } + + // Focus the close button + setTimeout(function () { + var closeBtn = qs("." + PREFIX + "-btn-close", overlay); + if (closeBtn) closeBtn.focus(); + }, TRANSITION_MS); + + startToolbarTimer(); + startAutoplay(); + } + + function close() { + if (!isOpen) return; + isOpen = false; + stopAutoplay(); + hideToolbarTooltips(); + + overlay.classList.remove(PREFIX + "-visible"); + overlay.classList.add(PREFIX + "-closing"); + overlay.setAttribute("aria-hidden", "true"); + document.body.classList.remove(PREFIX + "-open"); + + // Remove hash + if (window.location.hash.startsWith("#lightbox=")) { + history.replaceState(null, "", window.location.pathname + window.location.search); + } + + setTimeout(function () { + overlay.classList.remove(PREFIX + "-closing"); + // Restore focus + if (previousFocus) { + previousFocus.focus(); + } + }, TRANSITION_MS); + } + + function next() { + if (!currentGroup || currentGroup.length <= 1) return; + if (!loopEnabled && currentIndex >= currentGroup.length - 1) return; + currentIndex = (currentIndex + 1) % currentGroup.length; + showSlide(currentIndex); + announce("Image " + (currentIndex + 1) + " of " + currentGroup.length); + resetAutoplay(); + } + + function prev() { + if (!currentGroup || currentGroup.length <= 1) return; + if (!loopEnabled && currentIndex <= 0) return; + currentIndex = (currentIndex - 1 + currentGroup.length) % currentGroup.length; + showSlide(currentIndex); + announce("Image " + (currentIndex + 1) + " of " + currentGroup.length); + resetAutoplay(); + } + + // --------------------------------------------------------------------------- + // Autoplay + // --------------------------------------------------------------------------- + + /** Parse an interval string like "3s", "2000ms", or "3000" → milliseconds. */ + function parseInterval(val) { + if (!val) return 0; + val = val.trim().toLowerCase(); + if (val.endsWith("ms")) { + return parseInt(val, 10) || 0; + } + if (val.endsWith("s")) { + return (parseFloat(val) || 0) * 1000; + } + // Bare number: treat as ms if >=100, otherwise as seconds + var n = parseFloat(val); + if (!n || n <= 0) return 0; + return n >= 100 ? n : n * 1000; + } + + function startAutoplay() { + stopAutoplay(); + if (autoplayInterval <= 0 || !currentGroup || currentGroup.length <= 1) return; + autoplayTimer = setInterval(function () { + if (!loopEnabled && currentIndex >= currentGroup.length - 1) { + stopAutoplay(); + return; + } + currentIndex = (currentIndex + 1) % currentGroup.length; + showSlide(currentIndex); + announce("Image " + (currentIndex + 1) + " of " + currentGroup.length); + }, autoplayInterval); + } + + function stopAutoplay() { + if (autoplayTimer) { + clearInterval(autoplayTimer); + autoplayTimer = null; + } + } + + /** Reset autoplay timer (called on manual navigation to restart the interval). */ + function resetAutoplay() { + if (autoplayInterval > 0) { + startAutoplay(); + } + } + + // --------------------------------------------------------------------------- + // Zoom (toolbar-button controlled; zooms about the image center) + // --------------------------------------------------------------------------- + + function zoomIn() { setZoom(zoomScale + ZOOM_STEP); } + function zoomOut() { setZoom(zoomScale - ZOOM_STEP); } + function zoomReset() { setZoom(1); } + + function setZoom(scale) { + scale = Math.max(ZOOM_MIN, Math.min(ZOOM_MAX, Math.round(scale * 100) / 100)); + if (scale === zoomScale) { + updateZoomUI(); + return; + } + zoomScale = scale; + clampPan(); // pull pan back into bounds when zooming out + applyZoom(false); + announce("Zoom " + Math.round(zoomScale * 100) + " percent"); + } + + /** Reset to fit (100%). `immediate` skips the transition (slide changes). */ + function resetZoom(immediate) { + zoomScale = 1; + panX = 0; + panY = 0; + applyZoom(immediate); + } + + /** Build the transform for the current zoom + pan (empty string at fit). */ + function zoomTransform() { + if (zoomScale <= 1) return ""; + return "translate(" + panX + "px, " + panY + "px) scale(" + zoomScale + ")"; + } + + /** Apply just the transform (used during drag-pan; no transition juggling). */ + function applyTransform() { + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (mainImg) mainImg.style.transform = zoomTransform(); + } + + function applyZoom(immediate) { + if (!overlay) return; + if (zoomScale <= 1) { + panX = 0; + panY = 0; + } + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (mainImg) { + if (immediate) { + var prev = mainImg.style.transition; + mainImg.style.transition = "none"; + mainImg.style.transform = zoomTransform(); + mainImg.offsetHeight; // force reflow so future changes animate + mainImg.style.transition = prev; + } else { + mainImg.style.transform = zoomTransform(); + } + } + // Cursor affordance: grab when zoomed (grabbing handled while dragging). + overlay.classList.toggle(PREFIX + "-zoomed", zoomScale > 1); + // Annotations are hidden while zoomed (shown again at fit level). + var layer = qs("." + PREFIX + "-annotations", overlay); + if (layer) { + layer.style.display = zoomScale > 1 ? "none" : ""; + } + updateZoomUI(); + } + + /** Clamp pan so the image always covers its fit box (no gaps inside it). */ + function clampPan() { + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (!mainImg || zoomScale <= 1) { + panX = 0; + panY = 0; + return; + } + var maxX = (mainImg.offsetWidth * (zoomScale - 1)) / 2; + var maxY = (mainImg.offsetHeight * (zoomScale - 1)) / 2; + panX = Math.max(-maxX, Math.min(maxX, panX)); + panY = Math.max(-maxY, Math.min(maxY, panY)); + } + + // ── Drag-to-pan (pointer events: mouse + touch) ─────────────────────────── + + function onPanStart(e) { + if (zoomScale <= 1) return; + isPanning = true; + panPointerStartX = e.clientX; + panPointerStartY = e.clientY; + panOriginX = panX; + panOriginY = panY; + overlay.classList.add(PREFIX + "-panning"); + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (mainImg && mainImg.setPointerCapture) { + try { mainImg.setPointerCapture(e.pointerId); } catch (err) {} + } + e.preventDefault(); + } + + function onPanMove(e) { + if (!isPanning) return; + panX = panOriginX + (e.clientX - panPointerStartX); + panY = panOriginY + (e.clientY - panPointerStartY); + clampPan(); + applyTransform(); + e.preventDefault(); + } + + function onPanEnd() { + if (!isPanning) return; + isPanning = false; + overlay.classList.remove(PREFIX + "-panning"); + } + + function updateZoomUI() { + if (!overlay) return; + var level = qs("." + PREFIX + "-zoom-level", overlay); + if (level) level.textContent = Math.round(zoomScale * 100) + "%"; + var outBtn = qs("." + PREFIX + "-btn-zoom-out", overlay); + var inBtn = qs("." + PREFIX + "-btn-zoom-in", overlay); + var resetBtn = qs("." + PREFIX + "-btn-zoom-reset", overlay); + if (outBtn) outBtn.disabled = zoomScale <= ZOOM_MIN; + if (inBtn) inBtn.disabled = zoomScale >= ZOOM_MAX; + if (resetBtn) resetBtn.disabled = zoomScale === 1; + } + + function showSlide(index, originItem) { + var item = currentGroup[index]; + if (!item) return; + + // Each slide starts at fit (100%); clear any zoom from the previous image. + resetZoom(true); + + var mainImg = qs("." + PREFIX + "-main-img", overlay); + var captionText = qs("." + PREFIX + "-caption-text", overlay); + var creditText = qs("." + PREFIX + "-credit-text", overlay); + var counter = qs("." + PREFIX + "-counter", overlay); + + // Update image source — use highest-resolution source for lightbox display + var src = getFullResSrc(item); + mainImg.setAttribute("src", src); + mainImg.removeAttribute("srcset"); + mainImg.removeAttribute("sizes"); + mainImg.setAttribute("alt", item.alt); + + // Update dialog label for screen readers + overlay.setAttribute("aria-label", item.alt || item.caption || "Image lightbox"); + + // Update caption + if (item.caption) { + captionText.textContent = item.caption; + captionText.style.display = ""; + } else { + captionText.style.display = "none"; + } + + if (item.credit) { + creditText.textContent = item.credit; + creditText.style.display = ""; + } else { + creditText.style.display = "none"; + } + + // Update counter + if (currentGroup.length > 1) { + counter.textContent = (index + 1) + " / " + currentGroup.length; + counter.style.display = ""; + } else { + counter.style.display = "none"; + } + + // Update navigation visibility + var prevBtn = qs("." + PREFIX + "-nav-prev", overlay); + var nextBtn = qs("." + PREFIX + "-nav-next", overlay); + if (currentGroup.length <= 1) { + prevBtn.style.display = "none"; + nextBtn.style.display = "none"; + } else { + prevBtn.style.display = ""; + nextBtn.style.display = ""; + // Disable buttons at boundaries when loop is off + if (!loopEnabled) { + prevBtn.disabled = index <= 0; + nextBtn.disabled = index >= currentGroup.length - 1; + } else { + prevBtn.disabled = false; + nextBtn.disabled = false; + } + } + + // Update filmstrip + updateFilmstrip(); + + // Render any annotations over the enlarged image + renderAnnotations(item); + } + + // --------------------------------------------------------------------------- + // Annotations (over the enlarged image) + // --------------------------------------------------------------------------- + + /** + * Render annotation markers for the current slide using the shared + * GDAnnotate API, so they match the in-page annotations exactly. The markers + * live in a layer that is sized to the displayed image by positionAnnotations. + */ + function renderAnnotations(item) { + var imageWrap = qs("." + PREFIX + "-image-wrap", overlay); + if (!imageWrap) return; + + // Clear any layer from the previous slide + var existing = qs("." + PREFIX + "-annotations", imageWrap); + if (existing) existing.remove(); + + if (!item.annotations || !window.GDAnnotate || !window.GDAnnotate.buildOverlay) { + return; + } + + var layer = el("div", { className: PREFIX + "-annotations" }); + layer.appendChild(window.GDAnnotate.buildOverlay(item.annotations)); + imageWrap.appendChild(layer); + + // The image src was just (re)set, so its layout box may not be final yet. + // Position immediately (no reveal), then reveal once it has loaded and as a + // fallback after the open animation (covers cached images). + var mainImg = qs("." + PREFIX + "-main-img", overlay); + positionAnnotations(false); + if (mainImg) { + mainImg.addEventListener("load", function () { + positionAnnotations(true); + }, { once: true }); + } + setTimeout(function () { positionAnnotations(true); }, TRANSITION_MS + 60); + } + + /** Size/position the annotation layer to exactly cover the displayed image. */ + function positionAnnotations(reveal) { + if (!overlay) return; + var imageWrap = qs("." + PREFIX + "-image-wrap", overlay); + var mainImg = imageWrap && qs("." + PREFIX + "-main-img", overlay); + var layer = imageWrap && qs("." + PREFIX + "-annotations", imageWrap); + if (!layer || !mainImg) return; + + layer.style.left = mainImg.offsetLeft + "px"; + layer.style.top = mainImg.offsetTop + "px"; + layer.style.width = mainImg.offsetWidth + "px"; + layer.style.height = mainImg.offsetHeight + "px"; + if (reveal) layer.classList.add("visible"); + } + + // --------------------------------------------------------------------------- + // Filmstrip + // --------------------------------------------------------------------------- + + function updateFilmstrip() { + var filmstrip = qs("." + PREFIX + "-filmstrip", overlay); + if (!filmstrip) return; + + if (!currentGroup || currentGroup.length <= 1) { + filmstrip.style.display = "none"; + overlay.classList.remove(PREFIX + "-has-filmstrip"); + return; + } + + filmstrip.style.display = ""; + // Reserve bottom space so the caption clears the filmstrip (see CSS). + overlay.classList.add(PREFIX + "-has-filmstrip"); + filmstrip.innerHTML = ""; + + currentGroup.forEach(function (item, i) { + var thumb = el("button", { + className: + PREFIX + "-filmstrip-thumb" + (i === currentIndex ? " active" : ""), + "aria-label": "Go to image " + (i + 1), + onClick: function () { + currentIndex = i; + showSlide(i); + announce("Image " + (i + 1) + " of " + currentGroup.length); + }, + }); + var img = el("img", { + src: getImageSrc(item), + alt: "", + "aria-hidden": "true", + }); + thumb.appendChild(img); + filmstrip.appendChild(thumb); + }); + + // Scroll active thumb into view + var active = qs("." + PREFIX + "-filmstrip-thumb.active", filmstrip); + if (active) { + active.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" }); + } + } + + // --------------------------------------------------------------------------- + // Origin-Aware Animation + // --------------------------------------------------------------------------- + + function animateOpen(item) { + var rect = item.img.getBoundingClientRect(); + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (!mainImg) return; + + // Set starting transform to match thumbnail position + var vpW = window.innerWidth; + var vpH = window.innerHeight; + + // Calculate scale and translation + var targetW = Math.min(vpW * 0.9, mainImg.naturalWidth || vpW * 0.8); + var scaleX = rect.width / targetW; + var scaleY = rect.height / (targetW * (rect.height / rect.width)); + + mainImg.style.transition = "none"; + mainImg.style.transform = + "translate(" + + (rect.left + rect.width / 2 - vpW / 2) + + "px, " + + (rect.top + rect.height / 2 - vpH / 2) + + "px) scale(" + + scaleX + + ")"; + mainImg.style.opacity = "0.8"; + + // Force reflow + mainImg.offsetHeight; + + // Animate to center + mainImg.style.transition = + "transform " + TRANSITION_MS + "ms cubic-bezier(0.4, 0, 0.2, 1), " + + "opacity " + TRANSITION_MS + "ms ease"; + mainImg.style.transform = "translate(0, 0) scale(1)"; + mainImg.style.opacity = "1"; + + // Clean up after animation. Don't clobber an active zoom if the user + // zoomed during the open transition — only clear the open transform. + setTimeout(function () { + mainImg.style.transition = ""; + mainImg.style.transform = zoomScale > 1 ? "scale(" + zoomScale + ")" : ""; + }, TRANSITION_MS + 50); + } + + // --------------------------------------------------------------------------- + // Toolbar Actions + // --------------------------------------------------------------------------- + + function handleCopy() { + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (!mainImg || !mainImg.src) return; + var src = mainImg.src; + + // The async Clipboard API only reliably accepts image/png (SVG and other + // types are rejected), so we rasterize whatever is displayed — including + // SVG — to a PNG before copying. We hand a Promise to ClipboardItem so the + // async rasterization happens inside the user-activation window, which + // Safari requires; doing the work first and writing afterwards loses the + // gesture and the write (and any fallback) silently fails. + var canWriteImage = + window.ClipboardItem && navigator.clipboard && navigator.clipboard.write; + + if (canWriteImage) { + var item = new ClipboardItem({ "image/png": toPngBlob(src) }); + navigator.clipboard + .write([item]) + .then(function () { showToast("Image copied"); }) + .catch(function () { fallbackCopyUrl(src); }); + } else { + fallbackCopyUrl(src); + } + } + + /** + * Rasterize an image URL (raster or SVG) to a PNG Blob via canvas. + * Returns a Promise; rejects if the image can't be loaded or the + * canvas is tainted (e.g. a cross-origin source without CORS headers). + */ + function toPngBlob(src) { + return new Promise(function (resolve, reject) { + var img = new Image(); + img.crossOrigin = "anonymous"; + img.onload = function () { + var w = img.naturalWidth || img.width; + var h = img.naturalHeight || img.height; + if (!w || !h) { + reject(new Error("Image has no intrinsic size")); + return; + } + var canvas = document.createElement("canvas"); + canvas.width = w; + canvas.height = h; + try { + canvas.getContext("2d").drawImage(img, 0, 0, w, h); + canvas.toBlob(function (blob) { + blob ? resolve(blob) : reject(new Error("toBlob returned null")); + }, "image/png"); + } catch (e) { + reject(e); + } + }; + img.onerror = function () { reject(new Error("Image load failed")); }; + img.src = src; + }); + } + + /** Fallback when image copy isn't possible: copy the image URL as text. */ + function fallbackCopyUrl(src) { + if (navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard + .writeText(src) + .then(function () { showToast("Image URL copied"); }) + .catch(function () { showToast("Copy not supported"); }); + } else { + showToast("Copy not supported"); + } + } + + function handleDownload() { + var mainImg = qs("." + PREFIX + "-main-img", overlay); + if (!mainImg || !mainImg.src) return; + + var item = currentGroup[currentIndex]; + var filename = item + ? (item.alt || item.src.split("/").pop() || "image") + : "image"; + // Sanitize filename + filename = filename.replace(/[^a-zA-Z0-9_\-. ]/g, "_").slice(0, 100); + + var a = document.createElement("a"); + a.href = mainImg.src; + a.download = filename; + a.style.display = "none"; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + } + + function handleCopyLink() { + var item = currentGroup[currentIndex]; + if (!item || !item.id) { + showToast("No link available"); + return; + } + var url = window.location.origin + window.location.pathname + "#lightbox=" + item.id; + navigator.clipboard.writeText(url).then(function () { + showToast("Link copied"); + }).catch(function () { + showToast("Could not copy link"); + }); + } + + function showToast(msg) { + var existing = qs("." + PREFIX + "-toast"); + if (existing) existing.remove(); + + var toast = el("div", { className: PREFIX + "-toast" }, [msg]); + overlay.appendChild(toast); + + // Animate in + requestAnimationFrame(function () { + toast.classList.add("visible"); + }); + + setTimeout(function () { + toast.classList.remove("visible"); + setTimeout(function () { toast.remove(); }, 300); + }, 2000); + } + + // --------------------------------------------------------------------------- + // Toolbar Auto-Hide + // --------------------------------------------------------------------------- + + function startToolbarTimer() { + clearTimeout(toolbarTimer); + showToolbar(); + toolbarTimer = setTimeout(hideToolbar, TOOLBAR_HIDE_MS); + } + + function showToolbar() { + var tb = qs("." + PREFIX + "-toolbar", overlay); + if (tb) tb.classList.remove("hidden"); + } + + function hideToolbar() { + var tb = qs("." + PREFIX + "-toolbar", overlay); + if (tb) tb.classList.add("hidden"); + // The toolbar hides via opacity (it stays in the DOM), so a tippy tooltip + // attached to a button could linger visibly. Dismiss any active ones. + hideToolbarTooltips(); + } + + /** Hide any tippy tooltips currently attached to toolbar buttons. */ + function hideToolbarTooltips() { + if (!overlay) return; + qsa("." + PREFIX + "-btn", overlay).forEach(function (btn) { + if (btn._tippy) btn._tippy.hide(); + }); + } + + // --------------------------------------------------------------------------- + // Keyboard Navigation + // --------------------------------------------------------------------------- + + function handleKeydown(e) { + if (!isOpen) return; + + switch (e.key) { + case "Escape": + close(); + e.preventDefault(); + break; + case "ArrowRight": + next(); + e.preventDefault(); + break; + case "ArrowLeft": + prev(); + e.preventDefault(); + break; + case "Tab": + trapFocus(e); + break; + case "+": + case "=": // unshifted "+" key + zoomIn(); + e.preventDefault(); + break; + case "-": + case "_": + zoomOut(); + e.preventDefault(); + break; + case "0": + zoomReset(); + e.preventDefault(); + break; + } + } + + function trapFocus(e) { + var focusable = qsa( + 'button:not([disabled]), [tabindex]:not([tabindex="-1"])', + overlay + ); + if (focusable.length === 0) return; + + var first = focusable[0]; + var last = focusable[focusable.length - 1]; + + if (e.shiftKey) { + if (document.activeElement === first) { + last.focus(); + e.preventDefault(); + } + } else { + if (document.activeElement === last) { + first.focus(); + e.preventDefault(); + } + } + } + + // --------------------------------------------------------------------------- + // Touch / Swipe + // --------------------------------------------------------------------------- + + function handleTouchStart(e) { + if (!isOpen) return; + // When zoomed, touch drives pan (pointer events), not swipe-nav/close. + if (zoomScale > 1) return; + var touch = e.touches[0]; + touchStartX = touch.clientX; + touchStartY = touch.clientY; + touchDeltaX = 0; + touchDeltaY = 0; + isSwiping = false; + } + + function handleTouchMove(e) { + if (!isOpen) return; + if (zoomScale > 1) return; + var touch = e.touches[0]; + touchDeltaX = touch.clientX - touchStartX; + touchDeltaY = touch.clientY - touchStartY; + + // Determine if horizontal or vertical swipe + if (!isSwiping && (Math.abs(touchDeltaX) > 10 || Math.abs(touchDeltaY) > 10)) { + isSwiping = true; + } + + // Prevent page scroll while swiping in lightbox + if (isSwiping) { + e.preventDefault(); + } + } + + function handleTouchEnd() { + if (!isOpen || !isSwiping) return; + + var threshold = 50; + + // Horizontal swipe → gallery navigation + if (Math.abs(touchDeltaX) > Math.abs(touchDeltaY)) { + if (touchDeltaX > threshold) { + prev(); + } else if (touchDeltaX < -threshold) { + next(); + } + } else { + // Vertical swipe down → close + if (touchDeltaY > threshold) { + close(); + } + } + + isSwiping = false; + } + + // --------------------------------------------------------------------------- + // Dark Mode Observer + // --------------------------------------------------------------------------- + + function setupDarkModeObserver() { + var html = document.documentElement; + var observer = new MutationObserver(function (mutations) { + var newDarkMode = detectDarkMode(); + if (newDarkMode !== isDarkMode) { + isDarkMode = newDarkMode; + if (isOpen) { + // Swap image source + showSlide(currentIndex); + } + // Also swap thumbnails on the page + swapThumbnails(); + } + }); + observer.observe(html, { + attributes: true, + attributeFilter: ["class", "data-bs-theme"], + }); + } + + function swapThumbnails() { + allItems.forEach(function (item) { + if (item.darkSrc) { + item.img.setAttribute("src", getImageSrc(item)); + } + }); + } + + // --------------------------------------------------------------------------- + // Screen Reader Announcements + // --------------------------------------------------------------------------- + + function announce(msg) { + var region = qs("." + PREFIX + "-sr-announce", overlay); + if (region) { + region.textContent = msg; + } + } + + // --------------------------------------------------------------------------- + // Deep Linking + // --------------------------------------------------------------------------- + + function checkDeepLink() { + var hash = window.location.hash; + if (!hash.startsWith("#lightbox=")) return; + + var id = hash.slice("#lightbox=".length); + var item = allItems.find(function (it) { + return it.id === id; + }); + if (item) { + // Delay to allow page to render + setTimeout(function () { open(item); }, 100); + } + } + + // --------------------------------------------------------------------------- + // Event Binding + // --------------------------------------------------------------------------- + + function bindClick(item) { + // Click on wrapper or expand button opens lightbox + item.wrapper.addEventListener("click", function (e) { + e.preventDefault(); + e.stopPropagation(); + open(item); + }); + + // Make wrapper keyboard-accessible + item.wrapper.setAttribute("tabindex", "0"); + item.wrapper.setAttribute("role", "button"); + item.wrapper.setAttribute("aria-label", "View image: " + (item.alt || "image")); + item.wrapper.addEventListener("keydown", function (e) { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + open(item); + } + }); + } + + // --------------------------------------------------------------------------- + // Init + // --------------------------------------------------------------------------- + + function init() { + isDarkMode = detectDarkMode(); + collectItems(); + + if (allItems.length === 0) return; + + allItems.forEach(bindClick); + setupDarkModeObserver(); + + // Global keyboard handler + document.addEventListener("keydown", handleKeydown); + + // Touch handlers on overlay (after it's created) + document.addEventListener("touchstart", function (e) { + if (isOpen) handleTouchStart(e); + }, { passive: true }); + document.addEventListener("touchmove", function (e) { + if (isOpen) handleTouchMove(e); + }, { passive: false }); + document.addEventListener("touchend", function (e) { + if (isOpen) handleTouchEnd(e); + }, { passive: true }); + + // Mouse movement re-shows toolbar + document.addEventListener("mousemove", function () { + if (isOpen) startToolbarTimer(); + }); + + // Keep annotation markers aligned to the image when the viewport resizes + window.addEventListener("resize", function () { + if (!isOpen) return; + positionAnnotations(false); + if (zoomScale > 1) { + clampPan(); + applyTransform(); + } + }); + + // Deep link check + checkDeepLink(); + window.addEventListener("hashchange", checkDeepLink); + } + + // Run on DOM ready + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", init); + } else { + init(); + } +})(); diff --git a/docs/github-widget.js b/docs/github-widget.js new file mode 100644 index 0000000..8b50776 --- /dev/null +++ b/docs/github-widget.js @@ -0,0 +1,312 @@ +/** + * GitHub Widget for Great-Docs + * + * A souped-up GitHub icon link with: + * - Live star and fork counts + * - Dropdown menu linking to repo, issues, PRs + * - Caching to avoid API rate limits + */ + +(function() { + 'use strict'; + + // Configuration - will be set by data attributes + let config = { + owner: null, + repo: null, + cacheKey: 'great-docs-github-stats', + cacheDuration: 4 * 60 * 60 * 1000 // 4 hours + }; + + /** + * Initialize the GitHub widget + */ + function initGitHubWidget() { + const widget = document.getElementById('github-widget'); + if (!widget) return; + + config.owner = widget.dataset.owner; + config.repo = widget.dataset.repo; + + if (!config.owner || !config.repo) { + console.warn('GitHub widget: Missing owner or repo data attributes'); + return; + } + + // Create the widget structure + createWidgetStructure(widget); + + // Use build-time embedded stats if available, otherwise try API + const embeddedStars = widget.dataset.stars; + const embeddedForks = widget.dataset.forks; + if (embeddedStars !== undefined && embeddedForks !== undefined) { + updateStatsDisplay({ + stars: parseInt(embeddedStars, 10), + forks: parseInt(embeddedForks, 10) + }); + } else { + fetchGitHubStats(); + } + + // Setup dropdown behavior + setupDropdown(widget); + } + + /** + * Create the HTML structure for the widget + */ + function createWidgetStructure(container) { + const repoUrl = `https://github.com/${config.owner}/${config.repo}`; + + container.innerHTML = ` + + + `; + } + + /** + * Fetch GitHub stats from API with caching + */ + async function fetchGitHubStats() { + const cacheKey = `${config.cacheKey}-${config.owner}-${config.repo}`; + + // Check cache first + const cached = getFromCache(cacheKey); + if (cached) { + updateStatsDisplay(cached); + return; + } + + // Get stale cache (expired but still usable as fallback) + const staleCache = getFromCache(cacheKey, true); + + try { + // Fetch repo stats + const repoResponse = await fetch( + `https://api.github.com/repos/${config.owner}/${config.repo}`, + { + headers: { + 'Accept': 'application/vnd.github+json', + 'X-GitHub-Api-Version': '2022-11-28' + } + } + ); + + if (!repoResponse.ok) { + throw new Error(`GitHub API error: ${repoResponse.status}`); + } + + const repoData = await repoResponse.json(); + + const stats = { + stars: repoData.stargazers_count, + forks: repoData.forks_count, + openIssues: repoData.open_issues_count, + timestamp: Date.now() + }; + + // Cache the results + saveToCache(cacheKey, stats); + + // Update display + updateStatsDisplay(stats); + + } catch (error) { + console.warn('GitHub widget: Failed to fetch stats', error); + // Use stale cache if available, otherwise show fallback + if (staleCache) { + updateStatsDisplay(staleCache); + } else { + updateStatsDisplay({ stars: '?', forks: '?' }); + } + } + } + + /** + * Update the display with fetched stats + */ + function updateStatsDisplay(stats) { + const starsEl = document.querySelector('.gh-count[data-stat="stars"]'); + const forksEl = document.querySelector('.gh-count[data-stat="forks"]'); + const issuesBadge = document.querySelector('.gh-issues-count'); + const prsBadge = document.querySelector('.gh-prs-count'); + const starsTotalBadge = document.querySelector('.gh-stars-total'); + const forksTotalBadge = document.querySelector('.gh-forks-total'); + + if (starsEl) starsEl.textContent = formatCount(stats.stars); + if (forksEl) forksEl.textContent = formatCount(stats.forks); + + if (issuesBadge && stats.issues !== undefined) { + issuesBadge.textContent = formatCount(stats.issues); + issuesBadge.style.display = 'inline-flex'; + } + + if (prsBadge && stats.prs !== undefined) { + prsBadge.textContent = formatCount(stats.prs); + prsBadge.style.display = 'inline-flex'; + } + + if (starsTotalBadge && stats.stars !== undefined && stats.stars !== '?') { + starsTotalBadge.textContent = formatCount(stats.stars); + starsTotalBadge.style.display = 'inline-flex'; + } + + if (forksTotalBadge && stats.forks !== undefined && stats.forks !== '?') { + forksTotalBadge.textContent = formatCount(stats.forks); + forksTotalBadge.style.display = 'inline-flex'; + } + } + + /** + * Format large numbers (e.g., 1500 -> 1.5k) + */ + function formatCount(num) { + if (num === undefined || num === null || num === '?') return '?'; + if (num >= 1000000) { + return (num / 1000000).toFixed(1).replace(/\.0$/, '') + 'M'; + } + if (num >= 1000) { + return (num / 1000).toFixed(1).replace(/\.0$/, '') + 'k'; + } + return num.toString(); + } + + /** + * Get cached data if not expired (or any cached data if allowStale is true) + */ + function getFromCache(key, allowStale) { + try { + const data = localStorage.getItem(key); + if (!data) return null; + + const parsed = JSON.parse(data); + if (!allowStale && Date.now() - parsed.timestamp > config.cacheDuration) { + return null; + } + return parsed; + } catch (e) { + return null; + } + } + + /** + * Save data to cache + */ + function saveToCache(key, data) { + try { + localStorage.setItem(key, JSON.stringify(data)); + } catch (e) { + // Silently fail if localStorage is not available + } + } + + /** + * Setup dropdown toggle behavior + */ + function setupDropdown(widget) { + const trigger = widget.querySelector('.gh-widget-trigger'); + const dropdown = widget.querySelector('.gh-dropdown'); + + if (!trigger || !dropdown) return; + + // Toggle on click + trigger.addEventListener('click', (e) => { + e.stopPropagation(); + const isExpanded = trigger.getAttribute('aria-expanded') === 'true'; + trigger.setAttribute('aria-expanded', !isExpanded); + dropdown.setAttribute('aria-hidden', isExpanded); + widget.classList.toggle('gh-widget-open', !isExpanded); + }); + + // Toggle on Enter/Space key + trigger.addEventListener('keydown', (e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + trigger.click(); + } + }); + + // Close on click outside + document.addEventListener('click', (e) => { + if (!widget.contains(e.target)) { + trigger.setAttribute('aria-expanded', 'false'); + dropdown.setAttribute('aria-hidden', 'true'); + widget.classList.remove('gh-widget-open'); + } + }); + + // Close on Escape key + document.addEventListener('keydown', (e) => { + if (e.key === 'Escape') { + trigger.setAttribute('aria-expanded', 'false'); + dropdown.setAttribute('aria-hidden', 'true'); + widget.classList.remove('gh-widget-open'); + } + }); + } + + // Initialize when DOM is ready + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initGitHubWidget); + } else { + initGitHubWidget(); + } +})(); diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..b5ab674 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,819 @@ + + + + + + + + + +switchlang | switchlang + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+ + + + +
+ + + + + + +
+ +
+

AI / Agents

+

Skills
llms.txt
llms-full.txt

+
+
+

Developers

+
+ +

+Michael Kennedy +

+
+

+Author +

+
+
+
+
+

Community

+

Full license MIT

+
+
+

Meta

+

Requires: Python >=3.9
Provides-Extra: dev
Package Info

+
+
+

switchlang

+

+

Adds switch blocks to the Python language.

+

This module adds explicit switch functionality to Python without changing the language. It builds upon a standard way to define execution blocks: the with statement.

+

Full documentation, including the API reference, lives at mkennedy.codes/docs/python-switch.

+
+

Example

+
from switchlang import switch
+
+def main():
+    num = 7
+    val = input("Enter a character, a, b, c or any other: ")
+
+    with switch(val) as s:
+        s.case('a', process_a)
+        s.case('b', lambda: process_with_data(val, num, 'other values still'))
+        s.default(process_any)
+
+def process_a():
+    print("Found A!")
+
+def process_any():
+    print("Found Default!")
+
+def process_with_data(*value):
+    print(f"Found with data: {value}")
+
+main()
+
+
+

Installation

+

Simply install via pip or uv:

+
pip install switchlang
+# or
+uv add switchlang
+
+
+

Features

+
    +
  • More explicit than using dictionaries with functions as values.
  • +
  • Validates that case actions are callable
  • +
  • Supports default case
  • +
  • Checks for duplicate keys / cases
  • +
  • Keys can be anything hashable (numbers, strings, objects, etc.)
  • +
  • Capture the return value of the matched case with s.result
  • +
  • Supports “fall-through” cases (opt-in with fallthrough=True)
  • +
  • Use range and list for multiple cases mapped to a single action
  • +
+
+
+

Multiple cases, one action

+

You can map ranges and lists of cases to a single action as follows:

+
# with lists:
+value = 4  # matches even number case
+
+with switch(value) as s:
+    s.case([1, 3, 5, 7], lambda: ...)
+    s.case([0, 2, 4, 6, 8], lambda: ...)
+    s.default(lambda: ...)
+
# with ranges:
+value = 4  # matches first case
+
+with switch(value) as s:
+    s.case(range(1, 6), lambda: ...)
+    s.case(range(6, 10), lambda: ...)
+    s.default(lambda: ...)
+
+
+

Closed vs. Open ranges

+

Looking at the above code it’s a bit weird that 6 appears at the end of one case, beginning of the next. But range() is half open/closed.

+

To handle the inclusive case, I’ve added closed_range(start, stop). For example, closed_range(1, 5) -> [1, 2, 3, 4, 5]:

+
from switchlang import switch, closed_range
+
+with switch(value) as s:
+    s.case(closed_range(1, 5), lambda: 'one to five')  # matches 1, 2, 3, 4, 5
+    s.case(closed_range(6, 9), lambda: 'six to nine')  # matches 6, 7, 8, 9
+    s.default(lambda: 'something else')
+
+
+

Fall-through and results

+

Cases don’t fall through by default. Opt in per case with fallthrough=True and the next case runs too, whether or not its key matches:

+
value = 2
+
+with switch(value) as s:
+    s.case(1, lambda: 'one')
+    s.case(2, lambda: 'two', fallthrough=True)
+    s.case(3, lambda: 'three')  # runs as well, then stops here
+    s.default(lambda: 'other')
+
+print(s.result)  # 'three'
+

Whatever the executed case’s function returns is available after the block as s.result. When cases fall through, the last function executed wins.

+
+
+

Why not just raw dict?

+

The biggest push back on this idea is that we already have this problem solved. You write the following code.

+
switch = {
+    1: method_on_one,
+    2: method_on_two,
+    3: method_three
+}
+
+result = switch.get(value, default_method_to_run)()
+

This works but is very low on the functionality level. We have a better solution here I believe. Let’s take this example and see how it looks in python-switch vs raw dicts:

+
# with python-switch:
+
+while True:
+    action = get_action(action)
+
+    with switch(action) as s:
+        s.case(['c', 'a'], create_account)
+        s.case('l', log_into_account)
+        s.case('r', register_cage)
+        s.case('u', update_availability)
+        s.case(['v', 'b'], view_bookings)
+        s.case('x', exit_app)
+        s.case('', lambda: None)
+        s.case(range(1, 6), lambda: set_level(action))
+        s.default(unknown_command)
+
+    print(f'Result is {s.result}')
+

Now compare that to the espoused pythonic way:

+
# with raw dicts
+
+while True:
+    action = get_action(action)
+
+    switch = {
+        'c': create_account,
+        'a': create_account,
+        'l': log_into_account,
+        'r': register_cage,
+        'u': update_availability,
+        'v': view_bookings,
+        'b': view_bookings,
+        'x': exit_app,
+        1: lambda: set_level(action),
+        2: lambda: set_level(action),
+        3: lambda: set_level(action),
+        4: lambda: set_level(action),
+        5: lambda: set_level(action),
+        '': lambda: None,
+    }
+    result = switch.get(action, unknown_command)()
+    print(f'Result is {result}')
+

Personally, I much prefer to read and write the one above. That’s why I wrote this module. It seems to convey the intent of switch way more than the dict. But both are options.

+
+
+

Why not just if / elif / else?

+

Another push back on this idea is that we already have this problem solved. Switch statements are really if / elif / else blocks. So you write the following code.

+
# with if / elif / else
+
+while True:
+    action = get_action(action)
+
+    if action == 'c' or action == 'a':
+        result = create_account()
+    elif action == 'l':
+        result = log_into_account()
+    elif action == 'r':
+        result = register_cage()
+    elif action == 'a':
+        result = update_availability()
+    elif action == 'v' or action == 'b':
+        result = view_bookings()
+    elif action == 'x':
+        result = exit_app()
+    elif action in {1, 2, 3, 4, 5}:
+        result = set_level(action)
+    else:
+        unknown_command()
+
+    print(f'Result is {result}')
+

I actually believe this is a little better than the raw dict option. But there are still things that are harder.

+
    +
  • How would you deal with fall-through cleanly?
  • +
  • Did you notice the bug? We forgot to set result in default case (else) and will result in a runtime error (but only if that case hits).
  • +
  • There is another bug. update_availability will never run because its command (a) is bound to two cases. This is guarded against in switch and you would receive a duplicate case error the first time it runs at all.
  • +
  • While it’s pretty clear, it’s much more verbose and less declarative than the switch version.
  • +
+

Again, compare the if / elif / else to what you have with switch. This code is identical except doesn’t have the default case bug.

+
while True:
+    action = get_action(action)
+
+    with switch(action) as s:
+        s.case(['c', 'a'], create_account)
+        s.case('l', log_into_account)
+        s.case('r', register_cage)
+        s.case('u', update_availability)
+        s.case(['v', 'b'], view_bookings)
+        s.case('x', exit_app)
+        s.case('', lambda: None)
+        s.case(range(1, 6), lambda: set_level(action))
+        s.default(unknown_command)
+
+    print(f'Result is {s.result}')
+
+
+

Why not just match?

+

Python 3.10 added structural pattern matching, and it’s genuinely great at what it was built for: destructuring data by shape (tuples, dataclasses, nested structures, and so on). But it covers different ground than a classic switch statement:

+
    +
  • No fall-through. match arms are exclusive. With switchlang, fall-through is opt-in per case with fallthrough=True.
  • +
  • Cases are fixed syntax. You can’t build match arms from data at runtime, while s.case(some_list, action) and s.case(closed_range(1, 5), action) are plain method calls. Also watch out: a bare name in a case pattern captures the value rather than comparing against a constant — a classic match gotcha that can’t happen here.
  • +
  • No result capture. match arms are blocks of statements. switchlang dispatches to callables and hands back the chosen case’s return value as s.result.
  • +
  • Python version. match needs Python 3.10+, while switchlang supports 3.9+.
  • +
+

If you’re pattern-matching on the shape of objects, use match — that’s what it’s for. If you want explicit value-based dispatch with fall-through, ranges, and a captured result, that’s switchlang.

+ + +
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/keyboard-nav.js b/docs/keyboard-nav.js new file mode 100644 index 0000000..14ccfd1 --- /dev/null +++ b/docs/keyboard-nav.js @@ -0,0 +1,1139 @@ +/** + * Keyboard Navigation & Shortcuts for Great Docs + * + * Features: + * - `/` or `s` to focus search + * - `[` / `]` for previous/next page navigation + * - `q` to navigate to homepage + * - `u` to navigate to User Guide (when available) + * - `r` to navigate to API Reference (when available) + * - `m` or `n` to show/hide floating menu overlay (sidebar nav or navbar links) + * - `d` to toggle dark mode + * - `c` to copy page as Markdown (when available) + * - `h` or `?` to show/hide keyboard shortcuts help overlay + * - `Escape` to close overlay or unfocus active element + * - Dark mode aware + * - Respects reduced-motion preferences + * - Skips shortcuts when user is typing in inputs/textareas + * - ARIA attributes for screen reader accessibility + */ + +(function() { + 'use strict'; + + // i18n helper — read translations from + var _i18nCache = null; + function _gdT(key, fallback) { + if (!_i18nCache) { + try { + var meta = document.querySelector('meta[name="gd-i18n"]'); + _i18nCache = meta ? JSON.parse(meta.getAttribute('content')) : {}; + } catch (e) { _i18nCache = {}; } + } + return _i18nCache[key] || fallback; + } + + // State + var overlay = null; + var isOverlayOpen = false; + var menuOverlay = null; + var isMenuOpen = false; + + /** + * Check if the user prefers reduced motion + */ + function prefersReducedMotion() { + return window.matchMedia('(prefers-reduced-motion: reduce)').matches; + } + + /** + * Check if the active element is an input or editable area + */ + function isTyping() { + var el = document.activeElement; + if (!el) return false; + var tag = el.tagName; + if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return true; + if (el.isContentEditable) return true; + // Quarto search autocomplete input + if (el.classList.contains('aa-Input')) return true; + return false; + } + + // ── Search Focus ───────────────────────────────────────────────────── + + function focusSearch() { + // Try Quarto's Algolia-style autocomplete input first + var searchInput = document.querySelector('.aa-Input'); + if (!searchInput) { + // Fall back to the Quarto search container (clicking it usually opens the search) + var searchContainer = document.querySelector('#quarto-search'); + if (searchContainer) { + var btn = searchContainer.querySelector('button') || + searchContainer.querySelector('[role="button"]'); + if (btn) { + btn.click(); + return; + } + } + } + if (searchInput) { + searchInput.focus(); + if (searchInput.select) searchInput.select(); + } + } + + // ── Page Navigation ────────────────────────────────────────────────── + + function navigatePrev() { + var link = document.querySelector('.nav-page-previous a.pagination-link'); + if (link) { + link.click(); + } + } + + function navigateNext() { + var link = document.querySelector('.nav-page-next a.pagination-link'); + if (link) { + link.click(); + } + } + + function navigateHome() { + // Use the navbar brand link (always points to site root) + var brand = document.querySelector('.navbar-brand'); + if (brand && brand.href) { + window.location.href = brand.href; + return; + } + // Fallback: navigate to site root + window.location.href = './'; + } + + /** + * Find a navbar link whose href contains the given path segment. + */ + function findNavbarLink(pathSegment) { + var links = document.querySelectorAll( + '#navbarCollapse > .navbar-nav.me-auto > .nav-item > .nav-link' + ); + for (var i = 0; i < links.length; i++) { + var href = links[i].getAttribute('href') || ''; + if (href.indexOf(pathSegment) !== -1) return links[i]; + } + return null; + } + + function hasUserGuide() { return !!findNavbarLink('user-guide/'); } + function hasReference() { return !!findNavbarLink('reference/'); } + + function navigateUserGuide() { + var link = findNavbarLink('user-guide/'); + if (link) window.location.href = link.getAttribute('href'); + } + + function navigateReference() { + var link = findNavbarLink('reference/'); + if (link) window.location.href = link.getAttribute('href'); + } + + // ── Show Menu Overlay ────────────────────────────────────────────── + + /** + * Detect whether the current page is the homepage. + * Homepage body has `nav-fixed` but NOT `nav-sidebar`. + */ + function isHomepage() { + return !document.body.classList.contains('nav-sidebar'); + } + + /** + * Build menu items from the top navbar links (used on homepage). + * Returns an array of {text, href, active, section, html, badgeHtml} objects. + */ + function getNavbarItems() { + var items = []; + var links = document.querySelectorAll( + '#navbarCollapse > .navbar-nav.me-auto > .nav-item > .nav-link' + ); + for (var i = 0; i < links.length; i++) { + var a = links[i]; + var text = a.querySelector('.menu-text'); + if (!text) continue; + items.push({ + text: text.textContent.trim(), + html: text.innerHTML, + badgeHtml: '', + href: a.getAttribute('href') || '#', + active: a.classList.contains('active'), + section: null + }); + } + return items; + } + + /** + * Build menu items from the left sidebar navigation (used on content pages). + * Handles both sectioned sidebars (User Guide) and flat sidebars (Recipes). + * Returns an array of {text, href, active, section, html, badgeHtml, upcomingHtml} objects. + * - html: innerHTML of .menu-text (includes icons + text) + * - badgeHtml: outerHTML of .gd-sidebar-status-badge (if present) + * - upcomingHtml: outerHTML of .gd-sidebar-upcoming rocket icon (if present) + */ + function getSidebarItems() { + var items = []; + var sidebar = document.getElementById('quarto-sidebar'); + if (!sidebar) return items; + + function extractItem(a, sectionTitle) { + var menuText = a.querySelector('.menu-text'); + if (!menuText) return null; + var badge = a.querySelector('.gd-sidebar-status-badge'); + var upcoming = a.querySelector('.gd-sidebar-upcoming'); + return { + text: menuText.textContent.trim(), + html: menuText.innerHTML, + badgeHtml: badge ? badge.outerHTML : '', + upcomingHtml: upcoming ? upcoming.outerHTML : '', + href: a.getAttribute('href') || '#', + active: a.classList.contains('active'), + section: sectionTitle + }; + } + + function extractSectionHtml(sec) { + var headerEl = sec.querySelector(':scope > .sidebar-item-container .menu-text'); + if (!headerEl) { + // Try sidebar-item-text for section headers without .menu-text + headerEl = sec.querySelector(':scope > .sidebar-item-container .sidebar-item-text'); + } + return headerEl ? headerEl.innerHTML : null; + } + + var sections = sidebar.querySelectorAll('.sidebar-item-section'); + + if (sections.length > 0) { + // Sectioned sidebar (e.g., User Guide pages) + // First, capture any top-level links outside sections (e.g., "API Index") + var menuContainer = sidebar.querySelector('.sidebar-menu-container'); + if (menuContainer) { + var topLis = menuContainer.querySelectorAll(':scope > ul > li.sidebar-item:not(.sidebar-item-section)'); + for (var t = 0; t < topLis.length; t++) { + var topLink = topLis[t].querySelector('.sidebar-link'); + if (topLink) { + var topItem = extractItem(topLink, null); + if (topItem) items.push(topItem); + } + } + } + + for (var s = 0; s < sections.length; s++) { + var sec = sections[s]; + var sectionHtml = extractSectionHtml(sec); + + var links = sec.querySelectorAll('.sidebar-section .sidebar-link'); + for (var i = 0; i < links.length; i++) { + var item = extractItem(links[i], sectionHtml); + if (item) { + items.push(item); + sectionHtml = null; + } + } + } + } else { + // Flat sidebar (e.g., Recipes, custom sections) + var links = sidebar.querySelectorAll('.sidebar-item .sidebar-link'); + for (var i = 0; i < links.length; i++) { + var item = extractItem(links[i], null); + if (item) items.push(item); + } + } + + return items; + } + + /** + * Detect whether the current page is a Reference page (API or CLI). + */ + function isReferencePage() { + return document.body.classList.contains('gd-ref-sidebar'); + } + + /** + * Detect whether the current page is CLI Reference (vs API Reference). + */ + function isCliReferencePage() { + return window.location.pathname.indexOf('/reference/cli/') !== -1; + } + + /** + * Detect whether the current page is MCP Reference. + */ + function isMcpReferencePage() { + return window.location.pathname.indexOf('/reference/mcp/') !== -1; + } + + /** + * Get enabled reference sections from body data attribute. + */ + function getRefSections() { + var attr = document.body.getAttribute('data-gd-ref-sections'); + if (attr) return attr.split(',').map(function(s) { return s.trim(); }).filter(Boolean); + // Fallback detection + var sections = ['api']; + if (document.querySelector('.reference-switcher-container') || + document.querySelector('a[href*="/reference/cli/"]') || + isCliReferencePage()) { + sections.push('cli'); + } + if (document.querySelector('a[href*="/reference/mcp/"]') || + isMcpReferencePage()) { + sections.push('mcp'); + } + return sections; + } + + /** + * Check if CLI Reference docs exist (switcher should show both tabs). + */ + function hasCliReference() { + // Check multiple signals: the reference-switcher widget (injected by + // reference-switcher.js into the hidden sidebar), any to CLI docs, + // or being on a CLI page itself. + return !!document.querySelector('.reference-switcher-container') || + !!document.querySelector('a[href*="/reference/cli/"]') || + isCliReferencePage(); + } + + /** + * Build the reference switcher HTML for the keyboard nav overlay. + * Uses segmented buttons for 2 sections, dropdown for 3+. + */ + function buildRefSwitcherHtml() { + var sections = getRefSections(); + if (sections.length < 2) return ''; + + var currentRef = 'api'; + if (isMcpReferencePage()) currentRef = 'mcp'; + else if (isCliReferencePage()) currentRef = 'cli'; + + var sectionMeta = { + api: { label: _gdT('api', 'Python API'), svg: '' }, + cli: { label: _gdT('cli', 'CLI'), svg: '' }, + mcp: { label: _gdT('mcp', 'MCP Server'), svg: '' } + }; + + var html = '
'; + for (var i = 0; i < sections.length; i++) { + var id = sections[i]; + var meta = sectionMeta[id] || { label: id, svg: '' }; + var active = id === currentRef ? ' active' : ''; + html += ''; + } + html += '
'; + return html; + } + + /** + * Build the reference filter input HTML. + */ + function buildRefFilterHtml(itemCount) { + if (itemCount < 15) return ''; + var placeholder = _gdT('sidebar_filter_placeholder', 'Filter...'); + var html = '
'; + html += ''; + html += ''; + html += '
'; + return html; + } + + /** + * Attach filter behaviour to the overlay for reference pages. + */ + function attachRefFilter(overlay) { + var input = overlay.querySelector('.gd-menu-ref-filter-input'); + if (!input) return; + + input.addEventListener('input', function() { + var query = input.value.toLowerCase().trim(); + var items = overlay.querySelectorAll('.gd-menu-item'); + var sections = overlay.querySelectorAll('.gd-menu-section'); + + // Show/hide items based on text match + for (var i = 0; i < items.length; i++) { + var text = items[i].textContent.toLowerCase(); + items[i].parentElement.style.display = (!query || text.indexOf(query) !== -1) ? '' : 'none'; + } + + // Show section headers only if at least one child item is visible + for (var s = 0; s < sections.length; s++) { + var li = sections[s]; + var next = li.nextElementSibling; + var anyVisible = false; + while (next && !next.classList.contains('gd-menu-section')) { + if (next.style.display !== 'none') anyVisible = true; + next = next.nextElementSibling; + } + li.style.display = anyVisible ? '' : 'none'; + } + }); + + // Focus filter on open (after transition) + setTimeout(function() { input.focus(); }, 220); + } + + /** + * Parse sidebar items from an HTML string (fetched from another page). + * Returns an array of {text, html, href, section} objects. + */ + function parseSidebarItemsFromHtml(htmlStr, baseUrl) { + var parser = new DOMParser(); + var doc = parser.parseFromString(htmlStr, 'text/html'); + var sidebar = doc.getElementById('quarto-sidebar'); + if (!sidebar) return []; + + var items = []; + var sections = sidebar.querySelectorAll('.sidebar-item-section'); + + // Resolve relative URLs against the fetched page's base + var fullBase = new URL(baseUrl, window.location.origin).href; + function resolveHref(href) { + if (!href || href === '#') return '#'; + try { return new URL(href, fullBase).pathname; } + catch (e) { return href; } + } + + function extractParsedItem(a, sectionText) { + var menuText = a.querySelector('.menu-text'); + if (!menuText) return null; + return { + text: menuText.textContent.trim(), + html: menuText.innerHTML, + href: resolveHref(a.getAttribute('href')), + active: false, + section: sectionText + }; + } + + if (sections.length > 0) { + // Top-level links outside sections (like "API Index") + var menuContainer = sidebar.querySelector('.sidebar-menu-container'); + if (menuContainer) { + var topLis = menuContainer.querySelectorAll(':scope > ul > li.sidebar-item:not(.sidebar-item-section)'); + for (var t = 0; t < topLis.length; t++) { + var topLink = topLis[t].querySelector('.sidebar-link'); + if (topLink) { + var topItem = extractParsedItem(topLink, null); + if (topItem) items.push(topItem); + } + } + } + + for (var s = 0; s < sections.length; s++) { + var sec = sections[s]; + var headerEl = sec.querySelector(':scope > .sidebar-item-container .menu-text') || + sec.querySelector(':scope > .sidebar-item-container .sidebar-item-text'); + var sectionText = headerEl ? headerEl.innerHTML : null; + var links = sec.querySelectorAll('.sidebar-section .sidebar-link'); + for (var i = 0; i < links.length; i++) { + var item = extractParsedItem(links[i], sectionText); + if (item) { + items.push(item); + sectionText = null; + } + } + } + } else { + var flatLinks = sidebar.querySelectorAll('.sidebar-item .sidebar-link'); + for (var i = 0; i < flatLinks.length; i++) { + var item = extractParsedItem(flatLinks[i], null); + if (item) items.push(item); + } + } + + return items; + } + + /** + * Render items into the overlay list (replacing current contents). + */ + function renderItemsInOverlay(overlay, items) { + var listEl = overlay.querySelector('.gd-menu-list'); + if (!listEl) return; + + var html = ''; + var currentSection = null; + for (var i = 0; i < items.length; i++) { + var item = items[i]; + if (item.section && item.section !== currentSection) { + currentSection = item.section; + // Section text comes from innerHTML (already HTML-safe), so + // insert directly without escaping to avoid double-encoding + // entities like & → &amp; + html += ''; + } + var activeClass = item.active ? ' gd-menu-item-active' : ''; + var label = item.html || escapeHtml(item.text); + html += '
  • ' + + '' + label + '' + + '
  • '; + } + listEl.innerHTML = html; + + // Clear filter input if present + var filterInput = overlay.querySelector('.gd-menu-ref-filter-input'); + if (filterInput) { + filterInput.value = ''; + filterInput.dispatchEvent(new Event('input')); + } + } + + /** + * Attach switcher behaviour: clicking a tab fetches items from the + * other reference section and swaps the list in the overlay without + * navigating away. + */ + function attachRefSwitcher(overlay) { + var buttons = overlay.querySelectorAll('.gd-menu-ref-switcher-btn'); + if (!buttons.length) return; + + var basePath = window.location.pathname.split('/reference/')[0]; + var cache = {}; // cache fetched items by ref type + + // Pre-populate current section's items from what's already rendered + var currentType = 'api'; + if (isMcpReferencePage()) currentType = 'mcp'; + else if (isCliReferencePage()) currentType = 'cli'; + + var refPaths = { + api: basePath + '/reference/index.html', + cli: basePath + '/reference/cli/index.html', + mcp: basePath + '/reference/mcp/index.html' + }; + + for (var i = 0; i < buttons.length; i++) { + (function(btn) { + btn.addEventListener('click', function() { + var refType = btn.getAttribute('data-ref'); + + // Update active state on buttons + for (var b = 0; b < buttons.length; b++) { buttons[b].classList.remove('active'); } + btn.classList.add('active'); + + // If switching to the section we're already on, re-render from sidebar + if (refType === currentType) { + var items = getSidebarItems(); + renderItemsInOverlay(overlay, items); + return; + } + + // If cached, render immediately + if (cache[refType]) { + renderItemsInOverlay(overlay, cache[refType]); + return; + } + + // Fetch the target section's index page and parse its sidebar + var url = refPaths[refType] || basePath + '/reference/index.html'; + + fetch(url) + .then(function(res) { return res.text(); }) + .then(function(htmlStr) { + var items = parseSidebarItemsFromHtml(htmlStr, url); + cache[refType] = items; + // Only render if this tab is still active + if (btn.classList.contains('active')) { + renderItemsInOverlay(overlay, items); + } + }) + .catch(function() { + // On error, fall back to navigation + window.location.href = url; + }); + }); + })(buttons[i]); + } + } + + /** + * Create the floating menu overlay element. + */ + function createMenuOverlay() { + var el = document.createElement('div'); + el.className = 'gd-menu-overlay'; + el.setAttribute('role', 'dialog'); + el.setAttribute('aria-modal', 'true'); + el.setAttribute('aria-label', + _gdT('kb_show_menu', 'Show menu')); + + var homepage = isHomepage(); + var refPage = isReferencePage(); + var items = homepage ? getNavbarItems() : getSidebarItems(); + var title; + if (homepage) { + title = _gdT('kb_menu_title_site', 'Site Navigation'); + } else if (refPage) { + title = isCliReferencePage() + ? _gdT('cli_reference', 'CLI Reference') + : _gdT('api_reference', 'API Reference'); + } else { + title = _gdT('kb_menu_title_section', 'Section Navigation'); + } + + var html = '
    '; + html += '
    '; + html += '

    ' + escapeHtml(title) + '

    '; + html += ''; + html += '
    '; + + // Reference pages: inject switcher before the list + if (refPage) { + html += buildRefSwitcherHtml(); + } + + html += '
    '; + + el.innerHTML = html; + + // Attach reference-specific interactivity + if (refPage) { + attachRefSwitcher(el); + } + + return el; + } + + // Menu keyboard navigation state + var menuSelectedIndex = -1; + + /** + * Get all navigable menu items from the overlay. + */ + function getMenuItems() { + if (!menuOverlay) return []; + return menuOverlay.querySelectorAll('.gd-menu-item'); + } + + /** + * Update the visual focus indicator on menu items. + */ + function updateMenuFocus() { + var items = getMenuItems(); + for (var i = 0; i < items.length; i++) { + if (i === menuSelectedIndex) { + items[i].classList.add('gd-menu-item-focused'); + items[i].scrollIntoView({ block: 'nearest' }); + } else { + items[i].classList.remove('gd-menu-item-focused'); + } + } + } + + /** + * Handle keyboard events within the menu overlay. + */ + function handleMenuKeydown(e) { + var items = getMenuItems(); + if (items.length === 0) return; + + switch (e.key) { + case 'ArrowDown': + case 'ArrowRight': + case 'ArrowUp': + case 'ArrowLeft': + e.preventDefault(); + // Any arrow press selects the first item + if (menuSelectedIndex < 0) { + menuSelectedIndex = 0; + } else if (e.key === 'ArrowDown' || e.key === 'ArrowRight') { + menuSelectedIndex = Math.min(menuSelectedIndex + 1, items.length - 1); + } else { + menuSelectedIndex = Math.max(menuSelectedIndex - 1, 0); + } + updateMenuFocus(); + break; + + case 'Enter': + if (menuSelectedIndex >= 0 && menuSelectedIndex < items.length) { + e.preventDefault(); + items[menuSelectedIndex].click(); + } + break; + } + } + + function showMenu() { + // Always recreate to pick up current page state + if (menuOverlay) { + menuOverlay.remove(); + menuOverlay = null; + } + + menuOverlay = createMenuOverlay(); + document.body.appendChild(menuOverlay); + menuSelectedIndex = -1; + + // Close button + var closeBtn = menuOverlay.querySelector('.gd-menu-overlay-close'); + closeBtn.addEventListener('click', hideMenu); + + // Click on backdrop + menuOverlay.addEventListener('click', function(e) { + if (e.target === menuOverlay) { + hideMenu(); + } + }); + + // Lock body scroll and add backdrop blur on mobile + document.body.classList.add('gd-menu-open'); + + // On mobile, force headroom into the "unpinned" state so the + // full navbar slides up and only the Title Bar stays visible. + // This prevents the overlay card from appearing behind a tall + // header when the user is at the top of the page or has just + // scrolled up. + var header = document.querySelector('#quarto-header'); + var didFreezeHeadroom = false; + if (header && window.matchMedia('(max-width: 991.98px)').matches) { + header.classList.remove('headroom--pinned'); + header.classList.add('headroom--unpinned'); + // Freeze headroom via Quarto's toggle so it doesn't re-pin + if (typeof window.quartoToggleHeadroom === 'function') { + window.quartoToggleHeadroom(); // freeze + didFreezeHeadroom = true; + } + } + // Store so hideMenu can unfreeze only if we froze + showMenu._frozeHeadroom = didFreezeHeadroom; + + // Force reflow then show + void menuOverlay.offsetWidth; + menuOverlay.classList.add('gd-menu-overlay-visible'); + isMenuOpen = true; + + // Auto-scroll the active item into view (centered) + requestAnimationFrame(function() { + var activeItem = menuOverlay.querySelector('.gd-menu-item-active'); + if (activeItem) { + activeItem.scrollIntoView({ block: 'center', behavior: 'instant' }); + } + }); + } + + function hideMenu() { + if (!menuOverlay) return; + menuOverlay.classList.remove('gd-menu-overlay-visible'); + document.body.classList.remove('gd-menu-open'); + + // Resume headroom so it can pin/unpin normally again + if (showMenu._frozeHeadroom && typeof window.quartoToggleHeadroom === 'function') { + window.quartoToggleHeadroom(); // unfreeze + showMenu._frozeHeadroom = false; + } + + isMenuOpen = false; + menuSelectedIndex = -1; + // Remove after transition + setTimeout(function() { + if (menuOverlay && !isMenuOpen) { + menuOverlay.remove(); + menuOverlay = null; + } + }, 200); + } + + // ── Copy Page ──────────────────────────────────────────────────────── + + function copyPage() { + var btn = document.querySelector('.gd-copy-md-btn'); + if (btn) btn.click(); + } + + // ── Dark Mode Toggle ───────────────────────────────────────────────── + + function toggleDarkMode() { + // Delegate to the existing dark-mode-toggle button if present + var btn = document.getElementById('dark-mode-toggle'); + if (btn) { + btn.click(); + return; + } + } + + // ── Help Overlay ───────────────────────────────────────────────────── + + var SHORTCUT_GROUPS = [ + { + titleKey: 'kb_group_navigation', + titleFallback: 'Navigation', + shortcuts: [ + { keys: ['s', '/'], descKey: 'kb_focus_search', descFallback: 'Focus search' }, + { keys: ['[', ']'], descKey: 'kb_prev_next_page', descFallback: 'Previous / next page', separator: ' / ' }, + { keys: ['m', 'n'], descKey: 'kb_show_menu', descFallback: 'Show menu' }, + { keys: ['q'], descKey: 'kb_home', descFallback: 'Go to homepage' }, + { keys: ['u'], descKey: 'kb_user_guide', descFallback: 'User Guide', visible: hasUserGuide }, + { keys: ['r'], descKey: 'kb_api_reference', descFallback: 'API Reference', visible: hasReference }, + ] + }, + { + titleKey: 'kb_group_display', + titleFallback: 'Display', + shortcuts: [ + { keys: ['d'], descKey: 'kb_toggle_dark', descFallback: 'Toggle dark mode' }, + { keys: ['c'], descKey: 'kb_copy_page', descFallback: 'Copy page as Markdown' }, + ] + }, + { + titleKey: 'kb_group_general', + titleFallback: 'General', + shortcuts: [ + { keys: ['h', '?'], descKey: 'kb_show_help', descFallback: 'Show keyboard shortcuts' }, + { keys: ['Esc'], descKey: 'kb_close_dismiss', descFallback: 'Close / dismiss' }, + ] + }, + ]; + + function createOverlay() { + var el = document.createElement('div'); + el.className = 'gd-keyboard-overlay'; + el.setAttribute('role', 'dialog'); + el.setAttribute('aria-modal', 'true'); + el.setAttribute('aria-label', + _gdT('kb_overlay_title', 'Keyboard shortcuts')); + + var title = _gdT('kb_overlay_title', 'Keyboard shortcuts'); + + var html = '
    '; + html += '
    '; + html += '

    ' + escapeHtml(title) + '

    '; + html += ''; + html += '
    '; + + html += '
    '; + + for (var g = 0; g < SHORTCUT_GROUPS.length; g++) { + var group = SHORTCUT_GROUPS[g]; + html += '
    '; + html += '

    ' + escapeHtml(_gdT(group.titleKey, group.titleFallback)) + '

    '; + html += '
    '; + for (var s = 0; s < group.shortcuts.length; s++) { + var sc = group.shortcuts[s]; + if (sc.visible && !sc.visible()) continue; + html += '
    '; + html += '
    '; + for (var k = 0; k < sc.keys.length; k++) { + if (k > 0) { + var sep = sc.separator != null ? sc.separator : + ' ' + + escapeHtml(_gdT('kb_or', 'or')) + ' '; + html += sep; + } + html += '' + escapeHtml(sc.keys[k]) + ''; + } + html += '
    '; + html += '
    ' + escapeHtml(_gdT(sc.descKey, sc.descFallback)) + '
    '; + html += '
    '; + } + html += '
    '; + html += '
    '; + } + + html += '
    '; + + el.innerHTML = html; + return el; + } + + function escapeHtml(str) { + var div = document.createElement('div'); + div.appendChild(document.createTextNode(str)); + return div.innerHTML; + } + + function showOverlay() { + if (!overlay) { + overlay = createOverlay(); + document.body.appendChild(overlay); + + // Close button + var closeBtn = overlay.querySelector('.gd-keyboard-overlay-close'); + closeBtn.addEventListener('click', hideOverlay); + + // Click on backdrop + overlay.addEventListener('click', function(e) { + if (e.target === overlay) { + hideOverlay(); + } + }); + } + + if (prefersReducedMotion()) { + overlay.classList.add('gd-keyboard-overlay-visible'); + } else { + // Force reflow before adding the class for animation + void overlay.offsetWidth; + overlay.classList.add('gd-keyboard-overlay-visible'); + } + isOverlayOpen = true; + + // Focus the close button for keyboard users + var closeBtn = overlay.querySelector('.gd-keyboard-overlay-close'); + if (closeBtn) closeBtn.focus(); + } + + function hideOverlay() { + if (!overlay) return; + overlay.classList.remove('gd-keyboard-overlay-visible'); + isOverlayOpen = false; + } + + // ── Keyboard Event Handler ─────────────────────────────────────────── + + function handleKeydown(e) { + // When menu is open, handle all menu-related keys + if (isMenuOpen) { + if (e.key === 'Escape' || e.key === 'm' || e.key === 'n') { + e.preventDefault(); + hideMenu(); + return; + } + // Delegate arrow keys and Enter to menu navigation + handleMenuKeydown(e); + return; + } + + // When help overlay is open, handle Escape and toggle keys (h/?) + if (isOverlayOpen) { + if (e.key === 'Escape' || e.key === 'h' || e.key === '?') { + e.preventDefault(); + hideOverlay(); + } + return; + } + + // Skip if user is typing in an input + if (isTyping()) return; + + // Skip if modifier keys are held (allow browser/OS shortcuts) + if (e.ctrlKey || e.metaKey || e.altKey) return; + + switch (e.key) { + case '?': + case 'h': + e.preventDefault(); + showOverlay(); + break; + + case 's': + e.preventDefault(); + focusSearch(); + break; + + // Note: '/' is handled by sidebar-filter.js when it's active. + // When sidebar-filter is not present, we handle it here. + case '/': + // Only if sidebar-filter hasn't already handled it + if (!document.querySelector('.sidebar-filter-input')) { + e.preventDefault(); + focusSearch(); + } + break; + + case '[': + e.preventDefault(); + navigatePrev(); + break; + + case ']': + e.preventDefault(); + navigateNext(); + break; + + case 'm': + case 'n': + e.preventDefault(); + showMenu(); + break; + + case 'q': + e.preventDefault(); + navigateHome(); + break; + + case 'u': + if (hasUserGuide()) { + e.preventDefault(); + navigateUserGuide(); + } + break; + + case 'r': + if (hasReference()) { + e.preventDefault(); + navigateReference(); + } + break; + + case 'd': + e.preventDefault(); + toggleDarkMode(); + break; + + case 'c': + e.preventDefault(); + copyPage(); + break; + + case 'Escape': + // Blur the active element + if (document.activeElement && document.activeElement !== document.body) { + document.activeElement.blur(); + } + break; + } + } + + // ── Navbar Button ──────────────────────────────────────────────── + + /** + * Create the keyboard shortcuts navbar button. + * Uses the Lucide "keyboard" icon (MIT-licensed). + */ + function createKeyboardButton() { + var container = document.createElement('div'); + container.id = 'gd-keyboard-btn-container'; + + var btn = document.createElement('button'); + btn.id = 'gd-keyboard-btn'; + btn.className = 'gd-keyboard-btn'; + btn.type = 'button'; + btn.setAttribute('aria-label', + _gdT('kb_show_help', 'Show keyboard shortcuts')); + btn.setAttribute('data-tippy-content', + _gdT('kb_show_help', 'Show keyboard shortcuts')); + btn.innerHTML = + ''; + + container.appendChild(btn); + return container; + } + + /** + * Insert the keyboard button into the navbar. + */ + function insertKeyboardButton() { + // Insert into navbarCollapse; navbar-widgets.js will collect it + // into the unified #gd-navbar-widgets container. + var collapse = document.getElementById('navbarCollapse'); + if (!collapse) return; + + var container = createKeyboardButton(); + var navItem = document.createElement('li'); + navItem.className = 'nav-item'; + navItem.appendChild(container); + + // Append to navbarCollapse (the collector will move it) + collapse.appendChild(navItem); + + // Click handler + var btn = document.getElementById('gd-keyboard-btn'); + if (btn) { + btn.addEventListener('click', function() { + if (isOverlayOpen) { + hideOverlay(); + } else { + showOverlay(); + } + }); + + // Initialize tooltip directly — window.tippy is available from + // Quarto's bundle before any include-after-body scripts run. + if (window.tippy) { + window.tippy(btn, { + content: btn.getAttribute('data-tippy-content'), + placement: 'bottom', + animation: 'shift-away', + duration: [200, 150], + delay: [0, 0], + arrow: true, + }); + } + } + } + + // ── Initialization ─────────────────────────────────────────────────── + + function init() { + document.addEventListener('keydown', handleKeydown); + insertKeyboardButton(); + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } + + // Expose menu API so the sidebar toggle button can reuse it + window.__gdMenu = { + show: showMenu, + hide: hideMenu, + isOpen: function() { return isMenuOpen; } + }; +})(); diff --git a/docs/license.html b/docs/license.html new file mode 100644 index 0000000..5010daa --- /dev/null +++ b/docs/license.html @@ -0,0 +1,624 @@ + + + + + + + + + +License – switchlang | switchlang + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/llms-full.txt b/docs/llms-full.txt new file mode 100644 index 0000000..a99f748 --- /dev/null +++ b/docs/llms-full.txt @@ -0,0 +1,51 @@ +---------------------------------------------------------------------- +This is the API documentation for the switchlang library. +---------------------------------------------------------------------- + + +## The switch block + +The context manager that gives Python an explicit switch statement. Use it in a `with` block, register cases, then read `result`. + + + +switch(value: 'Any') -> 'None' + +An explicit switch statement for Python, implemented as a context manager. + +Use it in a `with` block: register cases with `case()` and `default()`, +then read the matched case's return value from `result`. + +See https://github.com/mikeckennedy/python-switch for full details. +Copyright Michael Kennedy (https://mkennedy.codes) +License: MIT + + +## Range helpers + +Helpers for mapping ranges of values to a single case. + + + +closed_range(start: 'int', stop: 'int', step: 'int' = 1) -> 'range' + +Create a closed range for a case: both `start` and `stop` are included. + +With the default step of 1, `closed_range(1, 5)` covers 1, 2, 3, 4, 5 — +unlike `range(1, 5)`, the upper bound is part of the range. With a larger +step the range never goes past `stop`: `closed_range(1, 6, 2)` covers +1, 3, 5, and `stop` itself is included when the step lands on it exactly, +as in `closed_range(1, 7, 2)` -> 1, 3, 5, 7. + +``` + with switch(value) as s: + s.case(closed_range(1, 5), lambda: "1-to-5") + s.case(closed_range(6, 7), lambda: "6-or-7") + s.default(lambda: 'default') +``` + +:param start: The inclusive lower bound of the range. +:param stop: The inclusive upper bound of the range. +:param step: The step size between elements; must be 1 or greater (defaults to 1). +:return: A range object with a closed (inclusive) upper bound. +:raises ValueError: If start is not less than stop, or step is less than 1. diff --git a/docs/llms.txt b/docs/llms.txt new file mode 100644 index 0000000..a8bc20d --- /dev/null +++ b/docs/llms.txt @@ -0,0 +1,19 @@ +# switchlang + +> Adds switch blocks to the Python language. + +## Docs + +### API Reference + +#### The switch block +> The context manager that gives Python an explicit switch statement. Use it in a `with` block, register cases, then read `result`. + + +- [switch](https://mkennedy.codes/docs/python-switch/reference/switch.html): An explicit switch statement for Python, implemented as a context manager + +#### Range helpers +> Helpers for mapping ranges of values to a single case. + + +- [closed_range](https://mkennedy.codes/docs/python-switch/reference/closed_range.html): Create a closed range for a case: both `start` and `stop` are included diff --git a/docs/mermaid-renderer.js b/docs/mermaid-renderer.js new file mode 100644 index 0000000..7a23f45 --- /dev/null +++ b/docs/mermaid-renderer.js @@ -0,0 +1,205 @@ +/** + * Great Docs Mermaid Theme Fix + * + * Forces mermaid diagrams to use light theme colors in dark mode + * by modifying the SVG's internal style block after Quarto renders. + */ + +(function() { + 'use strict'; + + function isDarkMode() { + return document.documentElement.classList.contains('quarto-dark') || + document.body.classList.contains('quarto-dark'); + } + + /** + * Light mode CSS rules to inject into SVG style blocks when in dark mode. + * These override the dark theme colors mermaid generates. + * Must be comprehensive to catch all text elements. + */ + function getLightModeOverrides(id) { + return '\n' + + /* Universal text color overrides - catch everything */ + '#' + id + ' text { fill: #333 !important; }\n' + + '#' + id + ' tspan { fill: #333 !important; }\n' + + '#' + id + ' .label { fill: #333 !important; color: #333 !important; }\n' + + '#' + id + ' .label text { fill: #333 !important; }\n' + + '#' + id + ' .label tspan { fill: #333 !important; }\n' + + '#' + id + ' span { color: #333 !important; }\n' + + '#' + id + ' p { color: #333 !important; }\n' + + '#' + id + ' div { color: #333 !important; }\n' + + '#' + id + ' foreignObject { color: #333 !important; }\n' + + '#' + id + ' foreignObject * { color: #333 !important; }\n' + + /* Node-specific text */ + '#' + id + ' .nodeLabel { color: #333 !important; fill: #333 !important; }\n' + + '#' + id + ' .nodeLabel p { color: #333 !important; }\n' + + '#' + id + ' .nodeLabel span { color: #333 !important; }\n' + + '#' + id + ' .node text { fill: #333 !important; }\n' + + '#' + id + ' .node tspan { fill: #333 !important; }\n' + + '#' + id + ' .node foreignObject div { color: #333 !important; }\n' + + /* Node shapes */ + '#' + id + ' .node rect, #' + id + ' .node circle, #' + id + ' .node ellipse, #' + id + ' .node polygon, #' + id + ' .node path { fill: #ECECFF !important; stroke: #9370DB !important; }\n' + + /* Edge labels */ + '#' + id + ' .edgeLabel { background-color: #e8e8e8 !important; color: #333 !important; }\n' + + '#' + id + ' .edgeLabel rect { fill: #e8e8e8 !important; }\n' + + '#' + id + ' .edgeLabel p { background-color: transparent !important; color: #333 !important; }\n' + + '#' + id + ' .edgeLabel span { color: #333 !important; }\n' + + '#' + id + ' .edgeLabel text { fill: #333 !important; }\n' + + '#' + id + ' .edgeLabel tspan { fill: #333 !important; }\n' + + '#' + id + ' .labelBkg { fill: #e8e8e8 !important; }\n' + + /* Edges and arrows */ + '#' + id + ' .edgePath .path, #' + id + ' .flowchart-link { stroke: #333 !important; }\n' + + '#' + id + ' .marker { fill: #333 !important; stroke: #333 !important; }\n' + + '#' + id + ' .arrowheadPath { fill: #333 !important; }\n' + + /* Clusters */ + '#' + id + ' .cluster rect { fill: #ffffde !important; stroke: #aaaa33 !important; }\n' + + '#' + id + ' .cluster text { fill: #333 !important; }\n' + + '#' + id + ' .cluster tspan { fill: #333 !important; }\n' + + '#' + id + ' .cluster span { color: #333 !important; }\n' + + '#' + id + ' .cluster-label text { fill: #333 !important; }\n' + + '#' + id + ' .cluster-label span { color: #333 !important; }\n' + + /* Sequence diagrams */ + '#' + id + ' .actor { fill: #ECECFF !important; stroke: #9370DB !important; }\n' + + '#' + id + ' .actor text { fill: #333 !important; }\n' + + '#' + id + ' .actor tspan { fill: #333 !important; }\n' + + '#' + id + ' text.actor { fill: #333 !important; }\n' + + '#' + id + ' text.actor > tspan { fill: #333 !important; }\n' + + '#' + id + ' .messageText { fill: #333 !important; stroke: none !important; }\n' + + '#' + id + ' .loopText { fill: #333 !important; }\n' + + '#' + id + ' .loopText tspan { fill: #333 !important; }\n' + + '#' + id + ' .noteText { fill: #333 !important; }\n' + + '#' + id + ' .noteText tspan { fill: #333 !important; }\n' + + '#' + id + ' .labelText { fill: #333 !important; color: #333 !important; }\n' + + '#' + id + ' .labelText tspan { fill: #333 !important; }\n' + + '#' + id + ' .sequenceNumber { fill: #fff !important; }\n' + + '#' + id + ' line { stroke: #999 !important; }\n' + + '#' + id + ' .messageLine0, #' + id + ' .messageLine1 { stroke: #333 !important; }\n' + + '#' + id + ' .labelBox { fill: #ECECFF !important; stroke: #9370DB !important; }\n' + + '#' + id + ' .loopLine { stroke: #9370DB !important; fill: #ECECFF !important; }\n' + + /* State diagrams */ + '#' + id + ' g.stateGroup rect { fill: #ECECFF !important; stroke: #9370DB !important; }\n' + + '#' + id + ' g.stateGroup text { fill: #333 !important; }\n' + + '#' + id + ' g.stateGroup .state-title { fill: #333 !important; }\n' + + '#' + id + ' .statediagram-state text { fill: #333 !important; }\n' + + '#' + id + ' .transition { stroke: #333 !important; }\n' + + /* Gantt */ + '#' + id + ' .section0, #' + id + ' .section2 { fill: #ECECFF !important; }\n' + + '#' + id + ' .section1, #' + id + ' .section3 { fill: #f8f8f8 !important; }\n' + + '#' + id + ' .taskText { fill: #333 !important; }\n' + + '#' + id + ' .taskTextOutsideLeft, #' + id + ' .taskTextOutsideRight { fill: #333 !important; }\n' + + '#' + id + ' .sectionTitle { fill: #333 !important; }\n' + + '#' + id + ' .grid .tick line { stroke: #ccc !important; }\n' + + '#' + id + ' .grid .tick text { fill: #333 !important; }\n' + + '#' + id + ' .titleText { fill: #333 !important; }\n' + + /* Pie */ + '#' + id + ' .pieCircle { stroke: #fff !important; }\n' + + '#' + id + ' .pieTitleText { fill: #333 !important; }\n' + + '#' + id + ' .pieOuterCircle { stroke: #333 !important; }\n' + + '#' + id + ' .slice { stroke: #fff !important; }\n' + + '#' + id + ' .legend text { fill: #333 !important; }\n' + + /* Class diagrams */ + '#' + id + ' .classGroup rect { fill: #ECECFF !important; stroke: #9370DB !important; }\n' + + '#' + id + ' .classGroup text { fill: #333 !important; }\n' + + '#' + id + ' .classGroup tspan { fill: #333 !important; }\n' + + '#' + id + ' .classGroup line, #' + id + ' .divider { stroke: #9370DB !important; }\n' + + '#' + id + ' .relation { stroke: #333 !important; }\n' + + '#' + id + ' .cardinality { fill: #333 !important; }\n' + + '#' + id + ' .classLabel text { fill: #333 !important; }\n' + + '#' + id + ' .classLabel tspan { fill: #333 !important; }\n' + + /* Flowchart title */ + '#' + id + ' .flowchartTitleText { fill: #333 !important; }\n'; + } + + /** + * Fix a single SVG by injecting light mode overrides and fixing inline styles + */ + function fixSvg(svg) { + if (!svg.id) return; + if (svg.dataset.gdFixed === 'true') return; + + var styleEl = svg.querySelector('style'); + if (!styleEl) return; + + // Inject CSS overrides + styleEl.textContent += getLightModeOverrides(svg.id); + + // Also directly fix inline styles on p, span, div elements + // This handles cases where mermaid sets inline style="color: ..." + var textElements = svg.querySelectorAll('p, span, div, .nodeLabel, .edgeLabel'); + textElements.forEach(function(el) { + el.style.setProperty('color', '#333', 'important'); + }); + + // Fix foreignObject children + var foreignObjects = svg.querySelectorAll('foreignObject *'); + foreignObjects.forEach(function(el) { + if (el.style) { + el.style.setProperty('color', '#333', 'important'); + } + }); + + svg.dataset.gdFixed = 'true'; + } + + /** + * Process all mermaid SVGs + */ + function processAllSvgs() { + var svgs = document.querySelectorAll('svg.mermaid-js, svg[id^="mermaid-"]'); + + if (isDarkMode()) { + svgs.forEach(fixSvg); + } + } + + /** + * Set up observer for theme changes and new SVGs + */ + function setupObserver() { + var observer = new MutationObserver(function(mutations) { + var shouldProcess = false; + + for (var i = 0; i < mutations.length; i++) { + var mutation = mutations[i]; + if (mutation.type === 'attributes' && mutation.attributeName === 'class') { + shouldProcess = true; + break; + } + if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { + shouldProcess = true; + break; + } + } + + if (shouldProcess) { + setTimeout(processAllSvgs, 100); + } + }); + + observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] }); + observer.observe(document.body, { + attributes: true, + attributeFilter: ['class'], + childList: true, + subtree: true + }); + } + + function init() { + setupObserver(); + + function afterLoad() { + setTimeout(processAllSvgs, 300); + setTimeout(processAllSvgs, 1000); + } + + if (document.readyState === 'complete') { + afterLoad(); + } else { + window.addEventListener('load', afterLoad); + } + } + + init(); +})(); diff --git a/docs/navbar-widgets.js b/docs/navbar-widgets.js new file mode 100644 index 0000000..977aa0f --- /dev/null +++ b/docs/navbar-widgets.js @@ -0,0 +1,255 @@ +/** + * Navbar Widget Collector for Great Docs + * + * Consolidates all right-side navbar widgets (dark-mode toggle, keyboard + * shortcuts button, GitHub icon/widget, and search) into a single flex + * container (#gd-navbar-widgets) placed inside .quarto-navbar-tools. + * + * This guarantees uniform spacing (via CSS gap) and a predictable order + * regardless of which widgets are enabled or the order scripts execute. + * + * Must be loaded AFTER the individual widget scripts (dark-mode-toggle.js, + * keyboard-nav.js, github-widget.js) and is included unconditionally. + */ +(function () { + 'use strict'; + + function ensureWrapper(containerFluid) { + var wrapper = document.getElementById('gd-navbar-widgets'); + if (wrapper) return wrapper; + + wrapper = document.createElement('div'); + wrapper.id = 'gd-navbar-widgets'; + + var tools = containerFluid.querySelector('.quarto-navbar-tools'); + if (tools) { + tools.appendChild(wrapper); + } else { + containerFluid.appendChild(wrapper); + } + + return wrapper; + } + + function moveToWrapper(wrapper, el) { + if (!el || wrapper.contains(el)) return; + wrapper.appendChild(el); + } + + function collect() { + var containerFluid = document.querySelector('.navbar .container-fluid'); + if (!containerFluid) return; + + var wrapper = ensureWrapper(containerFluid); + + // 1. Dark-mode toggle (unwrap from its
  • ) + var toggleContainer = document.getElementById('dark-mode-toggle-container'); + if (toggleContainer) { + var li = toggleContainer.closest('li.nav-item'); + moveToWrapper(wrapper, toggleContainer); + if (li && !li.hasChildNodes()) li.remove(); + } + + // 2. Keyboard shortcuts button (unwrap from its
  • ) + var kbContainer = document.getElementById('gd-keyboard-btn-container'); + if (kbContainer) { + var kbLi = kbContainer.closest('li.nav-item'); + moveToWrapper(wrapper, kbContainer); + if (kbLi && !kbLi.hasChildNodes()) kbLi.remove(); + } + + // 3. GitHub icon — compact nav-item (unwrap the from its
  • ) + var compactItem = containerFluid.querySelector( + '#navbarCollapse .nav-item.compact' + ); + if (compactItem) { + var link = compactItem.querySelector('.nav-link'); + if (link) { + link.classList.add('gd-navbar-icon'); + moveToWrapper(wrapper, link); + compactItem.remove(); + } + } + + // 4. GitHub widget — #github-widget (unwrap from its
  • ) + var ghWidget = document.getElementById('github-widget'); + if (ghWidget) { + var ghLi = ghWidget.closest('li.nav-item'); + moveToWrapper(wrapper, ghWidget); + if (ghLi && !ghLi.hasChildNodes()) ghLi.remove(); + } + + // 4b. Version selector — #gd-version-selector + var vsWidget = document.getElementById('gd-version-selector'); + if (vsWidget) { + moveToWrapper(wrapper, vsWidget); + } + + // 5. Search button + var search = document.getElementById('quarto-search'); + if (search) moveToWrapper(wrapper, search); + + // Clean up the now-empty ul.ms-auto + var msAuto = containerFluid.querySelector( + '#navbarCollapse .navbar-nav.ms-auto' + ); + if (msAuto) { + Array.prototype.forEach.call( + msAuto.querySelectorAll('li.nav-item'), + function (li) { + if ( + !li.textContent.trim() && + !li.querySelector('button, input, img, svg') + ) { + li.remove(); + } + } + ); + if (msAuto.children.length === 0) msAuto.remove(); + } + } + + function init() { + collect(); + + // Re-collect when widgets are injected after DOMContentLoaded + var scheduled = false; + function scheduleCollect() { + if (scheduled) return; + scheduled = true; + requestAnimationFrame(function () { + scheduled = false; + collect(); + }); + } + + var navbarCollapse = document.getElementById('navbarCollapse'); + if (navbarCollapse) { + var observer = new MutationObserver(scheduleCollect); + observer.observe(navbarCollapse, { childList: true, subtree: true }); + } + + // Also watch container-fluid for widgets appended outside navbarCollapse + // (e.g. version selector) + var containerFluid = document.querySelector('.navbar .container-fluid'); + if (containerFluid) { + var cfObserver = new MutationObserver(scheduleCollect); + cfObserver.observe(containerFluid, { childList: true }); + } + + window.addEventListener('load', scheduleCollect, { once: true }); + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } +})(); + +/** + * Mobile sidebar toggle → menu overlay redirect. + * + * On mobile (< 992px) the sidebar toggle button in the Title Bar + * (.quarto-btn-toggle) opens the polished menu overlay (same as the + * 'm'/'n' keyboard shortcut) instead of Bootstrap's collapse sidebar. + * This gives a smooth fade-in/slide, rounded card, backdrop blur, and + * auto-scroll to the current page — matching the desktop overlay UX. + */ +(function () { + "use strict"; + + var mql = window.matchMedia("(max-width: 991.98px)"); + + function intercept(e) { + if (!mql.matches) return; // desktop — let Bootstrap handle it + if (!window.__gdMenu) return; // keyboard-nav.js not loaded yet + + // Stop Bootstrap collapse and Quarto headroom toggle + e.preventDefault(); + e.stopPropagation(); + + if (window.__gdMenu.isOpen()) { + window.__gdMenu.hide(); + } else { + window.__gdMenu.show(); + } + } + + function attach() { + // The secondary-nav has two clickable elements: the + +
    +
    +
  • + + + +
    + + + + +
    + +
    +
    +

    Package Info

    +
    + + + +
    + + + + +
    + + + +
    + + +
    +

    Optional Dependencies

    +
    +

    dev

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PackageVersion ConstraintEnvironment MarkerLast PublishedPyPI
    pytest2026-06-19
    great-docspython_version >= "3.11"2026-07-10
    +
    +
    +
    +

    Summary

    +
      +
    • Requires: Python >=3.9
    • +
    • Runtime Dependencies: 0
    • +
    • Optional Dependencies: 1 groups (2 unique packages)
    • +
    • Total unique dependencies: 2
    • +
    + + +
    + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/package-info.md b/docs/package-info.md new file mode 100644 index 0000000..038a4e7 --- /dev/null +++ b/docs/package-info.md @@ -0,0 +1,20 @@ +# Package Info + + +# Optional Dependencies + + +## `dev` + +| Package | Version Constraint | Environment Marker | Last Published | PyPI | +|----|----|----|----|----| +| `pytest` | -- | | 2026-06-19 | | +| `great-docs` | -- | `python_version >= "3.11"` | 2026-07-10 | | + + +# Summary + +- **Requires:** Python `>=3.9` +- **Runtime Dependencies:** 0 +- **Optional Dependencies:** 1 groups (2 unique packages) +- **Total unique dependencies:** 2 diff --git a/docs/reference/closed_range.html b/docs/reference/closed_range.html new file mode 100644 index 0000000..6c210d8 --- /dev/null +++ b/docs/reference/closed_range.html @@ -0,0 +1,724 @@ + + + + + + + + + +closed_range() – switchlang | switchlang + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + +
    + +
    + + +
    + + + +
    + +
    +
    +

    closed_range()

    +
    + + + +
    + + + + +
    + + + +
    + + +
    +

    Create a closed range for a case: both start and stop are included.

    +
    +
    +

    Usage

    +

    Source

    +
    +
    +
    closed_range(
    +    start,
    +    stop,
    +    step=1,
    +)
    +
    +
    +

    With the default step of 1, closed_range(1, 5) covers 1, 2, 3, 4, 5 — unlike range(1, 5), the upper bound is part of the range. With a larger step the range never goes past stop: closed_range(1, 6, 2) covers 1, 3, 5, and stop itself is included when the step lands on it exactly, as in closed_range(1, 7, 2) -> 1, 3, 5, 7.

    +
        with switch(value) as s:
    +        s.case(closed_range(1, 5), lambda: "1-to-5")
    +        s.case(closed_range(6, 7), lambda: "6-or-7")
    +        s.default(lambda: 'default')
    +
    +
    +

    Parameters

    +
    +
    +
    start: int
    +
    +

    The inclusive lower bound of the range.

    +
    +
    stop: int
    +
    +

    The inclusive upper bound of the range.

    +
    +
    step: int = 1
    +
    +The step size between elements; must be 1 or greater (defaults to 1). +
    +
    +
    +
    +
    +

    Returns

    +
    +
    +
    range
    +
    +A range object with a closed (inclusive) upper bound. +
    +
    +
    +
    +
    +

    Raises

    +
    +
    +
    ValueError
    +
    +If start is not less than stop, or step is less than 1. +
    +
    +
    + + +
    + +
    +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/reference/closed_range.md b/docs/reference/closed_range.md new file mode 100644 index 0000000..8c25753 --- /dev/null +++ b/docs/reference/closed_range.md @@ -0,0 +1,50 @@ +## closed_range() + + +Create a closed range for a case: both `start` and `stop` are included. + + +Usage + +``` python +closed_range( + start, + stop, + step=1, +) +``` + + +With the default step of 1, `closed_range(1, 5)` covers 1, 2, 3, 4, 5 -- unlike `range(1, 5)`, the upper bound is part of the range. With a larger step the range never goes past `stop`: `closed_range(1, 6, 2)` covers 1, 3, 5, and `stop` itself is included when the step lands on it exactly, as in `closed_range(1, 7, 2)` -\> 1, 3, 5, 7. + + with switch(value) as s: + s.case(closed_range(1, 5), lambda: "1-to-5") + s.case(closed_range(6, 7), lambda: "6-or-7") + s.default(lambda: 'default') + + +## Parameters + + +`start: int` +The inclusive lower bound of the range. + +`stop: int` +The inclusive upper bound of the range. + +`step: int = ``1` +The step size between elements; must be 1 or greater (defaults to 1). + + +## Returns + + +`range` +A range object with a closed (inclusive) upper bound. + + +## Raises + + +`ValueError` +If start is not less than stop, or step is less than 1. diff --git a/docs/reference/index.html b/docs/reference/index.html new file mode 100644 index 0000000..1e7634e --- /dev/null +++ b/docs/reference/index.html @@ -0,0 +1,635 @@ + + + + + + + + + +API Reference – switchlang | switchlang + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + +
    + +
    + + +
    + + + +
    + +
    +
    +

    API Reference

    +
    + + + +
    + + + + +
    + + + +
    + + +
    +

    The switch block

    +
    +

    The context manager that gives Python an explicit switch statement. Use it in a with block, register cases, then read result.

    +
    +
    +
    switch
    +
    +

    An explicit switch statement for Python, implemented as a context manager.

    +
    +
    +
    +
    +

    Range helpers

    +
    +

    Helpers for mapping ranges of values to a single case.

    +
    +
    +
    closed_range()
    +
    +

    Create a closed range for a case: both start and stop are included.

    +
    +
    + + +
    + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/reference/index.md b/docs/reference/index.md new file mode 100644 index 0000000..afac58c --- /dev/null +++ b/docs/reference/index.md @@ -0,0 +1,21 @@ +# API Reference + + +## The switch block + + +The context manager that gives Python an explicit switch statement. Use it in a `with` block, register cases, then read `result`. + + +[switch](switch.md#switchlang.switch) +An explicit switch statement for Python, implemented as a context manager. + + +## Range helpers + + +Helpers for mapping ranges of values to a single case. + + +[closed_range()](closed_range.md#switchlang.closed_range) +Create a closed range for a case: both `start` and `stop` are included. diff --git a/docs/reference/switch.html b/docs/reference/switch.html new file mode 100644 index 0000000..1379716 --- /dev/null +++ b/docs/reference/switch.html @@ -0,0 +1,976 @@ + + + + + + + + + +switch – switchlang | switchlang + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + +
    + +
    + + +
    + + + +
    + +
    +
    +

    switch

    +
    + + + +
    + + + + +
    + + + +
    + + +
    +

    An explicit switch statement for Python, implemented as a context manager.

    +
    +
    +

    Usage

    +

    Source

    +
    +
    +
    switch(value)
    +
    +
    +

    Use it in a with block: register cases with case() and default(), then read the matched case’s return value from result.

    +

    See https://github.com/mikeckennedy/python-switch for full details. Copyright Michael Kennedy (https://mkennedy.codes) License: MIT

    +
    +
    +

    Attributes

    + + + + + + + + + + + + + +
    +Name + +Description +
    +result + +The value returned by the function of the matched case. +
    +
    +
    +

    result

    +
    +

    The value returned by the function of the matched case.

    +
    +
    +

    result: Any

    +
    +
    +

    When cases fall through, result is the return value of the last function executed.

    +
        value = 4
    +    with switch(value) as s:
    +        s.case(closed_range(1, 5), lambda: "1-to-5")
    +        # ...
    +
    +    res = s.result  # res == '1-to-5'
    +
    +
    +
    Raises
    +
    +
    +
    Exception
    +
    +If accessed before the switch block has exited and computed a result. +
    +
    +
    +
    +
    +
    +
    +

    Methods

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +Name + +Description +
    +__enter__() + +Enter the switch block. +
    +__exit__() + +Run the matched case (and any fall-through cases) as the block exits. +
    +__init__() + +Create a new switch block that tests cases against value. +
    +case() + +Register a case for the switch block: +
    +default() + +Register the default case: the action to run when no other case matches. +
    +
    +
    +

    __enter__()

    +
    +

    Enter the switch block.

    +
    +
    +

    Usage

    +

    Source

    +
    +
    +
    __enter__()
    +
    +
    +
    Returns
    +
    +
    +
    switch
    +
    +The switch instance itself (bind it with as s to register cases). +
    +
    +
    +
    +
    +
    +
    +

    __exit__()

    +
    +

    Run the matched case (and any fall-through cases) as the block exits.

    +
    +
    +

    Usage

    +

    Source

    +
    +
    +
    __exit__(exc_type, exc_val, exc_tb)
    +
    +
    +
    Raises
    +
    +
    +
    Exception
    +
    +If no case matched the value and no default case was registered. +
    +
    +
    +
    +
    +
    +
    +

    __init__()

    +
    +

    Create a new switch block that tests cases against value.

    +
    +
    +

    Usage

    +

    Source

    +
    +
    +
    __init__(value)
    +
    +
    +
    Parameters
    +
    +
    +
    value: Any
    +
    +The value each case key is compared against. +
    +
    +
    +
    +
    +
    +
    +

    case()

    +
    +

    Register a case for the switch block:

    +
    +
    +

    Usage

    +

    Source

    +
    +
    +
    case(key, func, fallthrough=False)
    +
    +
    +
        with switch(val) as s:
    +       s.case('a', function)
    +       s.case('b', function, fallthrough=True)
    +       s.default(function)
    +
    +
    +
    Parameters
    +
    +
    +
    key: Any
    +
    +

    Key for the case test. If this is a list or range, each item is added as a case for func.

    +
    +
    func: Callable[[], Any]
    +
    +

    Any callable taking no parameters, executed if this case matches.

    +
    +
    fallthrough: bool | None = False
    +
    +Optionally fall through to the subsequent case (defaults to False). None is reserved for internal use and leaves the fall-through state unchanged. +
    +
    +
    +
    +
    +
    Returns
    +
    +
    +
    bool
    +
    +True if this case (or any item of a list or range key) matched the switch value, otherwise False. +
    +
    +
    +
    +
    +
    Raises
    +
    +
    +
    ValueError
    +
    +If the key is a duplicate, the key is an empty collection, or func is not callable. +
    +
    +
    +
    +
    +
    +
    +

    default()

    +
    +

    Register the default case: the action to run when no other case matches.

    +
    +
    +

    Usage

    +

    Source

    +
    +
    +
    default(func)
    +
    +
    +

    Use it as the optional final statement in the switch block. Note that the ordering is not enforced: if default() is registered before a case that also matches, both will run. Always register it last.

    +
        with switch(val) as s:
    +       s.case(...)
    +       s.case(...)
    +       s.default(function)
    +
    +
    +
    Parameters
    +
    +
    +
    func: Callable[[], Any]
    +
    +Any callable taking no parameters, executed if no other case matched. +
    +
    +
    +
    +
    +
    Returns
    +
    +
    +
    None
    +
    +None +
    +
    +
    + + +
    +
    +
    + +
    +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/reference/switch.md b/docs/reference/switch.md new file mode 100644 index 0000000..e9e51fe --- /dev/null +++ b/docs/reference/switch.md @@ -0,0 +1,217 @@ +## switch + + +An explicit switch statement for Python, implemented as a context manager. + + +Usage + +``` python +switch(value) +``` + + +Use it in a `with` block: register cases with [case()](switch.md#switchlang.switch.case) and [default()](switch.md#switchlang.switch.default), then read the matched case's return value from [result](switch.md#switchlang.switch.result). + +See https://github.com/mikeckennedy/python-switch for full details. Copyright Michael Kennedy (https://mkennedy.codes) License: MIT + + +## Attributes + +| Name | Description | +|----|----| +| [result](#result) | The value returned by the function of the matched case. | + +------------------------------------------------------------------------ + + +#### result + + +The value returned by the function of the matched case. + + +`result: Any` + + +When cases fall through, [result](switch.md#switchlang.switch.result) is the return value of the last function executed. + + value = 4 + with switch(value) as s: + s.case(closed_range(1, 5), lambda: "1-to-5") + # ... + + res = s.result # res == '1-to-5' + + +##### Raises + + +`Exception` +If accessed before the switch block has exited and computed a result. + + +## Methods + +| Name | Description | +|----|----| +| [__enter__()](#__enter__) | Enter the switch block. | +| [__exit__()](#__exit__) | Run the matched case (and any fall-through cases) as the block exits. | +| [__init__()](#__init__) | Create a new switch block that tests cases against `value`. | +| [case()](#case) | Register a case for the switch block: | +| [default()](#default) | Register the default case: the action to run when no other case matches. | + +------------------------------------------------------------------------ + + +#### \_\_enter\_\_() + + +Enter the switch block. + + +Usage + +``` python +__enter__() +``` + + +##### Returns + + +`switch` +The switch instance itself (bind it with `as s` to register cases). + + +------------------------------------------------------------------------ + + +#### \_\_exit\_\_() + + +Run the matched case (and any fall-through cases) as the block exits. + + +Usage + +``` python +__exit__(exc_type, exc_val, exc_tb) +``` + + +##### Raises + + +`Exception` +If no case matched the value and no default case was registered. + + +------------------------------------------------------------------------ + + +#### \_\_init\_\_() + + +Create a new switch block that tests cases against `value`. + + +Usage + +``` python +__init__(value) +``` + + +##### Parameters + + +`value: Any` +The value each case key is compared against. + + +------------------------------------------------------------------------ + + +#### case() + + +Register a case for the switch block: + + +Usage + +``` python +case(key, func, fallthrough=False) +``` + + + with switch(val) as s: + s.case('a', function) + s.case('b', function, fallthrough=True) + s.default(function) + + +##### Parameters + + +`key: Any` +Key for the case test. If this is a list or range, each item is added as a case for `func`. + +`func: Callable[[], Any]` +Any callable taking no parameters, executed if this case matches. + +`fallthrough: bool | None = ``False` +Optionally fall through to the subsequent case (defaults to False). `None` is reserved for internal use and leaves the fall-through state unchanged. + + +##### Returns + + +`bool` +True if this case (or any item of a list or range key) matched the switch value, otherwise False. + + +##### Raises + + +`ValueError` +If the key is a duplicate, the key is an empty collection, or func is not callable. + + +------------------------------------------------------------------------ + + +#### default() + + +Register the default case: the action to run when no other case matches. + + +Usage + +``` python +default(func) +``` + + +Use it as the optional final statement in the switch block. Note that the ordering is not enforced: if [default()](switch.md#switchlang.switch.default) is registered before a case that also matches, both will run. Always register it last. + + with switch(val) as s: + s.case(...) + s.case(...) + s.default(function) + + +##### Parameters + + +`func: Callable[[], Any]` +Any callable taking no parameters, executed if no other case matched. + + +##### Returns + + +`None` +None diff --git a/docs/responsive-tables.js b/docs/responsive-tables.js new file mode 100644 index 0000000..e7743a7 --- /dev/null +++ b/docs/responsive-tables.js @@ -0,0 +1,346 @@ +/** + * Responsive Tables for Great Docs + * + * Enhances table display on narrow viewports with: + * - Horizontal scroll containers for wide tables + * - Touch-friendly scroll indicators + * - Consistent dark mode styling + * + * Uses double-wrapper structure for Safari compatibility: + * - Outer wrapper (.gd-table-responsive) has position:relative for indicators + * - Inner wrapper (.gd-table-scroll) has overflow-x:auto for scrolling + */ +(function () { + "use strict"; + + // Minimum width difference to consider a table "wide" + var OVERFLOW_THRESHOLD = 20; + + /** + * Wrap a table in a responsive scroll container + */ + function wrapTable(table) { + // Skip if already wrapped + if (table.closest(".gd-table-responsive")) { + return; + } + + // Skip tables inside code blocks or other special contexts + if (table.closest("pre, code, .sourceCode")) { + return; + } + + // Skip Great Tables output — these have their own styling and layout + if (table.classList.contains("gt_table")) { + return; + } + + // Create outer wrapper (for indicator positioning) + var outerWrapper = document.createElement("div"); + outerWrapper.className = "gd-table-responsive"; + + // Create inner scroll container + var scrollContainer = document.createElement("div"); + scrollContainer.className = "gd-table-scroll"; + scrollContainer.setAttribute("tabindex", "0"); + scrollContainer.setAttribute("role", "region"); + scrollContainer.setAttribute("aria-label", "Scrollable table"); + + // Insert outer wrapper and move table inside inner container + table.parentNode.insertBefore(outerWrapper, table); + scrollContainer.appendChild(table); + outerWrapper.appendChild(scrollContainer); + + // Add scroll indicators to outer wrapper (not inside scroll container) + var indicatorLeft = document.createElement("div"); + indicatorLeft.className = "gd-table-scroll-indicator gd-table-scroll-left"; + indicatorLeft.innerHTML = ''; + outerWrapper.appendChild(indicatorLeft); + + var indicatorRight = document.createElement("div"); + indicatorRight.className = "gd-table-scroll-indicator gd-table-scroll-right"; + indicatorRight.innerHTML = ''; + outerWrapper.appendChild(indicatorRight); + + // Update scroll indicator visibility based on scroll position + function updateScrollIndicators() { + var scrollLeft = scrollContainer.scrollLeft; + var maxScroll = scrollContainer.scrollWidth - scrollContainer.clientWidth; + + // Only show indicators if scrollable + if (maxScroll <= OVERFLOW_THRESHOLD) { + indicatorLeft.classList.remove("visible"); + indicatorRight.classList.remove("visible"); + return; + } + + // Show/hide based on scroll position + indicatorLeft.classList.toggle("visible", scrollLeft > OVERFLOW_THRESHOLD); + indicatorRight.classList.toggle("visible", scrollLeft < maxScroll - OVERFLOW_THRESHOLD); + } + + // Debounced scroll handler + var scrollTimeout; + scrollContainer.addEventListener("scroll", function () { + if (scrollTimeout) { + clearTimeout(scrollTimeout); + } + scrollTimeout = setTimeout(updateScrollIndicators, 50); + }); + + // Click to scroll + indicatorLeft.addEventListener("click", function () { + scrollContainer.scrollBy({ left: -150, behavior: "smooth" }); + }); + + indicatorRight.addEventListener("click", function () { + scrollContainer.scrollBy({ left: 150, behavior: "smooth" }); + }); + + // Initial indicator update + setTimeout(updateScrollIndicators, 100); + + // Update on resize + var resizeObserver; + if (typeof ResizeObserver !== "undefined") { + resizeObserver = new ResizeObserver(function () { + updateScrollIndicators(); + }); + resizeObserver.observe(scrollContainer); + } + + return outerWrapper; + } + + /** + * Scale content inside a .scale-to-fit container to fill the container width. + * + * Usage in .qmd: + * :::{.scale-to-fit} + * ```{python} + * my_wide_table() + * ``` + * ::: + */ + // Viewport breakpoints for keyword-based min-scale thresholds. + // Below the given width, scaling is disabled and horizontal scrolling is + // used instead. + var SCALE_BREAKPOINTS = { mobile: 576, tablet: 768, desktop: 992 }; + + /** + * Parse a data-min-scale attribute value. + * Returns an object: { type: "number", value: 0.4 } + * or { type: "keyword", width: 768 } + * or null (no threshold). + */ + function parseMinScale(raw) { + if (!raw) return null; + var lower = raw.toLowerCase(); + if (SCALE_BREAKPOINTS[lower] !== undefined) { + return { type: "keyword", width: SCALE_BREAKPOINTS[lower] }; + } + var n = parseFloat(raw); + if (!isNaN(n) && n > 0 && n < 1) { + return { type: "number", value: n }; + } + return null; + } + + function applyScaleToFit(container, minScaleObj) { + // minScaleObj: parsed result from parseMinScale(), or null. + // Per-container data-min-scale overrides the page/global threshold. + var containerMinScale = parseMinScale(container.getAttribute("data-min-scale")); + if (containerMinScale) { + minScaleObj = containerMinScale; + } + // Find the content to scale — first child element that has measurable width + var inner = container.querySelector(".cell-output-display, .cell-output, table, .gt_table"); + if (!inner) { + // Fall back to first element child + inner = container.firstElementChild; + } + if (!inner) return; + + // Wrap content in a scaling div if not already wrapped + var scaleWrapper = container.querySelector(".gd-scale-wrapper"); + if (!scaleWrapper) { + scaleWrapper = document.createElement("div"); + scaleWrapper.className = "gd-scale-wrapper"; + // Move all children into the wrapper + while (container.firstChild) { + scaleWrapper.appendChild(container.firstChild); + } + container.appendChild(scaleWrapper); + } + + function updateScale() { + // Reset transform to measure natural width + scaleWrapper.style.transform = "none"; + scaleWrapper.style.transformOrigin = "top left"; + scaleWrapper.style.width = "max-content"; + scaleWrapper.style.height = ""; + container.style.height = ""; + + // Allow layout to settle + var containerWidth = container.clientWidth; + var contentWidth = scaleWrapper.scrollWidth; + + if (contentWidth <= 0 || containerWidth <= 0) return; + + var scale = containerWidth / contentWidth; + + // Never upscale — only shrink to fit + if (scale >= 1) { + scaleWrapper.style.transform = "none"; + scaleWrapper.style.width = ""; + scaleWrapper.style.height = ""; + container.style.height = ""; + container.style.overflow = ""; + container.classList.remove("gd-scale-scrollable"); + return; + } + + // Check whether we should skip scaling and scroll instead. + // Keyword thresholds: if viewport is at or below the breakpoint, scroll. + // Numeric thresholds: if computed scale < min, scroll. + var shouldScroll = false; + if (minScaleObj) { + if (minScaleObj.type === "keyword") { + shouldScroll = window.innerWidth <= minScaleObj.width; + } else if (minScaleObj.type === "number") { + shouldScroll = scale < minScaleObj.value; + } + } + + if (shouldScroll) { + scaleWrapper.style.transform = "none"; + scaleWrapper.style.width = "max-content"; + scaleWrapper.style.height = ""; + container.style.height = ""; + container.style.overflowX = "auto"; + container.classList.add("gd-scale-scrollable"); + return; + } + + // Apply scale + scaleWrapper.style.transform = "scale(" + scale + ")"; + scaleWrapper.style.width = contentWidth + "px"; + + // Adjust container height to match scaled content + var contentHeight = scaleWrapper.scrollHeight; + container.style.height = (contentHeight * scale) + "px"; + container.style.overflow = "hidden"; + } + + updateScale(); + + // Re-scale on window resize + if (typeof ResizeObserver !== "undefined") { + var ro = new ResizeObserver(function () { + updateScale(); + }); + ro.observe(container); + } + } + + /** + * Initialize responsive tables + */ + function init() { + // Find all tables in the content area + var content = document.querySelector("#quarto-content, .content, main, article"); + if (!content) { + content = document.body; + } + + var tables = content.querySelectorAll("table"); + for (var i = 0; i < tables.length; i++) { + wrapTable(tables[i]); + } + + // Apply scale-to-fit to marked containers (manual :::{.scale-to-fit}) + var fitContainers = content.querySelectorAll(".scale-to-fit"); + for (var i = 0; i < fitContainers.length; i++) { + applyScaleToFit(fitContainers[i]); + } + + // Auto-scale elements matching CSS selectors from config or page frontmatter. + // Global selectors come from: + // Page-level selectors come from: + // Both may carry data-min-scale (float like "0.4" or keyword like "tablet"). + var allSelectors = []; + var minScaleObj = null; + var globalMeta = document.querySelector('meta[name="gd-scale-to-fit"]'); + var pageMeta = document.querySelector('meta[name="gd-scale-to-fit-page"]'); + + // Page-level takes precedence over global for both selectors and min-scale + var activeMeta = pageMeta || globalMeta; + if (activeMeta) { + try { allSelectors = JSON.parse(activeMeta.getAttribute("data-selectors") || "[]"); } catch (e) { /* ignore */ } + minScaleObj = parseMinScale(activeMeta.getAttribute("data-min-scale")); + // If page meta didn't specify min-scale, fall back to global meta + if (!minScaleObj && pageMeta && globalMeta && pageMeta !== globalMeta) { + minScaleObj = parseMinScale(globalMeta.getAttribute("data-min-scale")); + } + } + + // Also pass minScaleObj to manual .scale-to-fit containers + for (var i = 0; i < fitContainers.length; i++) { + // Re-apply with minScaleObj if we have one (first call was with null) + if (minScaleObj) { applyScaleToFit(fitContainers[i], minScaleObj); } + } + + for (var si = 0; si < allSelectors.length; si++) { + var selector = allSelectors[si]; + var matches; + try { matches = content.querySelectorAll(selector); } catch (e) { continue; } + + for (var mi = 0; mi < matches.length; mi++) { + var el = matches[mi]; + // Walk up to the nearest output container to scale + var scaleTarget = el.closest(".cell-output-display") || el.closest(".cell-output") || el.parentElement; + if (scaleTarget && !scaleTarget.classList.contains("scale-to-fit")) { + scaleTarget.classList.add("scale-to-fit"); + applyScaleToFit(scaleTarget, minScaleObj); + } + } + } + + // Handle dynamically added tables (e.g., from AJAX) + if (typeof MutationObserver !== "undefined") { + var observer = new MutationObserver(function (mutations) { + for (var i = 0; i < mutations.length; i++) { + var mutation = mutations[i]; + for (var j = 0; j < mutation.addedNodes.length; j++) { + var node = mutation.addedNodes[j]; + if (node.nodeType === 1) { + // Element node + if (node.tagName === "TABLE") { + wrapTable(node); + } else { + var nestedTables = node.querySelectorAll + ? node.querySelectorAll("table") + : []; + for (var k = 0; k < nestedTables.length; k++) { + wrapTable(nestedTables[k]); + } + } + } + } + } + }); + + observer.observe(document.body, { + childList: true, + subtree: true, + }); + } + } + + // Run after DOM is ready + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", init); + } else { + init(); + } +})(); diff --git a/docs/robots.txt b/docs/robots.txt new file mode 100644 index 0000000..042588c --- /dev/null +++ b/docs/robots.txt @@ -0,0 +1,10 @@ +# Robots.txt generated by Great Docs + +User-agent: * +Allow: / + +Sitemap: https://mkennedy.codes/docs/python-switch/sitemap.xml + +# AI agent context files +Llms-txt: https://mkennedy.codes/docs/python-switch/llms.txt +Llms-txt: https://mkennedy.codes/docs/python-switch/llms-full.txt diff --git a/docs/search.json b/docs/search.json new file mode 100644 index 0000000..989075b --- /dev/null +++ b/docs/search.json @@ -0,0 +1,263 @@ +[ + { + "objectID": "skills.html", + "href": "skills.html", + "title": "Skills", + "section": "", + "text": "A skill is a package of structured files that teaches an AI coding agent how to work with a specific tool or framework. The skill below was generated by Great Docs from this project’s documentation. Install it in your agent and it will be able to run commands, edit configuration, write content, and troubleshoot problems without step-by-step guidance from you.\n\n \n ▶ Install this skill\n \n \n \n \nAny agent — install with npx:\nnpx skills add https://mkennedy.codes/docs/python-switch/\nCodex / OpenCode\nTell the agent:Fetch the skill file at https://mkennedy.codes/docs/python-switch/skill.md and follow the instructions.\nManual — download the skill file:\ncurl -O https://mkennedy.codes/docs/python-switch/skill.md\nOr browse the SKILL.md file.\n \n \n \n\n\nSKILL.md\n---\nname: switchlang\ndescription: >\n Adds switch blocks to the Python language. Use when writing Python code that uses the switchlang package.\nlicense: MIT\ncompatibility: Requires Python >=3.9.\n---\n\n# switchlang\n\nAdds switch blocks to the Python language.\n\n## Installation\n\n```bash\npip install switchlang\n```\n\n## When to use what\n\n| Need | Use |\n|------|-----|\n| Map several discrete values to one action | `s.case(['c', 'a'], func) — list keys expand to one case per item` |\n| Match an inclusive numeric span | `s.case(closed_range(1, 5), func)` |\n| Run the next case too (fall-through) | `s.case(key, func, fallthrough=True)` |\n| Get the matched case's return value | `s.result, after the with block exits` |\n| Handle 'nothing matched' | `s.default(func), registered last` |\n| Match a key but do nothing | `s.case(key, lambda: None)` |\n\n## API overview\n\n### The switch block\n\nThe context manager that gives Python an explicit switch statement. Use it in a `with` block, register cases, then read `result`.\n\n\n- `switch`: An explicit switch statement for Python, implemented as a context manager\n\n### Range helpers\n\nHelpers for mapping ranges of values to a single case.\n\n\n- `closed_range`: Create a closed range for a case: both `start` and `stop` are included\n\n## Gotchas\n\n1. Cases execute on block exit, not at registration: case()/default() only register; the matched function runs in __exit__, and s.result is only readable after the with block (reading it inside raises).\n2. Case functions take no parameters — bind arguments with a lambda: s.case('b', lambda: process(val)). Passing process(val) calls it immediately and registers its return value.\n3. default() ordering is not enforced: a default registered before a matching case runs as well. Always register default() last.\n4. Adjacent closed_range cases overlap (closed_range(1, 5) and closed_range(5, 9) both contain 5) and raise a duplicate-case ValueError — follow closed_range(1, 5) with closed_range(6, 9).\n5. Keys are matched with == and stored in a set: they must be hashable, and equal-comparing keys (1 and True, 1 and 1.0) are duplicates.\n6. If no case matches and no default() is registered, the block raises Exception on exit.\n7. An exception raised inside the with block aborts the switch — it is re-raised and no case actions run.\n8. fallthrough=None is reserved for internal use — pass only True or False.\n\n## Best practices\n\n- Register default() as the last statement in every switch block.\n- Read s.result only after the with block exits; capture per-case data via lambdas or closures.\n- Use closed_range(start, stop) for inclusive numeric spans and plain range() for half-open ones.\n- Import from the package — from switchlang import switch, closed_range — never from the private __switchlang_impl module.\n\n## End-to-end wiring\n\nA complete, minimal switch — registration inside the `with` block, execution at block exit, result read after:\n\n```python\nfrom switchlang import switch, closed_range\n\naction = get_action()\n\nwith switch(action) as s:\n s.case(['c', 'a'], create_account) # several keys -> one action\n s.case('l', log_into_account)\n s.case('', lambda: None) # explicit \"do nothing\" case\n s.case(closed_range(1, 5), lambda: set_level(action)) # inclusive 1..5\n s.default(unknown_command) # ALWAYS register last\n\nprint(s.result) # return value of whichever case ran — only valid here, after the block\n```\n\n## The execution model (this is what code generators get wrong)\n\n`case()` and `default()` only **register** cases — nothing executes at those lines. The matched function (and any fall-through functions) run inside `__exit__` as the `with` block closes. Three consequences:\n\n- Case functions take **zero parameters**. Bind data with a lambda or closure: `s.case('b', lambda: process(val, num))` — never `s.case('b', process(val, num))`, which would call the function immediately and register its return value.\n- `s.result` is only readable **after** the block; reading it inside raises even when the case has already been registered and matched.\n- Registration errors (duplicate key, non-callable action, empty list/range) raise at the `s.case(...)` line, but the \"no case matched and no default\" error raises at the block's closing line.\n\n## Fall-through, from the usage side\n\nFall-through is opt-in per case. The next registered case then runs **whether or not its key matches**, continuing until a case without `fallthrough=True`. The last function executed supplies `result`:\n\n```python\nvalue = 2\nwith switch(value) as s:\n s.case(1, lambda: 'one')\n s.case(2, lambda: 'two', fallthrough=True)\n s.case(3, lambda: 'three') # runs too (its key is never compared), then the chain stops\n s.default(lambda: 'other')\n\ns.result # 'three'\n```\n\nPass only `True` or `False` — `fallthrough=None` is reserved for the library's internal list/range expansion.\n\n## Keys: equality, hashability, ranges\n\nMatching is plain `key == value`, and keys are stored in a `set`, so every key must be hashable and keys that compare equal are duplicates (`1` and `True`, `1` and `1.0` collide). A `list` or `range` key is expanded so each item becomes its own case for the same function. `closed_range(start, stop)` is inclusive on **both** ends — and because of that, adjacent closed ranges share their endpoint and raise the duplicate-case error: use `closed_range(1, 5)` with `closed_range(6, 9)`, not `closed_range(5, 9)`.\n\n## When to reach for this vs `match`\n\n`match` (3.10+) destructures by *shape*; `switchlang` dispatches on *values*. Prefer `switchlang` when you need opt-in fall-through, case lists built at runtime (`s.case(some_list, action)`), a captured return value (`s.result`), or Python 3.9 support. Prefer `match` for structural pattern matching on tuples/dataclasses/nested data. Remember: `import switchlang`, `pip install switchlang` — the repo name `python-switch` is not the import name.\n\n## Fetching the docs as Markdown\n\nEvery page on the documentation site has a plain-Markdown twin: swap the `.html` extension for `.md` to get token-efficient source without the site chrome. For example https://mkennedy.codes/docs/python-switch/reference/switch.html is also available at https://mkennedy.codes/docs/python-switch/reference/switch.md. Prefer the `.md` form when reading these docs programmatically.\n\n\n## Resources\n\n- [Full documentation](https://mkennedy.codes/docs/python-switch/)\n- [llms.txt](llms.txt) — Indexed API reference for LLMs\n- [llms-full.txt](llms-full.txt) — Comprehensive documentation for LLMs\n- [Source code](https://github.com/mikeckennedy/python-switch)" + }, + { + "objectID": "reference/index.html", + "href": "reference/index.html", + "title": "API Reference", + "section": "", + "text": "The switch block\n\nThe context manager that gives Python an explicit switch statement. Use it in a with block, register cases, then read result.\n\n\nswitch\n\nAn explicit switch statement for Python, implemented as a context manager.\n\n\n\n\nRange helpers\n\nHelpers for mapping ranges of values to a single case.\n\n\nclosed_range()\n\nCreate a closed range for a case: both start and stop are included.", + "crumbs": [ + "Reference", + "API Index" + ] + }, + { + "objectID": "package-info.html", + "href": "package-info.html", + "title": "Package Info", + "section": "", + "text": "Package\nVersion Constraint\nEnvironment Marker\nLast Published\nPyPI\n\n\n\n\npytest\n—\n\n2026-06-19\n\n\n\ngreat-docs\n—\npython_version >= \"3.11\"\n2026-07-10" + }, + { + "objectID": "package-info.html#dev", + "href": "package-info.html#dev", + "title": "Package Info", + "section": "", + "text": "Package\nVersion Constraint\nEnvironment Marker\nLast Published\nPyPI\n\n\n\n\npytest\n—\n\n2026-06-19\n\n\n\ngreat-docs\n—\npython_version >= \"3.11\"\n2026-07-10" + }, + { + "objectID": "index.html", + "href": "index.html", + "title": "switchlang", + "section": "", + "text": "View on PyPI Browse source code Issues Pypi Funding\n\n\n\nSkills llms.txt llms-full.txt\n\n\n\n\n\n\nMichael Kennedy\n\n\n\nAuthor\n\n \n\n\n\n\nFull license MIT\n\n\n\nRequires: Python >=3.9 Provides-Extra: dev Package Info" + }, + { + "objectID": "index.html#example", + "href": "index.html#example", + "title": "switchlang", + "section": "Example", + "text": "Example\nfrom switchlang import switch\n\ndef main():\n num = 7\n val = input(\"Enter a character, a, b, c or any other: \")\n\n with switch(val) as s:\n s.case('a', process_a)\n s.case('b', lambda: process_with_data(val, num, 'other values still'))\n s.default(process_any)\n\ndef process_a():\n print(\"Found A!\")\n\ndef process_any():\n print(\"Found Default!\")\n\ndef process_with_data(*value):\n print(f\"Found with data: {value}\")\n\nmain()" + }, + { + "objectID": "index.html#installation", + "href": "index.html#installation", + "title": "switchlang", + "section": "Installation", + "text": "Installation\nSimply install via pip or uv:\npip install switchlang\n# or\nuv add switchlang" + }, + { + "objectID": "index.html#features", + "href": "index.html#features", + "title": "switchlang", + "section": "Features", + "text": "Features\n\nMore explicit than using dictionaries with functions as values.\nValidates that case actions are callable\nSupports default case\nChecks for duplicate keys / cases\nKeys can be anything hashable (numbers, strings, objects, etc.)\nCapture the return value of the matched case with s.result\nSupports “fall-through” cases (opt-in with fallthrough=True)\nUse range and list for multiple cases mapped to a single action" + }, + { + "objectID": "index.html#multiple-cases-one-action", + "href": "index.html#multiple-cases-one-action", + "title": "switchlang", + "section": "Multiple cases, one action", + "text": "Multiple cases, one action\nYou can map ranges and lists of cases to a single action as follows:\n# with lists:\nvalue = 4 # matches even number case\n\nwith switch(value) as s:\n s.case([1, 3, 5, 7], lambda: ...)\n s.case([0, 2, 4, 6, 8], lambda: ...)\n s.default(lambda: ...)\n# with ranges:\nvalue = 4 # matches first case\n\nwith switch(value) as s:\n s.case(range(1, 6), lambda: ...)\n s.case(range(6, 10), lambda: ...)\n s.default(lambda: ...)" + }, + { + "objectID": "index.html#closed-vs.-open-ranges", + "href": "index.html#closed-vs.-open-ranges", + "title": "switchlang", + "section": "Closed vs. Open ranges", + "text": "Closed vs. Open ranges\nLooking at the above code it’s a bit weird that 6 appears at the end of one case, beginning of the next. But range() is half open/closed.\nTo handle the inclusive case, I’ve added closed_range(start, stop). For example, closed_range(1, 5) -> [1, 2, 3, 4, 5]:\nfrom switchlang import switch, closed_range\n\nwith switch(value) as s:\n s.case(closed_range(1, 5), lambda: 'one to five') # matches 1, 2, 3, 4, 5\n s.case(closed_range(6, 9), lambda: 'six to nine') # matches 6, 7, 8, 9\n s.default(lambda: 'something else')" + }, + { + "objectID": "index.html#fall-through-and-results", + "href": "index.html#fall-through-and-results", + "title": "switchlang", + "section": "Fall-through and results", + "text": "Fall-through and results\nCases don’t fall through by default. Opt in per case with fallthrough=True and the next case runs too, whether or not its key matches:\nvalue = 2\n\nwith switch(value) as s:\n s.case(1, lambda: 'one')\n s.case(2, lambda: 'two', fallthrough=True)\n s.case(3, lambda: 'three') # runs as well, then stops here\n s.default(lambda: 'other')\n\nprint(s.result) # 'three'\nWhatever the executed case’s function returns is available after the block as s.result. When cases fall through, the last function executed wins." + }, + { + "objectID": "index.html#why-not-just-raw-dict", + "href": "index.html#why-not-just-raw-dict", + "title": "switchlang", + "section": "Why not just raw dict?", + "text": "Why not just raw dict?\nThe biggest push back on this idea is that we already have this problem solved. You write the following code.\nswitch = {\n 1: method_on_one,\n 2: method_on_two,\n 3: method_three\n}\n\nresult = switch.get(value, default_method_to_run)()\nThis works but is very low on the functionality level. We have a better solution here I believe. Let’s take this example and see how it looks in python-switch vs raw dicts:\n# with python-switch:\n\nwhile True:\n action = get_action(action)\n\n with switch(action) as s:\n s.case(['c', 'a'], create_account)\n s.case('l', log_into_account)\n s.case('r', register_cage)\n s.case('u', update_availability)\n s.case(['v', 'b'], view_bookings)\n s.case('x', exit_app)\n s.case('', lambda: None)\n s.case(range(1, 6), lambda: set_level(action))\n s.default(unknown_command)\n\n print(f'Result is {s.result}')\nNow compare that to the espoused pythonic way:\n# with raw dicts\n\nwhile True:\n action = get_action(action)\n\n switch = {\n 'c': create_account,\n 'a': create_account,\n 'l': log_into_account,\n 'r': register_cage,\n 'u': update_availability,\n 'v': view_bookings,\n 'b': view_bookings,\n 'x': exit_app,\n 1: lambda: set_level(action),\n 2: lambda: set_level(action),\n 3: lambda: set_level(action),\n 4: lambda: set_level(action),\n 5: lambda: set_level(action),\n '': lambda: None,\n }\n result = switch.get(action, unknown_command)()\n print(f'Result is {result}')\nPersonally, I much prefer to read and write the one above. That’s why I wrote this module. It seems to convey the intent of switch way more than the dict. But both are options." + }, + { + "objectID": "index.html#why-not-just-if-elif-else", + "href": "index.html#why-not-just-if-elif-else", + "title": "switchlang", + "section": "Why not just if / elif / else?", + "text": "Why not just if / elif / else?\nAnother push back on this idea is that we already have this problem solved. Switch statements are really if / elif / else blocks. So you write the following code.\n# with if / elif / else\n\nwhile True:\n action = get_action(action)\n\n if action == 'c' or action == 'a':\n result = create_account()\n elif action == 'l':\n result = log_into_account()\n elif action == 'r':\n result = register_cage()\n elif action == 'a':\n result = update_availability()\n elif action == 'v' or action == 'b':\n result = view_bookings()\n elif action == 'x':\n result = exit_app()\n elif action in {1, 2, 3, 4, 5}:\n result = set_level(action)\n else:\n unknown_command()\n\n print(f'Result is {result}')\nI actually believe this is a little better than the raw dict option. But there are still things that are harder.\n\nHow would you deal with fall-through cleanly?\nDid you notice the bug? We forgot to set result in default case (else) and will result in a runtime error (but only if that case hits).\nThere is another bug. update_availability will never run because its command (a) is bound to two cases. This is guarded against in switch and you would receive a duplicate case error the first time it runs at all.\nWhile it’s pretty clear, it’s much more verbose and less declarative than the switch version.\n\nAgain, compare the if / elif / else to what you have with switch. This code is identical except doesn’t have the default case bug.\nwhile True:\n action = get_action(action)\n\n with switch(action) as s:\n s.case(['c', 'a'], create_account)\n s.case('l', log_into_account)\n s.case('r', register_cage)\n s.case('u', update_availability)\n s.case(['v', 'b'], view_bookings)\n s.case('x', exit_app)\n s.case('', lambda: None)\n s.case(range(1, 6), lambda: set_level(action))\n s.default(unknown_command)\n\n print(f'Result is {s.result}')" + }, + { + "objectID": "index.html#why-not-just-match", + "href": "index.html#why-not-just-match", + "title": "switchlang", + "section": "Why not just match?", + "text": "Why not just match?\nPython 3.10 added structural pattern matching, and it’s genuinely great at what it was built for: destructuring data by shape (tuples, dataclasses, nested structures, and so on). But it covers different ground than a classic switch statement:\n\nNo fall-through. match arms are exclusive. With switchlang, fall-through is opt-in per case with fallthrough=True.\nCases are fixed syntax. You can’t build match arms from data at runtime, while s.case(some_list, action) and s.case(closed_range(1, 5), action) are plain method calls. Also watch out: a bare name in a case pattern captures the value rather than comparing against a constant — a classic match gotcha that can’t happen here.\nNo result capture. match arms are blocks of statements. switchlang dispatches to callables and hands back the chosen case’s return value as s.result.\nPython version. match needs Python 3.10+, while switchlang supports 3.9+.\n\nIf you’re pattern-matching on the shape of objects, use match — that’s what it’s for. If you want explicit value-based dispatch with fall-through, ranges, and a captured result, that’s switchlang." + }, + { + "objectID": "changelog/index.html", + "href": "changelog/index.html", + "title": "Changelog", + "section": "", + "text": "All notable changes to switchlang are documented in this file.\nThe format is based on Keep a Changelog, and this project adheres to Semantic Versioning." + }, + { + "objectID": "changelog/index.html#fixed", + "href": "changelog/index.html#fixed", + "title": "Changelog", + "section": "Fixed", + "text": "Fixed\n\nAn exception raised inside the with block now always aborts the switch, even when the exception object is falsy. __exit__ guarded its re-raise with if exc_val:, a truthiness test that invokes the exception’s __bool__/__len__. An exception whose __bool__ returned False slipped past the guard, so the matched case action ran before the exception propagated. The guard now tests exc_val is not None, restoring the documented “no case actions run on exception” guarantee for every exception type. (#15)" + }, + { + "objectID": "changelog/index.html#added", + "href": "changelog/index.html#added", + "title": "Changelog", + "section": "Added", + "text": "Added\n\nType information now ships with the package. A py.typed marker makes the hints public API, so switchlang’s signatures type-check and autocomplete in IDEs and type checkers. Every public signature is annotated — case() -> bool, __enter__() -> switch, __exit__(...), result -> Any, and closed_range(...) -> range — using modern, Python 3.9-safe syntax (from __future__ import annotations). (#13)\nDocumentation site at mkennedy.codes/docs/python-switch, built with Great Docs (Quarto): a landing page plus an API reference for switch and closed_range. Includes scripts/build_docs.py and scripts/serve_docs.py. (#13)\nclosed_range() now validates its step. A step less than 1 raises a clear ValueError instead of surfacing a raw range error (for step=0) or silently producing an empty range (for a negative step). (#14)\nuv add switchlang installation instructions alongside pip. (#13)" + }, + { + "objectID": "changelog/index.html#changed", + "href": "changelog/index.html#changed", + "title": "Changelog", + "section": "Changed", + "text": "Changed\n\nPackaging modernized to pyproject.toml + hatchling: the version is read from package metadata, a [dev] extra is provided, Python 3.9–3.15 classifiers and a Typing :: Typed classifier are declared, and full project URLs (docs, repository, issues, PyPI, funding) are published. (#13)\ncase() now always returns bool. It previously returned None on a scalar no-match but False on a list no-match; the return value is now a consistent bool. (#13)\nTooling: ruff pinned to target-version = \"py39\" to match requires-python = \">=3.9\". (#13)" + }, + { + "objectID": "changelog/index.html#fixed-1", + "href": "changelog/index.html#fixed-1", + "title": "Changelog", + "section": "Fixed", + "text": "Fixed\n\nclosed_range(start, stop, step) no longer overshoots stop when step > 1. The inclusive bound was built as range(start, stop + step, step), which added a full extra step — e.g. closed_range(1, 6, 2) yielded [1, 3, 5, 7], letting 7 (a value outside the stated range) silently match the case. The bound is now computed as stop + 1, so values never pass stop while stop is still included when a step lands on it exactly (closed_range(1, 7, 2) -> 1, 3, 5, 7). (#14)\n.result no longer breaks for matched cases that return an always-equal object. The “no result” sentinel was compared with ==, so a returned object with a permissive __eq__ (a NumPy array is the real-world case) made .result raise “No result has been computed” even though a result existed. The sentinel is now compared by identity (is). (#14)" + }, + { + "objectID": "changelog/index.html#documentation", + "href": "changelog/index.html#documentation", + "title": "Changelog", + "section": "Documentation", + "text": "Documentation\n\nREADME refreshed: version and docs badges, a prominent link to the documentation site, an honest feature list (“Validates that case actions are callable”, replacing an inaccurate signature-verification claim), a new s.result bullet, a new “Fall-through and results” section, a new “Why not just match?” section, a closed_range usage example, and f-strings throughout. (#13)\nDocstrings rewritten to render as the API reference: switch is described as a context manager; default() documents that ordering is not enforced (register it last); case() documents its return contract, the ValueErrors it raises, and the internal no-match sentinel; result documents that the last function executed wins under fall-through; and closed_range is documented as returning a range object (not a “generator”) with its step semantics and ValueError. (#13)" + }, + { + "objectID": "changelog/index.html#changed-1", + "href": "changelog/index.html#changed-1", + "title": "Changelog", + "section": "Changed", + "text": "Changed\n\nStandardized string literals on double quotes across the codebase and added an initial round of type annotations, including a fix for a potential type warning on s.result." + }, + { + "objectID": "changelog/index.html#added-1", + "href": "changelog/index.html#added-1", + "title": "Changelog", + "section": "Added", + "text": "Added\n\nInitial public release of switchlang on PyPI: an explicit switch block for Python built on the with statement, with default cases, duplicate-case detection, list/range cases, opt-in fall-through, and the closed_range helper." + }, + { + "objectID": "license.html", + "href": "license.html", + "title": "License", + "section": "", + "text": "▶\n License features — MIT License\n\n\n\n\n\nPermissions\n\nCommercial use\nModification\nDistribution\nPrivate use\n\n\nConditions\n\nLicense and copyright notice\n\n\nLimitations\n\nLiability\nWarranty\n\n\n\n\nMIT License\n\nCopyright (c) 2017 Michael Kennedy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE." + }, + { + "objectID": "reference/closed_range.html", + "href": "reference/closed_range.html", + "title": "closed_range()", + "section": "", + "text": "Create a closed range for a case: both start and stop are included.\n\n\nUsage\nSource\n\n\nclosed_range(start, stop, step=1)\n\n\nWith the default step of 1, closed_range(1, 5) covers 1, 2, 3, 4, 5 — unlike range(1, 5), the upper bound is part of the range. With a larger step the range never goes past stop: closed_range(1, 6, 2) covers 1, 3, 5, and stop itself is included when the step lands on it exactly, as in closed_range(1, 7, 2) -> 1, 3, 5, 7.\n with switch(value) as s:\n s.case(closed_range(1, 5), lambda: \"1-to-5\")\n s.case(closed_range(6, 7), lambda: \"6-or-7\")\n s.default(lambda: 'default')\n\n\nParameters\n\n\nstart: int\n\nThe inclusive lower bound of the range.\n\nstop: int\n\nThe inclusive upper bound of the range.\n\nstep: int = 1\n\nThe step size between elements; must be 1 or greater (defaults to 1).\n\n\n\n\n\nReturns\n\n\n range\n\nA range object with a closed (inclusive) upper bound.\n\n\n\n\n\nRaises\n\n\n ValueError\n\nIf start is not less than stop, or step is less than 1.", + "crumbs": [ + "Reference", + "Range helpers", + "[closed_range()]{.doc-object-name .doc-function .doc-label .doc-label-function}" + ] + }, + { + "objectID": "reference/switch.html", + "href": "reference/switch.html", + "title": "switch", + "section": "", + "text": "An explicit switch statement for Python, implemented as a context manager.", + "crumbs": [ + "Reference", + "The switch block", + "[switch]{.doc-object-name .doc-class .doc-label .doc-label-class}" + ] + }, + { + "objectID": "reference/switch.html#result", + "href": "reference/switch.html#result", + "title": "switch", + "section": "result", + "text": "result\n\nThe value returned by the function of the matched case.\n\n\nresult: Any\n\n\nWhen cases fall through, result is the return value of the last function executed.\n value = 4\n with switch(value) as s:\n s.case(closed_range(1, 5), lambda: \"1-to-5\")\n # ...\n\n res = s.result # res == '1-to-5'\n\n\nRaises\n\n\n Exception\n\nIf accessed before the switch block has exited and computed a result.", + "crumbs": [ + "Reference", + "The switch block", + "[switch]{.doc-object-name .doc-class .doc-label .doc-label-class}" + ] + }, + { + "objectID": "reference/switch.html#enter__", + "href": "reference/switch.html#enter__", + "title": "switch", + "section": "__enter__()", + "text": "__enter__()\n\nEnter the switch block.\n\n\nUsage\nSource\n\n\n__enter__()\n\n\nReturns\n\n\n switch\n\nThe switch instance itself (bind it with as s to register cases).", + "crumbs": [ + "Reference", + "The switch block", + "[switch]{.doc-object-name .doc-class .doc-label .doc-label-class}" + ] + }, + { + "objectID": "reference/switch.html#exit__", + "href": "reference/switch.html#exit__", + "title": "switch", + "section": "__exit__()", + "text": "__exit__()\n\nRun the matched case (and any fall-through cases) as the block exits.\n\n\nUsage\nSource\n\n\n__exit__(exc_type, exc_val, exc_tb)\n\n\nRaises\n\n\n Exception\n\nIf no case matched the value and no default case was registered.", + "crumbs": [ + "Reference", + "The switch block", + "[switch]{.doc-object-name .doc-class .doc-label .doc-label-class}" + ] + }, + { + "objectID": "reference/switch.html#init__", + "href": "reference/switch.html#init__", + "title": "switch", + "section": "__init__()", + "text": "__init__()\n\nCreate a new switch block that tests cases against value.\n\n\nUsage\nSource\n\n\n__init__(value)\n\n\nParameters\n\n\nvalue: Any\n\nThe value each case key is compared against.", + "crumbs": [ + "Reference", + "The switch block", + "[switch]{.doc-object-name .doc-class .doc-label .doc-label-class}" + ] + }, + { + "objectID": "reference/switch.html#case", + "href": "reference/switch.html#case", + "title": "switch", + "section": "case()", + "text": "case()\n\nRegister a case for the switch block:\n\n\nUsage\nSource\n\n\ncase(key, func, fallthrough=False)\n\n\n with switch(val) as s:\n s.case('a', function)\n s.case('b', function, fallthrough=True)\n s.default(function)\n\n\nParameters\n\n\nkey: Any\n\nKey for the case test. If this is a list or range, each item is added as a case for func.\n\nfunc: Callable[[], Any]\n\nAny callable taking no parameters, executed if this case matches.\n\nfallthrough: bool | None = False\n\nOptionally fall through to the subsequent case (defaults to False). None is reserved for internal use and leaves the fall-through state unchanged.\n\n\n\n\n\nReturns\n\n\n bool\n\nTrue if this case (or any item of a list or range key) matched the switch value, otherwise False.\n\n\n\n\n\nRaises\n\n\n ValueError\n\nIf the key is a duplicate, the key is an empty collection, or func is not callable.", + "crumbs": [ + "Reference", + "The switch block", + "[switch]{.doc-object-name .doc-class .doc-label .doc-label-class}" + ] + }, + { + "objectID": "reference/switch.html#default", + "href": "reference/switch.html#default", + "title": "switch", + "section": "default()", + "text": "default()\n\nRegister the default case: the action to run when no other case matches.\n\n\nUsage\nSource\n\n\ndefault(func)\n\n\nUse it as the optional final statement in the switch block. Note that the ordering is not enforced: if default() is registered before a case that also matches, both will run. Always register it last.\n with switch(val) as s:\n s.case(...)\n s.case(...)\n s.default(function)\n\n\nParameters\n\n\nfunc: Callable[[], Any]\n\nAny callable taking no parameters, executed if no other case matched.\n\n\n\n\n\nReturns\n\n\n None\n\nNone", + "crumbs": [ + "Reference", + "The switch block", + "[switch]{.doc-object-name .doc-class .doc-label .doc-label-class}" + ] + } +] \ No newline at end of file diff --git a/docs/sidebar-filter.js b/docs/sidebar-filter.js new file mode 100644 index 0000000..349a1e0 --- /dev/null +++ b/docs/sidebar-filter.js @@ -0,0 +1,295 @@ +/** + * Sidebar Filter for Great Docs + * + * Adds a search/filter input to the API reference sidebar for quickly + * finding items in large APIs. Automatically enabled when there are + * 20+ items in the sidebar (configurable via data attribute). + */ + +(function() { + 'use strict'; + + // Configuration + const DEFAULT_MIN_ITEMS = 20; + const DEBOUNCE_DELAY = 150; + + /** + * Debounce function to limit filter execution rate + */ + function debounce(func, wait) { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + } + + /** + * Count total sidebar items (links to API reference pages) + */ + function countSidebarItems(sidebar) { + const items = sidebar.querySelectorAll('.sidebar-item:not(.sidebar-item-section) .sidebar-link'); + return items.length; + } + + /** + * Create the filter input element + */ + function createFilterInput() { + const container = document.createElement('div'); + container.className = 'sidebar-filter-container'; + container.innerHTML = ` + + + `; + return container; + } + + /** + * Check if a sidebar item is a top-level navigation link (not inside a section) + * These should not be filtered (e.g., "API" link) + */ + function isTopLevelNavItem(item) { + // Items inside a section (sidebar-item-section) are NOT top-level + // Check if any ancestor is a sidebar-item-section + let parent = item.parentElement; + while (parent) { + if (parent.classList && parent.classList.contains('sidebar-item-section')) { + return false; // Inside a section, so not top-level + } + if (parent.classList && parent.classList.contains('sidebar-menu-container')) { + break; // Reached the top of the sidebar + } + parent = parent.parentElement; + } + + // This item is directly in the main sidebar list (not inside any section) + return true; + } + + /** + * Check if we're on an API reference page (where the filter should show). + * Returns true only for /reference/ pages that are NOT CLI reference pages. + */ + function isApiReferencePage() { + const path = window.location.pathname; + return path.includes('/reference/') && !path.includes('/reference/cli/'); + } + + /** + * Filter sidebar items based on search query + */ + function filterSidebar(query, sidebar, countDisplay) { + const normalizedQuery = query.toLowerCase().trim(); + const sections = sidebar.querySelectorAll('.sidebar-item-section'); + const allItems = sidebar.querySelectorAll('.sidebar-item:not(.sidebar-item-section)'); + + // Separate top-level nav items from filterable items + const topLevelNavItems = []; + const filterableItems = []; + + allItems.forEach(item => { + if (isTopLevelNavItem(item)) { + topLevelNavItems.push(item); + } else { + filterableItems.push(item); + } + }); + + let visibleCount = 0; + const totalCount = filterableItems.length; + + // If query is empty, show everything + if (!normalizedQuery) { + filterableItems.forEach(item => { + item.style.display = ''; + item.classList.remove('sidebar-filter-match'); + }); + sections.forEach(section => { + section.style.display = ''; + // Restore original collapse state + const collapseTarget = section.querySelector('.sidebar-section'); + if (collapseTarget && !collapseTarget.classList.contains('show')) { + // Keep collapsed sections collapsed + } + }); + // Top-level nav items are always visible + topLevelNavItems.forEach(item => { + item.style.display = ''; + }); + countDisplay.style.display = 'none'; + return; + } + + // Filter items (excluding top-level nav items which are always visible) + filterableItems.forEach(item => { + const link = item.querySelector('.sidebar-link'); + const text = link ? link.textContent.toLowerCase() : ''; + const matches = text.includes(normalizedQuery); + + item.style.display = matches ? '' : 'none'; + item.classList.toggle('sidebar-filter-match', matches); + + if (matches) { + visibleCount++; + } + }); + + // Show/hide sections based on whether they have visible items + sections.forEach(section => { + const sectionItems = section.querySelectorAll('.sidebar-item:not(.sidebar-item-section)'); + const hasVisibleItems = Array.from(sectionItems).some( + item => item.style.display !== 'none' + ); + + section.style.display = hasVisibleItems ? '' : 'none'; + + // Expand sections that have matches + if (hasVisibleItems) { + const collapseTarget = section.querySelector('.sidebar-section'); + if (collapseTarget && !collapseTarget.classList.contains('show')) { + collapseTarget.classList.add('show'); + } + } + }); + + // Update count display + const countNum = countDisplay.querySelector('.filter-count-num'); + const countTotal = countDisplay.querySelector('.filter-count-total'); + countNum.textContent = visibleCount; + countTotal.textContent = totalCount; + countDisplay.style.display = ''; + } + + /** + * Initialize the sidebar filter + */ + function initSidebarFilter() { + // Only show filter on API reference pages + if (!isApiReferencePage()) { + return; + } + + // Find the sidebar + const sidebar = document.getElementById('quarto-sidebar'); + if (!sidebar) { + return; + } + + // Check if we're on a reference page (has sidebar with API items) + const sidebarMenu = sidebar.querySelector('.sidebar-menu-container'); + if (!sidebarMenu) { + return; + } + + // Get minimum items threshold from data attribute or use default + const minItems = parseInt( + document.body.dataset.sidebarFilterMinItems || DEFAULT_MIN_ITEMS, + 10 + ); + + // Check if filtering is disabled + if (document.body.dataset.sidebarFilterDisabled === 'true') { + return; + } + + // Count items and check threshold + const itemCount = countSidebarItems(sidebar); + if (itemCount < minItems) { + return; + } + + // Create and insert the filter input + const filterContainer = createFilterInput(); + const menuContainer = sidebar.querySelector('.sidebar-menu-container'); + menuContainer.insertBefore(filterContainer, menuContainer.firstChild); + + // Get references to elements + const input = filterContainer.querySelector('.sidebar-filter-input'); + const clearBtn = filterContainer.querySelector('.sidebar-filter-clear'); + const countDisplay = filterContainer.querySelector('.sidebar-filter-count'); + + // Set total count + const countTotal = countDisplay.querySelector('.filter-count-total'); + countTotal.textContent = itemCount; + + // Create debounced filter function + const debouncedFilter = debounce((query) => { + filterSidebar(query, sidebar, countDisplay); + }, DEBOUNCE_DELAY); + + // Event listeners + input.addEventListener('input', (e) => { + const query = e.target.value; + clearBtn.style.display = query ? '' : 'none'; + debouncedFilter(query); + }); + + clearBtn.addEventListener('click', () => { + input.value = ''; + clearBtn.style.display = 'none'; + filterSidebar('', sidebar, countDisplay); + input.focus(); + }); + + // Keyboard shortcut: Escape to clear + input.addEventListener('keydown', (e) => { + if (e.key === 'Escape') { + if (input.value) { + input.value = ''; + clearBtn.style.display = 'none'; + filterSidebar('', sidebar, countDisplay); + } else { + input.blur(); + } + } + }); + + // Global keyboard shortcut: "/" to focus filter (like GitHub) + document.addEventListener('keydown', (e) => { + // Don't trigger if user is typing in another input + if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') { + return; + } + + if (e.key === '/' && !e.ctrlKey && !e.metaKey && !e.altKey) { + e.preventDefault(); + input.focus(); + input.select(); + } + }); + + console.log(`Sidebar filter initialized (${itemCount} items)`); + } + + // Initialize when DOM is ready + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initSidebarFilter); + } else { + initSidebarFilter(); + } +})(); diff --git a/docs/sidebar-float.js b/docs/sidebar-float.js new file mode 100644 index 0000000..b3e3bb2 --- /dev/null +++ b/docs/sidebar-float.js @@ -0,0 +1,197 @@ +/** + * Floating Sidebar Navigation for Great Docs + * + * Transforms the default Quarto left sidebar on desktop (>= 992px) into a + * floating, pinned navigation panel with: + * - Independent scroll containment (no bleed to page body) + * - Dynamic top/bottom bounds that react to navbar and footer + * - A sticky "Pages" header label + * - Gradient + arrow scroll affordances (top & bottom) + * - Auto-scroll to the active page on load + * + * On tablet/mobile (< 992px) this script is a no-op — the overlay modal + * approach handles the sidebar there. + */ +(function () { + 'use strict'; + + // ── Constants ────────────────────────────────────────────── + var GAP = 12; // breathing room (px) between sidebar and navbar/footer + var FOOTER_BUFFER = 7; // extra px buffer before footer encroaches + + + // ── Media query guard ────────────────────────────────────── + var mql = window.matchMedia('(min-width: 992px)'); + + // ── State ────────────────────────────────────────────────── + var sidebar = null; // #quarto-sidebar + var menuContainer = null; // .sidebar-menu-container + var floatBody = null; // .gd-sidebar-float-body (scrollable wrapper) + var resizeObs = null; // ResizeObserver instance + var rafId = null; + var initialised = false; + + // ── Helpers ──────────────────────────────────────────────── + function getHeader() { + return document.getElementById('quarto-header'); + } + + function getFooter() { + return document.querySelector('footer.footer'); + } + + // ── Build the float structure ────────────────────────────── + function buildFloat() { + sidebar = document.getElementById('quarto-sidebar'); + if (!sidebar) return false; + menuContainer = sidebar.querySelector('.sidebar-menu-container'); + if (!menuContainer) return false; + + // Scrollable body wrapper + floatBody = document.createElement('div'); + floatBody.className = 'gd-sidebar-float-body'; + + // Move the menu container inside the scroll body + floatBody.appendChild(menuContainer); + + + + // Assemble inside #quarto-sidebar + sidebar.appendChild(floatBody); + + // Mark as enhanced + sidebar.classList.add('gd-sidebar-float'); + + return true; + } + + // ── Update sidebar bounds ────────────────────────────────── + // With position:sticky, `top` sets the stick offset from the viewport top. + // We can't use `bottom` to shrink the sidebar — instead we compute a + // dynamic `max-height` that accounts for the navbar and footer overlap. + function updateBounds() { + if (!sidebar || !mql.matches) return; + + var header = getHeader(); + var footer = getFooter(); + var viewportH = window.innerHeight; + + var navBottom = header ? header.getBoundingClientRect().bottom : 0; + var footerTop = footer ? footer.getBoundingClientRect().top : viewportH; + + var top = Math.max(0, navBottom) + GAP; + + // Available height = viewport minus navbar minus any footer overlap minus gaps + var footerOverlap = Math.max(0, viewportH - footerTop); + var maxH = viewportH - top - footerOverlap - GAP - FOOTER_BUFFER; + + sidebar.style.top = top + 'px'; + // Always apply maxHeight so the sidebar never overflows its bounds + sidebar.style.maxHeight = Math.max(100, maxH) + 'px'; + } + + + + // ── Scroll-to-active ─────────────────────────────────────── + function scrollToActive() { + if (!floatBody) return; + var active = floatBody.querySelector('.sidebar-link.active'); + if (active) { + // Scroll only the float body — NOT the main page. + // scrollIntoView() would bubble up and shift the document. + requestAnimationFrame(function () { + var bodyRect = floatBody.getBoundingClientRect(); + var activeRect = active.getBoundingClientRect(); + var offset = activeRect.top - bodyRect.top - (bodyRect.height / 2) + (activeRect.height / 2); + floatBody.scrollTop += offset; + }); + } + } + + // ── rAF-throttled scroll/resize handler ──────────────────── + function onFrameUpdate() { + updateBounds(); + rafId = null; + } + + function scheduleUpdate() { + if (rafId) return; + rafId = requestAnimationFrame(onFrameUpdate); + } + + // Immediate update on resize for more responsive bounds + function onResize() { + updateBounds(); + scheduleUpdate(); // also schedule a follow-up in case layout settles + } + + // ── Teardown (for breakpoint changes) ────────────────────── + function teardown() { + if (!initialised) return; + + // Move menu container back to sidebar root + if (menuContainer && sidebar) { + sidebar.appendChild(menuContainer); + } + + // Remove added elements + + if (floatBody && floatBody.parentNode) floatBody.parentNode.removeChild(floatBody); + + sidebar.classList.remove('gd-sidebar-float'); + sidebar.style.top = ''; + sidebar.style.maxHeight = ''; + + // Remove listeners + window.removeEventListener('scroll', scheduleUpdate); + window.removeEventListener('resize', onResize); + window.removeEventListener('quarto-hrChanged', scheduleUpdate); + if (resizeObs) { + resizeObs.disconnect(); + resizeObs = null; + } + floatBody = null; + initialised = false; + } + + // ── Initialise ───────────────────────────────────────────── + function init() { + if (initialised) return; + if (!mql.matches) return; + + if (!buildFloat()) return; + + // Bind events + window.addEventListener('scroll', scheduleUpdate, { passive: true }); + window.addEventListener('resize', onResize, { passive: true }); + window.addEventListener('quarto-hrChanged', scheduleUpdate); + + // ResizeObserver for more reliable size tracking + if (typeof ResizeObserver !== 'undefined') { + resizeObs = new ResizeObserver(scheduleUpdate); + resizeObs.observe(document.documentElement); + } + + initialised = true; + + // Initial measurements + updateBounds(); + scrollToActive(); + } + + // ── Respond to breakpoint changes ────────────────────────── + mql.addEventListener('change', function () { + if (mql.matches) { + init(); + } else { + teardown(); + } + }); + + // ── Boot ─────────────────────────────────────────────────── + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } +})(); diff --git a/docs/sidebar-wrap.js b/docs/sidebar-wrap.js new file mode 100644 index 0000000..d383f2a --- /dev/null +++ b/docs/sidebar-wrap.js @@ -0,0 +1,162 @@ +/** + * Sidebar Smart Wrap for Great Docs + * + * Inserts (word break opportunity) elements into long sidebar item + * names so the browser can break lines at aesthetically pleasing points: + * - After dots: store.DuckDBStore → break after each "." + * - After underscores: retrieve_bm25 → break after "_" + * - After open paren: connect() → break after "(" + * - At camelCase: DuckDBStore → break before uppercase runs + * + * The tag is invisible and zero-width; the browser only uses it as a + * line-break opportunity when the text overflows its container. + */ + +(function () { + 'use strict'; + + /** + * Insert elements at smart break points in a text node. + * + * Break opportunities are placed: + * 1. After every "." (module separators) + * 2. After every "_" (snake_case boundaries) + * 3. After every "(" (before argument lists) + * 4. Before a run of uppercase letters preceded by a lowercase letter + * (camelCase → camel + Case), but only when the run is followed by + * a lowercase letter (e.g. "DBStore" keeps "DB" together and breaks + * before "Store"). + * + * The regex uses zero-width look-behind/ahead so the actual characters + * are preserved in the output — only tags are inserted. + */ + function insertSmartBreaks(text) { + // Split text at break-opportunity points. + // The regex captures the delimiter so we can reassemble with + // after each delimiter character. + // + // Pattern pieces: + // ([._]) – capture a dot or underscore + // (\() – capture an opening paren + // (?<=[a-z])(?=[A-Z]) – zero-width camelCase boundary + // + // We use a two-pass approach because JS regex has limited support + // for look-behind in older runtimes. + + var result = document.createDocumentFragment(); + // Pattern: split around ".", "_", "(", and camelCase transitions + // Two camelCase lookarounds: + // (?<=[a-z])(?=[A-Z]) – lowercase-to-uppercase: "Duck|DB" + // (?<=[A-Z])(?=[A-Z][a-z]) – end of acronym run: "DB|Document" + var parts = text.split(/([._()])|(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/); + // Filter out empty/undefined entries produced by the regex split + var filtered = parts.filter(function (p) { return p !== undefined && p !== ''; }); + + // Merge parentheses onto preceding tokens to prevent orphan ")" or "()" + // e.g. ["directory", "(", ")"] → ["directory()"] + var merged = []; + for (var i = 0; i < filtered.length; i++) { + if (filtered[i] === '(' && i + 1 < filtered.length && filtered[i + 1] === ')') { + // "()" pair: attach to preceding token + if (merged.length > 0) { + merged[merged.length - 1] += '()'; + } else { + merged.push('()'); + } + i++; // skip the ")" + } else if (filtered[i] === ')') { + // lone ")": attach to preceding token + if (merged.length > 0) { + merged[merged.length - 1] += ')'; + } else { + merged.push(')'); + } + } else { + merged.push(filtered[i]); + } + } + + // Final pass: for any token still longer than 10 characters (e.g. + // all-lowercase names with no camelCase/separator break points), + // insert a every 10 characters as a fallback. + var CHUNK = 10; + for (var i = 0; i < merged.length; i++) { + var token = merged[i]; + if (token.length > CHUNK) { + for (var c = 0; c < token.length; c += CHUNK) { + if (c > 0) { + result.appendChild(document.createElement('wbr')); + } + result.appendChild(document.createTextNode(token.slice(c, c + CHUNK))); + } + } else { + result.appendChild(document.createTextNode(token)); + } + // Insert between every pair of adjacent parts. + if (i < merged.length - 1) { + result.appendChild(document.createElement('wbr')); + } + } + return result; + } + + /** + * Process all elements inside the sidebar. + */ + function processSidebar() { + var sidebar = document.getElementById('quarto-sidebar'); + if (!sidebar) return; + + var spans = sidebar.querySelectorAll('.menu-text'); + for (var i = 0; i < spans.length; i++) { + var span = spans[i]; + var text = span.textContent; + if (!text) continue; + // Only process items that contain separator characters, camelCase / + // acronym boundaries, or are simply too long to fit without wrapping. + // Skip plain short words like "API", "Classes". + var dominated = /[._()]/.test(text) || /[a-z][A-Z]/.test(text) || /[A-Z]{2,}[a-z]/.test(text); + if (!dominated && text.length <= 10) continue; + // Replace the text content with smart-break nodes + var fragment = insertSmartBreaks(text); + span.textContent = ''; + span.appendChild(fragment); + } + } + + /** + * Disable sidebar section collapsing by stripping Bootstrap collapse + * data attributes and ensuring all sections stay expanded. + */ + function disableSidebarCollapse() { + var sidebar = document.getElementById('quarto-sidebar'); + if (!sidebar) return; + + // Remove data-bs-toggle/target from all sidebar collapse triggers + var triggers = sidebar.querySelectorAll('[data-bs-toggle="collapse"]'); + for (var i = 0; i < triggers.length; i++) { + triggers[i].removeAttribute('data-bs-toggle'); + triggers[i].removeAttribute('data-bs-target'); + triggers[i].removeAttribute('aria-expanded'); + triggers[i].removeAttribute('role'); + } + + // Ensure all collapsible sections are permanently shown + var sections = sidebar.querySelectorAll('ul.collapse.sidebar-section'); + for (var j = 0; j < sections.length; j++) { + sections[j].classList.remove('collapse'); + sections[j].classList.add('show'); + } + } + + // Run after DOM is ready + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', function() { + processSidebar(); + disableSidebarCollapse(); + }); + } else { + processSidebar(); + disableSidebarCollapse(); + } +})(); diff --git a/docs/site_libs/bootstrap/bootstrap-b44a80f981ffe4e8ffda970bb00820f2.min.css b/docs/site_libs/bootstrap/bootstrap-b44a80f981ffe4e8ffda970bb00820f2.min.css new file mode 100644 index 0000000..1e3e058 --- /dev/null +++ b/docs/site_libs/bootstrap/bootstrap-b44a80f981ffe4e8ffda970bb00820f2.min.css @@ -0,0 +1,12 @@ +/*! + * Bootstrap v5.3.1 (https://getbootstrap.com/) + * Copyright 2011-2023 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */@import"https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap";:root,[data-bs-theme=light]{--bs-blue: #2c3e50;--bs-indigo: #6610f2;--bs-purple: #6f42c1;--bs-pink: #e83e8c;--bs-red: #e74c3c;--bs-orange: #fd7e14;--bs-yellow: #f39c12;--bs-green: #18bc9c;--bs-teal: #20c997;--bs-cyan: #3498db;--bs-black: #000;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #ecf0f1;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #7b8a8b;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-default: #6c757d;--bs-primary: #2c3e50;--bs-secondary: #6c757d;--bs-success: #18bc9c;--bs-info: #3498db;--bs-warning: #f39c12;--bs-danger: #e74c3c;--bs-light: #ecf0f1;--bs-dark: #7b8a8b;--bs-default-rgb: 108, 117, 125;--bs-primary-rgb: 44, 62, 80;--bs-secondary-rgb: 108, 117, 125;--bs-success-rgb: 24, 188, 156;--bs-info-rgb: 52, 152, 219;--bs-warning-rgb: 243, 156, 18;--bs-danger-rgb: 231, 76, 60;--bs-light-rgb: 236, 240, 241;--bs-dark-rgb: 123, 138, 139;--bs-primary-text-emphasis: rgb(17.6, 24.8, 32);--bs-secondary-text-emphasis: rgb(43.2, 46.8, 50);--bs-success-text-emphasis: rgb(9.6, 75.2, 62.4);--bs-info-text-emphasis: rgb(20.8, 60.8, 87.6);--bs-warning-text-emphasis: rgb(97.2, 62.4, 7.2);--bs-danger-text-emphasis: rgb(92.4, 30.4, 24);--bs-light-text-emphasis: #7b8a8b;--bs-dark-text-emphasis: #7b8a8b;--bs-primary-bg-subtle: rgb(212.8, 216.4, 220);--bs-secondary-bg-subtle: rgb(225.6, 227.4, 229);--bs-success-bg-subtle: rgb(208.8, 241.6, 235.2);--bs-info-bg-subtle: rgb(214.4, 234.4, 247.8);--bs-warning-bg-subtle: rgb(252.6, 235.2, 207.6);--bs-danger-bg-subtle: rgb(250.2, 219.2, 216);--bs-light-bg-subtle: rgb(251.5, 252, 252.5);--bs-dark-bg-subtle: #ced4da;--bs-primary-border-subtle: rgb(170.6, 177.8, 185);--bs-secondary-border-subtle: rgb(196.2, 199.8, 203);--bs-success-border-subtle: rgb(162.6, 228.2, 215.4);--bs-info-border-subtle: rgb(173.8, 213.8, 240.6);--bs-warning-border-subtle: rgb(250.2, 215.4, 160.2);--bs-danger-border-subtle: rgb(245.4, 183.4, 177);--bs-light-border-subtle: #ecf0f1;--bs-dark-border-subtle: #adb5bd;--bs-white-rgb: 255, 255, 255;--bs-black-rgb: 0, 0, 0;--bs-font-sans-serif: Lato, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-root-font-size: 17px;--bs-body-font-family: Lato, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--bs-body-font-size:1rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-color-rgb: 33, 37, 41;--bs-body-bg: #fff;--bs-body-bg-rgb: 255, 255, 255;--bs-emphasis-color: #000;--bs-emphasis-color-rgb: 0, 0, 0;--bs-secondary-color: rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb: 33, 37, 41;--bs-secondary-bg: #ecf0f1;--bs-secondary-bg-rgb: 236, 240, 241;--bs-tertiary-color: rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb: 33, 37, 41;--bs-tertiary-bg: #f8f9fa;--bs-tertiary-bg-rgb: 248, 249, 250;--bs-heading-color: inherit;--bs-link-color: #18bc9c;--bs-link-color-rgb: 24, 188, 156;--bs-link-decoration: underline;--bs-link-hover-color: rgb(19.2, 150.4, 124.8);--bs-link-hover-color-rgb: 19, 150, 125;--bs-code-color: #7d12ba;--bs-highlight-bg: rgb(252.6, 235.2, 207.6);--bs-border-width: 1px;--bs-border-style: solid;--bs-border-color: #dee2e6;--bs-border-color-translucent: rgba(0, 0, 0, 0.175);--bs-border-radius: 0.25rem;--bs-border-radius-sm: 0.2em;--bs-border-radius-lg: 0.5rem;--bs-border-radius-xl: 1rem;--bs-border-radius-xxl: 2rem;--bs-border-radius-2xl: var(--bs-border-radius-xxl);--bs-border-radius-pill: 50rem;--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width: 0.25rem;--bs-focus-ring-opacity: 0.25;--bs-focus-ring-color: rgba(44, 62, 80, 0.25);--bs-form-valid-color: #18bc9c;--bs-form-valid-border-color: #18bc9c;--bs-form-invalid-color: #e74c3c;--bs-form-invalid-border-color: #e74c3c}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color: #dee2e6;--bs-body-color-rgb: 222, 226, 230;--bs-body-bg: #212529;--bs-body-bg-rgb: 33, 37, 41;--bs-emphasis-color: #fff;--bs-emphasis-color-rgb: 255, 255, 255;--bs-secondary-color: rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb: 222, 226, 230;--bs-secondary-bg: #343a40;--bs-secondary-bg-rgb: 52, 58, 64;--bs-tertiary-color: rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb: 222, 226, 230;--bs-tertiary-bg: rgb(42.5, 47.5, 52.5);--bs-tertiary-bg-rgb: 43, 48, 53;--bs-primary-text-emphasis: rgb(128.4, 139.2, 150);--bs-secondary-text-emphasis: rgb(166.8, 172.2, 177);--bs-success-text-emphasis: rgb(116.4, 214.8, 195.6);--bs-info-text-emphasis: rgb(133.2, 193.2, 233.4);--bs-warning-text-emphasis: rgb(247.8, 195.6, 112.8);--bs-danger-text-emphasis: rgb(240.6, 147.6, 138);--bs-light-text-emphasis: #f8f9fa;--bs-dark-text-emphasis: #dee2e6;--bs-primary-bg-subtle: rgb(8.8, 12.4, 16);--bs-secondary-bg-subtle: rgb(21.6, 23.4, 25);--bs-success-bg-subtle: rgb(4.8, 37.6, 31.2);--bs-info-bg-subtle: rgb(10.4, 30.4, 43.8);--bs-warning-bg-subtle: rgb(48.6, 31.2, 3.6);--bs-danger-bg-subtle: rgb(46.2, 15.2, 12);--bs-light-bg-subtle: #343a40;--bs-dark-bg-subtle: #1a1d20;--bs-primary-border-subtle: rgb(26.4, 37.2, 48);--bs-secondary-border-subtle: rgb(64.8, 70.2, 75);--bs-success-border-subtle: rgb(14.4, 112.8, 93.6);--bs-info-border-subtle: rgb(31.2, 91.2, 131.4);--bs-warning-border-subtle: rgb(145.8, 93.6, 10.8);--bs-danger-border-subtle: rgb(138.6, 45.6, 36);--bs-light-border-subtle: #7b8a8b;--bs-dark-border-subtle: #343a40;--bs-heading-color: inherit;--bs-link-color: rgb(128.4, 139.2, 150);--bs-link-hover-color: rgb(153.72, 162.36, 171);--bs-link-color-rgb: 128, 139, 150;--bs-link-hover-color-rgb: 154, 162, 171;--bs-code-color: white;--bs-border-color: #7b8a8b;--bs-border-color-translucent: rgba(255, 255, 255, 0.15);--bs-form-valid-color: rgb(116.4, 214.8, 195.6);--bs-form-valid-border-color: rgb(116.4, 214.8, 195.6);--bs-form-invalid-color: rgb(240.6, 147.6, 138);--bs-form-invalid-border-color: rgb(240.6, 147.6, 138)}*,*::before,*::after{box-sizing:border-box}:root{font-size:var(--bs-root-font-size)}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}h6,.h6,h5,.h5,h4,.h4,h3,.h3,h2,.h2,h1,.h1{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}h1,.h1{font-size:calc(1.325rem + 0.9vw)}@media(min-width: 1200px){h1,.h1{font-size:2rem}}h2,.h2{font-size:calc(1.275rem + 0.3vw)}@media(min-width: 1200px){h2,.h2{font-size:1.5rem}}h3,.h3{font-size:calc(1.255rem + 0.06vw)}@media(min-width: 1200px){h3,.h3{font-size:1.3rem}}h4,.h4{font-size:1.25rem}h5,.h5{font-size:1.1rem}h6,.h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{text-decoration:underline dotted;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;-ms-text-decoration:underline dotted;-o-text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem;padding:.625rem 1.25rem;border-left:.25rem solid #ecf0f1}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}b,strong{font-weight:bolder}small,.small,.content span.doc-label::after{font-size:0.875em}mark,.mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:0.75em;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}a{color:rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}a:hover{--bs-link-color-rgb: var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:0.875em;color:#000;background-color:#f8f9fa;line-height:1.5;padding:.5rem;border:1px solid var(--bs-border-color, #dee2e6);border-radius:.25rem}pre code{background-color:rgba(0,0,0,0);font-size:inherit;color:inherit;word-break:normal}code{font-size:0.875em;color:var(--bs-code-color);background-color:#f8f9fa;border-radius:.25rem;padding:.125rem .25rem;word-wrap:break-word}a>code{color:inherit}kbd{padding:.4rem .4rem;font-size:0.875em;color:#fff;background-color:#212529;border-radius:.2em}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:rgba(33,37,41,.75);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none !important}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button:not(:disabled),[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + 0.3vw);line-height:inherit}@media(min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:0.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:0.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:0.875em;color:rgba(33,37,41,.75)}.container,.container-fluid,.container-xxl,.container-xl,.container-lg,.container-md,.container-sm{--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;width:100%;padding-right:calc(var(--bs-gutter-x)*.5);padding-left:calc(var(--bs-gutter-x)*.5);margin-right:auto;margin-left:auto}@media(min-width: 576px){.container-sm,.container{max-width:540px}}@media(min-width: 768px){.container-md,.container-sm,.container{max-width:720px}}@media(min-width: 992px){.container-lg,.container-md,.container-sm,.container{max-width:960px}}@media(min-width: 1200px){.container-xl,.container-lg,.container-md,.container-sm,.container{max-width:1140px}}@media(min-width: 1400px){.container-xxl,.container-xl,.container-lg,.container-md,.container-sm,.container{max-width:1320px}}:root{--bs-breakpoint-xs: 0;--bs-breakpoint-sm: 576px;--bs-breakpoint-md: 768px;--bs-breakpoint-lg: 992px;--bs-breakpoint-xl: 1200px;--bs-breakpoint-xxl: 1400px}.grid{display:grid;grid-template-rows:repeat(var(--bs-rows, 1), 1fr);grid-template-columns:repeat(var(--bs-columns, 12), 1fr);gap:var(--bs-gap, 1.5rem)}.grid .g-col-1{grid-column:auto/span 1}.grid .g-col-2{grid-column:auto/span 2}.grid .g-col-3{grid-column:auto/span 3}.grid .g-col-4{grid-column:auto/span 4}.grid .g-col-5{grid-column:auto/span 5}.grid .g-col-6{grid-column:auto/span 6}.grid .g-col-7{grid-column:auto/span 7}.grid .g-col-8{grid-column:auto/span 8}.grid .g-col-9{grid-column:auto/span 9}.grid .g-col-10{grid-column:auto/span 10}.grid .g-col-11{grid-column:auto/span 11}.grid .g-col-12{grid-column:auto/span 12}.grid .g-start-1{grid-column-start:1}.grid .g-start-2{grid-column-start:2}.grid .g-start-3{grid-column-start:3}.grid .g-start-4{grid-column-start:4}.grid .g-start-5{grid-column-start:5}.grid .g-start-6{grid-column-start:6}.grid .g-start-7{grid-column-start:7}.grid .g-start-8{grid-column-start:8}.grid .g-start-9{grid-column-start:9}.grid .g-start-10{grid-column-start:10}.grid .g-start-11{grid-column-start:11}@media(min-width: 576px){.grid .g-col-sm-1{grid-column:auto/span 1}.grid .g-col-sm-2{grid-column:auto/span 2}.grid .g-col-sm-3{grid-column:auto/span 3}.grid .g-col-sm-4{grid-column:auto/span 4}.grid .g-col-sm-5{grid-column:auto/span 5}.grid .g-col-sm-6{grid-column:auto/span 6}.grid .g-col-sm-7{grid-column:auto/span 7}.grid .g-col-sm-8{grid-column:auto/span 8}.grid .g-col-sm-9{grid-column:auto/span 9}.grid .g-col-sm-10{grid-column:auto/span 10}.grid .g-col-sm-11{grid-column:auto/span 11}.grid .g-col-sm-12{grid-column:auto/span 12}.grid .g-start-sm-1{grid-column-start:1}.grid .g-start-sm-2{grid-column-start:2}.grid .g-start-sm-3{grid-column-start:3}.grid .g-start-sm-4{grid-column-start:4}.grid .g-start-sm-5{grid-column-start:5}.grid .g-start-sm-6{grid-column-start:6}.grid .g-start-sm-7{grid-column-start:7}.grid .g-start-sm-8{grid-column-start:8}.grid .g-start-sm-9{grid-column-start:9}.grid .g-start-sm-10{grid-column-start:10}.grid .g-start-sm-11{grid-column-start:11}}@media(min-width: 768px){.grid .g-col-md-1{grid-column:auto/span 1}.grid .g-col-md-2{grid-column:auto/span 2}.grid .g-col-md-3{grid-column:auto/span 3}.grid .g-col-md-4{grid-column:auto/span 4}.grid .g-col-md-5{grid-column:auto/span 5}.grid .g-col-md-6{grid-column:auto/span 6}.grid .g-col-md-7{grid-column:auto/span 7}.grid .g-col-md-8{grid-column:auto/span 8}.grid .g-col-md-9{grid-column:auto/span 9}.grid .g-col-md-10{grid-column:auto/span 10}.grid .g-col-md-11{grid-column:auto/span 11}.grid .g-col-md-12{grid-column:auto/span 12}.grid .g-start-md-1{grid-column-start:1}.grid .g-start-md-2{grid-column-start:2}.grid .g-start-md-3{grid-column-start:3}.grid .g-start-md-4{grid-column-start:4}.grid .g-start-md-5{grid-column-start:5}.grid .g-start-md-6{grid-column-start:6}.grid .g-start-md-7{grid-column-start:7}.grid .g-start-md-8{grid-column-start:8}.grid .g-start-md-9{grid-column-start:9}.grid .g-start-md-10{grid-column-start:10}.grid .g-start-md-11{grid-column-start:11}}@media(min-width: 992px){.grid .g-col-lg-1{grid-column:auto/span 1}.grid .g-col-lg-2{grid-column:auto/span 2}.grid .g-col-lg-3{grid-column:auto/span 3}.grid .g-col-lg-4{grid-column:auto/span 4}.grid .g-col-lg-5{grid-column:auto/span 5}.grid .g-col-lg-6{grid-column:auto/span 6}.grid .g-col-lg-7{grid-column:auto/span 7}.grid .g-col-lg-8{grid-column:auto/span 8}.grid .g-col-lg-9{grid-column:auto/span 9}.grid .g-col-lg-10{grid-column:auto/span 10}.grid .g-col-lg-11{grid-column:auto/span 11}.grid .g-col-lg-12{grid-column:auto/span 12}.grid .g-start-lg-1{grid-column-start:1}.grid .g-start-lg-2{grid-column-start:2}.grid .g-start-lg-3{grid-column-start:3}.grid .g-start-lg-4{grid-column-start:4}.grid .g-start-lg-5{grid-column-start:5}.grid .g-start-lg-6{grid-column-start:6}.grid .g-start-lg-7{grid-column-start:7}.grid .g-start-lg-8{grid-column-start:8}.grid .g-start-lg-9{grid-column-start:9}.grid .g-start-lg-10{grid-column-start:10}.grid .g-start-lg-11{grid-column-start:11}}@media(min-width: 1200px){.grid .g-col-xl-1{grid-column:auto/span 1}.grid .g-col-xl-2{grid-column:auto/span 2}.grid .g-col-xl-3{grid-column:auto/span 3}.grid .g-col-xl-4{grid-column:auto/span 4}.grid .g-col-xl-5{grid-column:auto/span 5}.grid .g-col-xl-6{grid-column:auto/span 6}.grid .g-col-xl-7{grid-column:auto/span 7}.grid .g-col-xl-8{grid-column:auto/span 8}.grid .g-col-xl-9{grid-column:auto/span 9}.grid .g-col-xl-10{grid-column:auto/span 10}.grid .g-col-xl-11{grid-column:auto/span 11}.grid .g-col-xl-12{grid-column:auto/span 12}.grid .g-start-xl-1{grid-column-start:1}.grid .g-start-xl-2{grid-column-start:2}.grid .g-start-xl-3{grid-column-start:3}.grid .g-start-xl-4{grid-column-start:4}.grid .g-start-xl-5{grid-column-start:5}.grid .g-start-xl-6{grid-column-start:6}.grid .g-start-xl-7{grid-column-start:7}.grid .g-start-xl-8{grid-column-start:8}.grid .g-start-xl-9{grid-column-start:9}.grid .g-start-xl-10{grid-column-start:10}.grid .g-start-xl-11{grid-column-start:11}}@media(min-width: 1400px){.grid .g-col-xxl-1{grid-column:auto/span 1}.grid .g-col-xxl-2{grid-column:auto/span 2}.grid .g-col-xxl-3{grid-column:auto/span 3}.grid .g-col-xxl-4{grid-column:auto/span 4}.grid .g-col-xxl-5{grid-column:auto/span 5}.grid .g-col-xxl-6{grid-column:auto/span 6}.grid .g-col-xxl-7{grid-column:auto/span 7}.grid .g-col-xxl-8{grid-column:auto/span 8}.grid .g-col-xxl-9{grid-column:auto/span 9}.grid .g-col-xxl-10{grid-column:auto/span 10}.grid .g-col-xxl-11{grid-column:auto/span 11}.grid .g-col-xxl-12{grid-column:auto/span 12}.grid .g-start-xxl-1{grid-column-start:1}.grid .g-start-xxl-2{grid-column-start:2}.grid .g-start-xxl-3{grid-column-start:3}.grid .g-start-xxl-4{grid-column-start:4}.grid .g-start-xxl-5{grid-column-start:5}.grid .g-start-xxl-6{grid-column-start:6}.grid .g-start-xxl-7{grid-column-start:7}.grid .g-start-xxl-8{grid-column-start:8}.grid .g-start-xxl-9{grid-column-start:9}.grid .g-start-xxl-10{grid-column-start:10}.grid .g-start-xxl-11{grid-column-start:11}}.table,.doc-reference section.doc-group>dl{--bs-table-color-type: initial;--bs-table-bg-type: initial;--bs-table-color-state: initial;--bs-table-bg-state: initial;--bs-table-color: #212529;--bs-table-bg: #fff;--bs-table-border-color: #dee2e6;--bs-table-accent-bg: transparent;--bs-table-striped-color: #212529;--bs-table-striped-bg: rgba(0, 0, 0, 0.05);--bs-table-active-color: #212529;--bs-table-active-bg: rgba(0, 0, 0, 0.1);--bs-table-hover-color: #212529;--bs-table-hover-bg: rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*,.doc-reference section.doc-group>dl>:not(caption)>*>*{padding:.5rem .5rem;color:var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color)));background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state, var(--bs-table-bg-type, var(--bs-table-accent-bg)))}.table>tbody,.doc-reference section.doc-group>dl>tbody{vertical-align:inherit}.table>thead,.doc-reference section.doc-group>dl>thead{vertical-align:bottom}.table-group-divider{border-top:calc(1px*2) solid #909294}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*,table:not(.gt_table)>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*,table:not(.gt_table)>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type: var(--bs-table-striped-color);--bs-table-bg-type: var(--bs-table-striped-bg)}.table-striped-columns>:not(caption)>tr>:nth-child(even){--bs-table-color-type: var(--bs-table-striped-color);--bs-table-bg-type: var(--bs-table-striped-bg)}.table-active{--bs-table-color-state: var(--bs-table-active-color);--bs-table-bg-state: var(--bs-table-active-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state: var(--bs-table-hover-color);--bs-table-bg-state: var(--bs-table-hover-bg)}.table-primary{--bs-table-color: #fff;--bs-table-bg: #2c3e50;--bs-table-border-color: rgb(65.1, 81.3, 97.5);--bs-table-striped-bg: rgb(54.55, 71.65, 88.75);--bs-table-striped-color: #fff;--bs-table-active-bg: rgb(65.1, 81.3, 97.5);--bs-table-active-color: #fff;--bs-table-hover-bg: rgb(59.825, 76.475, 93.125);--bs-table-hover-color: #fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color: #fff;--bs-table-bg: #6c757d;--bs-table-border-color: rgb(122.7, 130.8, 138);--bs-table-striped-bg: rgb(115.35, 123.9, 131.5);--bs-table-striped-color: #fff;--bs-table-active-bg: rgb(122.7, 130.8, 138);--bs-table-active-color: #fff;--bs-table-hover-bg: rgb(119.025, 127.35, 134.75);--bs-table-hover-color: #fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color: #fff;--bs-table-bg: #18bc9c;--bs-table-border-color: rgb(47.1, 194.7, 165.9);--bs-table-striped-bg: rgb(35.55, 191.35, 160.95);--bs-table-striped-color: #fff;--bs-table-active-bg: rgb(47.1, 194.7, 165.9);--bs-table-active-color: #fff;--bs-table-hover-bg: rgb(41.325, 193.025, 163.425);--bs-table-hover-color: #fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color: #fff;--bs-table-bg: #3498db;--bs-table-border-color: rgb(72.3, 162.3, 222.6);--bs-table-striped-bg: rgb(62.15, 157.15, 220.8);--bs-table-striped-color: #fff;--bs-table-active-bg: rgb(72.3, 162.3, 222.6);--bs-table-active-color: #fff;--bs-table-hover-bg: rgb(67.225, 159.725, 221.7);--bs-table-hover-color: #fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color: #fff;--bs-table-bg: #f39c12;--bs-table-border-color: rgb(244.2, 165.9, 41.7);--bs-table-striped-bg: rgb(243.6, 160.95, 29.85);--bs-table-striped-color: #fff;--bs-table-active-bg: rgb(244.2, 165.9, 41.7);--bs-table-active-color: #000;--bs-table-hover-bg: rgb(243.9, 163.425, 35.775);--bs-table-hover-color: #fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color: #fff;--bs-table-bg: #e74c3c;--bs-table-border-color: rgb(233.4, 93.9, 79.5);--bs-table-striped-bg: rgb(232.2, 84.95, 69.75);--bs-table-striped-color: #fff;--bs-table-active-bg: rgb(233.4, 93.9, 79.5);--bs-table-active-color: #fff;--bs-table-hover-bg: rgb(232.8, 89.425, 74.625);--bs-table-hover-color: #fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color: #000;--bs-table-bg: #ecf0f1;--bs-table-border-color: rgb(212.4, 216, 216.9);--bs-table-striped-bg: rgb(224.2, 228, 228.95);--bs-table-striped-color: #000;--bs-table-active-bg: rgb(212.4, 216, 216.9);--bs-table-active-color: #000;--bs-table-hover-bg: rgb(218.3, 222, 222.925);--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color: #fff;--bs-table-bg: #7b8a8b;--bs-table-border-color: rgb(136.2, 149.7, 150.6);--bs-table-striped-bg: rgb(129.6, 143.85, 144.8);--bs-table-striped-color: #fff;--bs-table-active-bg: rgb(136.2, 149.7, 150.6);--bs-table-active-color: #fff;--bs-table-hover-bg: rgb(132.9, 146.775, 147.7);--bs-table-hover-color: #fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label,.shiny-input-container .control-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(0.375rem + 1px);padding-bottom:calc(0.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(0.5rem + 1px);padding-bottom:calc(0.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(0.25rem + 1px);padding-bottom:calc(0.25rem + 1px);font-size:0.875rem}.form-text{margin-top:.25rem;font-size:0.875em;color:rgba(33,37,41,.75)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:#fff;background-clip:padding-box;border:1px solid #dee2e6;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#212529;background-color:#fff;border-color:rgb(149.5,158.5,167.5);outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.form-control::-webkit-date-and-time-value{min-width:85px;height:1.5em;margin:0}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::placeholder{color:rgba(33,37,41,.75);opacity:1}.form-control:disabled{background-color:#ecf0f1;opacity:1}.form-control::file-selector-button{padding:.375rem .75rem;margin:-0.375rem -0.75rem;margin-inline-end:.75rem;color:#212529;background-color:#f8f9fa;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#ecf0f1}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#212529;background-color:rgba(0,0,0,0);border:solid rgba(0,0,0,0);border-width:1px 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + 0.5rem + calc(1px * 2));padding:.25rem .5rem;font-size:0.875rem;border-radius:.2em}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-0.25rem -0.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(1px * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-0.5rem -1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + 0.75rem + calc(1px * 2))}textarea.form-control-sm{min-height:calc(1.5em + 0.5rem + calc(1px * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(1px * 2))}.form-control-color{width:3rem;height:calc(1.5em + 0.75rem + calc(1px * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0 !important;border-radius:.25rem}.form-control-color::-webkit-color-swatch{border:0 !important;border-radius:.25rem}.form-control-color.form-control-sm{height:calc(1.5em + 0.5rem + calc(1px * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(1px * 2))}.form-select{--bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:#fff;background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon, none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #dee2e6;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:rgb(149.5,158.5,167.5);outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#ecf0f1}.form-select:-moz-focusring{color:rgba(0,0,0,0);text-shadow:0 0 0 #212529}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:0.875rem;border-radius:.2em}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.5rem}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check,.shiny-input-container .checkbox,.shiny-input-container .radio{display:block;min-height:1.5rem;padding-left:0;margin-bottom:.125rem}.form-check .form-check-input,.form-check .shiny-input-container .checkbox input,.form-check .shiny-input-container .radio input,.shiny-input-container .checkbox .form-check-input,.shiny-input-container .checkbox .shiny-input-container .checkbox input,.shiny-input-container .checkbox .shiny-input-container .radio input,.shiny-input-container .radio .form-check-input,.shiny-input-container .radio .shiny-input-container .checkbox input,.shiny-input-container .radio .shiny-input-container .radio input{float:left;margin-left:0}.form-check-reverse{padding-right:0;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:0;margin-left:0}.form-check-input,.shiny-input-container .checkbox input,.shiny-input-container .checkbox-inline input,.shiny-input-container .radio input,.shiny-input-container .radio-inline input{--bs-form-check-bg: #fff;width:1em;height:1em;margin-top:.25em;vertical-align:top;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid #dee2e6;print-color-adjust:exact}.form-check-input[type=checkbox],.shiny-input-container .checkbox input[type=checkbox],.shiny-input-container .checkbox-inline input[type=checkbox],.shiny-input-container .radio input[type=checkbox],.shiny-input-container .radio-inline input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio],.shiny-input-container .checkbox input[type=radio],.shiny-input-container .checkbox-inline input[type=radio],.shiny-input-container .radio input[type=radio],.shiny-input-container .radio-inline input[type=radio]{border-radius:50%}.form-check-input:active,.shiny-input-container .checkbox input:active,.shiny-input-container .checkbox-inline input:active,.shiny-input-container .radio input:active,.shiny-input-container .radio-inline input:active{filter:brightness(90%)}.form-check-input:focus,.shiny-input-container .checkbox input:focus,.shiny-input-container .checkbox-inline input:focus,.shiny-input-container .radio input:focus,.shiny-input-container .radio-inline input:focus{border-color:rgb(149.5,158.5,167.5);outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.form-check-input:checked,.shiny-input-container .checkbox input:checked,.shiny-input-container .checkbox-inline input:checked,.shiny-input-container .radio input:checked,.shiny-input-container .radio-inline input:checked{background-color:#2c3e50;border-color:#2c3e50}.form-check-input:checked[type=checkbox],.shiny-input-container .checkbox input:checked[type=checkbox],.shiny-input-container .checkbox-inline input:checked[type=checkbox],.shiny-input-container .radio input:checked[type=checkbox],.shiny-input-container .radio-inline input:checked[type=checkbox]{--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio],.shiny-input-container .checkbox input:checked[type=radio],.shiny-input-container .checkbox-inline input:checked[type=radio],.shiny-input-container .radio input:checked[type=radio],.shiny-input-container .radio-inline input:checked[type=radio]{--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate,.shiny-input-container .checkbox input[type=checkbox]:indeterminate,.shiny-input-container .checkbox-inline input[type=checkbox]:indeterminate,.shiny-input-container .radio input[type=checkbox]:indeterminate,.shiny-input-container .radio-inline input[type=checkbox]:indeterminate{background-color:#2c3e50;border-color:#2c3e50;--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled,.shiny-input-container .checkbox input:disabled,.shiny-input-container .checkbox-inline input:disabled,.shiny-input-container .radio input:disabled,.shiny-input-container .radio-inline input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled]~.form-check-label,.form-check-input[disabled]~span,.form-check-input:disabled~.form-check-label,.form-check-input:disabled~span,.shiny-input-container .checkbox input[disabled]~.form-check-label,.shiny-input-container .checkbox input[disabled]~span,.shiny-input-container .checkbox input:disabled~.form-check-label,.shiny-input-container .checkbox input:disabled~span,.shiny-input-container .checkbox-inline input[disabled]~.form-check-label,.shiny-input-container .checkbox-inline input[disabled]~span,.shiny-input-container .checkbox-inline input:disabled~.form-check-label,.shiny-input-container .checkbox-inline input:disabled~span,.shiny-input-container .radio input[disabled]~.form-check-label,.shiny-input-container .radio input[disabled]~span,.shiny-input-container .radio input:disabled~.form-check-label,.shiny-input-container .radio input:disabled~span,.shiny-input-container .radio-inline input[disabled]~.form-check-label,.shiny-input-container .radio-inline input[disabled]~span,.shiny-input-container .radio-inline input:disabled~.form-check-label,.shiny-input-container .radio-inline input:disabled~span{cursor:default;opacity:.5}.form-check-label,.shiny-input-container .checkbox label,.shiny-input-container .checkbox-inline label,.shiny-input-container .radio label,.shiny-input-container .radio-inline label{cursor:pointer}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgb%28149.5, 158.5, 167.5%29'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:rgba(0,0,0,0)}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(44,62,80,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(44,62,80,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-0.25rem;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:#2c3e50;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:rgb(191.7,197.1,202.5)}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#f8f9fa;border-color:rgba(0,0,0,0);border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:#2c3e50;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:rgb(191.7,197.1,202.5)}.form-range::-moz-range-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#f8f9fa;border-color:rgba(0,0,0,0);border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:rgba(33,37,41,.75)}.form-range:disabled::-moz-range-thumb{background-color:rgba(33,37,41,.75)}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(1px * 2));min-height:calc(3.5rem + calc(1px * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;z-index:2;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:1px solid rgba(0,0,0,0);transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media(prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control::placeholder,.form-floating>.form-control-plaintext::placeholder{color:rgba(0,0,0,0)}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown),.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill,.form-floating>.form-control-plaintext:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-control-plaintext~label,.form-floating>.form-select~label{color:rgba(var(--bs-body-color-rgb), 0.65);transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:focus~label::after,.form-floating>.form-control:not(:placeholder-shown)~label::after,.form-floating>.form-control-plaintext~label::after,.form-floating>.form-select~label::after{position:absolute;inset:1rem .375rem;z-index:-1;height:1.5em;content:"";background-color:#fff;border-radius:.25rem}.form-floating>.form-control:-webkit-autofill~label{color:rgba(var(--bs-body-color-rgb), 0.65);transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control-plaintext~label{border-width:1px 0}.form-floating>:disabled~label,.form-floating>.form-control:disabled~label{color:#6c757d}.form-floating>:disabled~label::after,.form-floating>.form-control:disabled~label::after{background-color:#ecf0f1}.input-group{position:relative;display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:stretch;-webkit-align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select,.input-group>.form-floating{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus,.input-group>.form-floating:focus-within{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:center;white-space:nowrap;background-color:#f8f9fa;border:1px solid #dee2e6;border-radius:.25rem}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:.25rem .5rem;font-size:0.875rem;border-radius:.2em}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select{border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(1px*-1);border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#18bc9c}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;color:#fff;background-color:#18bc9c;border-radius:.25rem}.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip,.is-valid~.valid-feedback,.is-valid~.valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#18bc9c;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2318bc9c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#18bc9c;box-shadow:0 0 0 .25rem rgba(24,188,156,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .form-select:valid,.form-select.is-valid{border-color:#18bc9c}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{--bs-form-select-bg-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2318bc9c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#18bc9c;box-shadow:0 0 0 .25rem rgba(24,188,156,.25)}.was-validated .form-control-color:valid,.form-control-color.is-valid{width:calc(3rem + calc(1.5em + 0.75rem))}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#18bc9c}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#18bc9c}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 .25rem rgba(24,188,156,.25)}.was-validated .form-check-input:valid~.form-check-label,.form-check-input.is-valid~.form-check-label{color:#18bc9c}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.was-validated .input-group>.form-control:not(:focus):valid,.input-group>.form-control:not(:focus).is-valid,.was-validated .input-group>.form-select:not(:focus):valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.input-group>.form-floating:not(:focus-within).is-valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#e74c3c}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;color:#fff;background-color:#e74c3c;border-radius:.25rem}.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip,.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#e74c3c;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#e74c3c}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.was-validated .form-control-color:invalid,.form-control-color.is-invalid{width:calc(3rem + calc(1.5em + 0.75rem))}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#e74c3c}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#e74c3c}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.was-validated .form-check-input:invalid~.form-check-label,.form-check-input.is-invalid~.form-check-label{color:#e74c3c}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.was-validated .input-group>.form-control:not(:focus):invalid,.input-group>.form-control:not(:focus).is-invalid,.was-validated .input-group>.form-select:not(:focus):invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.input-group>.form-floating:not(:focus-within).is-invalid{z-index:4}.btn{--bs-btn-padding-x: 0.75rem;--bs-btn-padding-y: 0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight: 400;--bs-btn-line-height: 1.5;--bs-btn-color: #212529;--bs-btn-bg: transparent;--bs-btn-border-width: 1px;--bs-btn-border-color: transparent;--bs-btn-border-radius: 0.25rem;--bs-btn-hover-border-color: transparent;--bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity: 0.65;--bs-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,:not(.btn-check)+.btn:active,.btn:first-child:active,.btn.active,.btn.show{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,:not(.btn-check)+.btn:active:focus-visible,.btn:first-child:active:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-default{--bs-btn-color: #fff;--bs-btn-bg: #6c757d;--bs-btn-border-color: #6c757d;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: rgb(91.8, 99.45, 106.25);--bs-btn-hover-border-color: rgb(86.4, 93.6, 100);--bs-btn-focus-shadow-rgb: 130, 138, 145;--bs-btn-active-color: #fff;--bs-btn-active-bg: rgb(86.4, 93.6, 100);--bs-btn-active-border-color: rgb(81, 87.75, 93.75);--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #6c757d;--bs-btn-disabled-border-color: #6c757d}.btn-primary{--bs-btn-color: #fff;--bs-btn-bg: #2c3e50;--bs-btn-border-color: #2c3e50;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: rgb(37.4, 52.7, 68);--bs-btn-hover-border-color: rgb(35.2, 49.6, 64);--bs-btn-focus-shadow-rgb: 76, 91, 106;--bs-btn-active-color: #fff;--bs-btn-active-bg: rgb(35.2, 49.6, 64);--bs-btn-active-border-color: rgb(33, 46.5, 60);--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #2c3e50;--bs-btn-disabled-border-color: #2c3e50}.btn-secondary{--bs-btn-color: #fff;--bs-btn-bg: #6c757d;--bs-btn-border-color: #6c757d;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: rgb(91.8, 99.45, 106.25);--bs-btn-hover-border-color: rgb(86.4, 93.6, 100);--bs-btn-focus-shadow-rgb: 130, 138, 145;--bs-btn-active-color: #fff;--bs-btn-active-bg: rgb(86.4, 93.6, 100);--bs-btn-active-border-color: rgb(81, 87.75, 93.75);--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #6c757d;--bs-btn-disabled-border-color: #6c757d}.btn-success{--bs-btn-color: #fff;--bs-btn-bg: #18bc9c;--bs-btn-border-color: #18bc9c;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: rgb(20.4, 159.8, 132.6);--bs-btn-hover-border-color: rgb(19.2, 150.4, 124.8);--bs-btn-focus-shadow-rgb: 59, 198, 171;--bs-btn-active-color: #fff;--bs-btn-active-bg: rgb(19.2, 150.4, 124.8);--bs-btn-active-border-color: #128d75;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #18bc9c;--bs-btn-disabled-border-color: #18bc9c}.btn-info{--bs-btn-color: #fff;--bs-btn-bg: #3498db;--bs-btn-border-color: #3498db;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: rgb(44.2, 129.2, 186.15);--bs-btn-hover-border-color: rgb(41.6, 121.6, 175.2);--bs-btn-focus-shadow-rgb: 82, 167, 224;--bs-btn-active-color: #fff;--bs-btn-active-bg: rgb(41.6, 121.6, 175.2);--bs-btn-active-border-color: rgb(39, 114, 164.25);--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #3498db;--bs-btn-disabled-border-color: #3498db}.btn-warning{--bs-btn-color: #fff;--bs-btn-bg: #f39c12;--bs-btn-border-color: #f39c12;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: rgb(206.55, 132.6, 15.3);--bs-btn-hover-border-color: rgb(194.4, 124.8, 14.4);--bs-btn-focus-shadow-rgb: 245, 171, 54;--bs-btn-active-color: #fff;--bs-btn-active-bg: rgb(194.4, 124.8, 14.4);--bs-btn-active-border-color: rgb(182.25, 117, 13.5);--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #f39c12;--bs-btn-disabled-border-color: #f39c12}.btn-danger{--bs-btn-color: #fff;--bs-btn-bg: #e74c3c;--bs-btn-border-color: #e74c3c;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: rgb(196.35, 64.6, 51);--bs-btn-hover-border-color: rgb(184.8, 60.8, 48);--bs-btn-focus-shadow-rgb: 235, 103, 89;--bs-btn-active-color: #fff;--bs-btn-active-bg: rgb(184.8, 60.8, 48);--bs-btn-active-border-color: rgb(173.25, 57, 45);--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #e74c3c;--bs-btn-disabled-border-color: #e74c3c}.btn-light{--bs-btn-color: #000;--bs-btn-bg: #ecf0f1;--bs-btn-border-color: #ecf0f1;--bs-btn-hover-color: #000;--bs-btn-hover-bg: rgb(200.6, 204, 204.85);--bs-btn-hover-border-color: rgb(188.8, 192, 192.8);--bs-btn-focus-shadow-rgb: 201, 204, 205;--bs-btn-active-color: #000;--bs-btn-active-bg: rgb(188.8, 192, 192.8);--bs-btn-active-border-color: rgb(177, 180, 180.75);--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #ecf0f1;--bs-btn-disabled-border-color: #ecf0f1}.btn-dark{--bs-btn-color: #fff;--bs-btn-bg: #7b8a8b;--bs-btn-border-color: #7b8a8b;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: rgb(142.8, 155.55, 156.4);--bs-btn-hover-border-color: rgb(136.2, 149.7, 150.6);--bs-btn-focus-shadow-rgb: 143, 156, 156;--bs-btn-active-color: #fff;--bs-btn-active-bg: rgb(149.4, 161.4, 162.2);--bs-btn-active-border-color: rgb(136.2, 149.7, 150.6);--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #7b8a8b;--bs-btn-disabled-border-color: #7b8a8b}.btn-outline-default{--bs-btn-color: #6c757d;--bs-btn-border-color: #6c757d;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #6c757d;--bs-btn-hover-border-color: #6c757d;--bs-btn-focus-shadow-rgb: 108, 117, 125;--bs-btn-active-color: #fff;--bs-btn-active-bg: #6c757d;--bs-btn-active-border-color: #6c757d;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #6c757d;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #6c757d;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-primary{--bs-btn-color: #2c3e50;--bs-btn-border-color: #2c3e50;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #2c3e50;--bs-btn-hover-border-color: #2c3e50;--bs-btn-focus-shadow-rgb: 44, 62, 80;--bs-btn-active-color: #fff;--bs-btn-active-bg: #2c3e50;--bs-btn-active-border-color: #2c3e50;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #2c3e50;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #2c3e50;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-secondary{--bs-btn-color: #6c757d;--bs-btn-border-color: #6c757d;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #6c757d;--bs-btn-hover-border-color: #6c757d;--bs-btn-focus-shadow-rgb: 108, 117, 125;--bs-btn-active-color: #fff;--bs-btn-active-bg: #6c757d;--bs-btn-active-border-color: #6c757d;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #6c757d;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #6c757d;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-success{--bs-btn-color: #18bc9c;--bs-btn-border-color: #18bc9c;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #18bc9c;--bs-btn-hover-border-color: #18bc9c;--bs-btn-focus-shadow-rgb: 24, 188, 156;--bs-btn-active-color: #fff;--bs-btn-active-bg: #18bc9c;--bs-btn-active-border-color: #18bc9c;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #18bc9c;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #18bc9c;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-info{--bs-btn-color: #3498db;--bs-btn-border-color: #3498db;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #3498db;--bs-btn-hover-border-color: #3498db;--bs-btn-focus-shadow-rgb: 52, 152, 219;--bs-btn-active-color: #fff;--bs-btn-active-bg: #3498db;--bs-btn-active-border-color: #3498db;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #3498db;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #3498db;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-warning{--bs-btn-color: #f39c12;--bs-btn-border-color: #f39c12;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #f39c12;--bs-btn-hover-border-color: #f39c12;--bs-btn-focus-shadow-rgb: 243, 156, 18;--bs-btn-active-color: #fff;--bs-btn-active-bg: #f39c12;--bs-btn-active-border-color: #f39c12;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #f39c12;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #f39c12;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-danger{--bs-btn-color: #e74c3c;--bs-btn-border-color: #e74c3c;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #e74c3c;--bs-btn-hover-border-color: #e74c3c;--bs-btn-focus-shadow-rgb: 231, 76, 60;--bs-btn-active-color: #fff;--bs-btn-active-bg: #e74c3c;--bs-btn-active-border-color: #e74c3c;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #e74c3c;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #e74c3c;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-light{--bs-btn-color: #ecf0f1;--bs-btn-border-color: #ecf0f1;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #ecf0f1;--bs-btn-hover-border-color: #ecf0f1;--bs-btn-focus-shadow-rgb: 236, 240, 241;--bs-btn-active-color: #000;--bs-btn-active-bg: #ecf0f1;--bs-btn-active-border-color: #ecf0f1;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #ecf0f1;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #ecf0f1;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-dark{--bs-btn-color: #7b8a8b;--bs-btn-border-color: #7b8a8b;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #7b8a8b;--bs-btn-hover-border-color: #7b8a8b;--bs-btn-focus-shadow-rgb: 123, 138, 139;--bs-btn-active-color: #fff;--bs-btn-active-bg: #7b8a8b;--bs-btn-active-border-color: #7b8a8b;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #7b8a8b;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #7b8a8b;--bs-btn-bg: transparent;--bs-gradient: none}.btn-link{--bs-btn-font-weight: 400;--bs-btn-color: #18bc9c;--bs-btn-bg: transparent;--bs-btn-border-color: transparent;--bs-btn-hover-color: rgb(19.2, 150.4, 124.8);--bs-btn-hover-border-color: transparent;--bs-btn-active-color: rgb(19.2, 150.4, 124.8);--bs-btn-active-border-color: transparent;--bs-btn-disabled-color: #6c757d;--bs-btn-disabled-border-color: transparent;--bs-btn-box-shadow: 0 0 0 #000;--bs-btn-focus-shadow-rgb: 59, 198, 171;text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-lg,.btn-group-lg>.btn{--bs-btn-padding-y: 0.5rem;--bs-btn-padding-x: 1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius: 0.5rem}.btn-sm,.btn-group-sm>.btn{--bs-btn-padding-y: 0.25rem;--bs-btn-padding-x: 0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius: 0.2em}.fade{transition:opacity .15s linear}@media(prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .2s ease}@media(prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media(prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}.dropup,.dropend,.dropdown,.dropstart,.dropup-center,.dropdown-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid rgba(0,0,0,0);border-bottom:0;border-left:.3em solid rgba(0,0,0,0)}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex: 1000;--bs-dropdown-min-width: 10rem;--bs-dropdown-padding-x: 0;--bs-dropdown-padding-y: 0.5rem;--bs-dropdown-spacer: 0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color: #212529;--bs-dropdown-bg: #fff;--bs-dropdown-border-color: rgba(0, 0, 0, 0.175);--bs-dropdown-border-radius: 0.25rem;--bs-dropdown-border-width: 1px;--bs-dropdown-inner-border-radius: calc(0.25rem - 1px);--bs-dropdown-divider-bg: rgba(0, 0, 0, 0.175);--bs-dropdown-divider-margin-y: 0.5rem;--bs-dropdown-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-dropdown-link-color: #7b8a8b;--bs-dropdown-link-hover-color: #fff;--bs-dropdown-link-hover-bg: #2c3e50;--bs-dropdown-link-active-color: #fff;--bs-dropdown-link-active-bg: #2c3e50;--bs-dropdown-link-disabled-color: rgba(33, 37, 41, 0.5);--bs-dropdown-item-padding-x: 1rem;--bs-dropdown-item-padding-y: 0.25rem;--bs-dropdown-header-color: #6c757d;--bs-dropdown-header-padding-x: 1rem;--bs-dropdown-header-padding-y: 0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media(min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid rgba(0,0,0,0);border-bottom:.3em solid;border-left:.3em solid rgba(0,0,0,0)}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid rgba(0,0,0,0);border-right:0;border-bottom:.3em solid rgba(0,0,0,0);border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid rgba(0,0,0,0);border-right:.3em solid;border-bottom:.3em solid rgba(0,0,0,0)}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;white-space:nowrap;background-color:rgba(0,0,0,0);border:0;border-radius:var(--bs-dropdown-item-border-radius, 0)}.dropdown-item:hover,.dropdown-item:focus{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:rgba(0,0,0,0)}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:0.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color: #dee2e6;--bs-dropdown-bg: #343a40;--bs-dropdown-border-color: rgba(0, 0, 0, 0.175);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color: #dee2e6;--bs-dropdown-link-hover-color: #fff;--bs-dropdown-divider-bg: rgba(0, 0, 0, 0.175);--bs-dropdown-link-hover-bg: rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color: #fff;--bs-dropdown-link-active-bg: #2c3e50;--bs-dropdown-link-disabled-color: #adb5bd;--bs-dropdown-header-color: #adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;justify-content:flex-start;-webkit-justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.25rem}.btn-group>:not(.btn-check:first-child)+.btn,.btn-group>.btn-group:not(:first-child){margin-left:calc(1px*-1)}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn,.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;-webkit-flex-direction:column;align-items:flex-start;-webkit-align-items:flex-start;justify-content:center;-webkit-justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:calc(1px*-1)}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn~.btn,.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x: 2rem;--bs-nav-link-padding-y: 0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color: #18bc9c;--bs-nav-link-hover-color: rgb(19.2, 150.4, 124.8);--bs-nav-link-disabled-color: #6c757d;display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background:none;border:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media(prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width: 1px;--bs-nav-tabs-border-color: #ecf0f1;--bs-nav-tabs-border-radius: 0.25rem;--bs-nav-tabs-link-hover-border-color: #ecf0f1 #ecf0f1 #ecf0f1;--bs-nav-tabs-link-active-color: #000;--bs-nav-tabs-link-active-bg: #fff;--bs-nav-tabs-link-active-border-color: #dee2e6 #dee2e6 #fff;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1*var(--bs-nav-tabs-border-width));border:var(--bs-nav-tabs-border-width) solid rgba(0,0,0,0);border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1*var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius: 0.25rem;--bs-nav-pills-link-active-color: #fff;--bs-nav-pills-link-active-bg: #2c3e50}.nav-pills .nav-link{border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-underline{--bs-nav-underline-gap: 1rem;--bs-nav-underline-border-width: 0.125rem;--bs-nav-underline-link-active-color: #000;gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{padding-right:0;padding-left:0;border-bottom:var(--bs-nav-underline-border-width) solid rgba(0,0,0,0)}.nav-underline .nav-link:hover,.nav-underline .nav-link:focus{border-bottom-color:currentcolor}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{font-weight:700;color:var(--bs-nav-underline-link-active-color);border-bottom-color:currentcolor}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;-webkit-flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;-webkit-flex-basis:0;flex-grow:1;-webkit-flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x: 0;--bs-navbar-padding-y: 1rem;--bs-navbar-color: rgb(204.36, 208.68, 213);--bs-navbar-hover-color: rgba(255, 255, 255, 0.8);--bs-navbar-disabled-color: rgba(204.36, 208.68, 213, 0.75);--bs-navbar-active-color: #fff;--bs-navbar-brand-padding-y: 0.3125rem;--bs-navbar-brand-margin-end: 1rem;--bs-navbar-brand-font-size: 1.25rem;--bs-navbar-brand-color: rgb(204.36, 208.68, 213);--bs-navbar-brand-hover-color: #fff;--bs-navbar-nav-link-padding-x: 0.5rem;--bs-navbar-toggler-padding-y: 0.25;--bs-navbar-toggler-padding-x: 0;--bs-navbar-toggler-font-size: 1.25rem;--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgb%28204.36, 208.68, 213%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color: rgba(204.36, 208.68, 213, 0);--bs-navbar-toggler-border-radius: 0.25rem;--bs-navbar-toggler-focus-width: 0.25rem;--bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out;position:relative;display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-sm,.navbar>.container-md,.navbar>.container-lg,.navbar>.container-xl,.navbar>.container-xxl{display:flex;display:-webkit-flex;flex-wrap:inherit;-webkit-flex-wrap:inherit;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;white-space:nowrap}.navbar-brand:hover,.navbar-brand:focus{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x: 0;--bs-nav-link-padding-y: 0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color: var(--bs-navbar-color);--bs-nav-link-hover-color: var(--bs-navbar-hover-color);--bs-nav-link-disabled-color: var(--bs-navbar-disabled-color);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:hover,.navbar-text a:focus{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;-webkit-flex-basis:100%;flex-grow:1;-webkit-flex-grow:1;align-items:center;-webkit-align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:rgba(0,0,0,0);border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media(prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media(min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}.navbar-dark,.navbar[data-bs-theme=dark]{--bs-navbar-color: rgb(204.36, 208.68, 213);--bs-navbar-hover-color: rgba(255, 255, 255, 0.8);--bs-navbar-disabled-color: rgba(204.36, 208.68, 213, 0.75);--bs-navbar-active-color: #fff;--bs-navbar-brand-color: rgb(204.36, 208.68, 213);--bs-navbar-brand-hover-color: #fff;--bs-navbar-toggler-border-color: rgba(204.36, 208.68, 213, 0);--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgb%28204.36, 208.68, 213%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar-toggler-icon{--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgb%28204.36, 208.68, 213%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y: 1rem;--bs-card-spacer-x: 1rem;--bs-card-title-spacer-y: 0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width: 1px;--bs-card-border-color: rgba(0, 0, 0, 0.175);--bs-card-border-radius: 0.25rem;--bs-card-box-shadow: ;--bs-card-inner-border-radius: calc(0.25rem - 1px);--bs-card-cap-padding-y: 0.5rem;--bs-card-cap-padding-x: 1rem;--bs-card-cap-bg: rgba(52, 58, 64, 0.25);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg: #fff;--bs-card-img-overlay-padding: 1rem;--bs-card-group-margin: 0.75rem;position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;-webkit-flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-0.5*var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-0.5*var(--bs-card-cap-padding-x));margin-bottom:calc(-1*var(--bs-card-cap-padding-y));margin-left:calc(-0.5*var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-0.5*var(--bs-card-cap-padding-x));margin-left:calc(-0.5*var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media(min-width: 576px){.card-group{display:flex;display:-webkit-flex;flex-flow:row wrap;-webkit-flex-flow:row wrap}.card-group>.card{flex:1 0 0%;-webkit-flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-img-top,.card-group>.card:not(:last-child) .card-header{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-img-bottom,.card-group>.card:not(:last-child) .card-footer{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-img-top,.card-group>.card:not(:first-child) .card-header{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-img-bottom,.card-group>.card:not(:first-child) .card-footer{border-bottom-left-radius:0}}.accordion{--bs-accordion-color: #212529;--bs-accordion-bg: #fff;--bs-accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;--bs-accordion-border-color: #dee2e6;--bs-accordion-border-width: 1px;--bs-accordion-border-radius: 0.25rem;--bs-accordion-inner-border-radius: calc(0.25rem - 1px);--bs-accordion-btn-padding-x: 1.25rem;--bs-accordion-btn-padding-y: 1rem;--bs-accordion-btn-color: #212529;--bs-accordion-btn-bg: #fff;--bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width: 1.25rem;--bs-accordion-btn-icon-transform: rotate(-180deg);--bs-accordion-btn-icon-transition: transform 0.2s ease-in-out;--bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='rgb%2817.6, 24.8, 32%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color: rgb(149.5, 158.5, 167.5);--bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(44, 62, 80, 0.25);--bs-accordion-body-padding-x: 1.25rem;--bs-accordion-body-padding-y: 1rem;--bs-accordion-active-color: rgb(17.6, 24.8, 32);--bs-accordion-active-bg: rgb(212.8, 216.4, 220)}.accordion-button{position:relative;display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media(prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1*var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;-webkit-flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media(prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='rgb%28128.4, 139.2, 150%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='rgb%28128.4, 139.2, 150%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x: 0.75rem;--bs-breadcrumb-padding-y: 0.375rem;--bs-breadcrumb-margin-bottom: 1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: 0.25rem;--bs-breadcrumb-divider-color: rgba(33, 37, 41, 0.75);--bs-breadcrumb-item-padding-x: 0.5rem;--bs-breadcrumb-item-active-color: rgba(33, 37, 41, 0.75);display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, ">") /* rtl: var(--bs-breadcrumb-divider, ">") */}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x: 0.75rem;--bs-pagination-padding-y: 0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color: #fff;--bs-pagination-bg: #18bc9c;--bs-pagination-border-width: 0;--bs-pagination-border-color: transparent;--bs-pagination-border-radius: 0.25rem;--bs-pagination-hover-color: #fff;--bs-pagination-hover-bg: rgb(15.3396226415, 120.1603773585, 99.7075471698);--bs-pagination-hover-border-color: transparent;--bs-pagination-focus-color: rgb(19.2, 150.4, 124.8);--bs-pagination-focus-bg: #ecf0f1;--bs-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(44, 62, 80, 0.25);--bs-pagination-active-color: #fff;--bs-pagination-active-bg: rgb(15.3396226415, 120.1603773585, 99.7075471698);--bs-pagination-active-border-color: transparent;--bs-pagination-disabled-color: #ecf0f1;--bs-pagination-disabled-bg: rgb(58.5754716981, 229.9245283019, 196.4905660377);--bs-pagination-disabled-border-color: transparent;display:flex;display:-webkit-flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.page-link.active,.active>.page-link{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.page-link.disabled,.disabled>.page-link{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(0*-1)}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x: 1.5rem;--bs-pagination-padding-y: 0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius: 0.5rem}.pagination-sm{--bs-pagination-padding-x: 0.5rem;--bs-pagination-padding-y: 0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius: 0.2em}.badge{--bs-badge-padding-x: 0.65em;--bs-badge-padding-y: 0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight: 700;--bs-badge-color: #fff;--bs-badge-border-radius: 0.25rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg: transparent;--bs-alert-padding-x: 1rem;--bs-alert-padding-y: 1rem;--bs-alert-margin-bottom: 1rem;--bs-alert-color: inherit;--bs-alert-border-color: transparent;--bs-alert-border: 1px solid var(--bs-alert-border-color);--bs-alert-border-radius: 0.25rem;--bs-alert-link-color: inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-default{--bs-alert-color: var(--bs-default-text-emphasis);--bs-alert-bg: var(--bs-default-bg-subtle);--bs-alert-border-color: var(--bs-default-border-subtle);--bs-alert-link-color: var(--bs-default-text-emphasis)}.alert-primary{--bs-alert-color: var(--bs-primary-text-emphasis);--bs-alert-bg: var(--bs-primary-bg-subtle);--bs-alert-border-color: var(--bs-primary-border-subtle);--bs-alert-link-color: var(--bs-primary-text-emphasis)}.alert-secondary{--bs-alert-color: var(--bs-secondary-text-emphasis);--bs-alert-bg: var(--bs-secondary-bg-subtle);--bs-alert-border-color: var(--bs-secondary-border-subtle);--bs-alert-link-color: var(--bs-secondary-text-emphasis)}.alert-success{--bs-alert-color: var(--bs-success-text-emphasis);--bs-alert-bg: var(--bs-success-bg-subtle);--bs-alert-border-color: var(--bs-success-border-subtle);--bs-alert-link-color: var(--bs-success-text-emphasis)}.alert-info{--bs-alert-color: var(--bs-info-text-emphasis);--bs-alert-bg: var(--bs-info-bg-subtle);--bs-alert-border-color: var(--bs-info-border-subtle);--bs-alert-link-color: var(--bs-info-text-emphasis)}.alert-warning{--bs-alert-color: var(--bs-warning-text-emphasis);--bs-alert-bg: var(--bs-warning-bg-subtle);--bs-alert-border-color: var(--bs-warning-border-subtle);--bs-alert-link-color: var(--bs-warning-text-emphasis)}.alert-danger{--bs-alert-color: var(--bs-danger-text-emphasis);--bs-alert-bg: var(--bs-danger-bg-subtle);--bs-alert-border-color: var(--bs-danger-border-subtle);--bs-alert-link-color: var(--bs-danger-text-emphasis)}.alert-light{--bs-alert-color: var(--bs-light-text-emphasis);--bs-alert-bg: var(--bs-light-bg-subtle);--bs-alert-border-color: var(--bs-light-border-subtle);--bs-alert-link-color: var(--bs-light-text-emphasis)}.alert-dark{--bs-alert-color: var(--bs-dark-text-emphasis);--bs-alert-bg: var(--bs-dark-bg-subtle);--bs-alert-border-color: var(--bs-dark-border-subtle);--bs-alert-link-color: var(--bs-dark-text-emphasis)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress,.progress-stacked{--bs-progress-height: 1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg: #ecf0f1;--bs-progress-border-radius: 0.25rem;--bs-progress-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-progress-bar-color: #fff;--bs-progress-bar-bg: #2c3e50;--bs-progress-bar-transition: width 0.6s ease;display:flex;display:-webkit-flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;justify-content:center;-webkit-justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media(prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media(prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color: #212529;--bs-list-group-bg: #fff;--bs-list-group-border-color: #dee2e6;--bs-list-group-border-width: 1px;--bs-list-group-border-radius: 0.25rem;--bs-list-group-item-padding-x: 1rem;--bs-list-group-item-padding-y: 0.5rem;--bs-list-group-action-color: rgba(33, 37, 41, 0.75);--bs-list-group-action-hover-color: #000;--bs-list-group-action-hover-bg: #ecf0f1;--bs-list-group-action-active-color: #212529;--bs-list-group-action-active-bg: #ecf0f1;--bs-list-group-disabled-color: rgba(33, 37, 41, 0.75);--bs-list-group-disabled-bg: #ecf0f1;--bs-list-group-active-color: #fff;--bs-list-group-active-bg: #2c3e50;--bs-list-group-active-border-color: #2c3e50;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1*var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media(min-width: 576px){.list-group-horizontal-sm{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width: 768px){.list-group-horizontal-md{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width: 992px){.list-group-horizontal-lg{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width: 1200px){.list-group-horizontal-xl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-default{--bs-list-group-color: var(--bs-default-text-emphasis);--bs-list-group-bg: var(--bs-default-bg-subtle);--bs-list-group-border-color: var(--bs-default-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-default-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-default-border-subtle);--bs-list-group-active-color: var(--bs-default-bg-subtle);--bs-list-group-active-bg: var(--bs-default-text-emphasis);--bs-list-group-active-border-color: var(--bs-default-text-emphasis)}.list-group-item-primary{--bs-list-group-color: var(--bs-primary-text-emphasis);--bs-list-group-bg: var(--bs-primary-bg-subtle);--bs-list-group-border-color: var(--bs-primary-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-primary-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-primary-border-subtle);--bs-list-group-active-color: var(--bs-primary-bg-subtle);--bs-list-group-active-bg: var(--bs-primary-text-emphasis);--bs-list-group-active-border-color: var(--bs-primary-text-emphasis)}.list-group-item-secondary{--bs-list-group-color: var(--bs-secondary-text-emphasis);--bs-list-group-bg: var(--bs-secondary-bg-subtle);--bs-list-group-border-color: var(--bs-secondary-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-secondary-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-secondary-border-subtle);--bs-list-group-active-color: var(--bs-secondary-bg-subtle);--bs-list-group-active-bg: var(--bs-secondary-text-emphasis);--bs-list-group-active-border-color: var(--bs-secondary-text-emphasis)}.list-group-item-success{--bs-list-group-color: var(--bs-success-text-emphasis);--bs-list-group-bg: var(--bs-success-bg-subtle);--bs-list-group-border-color: var(--bs-success-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-success-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-success-border-subtle);--bs-list-group-active-color: var(--bs-success-bg-subtle);--bs-list-group-active-bg: var(--bs-success-text-emphasis);--bs-list-group-active-border-color: var(--bs-success-text-emphasis)}.list-group-item-info{--bs-list-group-color: var(--bs-info-text-emphasis);--bs-list-group-bg: var(--bs-info-bg-subtle);--bs-list-group-border-color: var(--bs-info-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-info-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-info-border-subtle);--bs-list-group-active-color: var(--bs-info-bg-subtle);--bs-list-group-active-bg: var(--bs-info-text-emphasis);--bs-list-group-active-border-color: var(--bs-info-text-emphasis)}.list-group-item-warning{--bs-list-group-color: var(--bs-warning-text-emphasis);--bs-list-group-bg: var(--bs-warning-bg-subtle);--bs-list-group-border-color: var(--bs-warning-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-warning-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-warning-border-subtle);--bs-list-group-active-color: var(--bs-warning-bg-subtle);--bs-list-group-active-bg: var(--bs-warning-text-emphasis);--bs-list-group-active-border-color: var(--bs-warning-text-emphasis)}.list-group-item-danger{--bs-list-group-color: var(--bs-danger-text-emphasis);--bs-list-group-bg: var(--bs-danger-bg-subtle);--bs-list-group-border-color: var(--bs-danger-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-danger-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-danger-border-subtle);--bs-list-group-active-color: var(--bs-danger-bg-subtle);--bs-list-group-active-bg: var(--bs-danger-text-emphasis);--bs-list-group-active-border-color: var(--bs-danger-text-emphasis)}.list-group-item-light{--bs-list-group-color: var(--bs-light-text-emphasis);--bs-list-group-bg: var(--bs-light-bg-subtle);--bs-list-group-border-color: var(--bs-light-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-light-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-light-border-subtle);--bs-list-group-active-color: var(--bs-light-bg-subtle);--bs-list-group-active-bg: var(--bs-light-text-emphasis);--bs-list-group-active-border-color: var(--bs-light-text-emphasis)}.list-group-item-dark{--bs-list-group-color: var(--bs-dark-text-emphasis);--bs-list-group-bg: var(--bs-dark-bg-subtle);--bs-list-group-border-color: var(--bs-dark-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-dark-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-dark-border-subtle);--bs-list-group-active-color: var(--bs-dark-bg-subtle);--bs-list-group-active-bg: var(--bs-dark-text-emphasis);--bs-list-group-active-border-color: var(--bs-dark-text-emphasis)}.btn-close{--bs-btn-close-color: #fff;--bs-btn-close-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");--bs-btn-close-opacity: 0.4;--bs-btn-close-hover-opacity: 1;--bs-btn-close-focus-shadow: 0 0 0 0.25rem rgba(44, 62, 80, 0.25);--bs-btn-close-focus-opacity: 1;--bs-btn-close-disabled-opacity: 0.25;--bs-btn-close-white-filter: invert(1) grayscale(100%) brightness(200%);box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:var(--bs-btn-close-color);background:rgba(0,0,0,0) var(--bs-btn-close-bg) center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{filter:var(--bs-btn-close-white-filter)}[data-bs-theme=dark] .btn-close{filter:var(--bs-btn-close-white-filter)}.toast{--bs-toast-zindex: 1090;--bs-toast-padding-x: 0.75rem;--bs-toast-padding-y: 0.5rem;--bs-toast-spacing: 1.5rem;--bs-toast-max-width: 350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg: rgba(255, 255, 255, 0.85);--bs-toast-border-width: 1px;--bs-toast-border-color: rgba(0, 0, 0, 0.175);--bs-toast-border-radius: 0.25rem;--bs-toast-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-toast-header-color: rgba(33, 37, 41, 0.75);--bs-toast-header-bg: rgba(255, 255, 255, 0.85);--bs-toast-header-border-color: rgba(0, 0, 0, 0.175);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex: 1090;position:absolute;z-index:var(--bs-toast-zindex);width:max-content;width:-webkit-max-content;width:-moz-max-content;width:-ms-max-content;width:-o-max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-0.5*var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex: 1055;--bs-modal-width: 500px;--bs-modal-padding: 1rem;--bs-modal-margin: 0.5rem;--bs-modal-color: ;--bs-modal-bg: #fff;--bs-modal-border-color: rgba(0, 0, 0, 0.175);--bs-modal-border-width: 1px;--bs-modal-border-radius: 0.5rem;--bs-modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-modal-inner-border-radius: calc(0.5rem - 1px);--bs-modal-header-padding-x: 1rem;--bs-modal-header-padding-y: 1rem;--bs-modal-header-padding: 1rem 1rem;--bs-modal-header-border-color: #dee2e6;--bs-modal-header-border-width: 1px;--bs-modal-title-line-height: 1.5;--bs-modal-footer-gap: 0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color: #dee2e6;--bs-modal-footer-border-width: 1px;position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0, -50px)}@media(prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin)*2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;min-height:calc(100% - var(--bs-modal-margin)*2)}.modal-content{position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex: 1050;--bs-backdrop-bg: #000;--bs-backdrop-opacity: 0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;display:-webkit-flex;flex-shrink:0;-webkit-flex-shrink:0;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y)*.5) calc(var(--bs-modal-header-padding-x)*.5);margin:calc(-0.5*var(--bs-modal-header-padding-y)) calc(-0.5*var(--bs-modal-header-padding-x)) calc(-0.5*var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;display:-webkit-flex;flex-shrink:0;-webkit-flex-shrink:0;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:center;-webkit-align-items:center;justify-content:flex-end;-webkit-justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap)*.5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap)*.5)}@media(min-width: 576px){.modal{--bs-modal-margin: 1.75rem;--bs-modal-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width: 300px}}@media(min-width: 992px){.modal-lg,.modal-xl{--bs-modal-width: 800px}}@media(min-width: 1200px){.modal-xl{--bs-modal-width: 1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header,.modal-fullscreen .modal-footer{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media(max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header,.modal-fullscreen-sm-down .modal-footer{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media(max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header,.modal-fullscreen-md-down .modal-footer{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media(max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header,.modal-fullscreen-lg-down .modal-footer{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media(max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header,.modal-fullscreen-xl-down .modal-footer{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media(max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header,.modal-fullscreen-xxl-down .modal-footer{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex: 1080;--bs-tooltip-max-width: 200px;--bs-tooltip-padding-x: 0.5rem;--bs-tooltip-padding-y: 0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color: #fff;--bs-tooltip-bg: #000;--bs-tooltip-border-radius: 0.25rem;--bs-tooltip-opacity: 0.9;--bs-tooltip-arrow-width: 0.8rem;--bs-tooltip-arrow-height: 0.4rem;z-index:var(--bs-tooltip-zindex);display:block;margin:var(--bs-tooltip-margin);font-family:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:rgba(0,0,0,0);border-style:solid}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow{bottom:calc(-1*var(--bs-tooltip-arrow-height))}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width)*.5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow{left:calc(-1*var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width)*.5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow{top:calc(-1*var(--bs-tooltip-arrow-height))}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow{right:calc(-1*var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width)*.5) 0 calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex: 1070;--bs-popover-max-width: 276px;--bs-popover-font-size:0.875rem;--bs-popover-bg: #fff;--bs-popover-border-width: 1px;--bs-popover-border-color: rgba(0, 0, 0, 0.175);--bs-popover-border-radius: 0.5rem;--bs-popover-inner-border-radius: calc(0.5rem - 1px);--bs-popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-popover-header-padding-x: 1rem;--bs-popover-header-padding-y: 0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color: inherit;--bs-popover-header-bg: #ecf0f1;--bs-popover-body-padding-x: 1rem;--bs-popover-body-padding-y: 1rem;--bs-popover-body-color: #212529;--bs-popover-arrow-width: 1rem;--bs-popover-arrow-height: 0.5rem;--bs-popover-arrow-border: var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:rgba(0,0,0,0);border-style:solid;border-width:0}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow{bottom:calc(-1*(var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width)*.5) 0}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow{left:calc(-1*(var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after{border-width:calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width)*.5) 0}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow{top:calc(-1*(var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after{border-width:0 calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-0.5*var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow{right:calc(-1*(var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after{border-width:calc(var(--bs-popover-arrow-width)*.5) 0 calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height)}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y;-webkit-touch-action:pan-y;-moz-touch-action:pan-y;-ms-touch-action:pan-y;-o-touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;transition:transform .6s ease-in-out}@media(prefers-reduced-motion: reduce){.carousel-item{transition:none}}.carousel-item.active,.carousel-item-next,.carousel-item-prev{display:block}.carousel-item-next:not(.carousel-item-start),.active.carousel-item-end{transform:translateX(100%)}.carousel-item-prev:not(.carousel-item-end),.active.carousel-item-start{transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item.active,.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end{z-index:1;opacity:1}.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{z-index:0;opacity:0;transition:opacity 0s .6s}@media(prefers-reduced-motion: reduce){.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{transition:none}}.carousel-control-prev,.carousel-control-next{position:absolute;top:0;bottom:0;z-index:1;display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;justify-content:center;-webkit-justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:none;border:0;opacity:.5;transition:opacity .15s ease}@media(prefers-reduced-motion: reduce){.carousel-control-prev,.carousel-control-next{transition:none}}.carousel-control-prev:hover,.carousel-control-prev:focus,.carousel-control-next:hover,.carousel-control-next:focus{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-prev-icon,.carousel-control-next-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;display:-webkit-flex;justify-content:center;-webkit-justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;-webkit-flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid rgba(0,0,0,0);border-bottom:10px solid rgba(0,0,0,0);opacity:.5;transition:opacity .6s ease}@media(prefers-reduced-motion: reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-prev-icon,.carousel-dark .carousel-control-next-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}[data-bs-theme=dark] .carousel .carousel-control-prev-icon,[data-bs-theme=dark] .carousel .carousel-control-next-icon,[data-bs-theme=dark].carousel .carousel-control-prev-icon,[data-bs-theme=dark].carousel .carousel-control-next-icon{filter:invert(1) grayscale(100)}[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target],[data-bs-theme=dark].carousel .carousel-indicators [data-bs-target]{background-color:#000}[data-bs-theme=dark] .carousel .carousel-caption,[data-bs-theme=dark].carousel .carousel-caption{color:#000}.spinner-grow,.spinner-border{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{--bs-spinner-width: 2rem;--bs-spinner-height: 2rem;--bs-spinner-vertical-align: -0.125em;--bs-spinner-border-width: 0.25em;--bs-spinner-animation-speed: 0.75s;--bs-spinner-animation-name: spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:rgba(0,0,0,0)}.spinner-border-sm{--bs-spinner-width: 1rem;--bs-spinner-height: 1rem;--bs-spinner-border-width: 0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width: 2rem;--bs-spinner-height: 2rem;--bs-spinner-vertical-align: -0.125em;--bs-spinner-animation-speed: 0.75s;--bs-spinner-animation-name: spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width: 1rem;--bs-spinner-height: 1rem}@media(prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed: 1.5s}}.offcanvas,.offcanvas-xxl,.offcanvas-xl,.offcanvas-lg,.offcanvas-md,.offcanvas-sm{--bs-offcanvas-zindex: 1045;--bs-offcanvas-width: 400px;--bs-offcanvas-height: 30vh;--bs-offcanvas-padding-x: 1rem;--bs-offcanvas-padding-y: 1rem;--bs-offcanvas-color: #212529;--bs-offcanvas-bg: #fff;--bs-offcanvas-border-width: 1px;--bs-offcanvas-border-color: rgba(0, 0, 0, 0.175);--bs-offcanvas-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-offcanvas-transition: transform 0.3s ease-in-out;--bs-offcanvas-title-line-height: 1.5}@media(max-width: 575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 575.98px)and (prefers-reduced-motion: reduce){.offcanvas-sm{transition:none}}@media(max-width: 575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.showing,.offcanvas-sm.show:not(.hiding){transform:none}.offcanvas-sm.showing,.offcanvas-sm.hiding,.offcanvas-sm.show{visibility:visible}}@media(min-width: 576px){.offcanvas-sm{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}@media(max-width: 767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 767.98px)and (prefers-reduced-motion: reduce){.offcanvas-md{transition:none}}@media(max-width: 767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.showing,.offcanvas-md.show:not(.hiding){transform:none}.offcanvas-md.showing,.offcanvas-md.hiding,.offcanvas-md.show{visibility:visible}}@media(min-width: 768px){.offcanvas-md{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}@media(max-width: 991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 991.98px)and (prefers-reduced-motion: reduce){.offcanvas-lg{transition:none}}@media(max-width: 991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.showing,.offcanvas-lg.show:not(.hiding){transform:none}.offcanvas-lg.showing,.offcanvas-lg.hiding,.offcanvas-lg.show{visibility:visible}}@media(min-width: 992px){.offcanvas-lg{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}@media(max-width: 1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 1199.98px)and (prefers-reduced-motion: reduce){.offcanvas-xl{transition:none}}@media(max-width: 1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.showing,.offcanvas-xl.show:not(.hiding){transform:none}.offcanvas-xl.showing,.offcanvas-xl.hiding,.offcanvas-xl.show{visibility:visible}}@media(min-width: 1200px){.offcanvas-xl{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}@media(max-width: 1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 1399.98px)and (prefers-reduced-motion: reduce){.offcanvas-xxl{transition:none}}@media(max-width: 1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xxl.showing,.offcanvas-xxl.show:not(.hiding){transform:none}.offcanvas-xxl.showing,.offcanvas-xxl.hiding,.offcanvas-xxl.show{visibility:visible}}@media(min-width: 1400px){.offcanvas-xxl{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media(prefers-reduced-motion: reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.showing,.offcanvas.show:not(.hiding){transform:none}.offcanvas.showing,.offcanvas.hiding,.offcanvas.show{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y)*.5) calc(var(--bs-offcanvas-padding-x)*.5);margin-top:calc(-0.5*var(--bs-offcanvas-padding-y));margin-right:calc(-0.5*var(--bs-offcanvas-padding-x));margin-bottom:calc(-0.5*var(--bs-offcanvas-padding-y))}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;-webkit-flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{mask-image:linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);-webkit-mask-image:linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);mask-size:200% 100%;-webkit-mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{mask-position:-200% 0%;-webkit-mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-default{color:#fff !important;background-color:RGBA(var(--bs-default-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-primary{color:#fff !important;background-color:RGBA(var(--bs-primary-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-secondary{color:#fff !important;background-color:RGBA(var(--bs-secondary-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-success{color:#fff !important;background-color:RGBA(var(--bs-success-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-info{color:#fff !important;background-color:RGBA(var(--bs-info-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-warning{color:#fff !important;background-color:RGBA(var(--bs-warning-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-danger{color:#fff !important;background-color:RGBA(var(--bs-danger-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-light{color:#000 !important;background-color:RGBA(var(--bs-light-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-dark{color:#fff !important;background-color:RGBA(var(--bs-dark-rgb), var(--bs-bg-opacity, 1)) !important}.link-default{color:RGBA(var(--bs-default-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-default-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-default:hover,.link-default:focus{color:RGBA(86, 94, 100, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(86, 94, 100, var(--bs-link-underline-opacity, 1)) !important}.link-primary{color:RGBA(var(--bs-primary-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-primary-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-primary:hover,.link-primary:focus{color:RGBA(35, 50, 64, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(35, 50, 64, var(--bs-link-underline-opacity, 1)) !important}.link-secondary{color:RGBA(var(--bs-secondary-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-secondary-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-secondary:hover,.link-secondary:focus{color:RGBA(86, 94, 100, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(86, 94, 100, var(--bs-link-underline-opacity, 1)) !important}.link-success{color:RGBA(var(--bs-success-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-success-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-success:hover,.link-success:focus{color:RGBA(19, 150, 125, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(19, 150, 125, var(--bs-link-underline-opacity, 1)) !important}.link-info{color:RGBA(var(--bs-info-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-info-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-info:hover,.link-info:focus{color:RGBA(42, 122, 175, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(42, 122, 175, var(--bs-link-underline-opacity, 1)) !important}.link-warning{color:RGBA(var(--bs-warning-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-warning-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-warning:hover,.link-warning:focus{color:RGBA(194, 125, 14, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(194, 125, 14, var(--bs-link-underline-opacity, 1)) !important}.link-danger{color:RGBA(var(--bs-danger-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-danger-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-danger:hover,.link-danger:focus{color:RGBA(185, 61, 48, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(185, 61, 48, var(--bs-link-underline-opacity, 1)) !important}.link-light{color:RGBA(var(--bs-light-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-light-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-light:hover,.link-light:focus{color:RGBA(240, 243, 244, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(240, 243, 244, var(--bs-link-underline-opacity, 1)) !important}.link-dark{color:RGBA(var(--bs-dark-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-dark-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-dark:hover,.link-dark:focus{color:RGBA(98, 110, 111, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(98, 110, 111, var(--bs-link-underline-opacity, 1)) !important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-body-emphasis:hover,.link-body-emphasis:focus{color:RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-opacity, 0.75)) !important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 0.75)) !important}.focus-ring:focus{outline:0;box-shadow:var(--bs-focus-ring-x, 0) var(--bs-focus-ring-y, 0) var(--bs-focus-ring-blur, 0) var(--bs-focus-ring-width) var(--bs-focus-ring-color)}.icon-link{display:inline-flex;gap:.375rem;align-items:center;-webkit-align-items:center;text-decoration-color:rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 0.5));text-underline-offset:.25em;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden}.icon-link>.bi{flex-shrink:0;-webkit-flex-shrink:0;width:1em;height:1em;fill:currentcolor;transition:.2s ease-in-out transform}@media(prefers-reduced-motion: reduce){.icon-link>.bi{transition:none}}.icon-link-hover:hover>.bi,.icon-link-hover:focus-visible>.bi{transform:var(--bs-icon-link-transform, translate3d(0.25em, 0, 0))}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: 75%}.ratio-16x9{--bs-aspect-ratio: 56.25%}.ratio-21x9{--bs-aspect-ratio: 42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}.sticky-bottom{position:sticky;bottom:0;z-index:1020}@media(min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;display:-webkit-flex;flex-direction:row;-webkit-flex-direction:row;align-items:center;-webkit-align-items:center;align-self:stretch;-webkit-align-self:stretch}.vstack{display:flex;display:-webkit-flex;flex:1 1 auto;-webkit-flex:1 1 auto;flex-direction:column;-webkit-flex-direction:column;align-self:stretch;-webkit-align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.visually-hidden:not(caption),.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption){position:absolute !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;-webkit-align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.object-fit-contain{object-fit:contain !important}.object-fit-cover{object-fit:cover !important}.object-fit-fill{object-fit:fill !important}.object-fit-scale{object-fit:scale-down !important}.object-fit-none{object-fit:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.overflow-x-auto{overflow-x:auto !important}.overflow-x-hidden{overflow-x:hidden !important}.overflow-x-visible{overflow-x:visible !important}.overflow-x-scroll{overflow-x:scroll !important}.overflow-y-auto{overflow-y:auto !important}.overflow-y-hidden{overflow-y:hidden !important}.overflow-y-visible{overflow-y:visible !important}.overflow-y-scroll{overflow-y:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-inline-grid{display:inline-grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15) !important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175) !important}.shadow-none{box-shadow:none !important}.focus-ring-default{--bs-focus-ring-color: rgba(var(--bs-default-rgb), var(--bs-focus-ring-opacity))}.focus-ring-primary{--bs-focus-ring-color: rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-secondary{--bs-focus-ring-color: rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-success{--bs-focus-ring-color: rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity))}.focus-ring-info{--bs-focus-ring-color: rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity))}.focus-ring-warning{--bs-focus-ring-color: rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity))}.focus-ring-danger{--bs-focus-ring-color: rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity))}.focus-ring-light{--bs-focus-ring-color: rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity))}.focus-ring-dark{--bs-focus-ring-color: rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity))}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-0{border:0 !important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-top-0{border-top:0 !important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-start-0{border-left:0 !important}.border-default{--bs-border-opacity: 1;border-color:rgba(var(--bs-default-rgb), var(--bs-border-opacity)) !important}.border-primary{--bs-border-opacity: 1;border-color:rgba(var(--bs-primary-rgb), var(--bs-border-opacity)) !important}.border-secondary{--bs-border-opacity: 1;border-color:rgba(var(--bs-secondary-rgb), var(--bs-border-opacity)) !important}.border-success{--bs-border-opacity: 1;border-color:rgba(var(--bs-success-rgb), var(--bs-border-opacity)) !important}.border-info{--bs-border-opacity: 1;border-color:rgba(var(--bs-info-rgb), var(--bs-border-opacity)) !important}.border-warning{--bs-border-opacity: 1;border-color:rgba(var(--bs-warning-rgb), var(--bs-border-opacity)) !important}.border-danger{--bs-border-opacity: 1;border-color:rgba(var(--bs-danger-rgb), var(--bs-border-opacity)) !important}.border-light{--bs-border-opacity: 1;border-color:rgba(var(--bs-light-rgb), var(--bs-border-opacity)) !important}.border-dark{--bs-border-opacity: 1;border-color:rgba(var(--bs-dark-rgb), var(--bs-border-opacity)) !important}.border-black{--bs-border-opacity: 1;border-color:rgba(var(--bs-black-rgb), var(--bs-border-opacity)) !important}.border-white{--bs-border-opacity: 1;border-color:rgba(var(--bs-white-rgb), var(--bs-border-opacity)) !important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle) !important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle) !important}.border-success-subtle{border-color:var(--bs-success-border-subtle) !important}.border-info-subtle{border-color:var(--bs-info-border-subtle) !important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle) !important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle) !important}.border-light-subtle{border-color:var(--bs-light-border-subtle) !important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle) !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.border-opacity-10{--bs-border-opacity: 0.1}.border-opacity-25{--bs-border-opacity: 0.25}.border-opacity-50{--bs-border-opacity: 0.5}.border-opacity-75{--bs-border-opacity: 0.75}.border-opacity-100{--bs-border-opacity: 1}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3,.doc-signature>p:first-child{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3,:is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dl>dt:not(:first-child),h5,.h5{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0,:is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dl>dd{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2,header p{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1,.doc-text dt code{padding:.25rem !important}.p-2,.doc-signature>p:first-child code{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1,span.doc-object-name:is(.doc-class-name,.doc-method-name,.doc-module-name,.doc-function-name,.doc-alias-name,.doc-attribute-name,.doc-type-name,.doc-typevar)::before{padding-right:.25rem !important;padding-left:.25rem !important}.px-2,:is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dl>dd>table td{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1,:is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dl>dd>table td{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4,section.doc-attributes>section.doc-attribute,section.doc-methods>section.doc-method{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.row-gap-0{row-gap:0 !important}.row-gap-1{row-gap:.25rem !important}.row-gap-2{row-gap:.5rem !important}.row-gap-3{row-gap:1rem !important}.row-gap-4{row-gap:1.5rem !important}.row-gap-5{row-gap:3rem !important}.column-gap-0{column-gap:0 !important}.column-gap-1{column-gap:.25rem !important}.column-gap-2{column-gap:.5rem !important}.column-gap-3{column-gap:1rem !important}.column-gap-4{column-gap:1.5rem !important}.column-gap-5{column-gap:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.325rem + 0.9vw) !important}.fs-2{font-size:calc(1.275rem + 0.3vw) !important}.fs-3{font-size:calc(1.255rem + 0.06vw) !important}.fs-4{font-size:1.25rem !important}.fs-5{font-size:1.1rem !important}.fs-6{font-size:1rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-lighter{font-weight:lighter !important}.fw-light{font-weight:300 !important}.fw-normal,.content span.doc-label::after{font-weight:400 !important}.fw-medium,h1,.h1,.h2,h2,h3,.h3{font-weight:500 !important}.fw-semibold{font-weight:600 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-default{--bs-text-opacity: 1;color:rgba(var(--bs-default-rgb), var(--bs-text-opacity)) !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--bs-secondary-color) !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,.5) !important}.text-white-50{--bs-text-opacity: 1;color:hsla(0,0%,100%,.5) !important}.text-body-secondary{--bs-text-opacity: 1;color:var(--bs-secondary-color) !important}.text-body-tertiary{--bs-text-opacity: 1;color:var(--bs-tertiary-color) !important}.text-body-emphasis{--bs-text-opacity: 1;color:var(--bs-emphasis-color) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: 0.25}.text-opacity-50{--bs-text-opacity: 0.5}.text-opacity-75{--bs-text-opacity: 0.75}.text-opacity-100{--bs-text-opacity: 1}.text-primary-emphasis{color:var(--bs-primary-text-emphasis) !important}.text-secondary-emphasis{color:var(--bs-secondary-text-emphasis) !important}.text-success-emphasis{color:var(--bs-success-text-emphasis) !important}.text-info-emphasis{color:var(--bs-info-text-emphasis) !important}.text-warning-emphasis{color:var(--bs-warning-text-emphasis) !important}.text-danger-emphasis{color:var(--bs-danger-text-emphasis) !important}.text-light-emphasis{color:var(--bs-light-text-emphasis) !important}.text-dark-emphasis{color:var(--bs-dark-text-emphasis) !important}.link-opacity-10{--bs-link-opacity: 0.1}.link-opacity-10-hover:hover{--bs-link-opacity: 0.1}.link-opacity-25{--bs-link-opacity: 0.25}.link-opacity-25-hover:hover{--bs-link-opacity: 0.25}.link-opacity-50{--bs-link-opacity: 0.5}.link-opacity-50-hover:hover{--bs-link-opacity: 0.5}.link-opacity-75{--bs-link-opacity: 0.75}.link-opacity-75-hover:hover{--bs-link-opacity: 0.75}.link-opacity-100{--bs-link-opacity: 1}.link-opacity-100-hover:hover{--bs-link-opacity: 1}.link-offset-1{text-underline-offset:.125em !important}.link-offset-1-hover:hover{text-underline-offset:.125em !important}.link-offset-2{text-underline-offset:.25em !important}.link-offset-2-hover:hover{text-underline-offset:.25em !important}.link-offset-3{text-underline-offset:.375em !important}.link-offset-3-hover:hover{text-underline-offset:.375em !important}.link-underline-default{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-default-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-primary{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-primary-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-secondary{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-secondary-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-success{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-success-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-info{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-info-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-warning{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-warning-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-danger{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-danger-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-light{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-light-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-dark{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-dark-rgb), var(--bs-link-underline-opacity)) !important}.link-underline{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-link-color-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-underline-opacity-0{--bs-link-underline-opacity: 0}.link-underline-opacity-0-hover:hover{--bs-link-underline-opacity: 0}.link-underline-opacity-10{--bs-link-underline-opacity: 0.1}.link-underline-opacity-10-hover:hover{--bs-link-underline-opacity: 0.1}.link-underline-opacity-25{--bs-link-underline-opacity: 0.25}.link-underline-opacity-25-hover:hover{--bs-link-underline-opacity: 0.25}.link-underline-opacity-50{--bs-link-underline-opacity: 0.5}.link-underline-opacity-50-hover:hover{--bs-link-underline-opacity: 0.5}.link-underline-opacity-75{--bs-link-underline-opacity: 0.75}.link-underline-opacity-75-hover:hover{--bs-link-underline-opacity: 0.75}.link-underline-opacity-100{--bs-link-underline-opacity: 1}.link-underline-opacity-100-hover:hover{--bs-link-underline-opacity: 1}.bg-default{--bs-bg-opacity: 1;background-color:rgba(var(--bs-default-rgb), var(--bs-bg-opacity)) !important}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:rgba(0,0,0,0) !important}.bg-body-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-bg-rgb), var(--bs-bg-opacity)) !important}.bg-body-tertiary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-tertiary-bg-rgb), var(--bs-bg-opacity)) !important}.bg-opacity-10{--bs-bg-opacity: 0.1}.bg-opacity-25{--bs-bg-opacity: 0.25}.bg-opacity-50{--bs-bg-opacity: 0.5}.bg-opacity-75{--bs-bg-opacity: 0.75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle) !important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle) !important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle) !important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle) !important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle) !important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle) !important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle) !important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle) !important}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:var(--bs-border-radius) !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:var(--bs-border-radius-sm) !important}.rounded-2{border-radius:var(--bs-border-radius) !important}.rounded-3{border-radius:var(--bs-border-radius-lg) !important}.rounded-4{border-radius:var(--bs-border-radius-xl) !important}.rounded-5{border-radius:var(--bs-border-radius-xxl) !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:var(--bs-border-radius-pill) !important}.rounded-top{border-top-left-radius:var(--bs-border-radius) !important;border-top-right-radius:var(--bs-border-radius) !important}.rounded-top-0{border-top-left-radius:0 !important;border-top-right-radius:0 !important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm) !important;border-top-right-radius:var(--bs-border-radius-sm) !important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius) !important;border-top-right-radius:var(--bs-border-radius) !important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg) !important;border-top-right-radius:var(--bs-border-radius-lg) !important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl) !important;border-top-right-radius:var(--bs-border-radius-xl) !important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-xxl) !important;border-top-right-radius:var(--bs-border-radius-xxl) !important}.rounded-top-circle{border-top-left-radius:50% !important;border-top-right-radius:50% !important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill) !important;border-top-right-radius:var(--bs-border-radius-pill) !important}.rounded-end{border-top-right-radius:var(--bs-border-radius) !important;border-bottom-right-radius:var(--bs-border-radius) !important}.rounded-end-0{border-top-right-radius:0 !important;border-bottom-right-radius:0 !important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm) !important;border-bottom-right-radius:var(--bs-border-radius-sm) !important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius) !important;border-bottom-right-radius:var(--bs-border-radius) !important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg) !important;border-bottom-right-radius:var(--bs-border-radius-lg) !important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl) !important;border-bottom-right-radius:var(--bs-border-radius-xl) !important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-xxl) !important;border-bottom-right-radius:var(--bs-border-radius-xxl) !important}.rounded-end-circle{border-top-right-radius:50% !important;border-bottom-right-radius:50% !important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill) !important;border-bottom-right-radius:var(--bs-border-radius-pill) !important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius) !important;border-bottom-left-radius:var(--bs-border-radius) !important}.rounded-bottom-0{border-bottom-right-radius:0 !important;border-bottom-left-radius:0 !important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm) !important;border-bottom-left-radius:var(--bs-border-radius-sm) !important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius) !important;border-bottom-left-radius:var(--bs-border-radius) !important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg) !important;border-bottom-left-radius:var(--bs-border-radius-lg) !important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl) !important;border-bottom-left-radius:var(--bs-border-radius-xl) !important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-xxl) !important;border-bottom-left-radius:var(--bs-border-radius-xxl) !important}.rounded-bottom-circle{border-bottom-right-radius:50% !important;border-bottom-left-radius:50% !important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill) !important;border-bottom-left-radius:var(--bs-border-radius-pill) !important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius) !important;border-top-left-radius:var(--bs-border-radius) !important}.rounded-start-0{border-bottom-left-radius:0 !important;border-top-left-radius:0 !important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm) !important;border-top-left-radius:var(--bs-border-radius-sm) !important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius) !important;border-top-left-radius:var(--bs-border-radius) !important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg) !important;border-top-left-radius:var(--bs-border-radius-lg) !important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl) !important;border-top-left-radius:var(--bs-border-radius-xl) !important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-xxl) !important;border-top-left-radius:var(--bs-border-radius-xxl) !important}.rounded-start-circle{border-bottom-left-radius:50% !important;border-top-left-radius:50% !important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill) !important;border-top-left-radius:var(--bs-border-radius-pill) !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}.z-n1{z-index:-1 !important}.z-0{z-index:0 !important}.z-1{z-index:1 !important}.z-2{z-index:2 !important}.z-3{z-index:3 !important}@media(min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.object-fit-sm-contain{object-fit:contain !important}.object-fit-sm-cover{object-fit:cover !important}.object-fit-sm-fill{object-fit:fill !important}.object-fit-sm-scale{object-fit:scale-down !important}.object-fit-sm-none{object-fit:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-inline-grid{display:inline-grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.row-gap-sm-0{row-gap:0 !important}.row-gap-sm-1{row-gap:.25rem !important}.row-gap-sm-2{row-gap:.5rem !important}.row-gap-sm-3{row-gap:1rem !important}.row-gap-sm-4{row-gap:1.5rem !important}.row-gap-sm-5{row-gap:3rem !important}.column-gap-sm-0{column-gap:0 !important}.column-gap-sm-1{column-gap:.25rem !important}.column-gap-sm-2{column-gap:.5rem !important}.column-gap-sm-3{column-gap:1rem !important}.column-gap-sm-4{column-gap:1.5rem !important}.column-gap-sm-5{column-gap:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media(min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.object-fit-md-contain{object-fit:contain !important}.object-fit-md-cover{object-fit:cover !important}.object-fit-md-fill{object-fit:fill !important}.object-fit-md-scale{object-fit:scale-down !important}.object-fit-md-none{object-fit:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-inline-grid{display:inline-grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.row-gap-md-0{row-gap:0 !important}.row-gap-md-1{row-gap:.25rem !important}.row-gap-md-2{row-gap:.5rem !important}.row-gap-md-3{row-gap:1rem !important}.row-gap-md-4{row-gap:1.5rem !important}.row-gap-md-5{row-gap:3rem !important}.column-gap-md-0{column-gap:0 !important}.column-gap-md-1{column-gap:.25rem !important}.column-gap-md-2{column-gap:.5rem !important}.column-gap-md-3{column-gap:1rem !important}.column-gap-md-4{column-gap:1.5rem !important}.column-gap-md-5{column-gap:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media(min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.object-fit-lg-contain{object-fit:contain !important}.object-fit-lg-cover{object-fit:cover !important}.object-fit-lg-fill{object-fit:fill !important}.object-fit-lg-scale{object-fit:scale-down !important}.object-fit-lg-none{object-fit:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-inline-grid{display:inline-grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.row-gap-lg-0{row-gap:0 !important}.row-gap-lg-1{row-gap:.25rem !important}.row-gap-lg-2{row-gap:.5rem !important}.row-gap-lg-3{row-gap:1rem !important}.row-gap-lg-4{row-gap:1.5rem !important}.row-gap-lg-5{row-gap:3rem !important}.column-gap-lg-0{column-gap:0 !important}.column-gap-lg-1{column-gap:.25rem !important}.column-gap-lg-2{column-gap:.5rem !important}.column-gap-lg-3{column-gap:1rem !important}.column-gap-lg-4{column-gap:1.5rem !important}.column-gap-lg-5{column-gap:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media(min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.object-fit-xl-contain{object-fit:contain !important}.object-fit-xl-cover{object-fit:cover !important}.object-fit-xl-fill{object-fit:fill !important}.object-fit-xl-scale{object-fit:scale-down !important}.object-fit-xl-none{object-fit:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-inline-grid{display:inline-grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.row-gap-xl-0{row-gap:0 !important}.row-gap-xl-1{row-gap:.25rem !important}.row-gap-xl-2{row-gap:.5rem !important}.row-gap-xl-3{row-gap:1rem !important}.row-gap-xl-4{row-gap:1.5rem !important}.row-gap-xl-5{row-gap:3rem !important}.column-gap-xl-0{column-gap:0 !important}.column-gap-xl-1{column-gap:.25rem !important}.column-gap-xl-2{column-gap:.5rem !important}.column-gap-xl-3{column-gap:1rem !important}.column-gap-xl-4{column-gap:1.5rem !important}.column-gap-xl-5{column-gap:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media(min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.object-fit-xxl-contain{object-fit:contain !important}.object-fit-xxl-cover{object-fit:cover !important}.object-fit-xxl-fill{object-fit:fill !important}.object-fit-xxl-scale{object-fit:scale-down !important}.object-fit-xxl-none{object-fit:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-inline-grid{display:inline-grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.row-gap-xxl-0{row-gap:0 !important}.row-gap-xxl-1{row-gap:.25rem !important}.row-gap-xxl-2{row-gap:.5rem !important}.row-gap-xxl-3{row-gap:1rem !important}.row-gap-xxl-4{row-gap:1.5rem !important}.row-gap-xxl-5{row-gap:3rem !important}.column-gap-xxl-0{column-gap:0 !important}.column-gap-xxl-1{column-gap:.25rem !important}.column-gap-xxl-2{column-gap:.5rem !important}.column-gap-xxl-3{column-gap:1rem !important}.column-gap-xxl-4{column-gap:1.5rem !important}.column-gap-xxl-5{column-gap:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}.bg-default{color:#fff}.bg-primary{color:#fff}.bg-secondary{color:#fff}.bg-success{color:#fff}.bg-info{color:#fff}.bg-warning{color:#fff}.bg-danger{color:#fff}.bg-light{color:#000}.bg-dark{color:#fff}@media(min-width: 1200px){.fs-1{font-size:2rem !important}.fs-2{font-size:1.5rem !important}.fs-3{font-size:1.3rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-inline-grid{display:inline-grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}:root{--bslib-spacer: 1rem;--bslib-mb-spacer: var(--bslib-spacer, 1rem)}.bslib-mb-spacing{margin-bottom:var(--bslib-mb-spacer)}.bslib-gap-spacing{gap:var(--bslib-mb-spacer)}.bslib-gap-spacing>.bslib-mb-spacing,.bslib-gap-spacing>.form-group,.bslib-gap-spacing>p,.bslib-gap-spacing>pre{margin-bottom:0}.html-fill-container>.html-fill-item.bslib-mb-spacing{margin-bottom:0}.tab-content>.tab-pane.html-fill-container{display:none}.tab-content>.active.html-fill-container{display:flex}.tab-content.html-fill-container{padding:0}.bg-blue{--bslib-color-bg: #2c3e50;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-blue{--bslib-color-fg: #2c3e50;color:var(--bslib-color-fg)}.bg-indigo{--bslib-color-bg: #6610f2;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-indigo{--bslib-color-fg: #6610f2;color:var(--bslib-color-fg)}.bg-purple{--bslib-color-bg: #6f42c1;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-purple{--bslib-color-fg: #6f42c1;color:var(--bslib-color-fg)}.bg-pink{--bslib-color-bg: #e83e8c;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-pink{--bslib-color-fg: #e83e8c;color:var(--bslib-color-fg)}.bg-red{--bslib-color-bg: #e74c3c;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-red{--bslib-color-fg: #e74c3c;color:var(--bslib-color-fg)}.bg-orange{--bslib-color-bg: #fd7e14;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-orange{--bslib-color-fg: #fd7e14;color:var(--bslib-color-fg)}.bg-yellow{--bslib-color-bg: #f39c12;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-yellow{--bslib-color-fg: #f39c12;color:var(--bslib-color-fg)}.bg-green{--bslib-color-bg: #18bc9c;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-green{--bslib-color-fg: #18bc9c;color:var(--bslib-color-fg)}.bg-teal{--bslib-color-bg: #20c997;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-teal{--bslib-color-fg: #20c997;color:var(--bslib-color-fg)}.bg-cyan{--bslib-color-bg: #3498db;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-cyan{--bslib-color-fg: #3498db;color:var(--bslib-color-fg)}.text-default{--bslib-color-fg: #6c757d}.bg-default{--bslib-color-bg: #6c757d;--bslib-color-fg: #fff}.text-primary{--bslib-color-fg: #2c3e50}.bg-primary{--bslib-color-bg: #2c3e50;--bslib-color-fg: #fff}.text-secondary{--bslib-color-fg: #6c757d}.bg-secondary{--bslib-color-bg: #6c757d;--bslib-color-fg: #fff}.text-success{--bslib-color-fg: #18bc9c}.bg-success{--bslib-color-bg: #18bc9c;--bslib-color-fg: #fff}.text-info{--bslib-color-fg: #3498db}.bg-info{--bslib-color-bg: #3498db;--bslib-color-fg: #fff}.text-warning{--bslib-color-fg: #f39c12}.bg-warning{--bslib-color-bg: #f39c12;--bslib-color-fg: #fff}.text-danger{--bslib-color-fg: #e74c3c}.bg-danger{--bslib-color-bg: #e74c3c;--bslib-color-fg: #fff}.text-light{--bslib-color-fg: #ecf0f1}.bg-light{--bslib-color-bg: #ecf0f1;--bslib-color-fg: #000}.text-dark{--bslib-color-fg: #7b8a8b}.bg-dark{--bslib-color-bg: #7b8a8b;--bslib-color-fg: #fff}.bg-gradient-blue-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(67.2, 43.6, 144.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(67.2,43.6,144.8);color:#fff}.bg-gradient-blue-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(70.8, 63.6, 125.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(70.8,63.6,125.2);color:#fff}.bg-gradient-blue-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(119.2, 62, 104);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(119.2,62,104);color:#fff}.bg-gradient-blue-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(118.8, 67.6, 72);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(118.8,67.6,72);color:#fff}.bg-gradient-blue-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(127.6, 87.6, 56);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(127.6,87.6,56);color:#fff}.bg-gradient-blue-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(123.6, 99.6, 55.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(123.6,99.6,55.2);color:#fff}.bg-gradient-blue-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(36, 112.4, 110.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(36,112.4,110.4);color:#fff}.bg-gradient-blue-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(39.2, 117.6, 108.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(39.2,117.6,108.4);color:#fff}.bg-gradient-blue-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(47.2, 98, 135.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(47.2,98,135.6);color:#fff}.bg-gradient-indigo-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(78.8, 34.4, 177.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(78.8,34.4,177.2);color:#fff}.bg-gradient-indigo-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(105.6, 36, 222.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(105.6,36,222.4);color:#fff}.bg-gradient-indigo-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(154, 34.4, 201.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(154,34.4,201.2);color:#fff}.bg-gradient-indigo-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(153.6, 40, 169.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(153.6,40,169.2);color:#fff}.bg-gradient-indigo-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(162.4, 60, 153.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(162.4,60,153.2);color:#fff}.bg-gradient-indigo-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(158.4, 72, 152.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(158.4,72,152.4);color:#fff}.bg-gradient-indigo-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(70.8, 84.8, 207.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(70.8,84.8,207.6);color:#fff}.bg-gradient-indigo-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(74, 90, 205.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(74,90,205.6);color:#fff}.bg-gradient-indigo-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(82, 70.4, 232.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(82,70.4,232.8);color:#fff}.bg-gradient-purple-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(84.2, 64.4, 147.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(84.2,64.4,147.8);color:#fff}.bg-gradient-purple-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(107.4, 46, 212.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(107.4,46,212.6);color:#fff}.bg-gradient-purple-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(159.4, 64.4, 171.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(159.4,64.4,171.8);color:#fff}.bg-gradient-purple-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(159, 70, 139.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(159,70,139.8);color:#fff}.bg-gradient-purple-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(167.8, 90, 123.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(167.8,90,123.8);color:#fff}.bg-gradient-purple-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(163.8, 102, 123);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(163.8,102,123);color:#fff}.bg-gradient-purple-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(76.2, 114.8, 178.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(76.2,114.8,178.2);color:#fff}.bg-gradient-purple-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(79.4, 120, 176.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(79.4,120,176.2);color:#fff}.bg-gradient-purple-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(87.4, 100.4, 203.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(87.4,100.4,203.4);color:#fff}.bg-gradient-pink-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(156.8, 62, 116);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(156.8,62,116);color:#fff}.bg-gradient-pink-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(180, 43.6, 180.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(180,43.6,180.8);color:#fff}.bg-gradient-pink-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(183.6, 63.6, 161.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(183.6,63.6,161.2);color:#fff}.bg-gradient-pink-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(231.6, 67.6, 108);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(231.6,67.6,108);color:#fff}.bg-gradient-pink-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(240.4, 87.6, 92);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(240.4,87.6,92);color:#fff}.bg-gradient-pink-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(236.4, 99.6, 91.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(236.4,99.6,91.2);color:#fff}.bg-gradient-pink-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(148.8, 112.4, 146.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(148.8,112.4,146.4);color:#fff}.bg-gradient-pink-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(152, 117.6, 144.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(152,117.6,144.4);color:#fff}.bg-gradient-pink-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(160, 98, 171.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(160,98,171.6);color:#fff}.bg-gradient-red-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(156.2, 70.4, 68);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(156.2,70.4,68);color:#fff}.bg-gradient-red-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(179.4, 52, 132.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(179.4,52,132.8);color:#fff}.bg-gradient-red-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(183, 72, 113.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(183,72,113.2);color:#fff}.bg-gradient-red-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(231.4, 70.4, 92);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(231.4,70.4,92);color:#fff}.bg-gradient-red-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(239.8, 96, 44);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(239.8,96,44);color:#fff}.bg-gradient-red-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(235.8, 108, 43.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(235.8,108,43.2);color:#fff}.bg-gradient-red-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(148.2, 120.8, 98.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(148.2,120.8,98.4);color:#fff}.bg-gradient-red-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(151.4, 126, 96.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(151.4,126,96.4);color:#fff}.bg-gradient-red-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(159.4, 106.4, 123.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(159.4,106.4,123.6);color:#fff}.bg-gradient-orange-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(169.4, 100.4, 44);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(169.4,100.4,44);color:#fff}.bg-gradient-orange-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(192.6, 82, 108.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(192.6,82,108.8);color:#fff}.bg-gradient-orange-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(196.2, 102, 89.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(196.2,102,89.2);color:#fff}.bg-gradient-orange-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(244.6, 100.4, 68);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(244.6,100.4,68);color:#fff}.bg-gradient-orange-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(244.2, 106, 36);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(244.2,106,36);color:#fff}.bg-gradient-orange-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(249, 138, 19.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(249,138,19.2);color:#fff}.bg-gradient-orange-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(161.4, 150.8, 74.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(161.4,150.8,74.4);color:#fff}.bg-gradient-orange-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(164.6, 156, 72.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(164.6,156,72.4);color:#fff}.bg-gradient-orange-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(172.6, 136.4, 99.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(172.6,136.4,99.6);color:#fff}.bg-gradient-yellow-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(163.4, 118.4, 42.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(163.4,118.4,42.8);color:#fff}.bg-gradient-yellow-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(186.6, 100, 107.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(186.6,100,107.6);color:#fff}.bg-gradient-yellow-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(190.2, 120, 88);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(190.2,120,88);color:#fff}.bg-gradient-yellow-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(238.6, 118.4, 66.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(238.6,118.4,66.8);color:#fff}.bg-gradient-yellow-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(238.2, 124, 34.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(238.2,124,34.8);color:#fff}.bg-gradient-yellow-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(247, 144, 18.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(247,144,18.8);color:#fff}.bg-gradient-yellow-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(155.4, 168.8, 73.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(155.4,168.8,73.2);color:#fff}.bg-gradient-yellow-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(158.6, 174, 71.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(158.6,174,71.2);color:#fff}.bg-gradient-yellow-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(166.6, 154.4, 98.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(166.6,154.4,98.4);color:#fff}.bg-gradient-green-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(32, 137.6, 125.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(32,137.6,125.6);color:#fff}.bg-gradient-green-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(55.2, 119.2, 190.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(55.2,119.2,190.4);color:#fff}.bg-gradient-green-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(58.8, 139.2, 170.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(58.8,139.2,170.8);color:#fff}.bg-gradient-green-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(107.2, 137.6, 149.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(107.2,137.6,149.6);color:#fff}.bg-gradient-green-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(106.8, 143.2, 117.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(106.8,143.2,117.6);color:#fff}.bg-gradient-green-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(115.6, 163.2, 101.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(115.6,163.2,101.6);color:#fff}.bg-gradient-green-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(111.6, 175.2, 100.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(111.6,175.2,100.8);color:#fff}.bg-gradient-green-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(27.2, 193.2, 154);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(27.2,193.2,154);color:#fff}.bg-gradient-green-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(35.2, 173.6, 181.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(35.2,173.6,181.2);color:#fff}.bg-gradient-teal-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(36.8, 145.4, 122.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(36.8,145.4,122.6);color:#fff}.bg-gradient-teal-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(60, 127, 187.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(60,127,187.4);color:#fff}.bg-gradient-teal-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(63.6, 147, 167.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(63.6,147,167.8);color:#fff}.bg-gradient-teal-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(112, 145.4, 146.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(112,145.4,146.6);color:#fff}.bg-gradient-teal-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(111.6, 151, 114.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(111.6,151,114.6);color:#fff}.bg-gradient-teal-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(120.4, 171, 98.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(120.4,171,98.6);color:#fff}.bg-gradient-teal-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(116.4, 183, 97.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(116.4,183,97.8);color:#fff}.bg-gradient-teal-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(28.8, 195.8, 153);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(28.8,195.8,153);color:#fff}.bg-gradient-teal-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(40, 181.4, 178.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(40,181.4,178.2);color:#fff}.bg-gradient-cyan-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(48.8, 116, 163.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(48.8,116,163.4);color:#fff}.bg-gradient-cyan-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(72, 97.6, 228.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(72,97.6,228.2);color:#fff}.bg-gradient-cyan-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(75.6, 117.6, 208.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(75.6,117.6,208.6);color:#fff}.bg-gradient-cyan-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(124, 116, 187.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(124,116,187.4);color:#fff}.bg-gradient-cyan-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(123.6, 121.6, 155.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(123.6,121.6,155.4);color:#fff}.bg-gradient-cyan-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(132.4, 141.6, 139.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(132.4,141.6,139.4);color:#fff}.bg-gradient-cyan-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(128.4, 153.6, 138.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(128.4,153.6,138.6);color:#fff}.bg-gradient-cyan-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(40.8, 166.4, 193.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(40.8,166.4,193.8);color:#fff}.bg-gradient-cyan-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(44, 171.6, 191.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(44,171.6,191.8);color:#fff}.tab-content>.tab-pane.html-fill-container{display:none}.tab-content>.active.html-fill-container{display:flex}.tab-content.html-fill-container{padding:0}:root{--bslib-spacer: 1rem;--bslib-mb-spacer: var(--bslib-spacer, 1rem)}.bslib-mb-spacing{margin-bottom:var(--bslib-mb-spacer)}.bslib-gap-spacing{gap:var(--bslib-mb-spacer)}.bslib-gap-spacing>.bslib-mb-spacing,.bslib-gap-spacing>.form-group,.bslib-gap-spacing>p,.bslib-gap-spacing>pre{margin-bottom:0}.html-fill-container>.html-fill-item.bslib-mb-spacing{margin-bottom:0}.bg-blue{--bslib-color-bg: #2c3e50;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-blue{--bslib-color-fg: #2c3e50;color:var(--bslib-color-fg)}.bg-indigo{--bslib-color-bg: #6610f2;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-indigo{--bslib-color-fg: #6610f2;color:var(--bslib-color-fg)}.bg-purple{--bslib-color-bg: #6f42c1;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-purple{--bslib-color-fg: #6f42c1;color:var(--bslib-color-fg)}.bg-pink{--bslib-color-bg: #e83e8c;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-pink{--bslib-color-fg: #e83e8c;color:var(--bslib-color-fg)}.bg-red{--bslib-color-bg: #e74c3c;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-red{--bslib-color-fg: #e74c3c;color:var(--bslib-color-fg)}.bg-orange{--bslib-color-bg: #fd7e14;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-orange{--bslib-color-fg: #fd7e14;color:var(--bslib-color-fg)}.bg-yellow{--bslib-color-bg: #f39c12;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-yellow{--bslib-color-fg: #f39c12;color:var(--bslib-color-fg)}.bg-green{--bslib-color-bg: #18bc9c;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-green{--bslib-color-fg: #18bc9c;color:var(--bslib-color-fg)}.bg-teal{--bslib-color-bg: #20c997;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-teal{--bslib-color-fg: #20c997;color:var(--bslib-color-fg)}.bg-cyan{--bslib-color-bg: #3498db;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-cyan{--bslib-color-fg: #3498db;color:var(--bslib-color-fg)}.text-default{--bslib-color-fg: #6c757d}.bg-default{--bslib-color-bg: #6c757d;--bslib-color-fg: #fff}.text-primary{--bslib-color-fg: #2c3e50}.bg-primary{--bslib-color-bg: #2c3e50;--bslib-color-fg: #fff}.text-secondary{--bslib-color-fg: #6c757d}.bg-secondary{--bslib-color-bg: #6c757d;--bslib-color-fg: #fff}.text-success{--bslib-color-fg: #18bc9c}.bg-success{--bslib-color-bg: #18bc9c;--bslib-color-fg: #fff}.text-info{--bslib-color-fg: #3498db}.bg-info{--bslib-color-bg: #3498db;--bslib-color-fg: #fff}.text-warning{--bslib-color-fg: #f39c12}.bg-warning{--bslib-color-bg: #f39c12;--bslib-color-fg: #fff}.text-danger{--bslib-color-fg: #e74c3c}.bg-danger{--bslib-color-bg: #e74c3c;--bslib-color-fg: #fff}.text-light{--bslib-color-fg: #ecf0f1}.bg-light{--bslib-color-bg: #ecf0f1;--bslib-color-fg: #000}.text-dark{--bslib-color-fg: #7b8a8b}.bg-dark{--bslib-color-bg: #7b8a8b;--bslib-color-fg: #fff}.bg-gradient-blue-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(67.2, 43.6, 144.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(67.2,43.6,144.8);color:#fff}.bg-gradient-blue-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(70.8, 63.6, 125.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(70.8,63.6,125.2);color:#fff}.bg-gradient-blue-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(119.2, 62, 104);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(119.2,62,104);color:#fff}.bg-gradient-blue-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(118.8, 67.6, 72);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(118.8,67.6,72);color:#fff}.bg-gradient-blue-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(127.6, 87.6, 56);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(127.6,87.6,56);color:#fff}.bg-gradient-blue-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(123.6, 99.6, 55.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(123.6,99.6,55.2);color:#fff}.bg-gradient-blue-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(36, 112.4, 110.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(36,112.4,110.4);color:#fff}.bg-gradient-blue-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(39.2, 117.6, 108.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(39.2,117.6,108.4);color:#fff}.bg-gradient-blue-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(47.2, 98, 135.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #2c3e50 var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(47.2,98,135.6);color:#fff}.bg-gradient-indigo-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(78.8, 34.4, 177.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(78.8,34.4,177.2);color:#fff}.bg-gradient-indigo-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(105.6, 36, 222.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(105.6,36,222.4);color:#fff}.bg-gradient-indigo-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(154, 34.4, 201.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(154,34.4,201.2);color:#fff}.bg-gradient-indigo-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(153.6, 40, 169.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(153.6,40,169.2);color:#fff}.bg-gradient-indigo-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(162.4, 60, 153.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(162.4,60,153.2);color:#fff}.bg-gradient-indigo-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(158.4, 72, 152.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(158.4,72,152.4);color:#fff}.bg-gradient-indigo-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(70.8, 84.8, 207.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(70.8,84.8,207.6);color:#fff}.bg-gradient-indigo-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(74, 90, 205.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(74,90,205.6);color:#fff}.bg-gradient-indigo-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(82, 70.4, 232.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(82,70.4,232.8);color:#fff}.bg-gradient-purple-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(84.2, 64.4, 147.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(84.2,64.4,147.8);color:#fff}.bg-gradient-purple-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(107.4, 46, 212.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(107.4,46,212.6);color:#fff}.bg-gradient-purple-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(159.4, 64.4, 171.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(159.4,64.4,171.8);color:#fff}.bg-gradient-purple-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(159, 70, 139.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(159,70,139.8);color:#fff}.bg-gradient-purple-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(167.8, 90, 123.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(167.8,90,123.8);color:#fff}.bg-gradient-purple-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(163.8, 102, 123);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(163.8,102,123);color:#fff}.bg-gradient-purple-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(76.2, 114.8, 178.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(76.2,114.8,178.2);color:#fff}.bg-gradient-purple-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(79.4, 120, 176.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(79.4,120,176.2);color:#fff}.bg-gradient-purple-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(87.4, 100.4, 203.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #6f42c1 var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(87.4,100.4,203.4);color:#fff}.bg-gradient-pink-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(156.8, 62, 116);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(156.8,62,116);color:#fff}.bg-gradient-pink-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(180, 43.6, 180.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(180,43.6,180.8);color:#fff}.bg-gradient-pink-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(183.6, 63.6, 161.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(183.6,63.6,161.2);color:#fff}.bg-gradient-pink-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(231.6, 67.6, 108);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(231.6,67.6,108);color:#fff}.bg-gradient-pink-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(240.4, 87.6, 92);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(240.4,87.6,92);color:#fff}.bg-gradient-pink-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(236.4, 99.6, 91.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(236.4,99.6,91.2);color:#fff}.bg-gradient-pink-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(148.8, 112.4, 146.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(148.8,112.4,146.4);color:#fff}.bg-gradient-pink-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(152, 117.6, 144.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(152,117.6,144.4);color:#fff}.bg-gradient-pink-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(160, 98, 171.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(160,98,171.6);color:#fff}.bg-gradient-red-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(156.2, 70.4, 68);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(156.2,70.4,68);color:#fff}.bg-gradient-red-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(179.4, 52, 132.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(179.4,52,132.8);color:#fff}.bg-gradient-red-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(183, 72, 113.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(183,72,113.2);color:#fff}.bg-gradient-red-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(231.4, 70.4, 92);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(231.4,70.4,92);color:#fff}.bg-gradient-red-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(239.8, 96, 44);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(239.8,96,44);color:#fff}.bg-gradient-red-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(235.8, 108, 43.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(235.8,108,43.2);color:#fff}.bg-gradient-red-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(148.2, 120.8, 98.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(148.2,120.8,98.4);color:#fff}.bg-gradient-red-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(151.4, 126, 96.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(151.4,126,96.4);color:#fff}.bg-gradient-red-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(159.4, 106.4, 123.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #e74c3c var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(159.4,106.4,123.6);color:#fff}.bg-gradient-orange-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(169.4, 100.4, 44);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(169.4,100.4,44);color:#fff}.bg-gradient-orange-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(192.6, 82, 108.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(192.6,82,108.8);color:#fff}.bg-gradient-orange-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(196.2, 102, 89.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(196.2,102,89.2);color:#fff}.bg-gradient-orange-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(244.6, 100.4, 68);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(244.6,100.4,68);color:#fff}.bg-gradient-orange-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(244.2, 106, 36);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(244.2,106,36);color:#fff}.bg-gradient-orange-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(249, 138, 19.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(249,138,19.2);color:#fff}.bg-gradient-orange-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(161.4, 150.8, 74.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(161.4,150.8,74.4);color:#fff}.bg-gradient-orange-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(164.6, 156, 72.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(164.6,156,72.4);color:#fff}.bg-gradient-orange-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(172.6, 136.4, 99.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #fd7e14 var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(172.6,136.4,99.6);color:#fff}.bg-gradient-yellow-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(163.4, 118.4, 42.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(163.4,118.4,42.8);color:#fff}.bg-gradient-yellow-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(186.6, 100, 107.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(186.6,100,107.6);color:#fff}.bg-gradient-yellow-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(190.2, 120, 88);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(190.2,120,88);color:#fff}.bg-gradient-yellow-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(238.6, 118.4, 66.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(238.6,118.4,66.8);color:#fff}.bg-gradient-yellow-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(238.2, 124, 34.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(238.2,124,34.8);color:#fff}.bg-gradient-yellow-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(247, 144, 18.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(247,144,18.8);color:#fff}.bg-gradient-yellow-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(155.4, 168.8, 73.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(155.4,168.8,73.2);color:#fff}.bg-gradient-yellow-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(158.6, 174, 71.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(158.6,174,71.2);color:#fff}.bg-gradient-yellow-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(166.6, 154.4, 98.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #f39c12 var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(166.6,154.4,98.4);color:#fff}.bg-gradient-green-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(32, 137.6, 125.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(32,137.6,125.6);color:#fff}.bg-gradient-green-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(55.2, 119.2, 190.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(55.2,119.2,190.4);color:#fff}.bg-gradient-green-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(58.8, 139.2, 170.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(58.8,139.2,170.8);color:#fff}.bg-gradient-green-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(107.2, 137.6, 149.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(107.2,137.6,149.6);color:#fff}.bg-gradient-green-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(106.8, 143.2, 117.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(106.8,143.2,117.6);color:#fff}.bg-gradient-green-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(115.6, 163.2, 101.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(115.6,163.2,101.6);color:#fff}.bg-gradient-green-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(111.6, 175.2, 100.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(111.6,175.2,100.8);color:#fff}.bg-gradient-green-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(27.2, 193.2, 154);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(27.2,193.2,154);color:#fff}.bg-gradient-green-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(35.2, 173.6, 181.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #18bc9c var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(35.2,173.6,181.2);color:#fff}.bg-gradient-teal-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(36.8, 145.4, 122.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(36.8,145.4,122.6);color:#fff}.bg-gradient-teal-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(60, 127, 187.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(60,127,187.4);color:#fff}.bg-gradient-teal-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(63.6, 147, 167.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(63.6,147,167.8);color:#fff}.bg-gradient-teal-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(112, 145.4, 146.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(112,145.4,146.6);color:#fff}.bg-gradient-teal-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(111.6, 151, 114.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(111.6,151,114.6);color:#fff}.bg-gradient-teal-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(120.4, 171, 98.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(120.4,171,98.6);color:#fff}.bg-gradient-teal-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(116.4, 183, 97.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(116.4,183,97.8);color:#fff}.bg-gradient-teal-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(28.8, 195.8, 153);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(28.8,195.8,153);color:#fff}.bg-gradient-teal-cyan{--bslib-color-fg: #fff;--bslib-color-bg: rgb(40, 181.4, 178.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #3498db var(--bg-gradient-end, 180%)) rgb(40,181.4,178.2);color:#fff}.bg-gradient-cyan-blue{--bslib-color-fg: #fff;--bslib-color-bg: rgb(48.8, 116, 163.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #2c3e50 var(--bg-gradient-end, 180%)) rgb(48.8,116,163.4);color:#fff}.bg-gradient-cyan-indigo{--bslib-color-fg: #fff;--bslib-color-bg: rgb(72, 97.6, 228.2);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) rgb(72,97.6,228.2);color:#fff}.bg-gradient-cyan-purple{--bslib-color-fg: #fff;--bslib-color-bg: rgb(75.6, 117.6, 208.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #6f42c1 var(--bg-gradient-end, 180%)) rgb(75.6,117.6,208.6);color:#fff}.bg-gradient-cyan-pink{--bslib-color-fg: #fff;--bslib-color-bg: rgb(124, 116, 187.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) rgb(124,116,187.4);color:#fff}.bg-gradient-cyan-red{--bslib-color-fg: #fff;--bslib-color-bg: rgb(123.6, 121.6, 155.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #e74c3c var(--bg-gradient-end, 180%)) rgb(123.6,121.6,155.4);color:#fff}.bg-gradient-cyan-orange{--bslib-color-fg: #fff;--bslib-color-bg: rgb(132.4, 141.6, 139.4);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #fd7e14 var(--bg-gradient-end, 180%)) rgb(132.4,141.6,139.4);color:#fff}.bg-gradient-cyan-yellow{--bslib-color-fg: #fff;--bslib-color-bg: rgb(128.4, 153.6, 138.6);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #f39c12 var(--bg-gradient-end, 180%)) rgb(128.4,153.6,138.6);color:#fff}.bg-gradient-cyan-green{--bslib-color-fg: #fff;--bslib-color-bg: rgb(40.8, 166.4, 193.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #18bc9c var(--bg-gradient-end, 180%)) rgb(40.8,166.4,193.8);color:#fff}.bg-gradient-cyan-teal{--bslib-color-fg: #fff;--bslib-color-bg: rgb(44, 171.6, 191.8);background:linear-gradient(var(--bg-gradient-deg, 140deg), #3498db var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) rgb(44,171.6,191.8);color:#fff}:root{--bslib-value-box-shadow: none;--bslib-value-box-border-width-auto-yes: var(--bslib-value-box-border-width-baseline);--bslib-value-box-border-width-auto-no: 0;--bslib-value-box-border-width-baseline: 1px}.bslib-value-box{border-width:var(--bslib-value-box-border-width-auto-no, var(--bslib-value-box-border-width-baseline));container-name:bslib-value-box;container-type:inline-size}.bslib-value-box.card{box-shadow:var(--bslib-value-box-shadow)}.bslib-value-box.border-auto{border-width:var(--bslib-value-box-border-width-auto-yes, var(--bslib-value-box-border-width-baseline))}.bslib-value-box.default{--bslib-value-box-bg-default: var(--bs-card-bg, #fff);--bslib-value-box-border-color-default: var(--bs-card-border-color, rgba(0, 0, 0, 0.175));color:var(--bslib-value-box-color);background-color:var(--bslib-value-box-bg, var(--bslib-value-box-bg-default));border-color:var(--bslib-value-box-border-color, var(--bslib-value-box-border-color-default))}.bslib-value-box .value-box-grid{display:grid;grid-template-areas:"left right";align-items:center;overflow:hidden}.bslib-value-box .value-box-showcase{height:100%;max-height:var(---bslib-value-box-showcase-max-h, 100%)}.bslib-value-box .value-box-showcase,.bslib-value-box .value-box-showcase>.html-fill-item{width:100%}.bslib-value-box[data-full-screen=true] .value-box-showcase{max-height:var(---bslib-value-box-showcase-max-h-fs, 100%)}@media screen and (min-width: 575.98px){@container bslib-value-box (max-width: 300px){.bslib-value-box:not(.showcase-bottom) .value-box-grid{grid-template-columns:1fr !important;grid-template-rows:auto auto;grid-template-areas:"top" "bottom"}.bslib-value-box:not(.showcase-bottom) .value-box-grid .value-box-showcase{grid-area:top !important}.bslib-value-box:not(.showcase-bottom) .value-box-grid .value-box-area{grid-area:bottom !important;justify-content:end}}}.bslib-value-box .value-box-area{justify-content:center;padding:1.5rem 1rem;font-size:.9rem;font-weight:500}.bslib-value-box .value-box-area *{margin-bottom:0;margin-top:0}.bslib-value-box .value-box-title{font-size:1rem;margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.bslib-value-box .value-box-title:empty::after{content:" "}.bslib-value-box .value-box-value{font-size:calc(1.275rem + 0.3vw);margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}@media(min-width: 1200px){.bslib-value-box .value-box-value{font-size:1.5rem}}.bslib-value-box .value-box-value:empty::after{content:" "}.bslib-value-box .value-box-showcase{align-items:center;justify-content:center;margin-top:auto;margin-bottom:auto;padding:1rem}.bslib-value-box .value-box-showcase .bi,.bslib-value-box .value-box-showcase .fa,.bslib-value-box .value-box-showcase .fab,.bslib-value-box .value-box-showcase .fas,.bslib-value-box .value-box-showcase .far{opacity:.85;min-width:50px;max-width:125%}.bslib-value-box .value-box-showcase .bi,.bslib-value-box .value-box-showcase .fa,.bslib-value-box .value-box-showcase .fab,.bslib-value-box .value-box-showcase .fas,.bslib-value-box .value-box-showcase .far{font-size:4rem}.bslib-value-box.showcase-top-right .value-box-grid{grid-template-columns:1fr var(---bslib-value-box-showcase-w, 50%)}.bslib-value-box.showcase-top-right .value-box-grid .value-box-showcase{grid-area:right;margin-left:auto;align-self:start;align-items:end;padding-left:0;padding-bottom:0}.bslib-value-box.showcase-top-right .value-box-grid .value-box-area{grid-area:left;align-self:end}.bslib-value-box.showcase-top-right[data-full-screen=true] .value-box-grid{grid-template-columns:auto var(---bslib-value-box-showcase-w-fs, 1fr)}.bslib-value-box.showcase-top-right[data-full-screen=true] .value-box-grid>div{align-self:center}.bslib-value-box.showcase-top-right:not([data-full-screen=true]) .value-box-showcase{margin-top:0}@container bslib-value-box (max-width: 300px){.bslib-value-box.showcase-top-right:not([data-full-screen=true]) .value-box-grid .value-box-showcase{padding-left:1rem}}.bslib-value-box.showcase-left-center .value-box-grid{grid-template-columns:var(---bslib-value-box-showcase-w, 30%) auto}.bslib-value-box.showcase-left-center[data-full-screen=true] .value-box-grid{grid-template-columns:var(---bslib-value-box-showcase-w-fs, 1fr) auto}.bslib-value-box.showcase-left-center:not([data-fill-screen=true]) .value-box-grid .value-box-showcase{grid-area:left}.bslib-value-box.showcase-left-center:not([data-fill-screen=true]) .value-box-grid .value-box-area{grid-area:right}.bslib-value-box.showcase-bottom .value-box-grid{grid-template-columns:1fr;grid-template-rows:1fr var(---bslib-value-box-showcase-h, auto);grid-template-areas:"top" "bottom";overflow:hidden}.bslib-value-box.showcase-bottom .value-box-grid .value-box-showcase{grid-area:bottom;padding:0;margin:0}.bslib-value-box.showcase-bottom .value-box-grid .value-box-area{grid-area:top}.bslib-value-box.showcase-bottom[data-full-screen=true] .value-box-grid{grid-template-rows:1fr var(---bslib-value-box-showcase-h-fs, 2fr)}.bslib-value-box.showcase-bottom[data-full-screen=true] .value-box-grid .value-box-showcase{padding:1rem}[data-bs-theme=dark] .bslib-value-box{--bslib-value-box-shadow: 0 0.5rem 1rem rgb(0 0 0 / 50%)}@media(min-width: 576px){.nav:not(.nav-hidden){display:flex !important;display:-webkit-flex !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column){float:none !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column)>.bslib-nav-spacer{margin-left:auto !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column)>.form-inline{margin-top:auto;margin-bottom:auto}.nav:not(.nav-hidden).nav-stacked{flex-direction:column;-webkit-flex-direction:column;height:100%}.nav:not(.nav-hidden).nav-stacked>.bslib-nav-spacer{margin-top:auto !important}}.bslib-card{overflow:auto}.bslib-card .card-body+.card-body{padding-top:0}.bslib-card .card-body{overflow:auto}.bslib-card .card-body p{margin-top:0}.bslib-card .card-body p:last-child{margin-bottom:0}.bslib-card .card-body{max-height:var(--bslib-card-body-max-height, none)}.bslib-card[data-full-screen=true]>.card-body{max-height:var(--bslib-card-body-max-height-full-screen, none)}.bslib-card .card-header .form-group{margin-bottom:0}.bslib-card .card-header .selectize-control{margin-bottom:0}.bslib-card .card-header .selectize-control .item{margin-right:1.15rem}.bslib-card .card-footer{margin-top:auto}.bslib-card .bslib-navs-card-title{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center}.bslib-card .bslib-navs-card-title .nav{margin-left:auto}.bslib-card .bslib-sidebar-layout:not([data-bslib-sidebar-border=true]){border:none}.bslib-card .bslib-sidebar-layout:not([data-bslib-sidebar-border-radius=true]){border-top-left-radius:0;border-top-right-radius:0}[data-full-screen=true]{position:fixed;inset:3.5rem 1rem 1rem;height:auto !important;max-height:none !important;width:auto !important;z-index:1070}.bslib-full-screen-enter{display:none;position:absolute;bottom:var(--bslib-full-screen-enter-bottom, 0.2rem);right:var(--bslib-full-screen-enter-right, 0);top:var(--bslib-full-screen-enter-top);left:var(--bslib-full-screen-enter-left);color:var(--bslib-color-fg, var(--bs-card-color));background-color:var(--bslib-color-bg, var(--bs-card-bg, var(--bs-body-bg)));border:var(--bs-card-border-width) solid var(--bslib-color-fg, var(--bs-card-border-color));box-shadow:0 2px 4px rgba(0,0,0,.15);margin:.2rem .4rem;padding:.55rem !important;font-size:.8rem;cursor:pointer;opacity:.7;z-index:1070}.bslib-full-screen-enter:hover{opacity:1}.card[data-full-screen=false]:hover>*>.bslib-full-screen-enter{display:block}.bslib-has-full-screen .card:hover>*>.bslib-full-screen-enter{display:none}@media(max-width: 575.98px){.bslib-full-screen-enter{display:none !important}}.bslib-full-screen-exit{position:relative;top:1.35rem;font-size:.9rem;cursor:pointer;text-decoration:none;display:flex;float:right;margin-right:2.15rem;align-items:center;color:rgba(var(--bs-body-bg-rgb), 0.8)}.bslib-full-screen-exit:hover{color:rgba(var(--bs-body-bg-rgb), 1)}.bslib-full-screen-exit svg{margin-left:.5rem;font-size:1.5rem}#bslib-full-screen-overlay{position:fixed;inset:0;background-color:rgba(var(--bs-body-color-rgb), 0.6);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);z-index:1069;animation:bslib-full-screen-overlay-enter 400ms cubic-bezier(0.6, 0.02, 0.65, 1) forwards}@keyframes bslib-full-screen-overlay-enter{0%{opacity:0}100%{opacity:1}}.bslib-grid{display:grid !important;gap:var(--bslib-spacer, 1rem);height:var(--bslib-grid-height)}.bslib-grid.grid{grid-template-columns:repeat(var(--bs-columns, 12), minmax(0, 1fr));grid-template-rows:unset;grid-auto-rows:var(--bslib-grid--row-heights);--bslib-grid--row-heights--xs: unset;--bslib-grid--row-heights--sm: unset;--bslib-grid--row-heights--md: unset;--bslib-grid--row-heights--lg: unset;--bslib-grid--row-heights--xl: unset;--bslib-grid--row-heights--xxl: unset}.bslib-grid.grid.bslib-grid--row-heights--xs{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xs)}@media(min-width: 576px){.bslib-grid.grid.bslib-grid--row-heights--sm{--bslib-grid--row-heights: var(--bslib-grid--row-heights--sm)}}@media(min-width: 768px){.bslib-grid.grid.bslib-grid--row-heights--md{--bslib-grid--row-heights: var(--bslib-grid--row-heights--md)}}@media(min-width: 992px){.bslib-grid.grid.bslib-grid--row-heights--lg{--bslib-grid--row-heights: var(--bslib-grid--row-heights--lg)}}@media(min-width: 1200px){.bslib-grid.grid.bslib-grid--row-heights--xl{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xl)}}@media(min-width: 1400px){.bslib-grid.grid.bslib-grid--row-heights--xxl{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xxl)}}.bslib-grid>*>.shiny-input-container{width:100%}.bslib-grid-item{grid-column:auto/span 1}@media(max-width: 767.98px){.bslib-grid-item{grid-column:1/-1}}@media(max-width: 575.98px){.bslib-grid{grid-template-columns:1fr !important;height:var(--bslib-grid-height-mobile)}.bslib-grid.grid{height:unset !important;grid-auto-rows:var(--bslib-grid--row-heights--xs, auto)}}.accordion .accordion-header{font-size:calc(1.275rem + 0.3vw);margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color);margin-bottom:0}@media(min-width: 1200px){.accordion .accordion-header{font-size:1.5rem}}.accordion .accordion-icon:not(:empty){margin-right:.75rem;display:flex}.accordion .accordion-button:not(.collapsed){box-shadow:none}.accordion .accordion-button:not(.collapsed):focus{box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.navbar+.container-fluid:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-sm:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-md:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-lg:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-xl:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-xxl:has(>.tab-content>.tab-pane.active.html-fill-container){padding-left:0;padding-right:0}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-sm>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-md>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-lg>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-xl>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-xxl>.tab-content>.tab-pane.active.html-fill-container{padding:var(--bslib-spacer, 1rem);gap:var(--bslib-spacer, 1rem)}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-sm>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-md>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-lg>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-xl>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-xxl>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child){padding:0}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-sm>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-md>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-lg>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-xl>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-xxl>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]){border-left:none;border-right:none;border-bottom:none}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-sm>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-md>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-lg>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-xl>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-xxl>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]){border-radius:0}.navbar+div>.bslib-sidebar-layout{border-top:var(--bslib-sidebar-border)}html{height:100%}.bslib-page-fill{width:100%;height:100%;margin:0;padding:var(--bslib-spacer, 1rem);gap:var(--bslib-spacer, 1rem)}@media(max-width: 575.98px){.bslib-page-fill{height:var(--bslib-page-fill-mobile-height, auto)}}:root{--bslib-page-sidebar-title-bg: #2c3e50;--bslib-page-sidebar-title-color: #fff}.bslib-page-title{background-color:var(--bslib-page-sidebar-title-bg);color:var(--bslib-page-sidebar-title-color);font-size:1.25rem;font-weight:300;padding:var(--bslib-spacer, 1rem);padding-left:1.5rem;margin-bottom:0;border-bottom:1px solid #dee2e6}.bslib-sidebar-layout{--bslib-sidebar-transition-duration: 500ms;--bslib-sidebar-transition-easing-x: cubic-bezier(0.8, 0.78, 0.22, 1.07);--bslib-sidebar-border: var(--bs-card-border-width, 1px) solid var(--bs-card-border-color, rgba(0, 0, 0, 0.175));--bslib-sidebar-border-radius: var(--bs-border-radius);--bslib-sidebar-vert-border: var(--bs-card-border-width, 1px) solid var(--bs-card-border-color, rgba(0, 0, 0, 0.175));--bslib-sidebar-bg: rgba(var(--bs-emphasis-color-rgb, 0, 0, 0), 0.05);--bslib-sidebar-fg: var(--bs-emphasis-color, black);--bslib-sidebar-main-fg: var(--bs-card-color, var(--bs-body-color));--bslib-sidebar-main-bg: var(--bs-card-bg, var(--bs-body-bg));--bslib-sidebar-toggle-bg: rgba(var(--bs-emphasis-color-rgb, 0, 0, 0), 0.1);--bslib-sidebar-padding: calc(var(--bslib-spacer) * 1.5);--bslib-sidebar-icon-size: var(--bslib-spacer, 1rem);--bslib-sidebar-icon-button-size: calc(var(--bslib-sidebar-icon-size, 1rem) * 2);--bslib-sidebar-padding-icon: calc(var(--bslib-sidebar-icon-button-size, 2rem) * 1.5);--bslib-collapse-toggle-border-radius: var(--bs-border-radius, 0.25rem);--bslib-collapse-toggle-transform: 0deg;--bslib-sidebar-toggle-transition-easing: cubic-bezier(1, 0, 0, 1);--bslib-collapse-toggle-right-transform: 180deg;--bslib-sidebar-column-main: minmax(0, 1fr);display:grid !important;grid-template-columns:min(100% - var(--bslib-sidebar-icon-size),var(--bslib-sidebar-width, 250px)) var(--bslib-sidebar-column-main);position:relative;transition:grid-template-columns ease-in-out var(--bslib-sidebar-transition-duration);border:var(--bslib-sidebar-border);border-radius:var(--bslib-sidebar-border-radius)}@media(prefers-reduced-motion: reduce){.bslib-sidebar-layout{transition:none}}.bslib-sidebar-layout[data-bslib-sidebar-border=false]{border:none}.bslib-sidebar-layout[data-bslib-sidebar-border-radius=false]{border-radius:initial}.bslib-sidebar-layout>.main,.bslib-sidebar-layout>.sidebar{grid-row:1/2;border-radius:inherit;overflow:auto}.bslib-sidebar-layout>.main{grid-column:2/3;border-top-left-radius:0;border-bottom-left-radius:0;padding:var(--bslib-sidebar-padding);transition:padding var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration);color:var(--bslib-sidebar-main-fg);background-color:var(--bslib-sidebar-main-bg)}.bslib-sidebar-layout>.sidebar{grid-column:1/2;width:100%;height:100%;border-right:var(--bslib-sidebar-vert-border);border-top-right-radius:0;border-bottom-right-radius:0;color:var(--bslib-sidebar-fg);background-color:var(--bslib-sidebar-bg);backdrop-filter:blur(5px)}.bslib-sidebar-layout>.sidebar>.sidebar-content{display:flex;flex-direction:column;gap:var(--bslib-spacer, 1rem);padding:var(--bslib-sidebar-padding);padding-top:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout>.sidebar>.sidebar-content>:last-child:not(.sidebar-title){margin-bottom:0}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion{margin-left:calc(-1*var(--bslib-sidebar-padding));margin-right:calc(-1*var(--bslib-sidebar-padding))}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:last-child{margin-bottom:calc(-1*var(--bslib-sidebar-padding))}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:not(:last-child){margin-bottom:1rem}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion .accordion-body{display:flex;flex-direction:column}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:not(:first-child) .accordion-item:first-child{border-top:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:not(:last-child) .accordion-item:last-child{border-bottom:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.bslib-sidebar-layout>.sidebar>.sidebar-content.has-accordion>.sidebar-title{border-bottom:none;padding-bottom:0}.bslib-sidebar-layout>.sidebar .shiny-input-container{width:100%}.bslib-sidebar-layout[data-bslib-sidebar-open=always]>.sidebar>.sidebar-content{padding-top:var(--bslib-sidebar-padding)}.bslib-sidebar-layout>.collapse-toggle{grid-row:1/2;grid-column:1/2;display:inline-flex;align-items:center;position:absolute;right:calc(var(--bslib-sidebar-icon-size));top:calc(var(--bslib-sidebar-icon-size, 1rem)/2);border:none;border-radius:var(--bslib-collapse-toggle-border-radius);height:var(--bslib-sidebar-icon-button-size, 2rem);width:var(--bslib-sidebar-icon-button-size, 2rem);display:flex;align-items:center;justify-content:center;padding:0;color:var(--bslib-sidebar-fg);background-color:unset;transition:color var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration),top var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration),right var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration),left var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration)}.bslib-sidebar-layout>.collapse-toggle:hover{background-color:var(--bslib-sidebar-toggle-bg)}.bslib-sidebar-layout>.collapse-toggle>.collapse-icon{opacity:.8;width:var(--bslib-sidebar-icon-size);height:var(--bslib-sidebar-icon-size);transform:rotateY(var(--bslib-collapse-toggle-transform));transition:transform var(--bslib-sidebar-toggle-transition-easing) var(--bslib-sidebar-transition-duration)}.bslib-sidebar-layout>.collapse-toggle:hover>.collapse-icon{opacity:1}.bslib-sidebar-layout .sidebar-title{font-size:1.25rem;line-height:1.25;margin-top:0;margin-bottom:1rem;padding-bottom:1rem;border-bottom:var(--bslib-sidebar-border)}.bslib-sidebar-layout.sidebar-right{grid-template-columns:var(--bslib-sidebar-column-main) min(100% - var(--bslib-sidebar-icon-size),var(--bslib-sidebar-width, 250px))}.bslib-sidebar-layout.sidebar-right>.main{grid-column:1/2;border-top-right-radius:0;border-bottom-right-radius:0;border-top-left-radius:inherit;border-bottom-left-radius:inherit}.bslib-sidebar-layout.sidebar-right>.sidebar{grid-column:2/3;border-right:none;border-left:var(--bslib-sidebar-vert-border);border-top-left-radius:0;border-bottom-left-radius:0}.bslib-sidebar-layout.sidebar-right>.collapse-toggle{grid-column:2/3;left:var(--bslib-sidebar-icon-size);right:unset;border:var(--bslib-collapse-toggle-border)}.bslib-sidebar-layout.sidebar-right>.collapse-toggle>.collapse-icon{transform:rotateY(var(--bslib-collapse-toggle-right-transform))}.bslib-sidebar-layout.sidebar-collapsed{--bslib-collapse-toggle-transform: 180deg;--bslib-collapse-toggle-right-transform: 0deg;--bslib-sidebar-vert-border: none;grid-template-columns:0 minmax(0, 1fr)}.bslib-sidebar-layout.sidebar-collapsed.sidebar-right{grid-template-columns:minmax(0, 1fr) 0}.bslib-sidebar-layout.sidebar-collapsed:not(.transitioning)>.sidebar>*{display:none}.bslib-sidebar-layout.sidebar-collapsed>.main{border-radius:inherit}.bslib-sidebar-layout.sidebar-collapsed:not(.sidebar-right)>.main{padding-left:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout.sidebar-collapsed.sidebar-right>.main{padding-right:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout.sidebar-collapsed>.collapse-toggle{color:var(--bslib-sidebar-main-fg);top:calc(var(--bslib-sidebar-overlap-counter, 0)*(var(--bslib-sidebar-icon-size) + var(--bslib-sidebar-padding)) + var(--bslib-sidebar-icon-size, 1rem)/2);right:calc(-2.5*var(--bslib-sidebar-icon-size) - var(--bs-card-border-width, 1px))}.bslib-sidebar-layout.sidebar-collapsed.sidebar-right>.collapse-toggle{left:calc(-2.5*var(--bslib-sidebar-icon-size) - var(--bs-card-border-width, 1px));right:unset}@media(min-width: 576px){.bslib-sidebar-layout.transitioning>.sidebar>.sidebar-content{display:none}}@media(max-width: 575.98px){.bslib-sidebar-layout[data-bslib-sidebar-open=desktop]{--bslib-sidebar-js-init-collapsed: true}.bslib-sidebar-layout>.sidebar,.bslib-sidebar-layout.sidebar-right>.sidebar{border:none}.bslib-sidebar-layout>.main,.bslib-sidebar-layout.sidebar-right>.main{grid-column:1/3}.bslib-sidebar-layout[data-bslib-sidebar-open=always]{display:block !important}.bslib-sidebar-layout[data-bslib-sidebar-open=always]>.sidebar{max-height:var(--bslib-sidebar-max-height-mobile);overflow-y:auto;border-top:var(--bslib-sidebar-vert-border)}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]){grid-template-columns:100% 0}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]):not(.sidebar-collapsed)>.sidebar{z-index:1}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]):not(.sidebar-collapsed)>.collapse-toggle{z-index:1}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-right{grid-template-columns:0 100%}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-collapsed{grid-template-columns:0 100%}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-collapsed.sidebar-right{grid-template-columns:100% 0}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]):not(.sidebar-right)>.main{padding-left:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-right>.main{padding-right:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always])>.main{opacity:0;transition:opacity var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration)}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-collapsed>.main{opacity:1}}.html-fill-container{display:flex;flex-direction:column;min-height:0;min-width:0}.html-fill-container>.html-fill-item{flex:1 1 auto;min-height:0;min-width:0}.html-fill-container>:not(.html-fill-item){flex:0 0 auto}.quarto-container{min-height:calc(100vh - 132px)}body.hypothesis-enabled #quarto-header{margin-right:16px}footer.footer .nav-footer,#quarto-header>nav{padding-left:1em;padding-right:1em}footer.footer div.nav-footer p:first-child{margin-top:0}footer.footer div.nav-footer p:last-child{margin-bottom:0}#quarto-content>*{padding-top:14px}#quarto-content>#quarto-sidebar-glass{padding-top:0px}@media(max-width: 991.98px){#quarto-content>*{padding-top:0}#quarto-content .subtitle{padding-top:14px}#quarto-content section:first-of-type h2:first-of-type,#quarto-content section:first-of-type .h2:first-of-type{margin-top:1rem}}.headroom-target,header.headroom{will-change:transform;transition:position 200ms linear;transition:all 200ms linear}header.headroom--pinned{transform:translateY(0%)}header.headroom--unpinned{transform:translateY(-100%)}.navbar-container{width:100%}.navbar-brand{overflow:hidden;text-overflow:ellipsis}.navbar-brand-container{max-width:calc(100% - 115px);min-width:0;display:flex;align-items:center}@media(min-width: 992px){.navbar-brand-container{margin-right:1em}}.navbar-brand.navbar-brand-logo{margin-right:4px;display:inline-flex}.navbar-toggler{flex-basis:content;flex-shrink:0}.navbar .navbar-brand-container{order:2}.navbar .navbar-toggler{order:1}.navbar .navbar-container>.navbar-nav{order:20}.navbar .navbar-container>.navbar-brand-container{margin-left:0 !important;margin-right:0 !important}.navbar .navbar-collapse{order:20}.navbar #quarto-search{order:4;margin-left:auto}.navbar .navbar-toggler{margin-right:.5em}.navbar-collapse .quarto-navbar-tools{margin-left:.5em}.navbar-logo{max-height:24px;width:auto;padding-right:4px}nav .nav-item:not(.compact){padding-top:1px}nav .nav-link i,nav .dropdown-item i{padding-right:1px}.navbar-expand-lg .navbar-nav .nav-link{padding-left:.6rem;padding-right:.6rem}nav .nav-item.compact .nav-link{padding-left:.5rem;padding-right:.5rem;font-size:1.1rem}.navbar .quarto-navbar-tools{order:3}.navbar .quarto-navbar-tools div.dropdown{display:inline-block}.navbar .quarto-navbar-tools .quarto-navigation-tool{color:rgb(204.36,208.68,213)}.navbar .quarto-navbar-tools .quarto-navigation-tool:hover{color:#fff}.navbar-nav .dropdown-menu{min-width:220px;font-size:.9rem}.navbar .navbar-nav .nav-link.dropdown-toggle::after{opacity:.75;vertical-align:.175em}.navbar ul.dropdown-menu{padding-top:0;padding-bottom:0}.navbar .dropdown-header{text-transform:uppercase;font-size:.8rem;padding:0 .5rem}.navbar .dropdown-item{padding:.4rem .5rem}.navbar .dropdown-item>i.bi{margin-left:.1rem;margin-right:.25em}.sidebar #quarto-search{margin-top:-1px}.sidebar #quarto-search svg.aa-SubmitIcon{width:16px;height:16px}.sidebar-navigation a{color:inherit}.sidebar-title{margin-top:.25rem;padding-bottom:.5rem;font-size:1.3rem;line-height:1.6rem;visibility:visible}.sidebar-title>a{font-size:inherit;text-decoration:none}.sidebar-title .sidebar-tools-main{margin-top:-6px}@media(max-width: 991.98px){#quarto-sidebar div.sidebar-header{padding-top:.2em}}.sidebar-header-stacked .sidebar-title{margin-top:.6rem}.sidebar-logo{max-width:90%;padding-bottom:.5rem}.sidebar-logo-link{text-decoration:none}.sidebar-navigation li a{text-decoration:none}.sidebar-navigation .quarto-navigation-tool{opacity:.7;font-size:.875rem}#quarto-sidebar>nav>.sidebar-tools-main{margin-left:14px}.sidebar-tools-main{display:inline-flex;margin-left:0px;order:2}.sidebar-tools-main:not(.tools-wide){vertical-align:middle}.sidebar-navigation .quarto-navigation-tool.dropdown-toggle::after{display:none}.sidebar.sidebar-navigation>*{padding-top:1em}.sidebar-item{margin-bottom:.2em;line-height:1rem;margin-top:.4rem}.sidebar-section{padding-left:.5em;padding-bottom:.2em}.sidebar-item .sidebar-item-container{display:flex;justify-content:space-between;cursor:pointer}.sidebar-item-toggle:hover{cursor:pointer}.sidebar-item .sidebar-item-toggle .bi{font-size:.7rem;text-align:center}.sidebar-item .sidebar-item-toggle .bi-chevron-right::before{transition:transform 200ms ease}.sidebar-item .sidebar-item-toggle[aria-expanded=false] .bi-chevron-right::before{transform:none}.sidebar-item .sidebar-item-toggle[aria-expanded=true] .bi-chevron-right::before{transform:rotate(90deg)}.sidebar-item-text{width:100%}.sidebar-navigation .sidebar-divider{margin-left:0;margin-right:0;margin-top:.5rem;margin-bottom:.5rem}@media(max-width: 991.98px){.quarto-secondary-nav{display:block}.quarto-secondary-nav button.quarto-search-button{padding-right:0em;padding-left:2em}.quarto-secondary-nav button.quarto-btn-toggle{margin-left:-0.75rem;margin-right:.15rem}.quarto-secondary-nav nav.quarto-title-breadcrumbs{display:none}.quarto-secondary-nav nav.quarto-page-breadcrumbs{display:flex;align-items:center;padding-right:1em;margin-left:-0.25em}.quarto-secondary-nav nav.quarto-page-breadcrumbs a{text-decoration:none}.quarto-secondary-nav nav.quarto-page-breadcrumbs ol.breadcrumb{margin-bottom:0}}@media(min-width: 992px){.quarto-secondary-nav{display:none}}.quarto-title-breadcrumbs .breadcrumb{margin-bottom:.5em;font-size:.9rem}.quarto-title-breadcrumbs .breadcrumb li:last-of-type a{color:#6c757d}.quarto-secondary-nav .quarto-btn-toggle{color:hsl(0,0%,35%)}.quarto-secondary-nav[aria-expanded=false] .quarto-btn-toggle .bi-chevron-right::before{transform:none}.quarto-secondary-nav[aria-expanded=true] .quarto-btn-toggle .bi-chevron-right::before{transform:rotate(90deg)}.quarto-secondary-nav .quarto-btn-toggle .bi-chevron-right::before{transition:transform 200ms ease}.quarto-secondary-nav{cursor:pointer}.no-decor{text-decoration:none}.quarto-secondary-nav-title{margin-top:.3em;color:hsl(0,0%,35%);padding-top:4px}.quarto-secondary-nav nav.quarto-page-breadcrumbs{color:hsl(0,0%,35%)}.quarto-secondary-nav nav.quarto-page-breadcrumbs a{color:hsl(0,0%,35%)}.quarto-secondary-nav nav.quarto-page-breadcrumbs a:hover{color:rgba(12.72,99.64,82.68,.8)}.quarto-secondary-nav nav.quarto-page-breadcrumbs .breadcrumb-item::before{color:hsl(0,0%,55%)}.breadcrumb-item{line-height:1.2rem}div.sidebar-item-container{color:hsl(0,0%,35%)}div.sidebar-item-container:hover,div.sidebar-item-container:focus{color:rgba(12.72,99.64,82.68,.8)}div.sidebar-item-container.disabled{color:hsla(0,0%,35%,.75)}div.sidebar-item-container .active,div.sidebar-item-container .show>.nav-link,div.sidebar-item-container .sidebar-link>code{color:rgb(12.72,99.64,82.68)}div.sidebar.sidebar-navigation.rollup.quarto-sidebar-toggle-contents,nav.sidebar.sidebar-navigation:not(.rollup){background-color:#fff}@media(max-width: 991.98px){.sidebar-navigation .sidebar-item a,.nav-page .nav-page-text,.sidebar-navigation{font-size:1rem}.sidebar-navigation ul.sidebar-section.depth1 .sidebar-section-item{font-size:1.1rem}.sidebar-logo{display:none}.sidebar.sidebar-navigation{position:static;border-bottom:1px solid #dee2e6}.sidebar.sidebar-navigation.collapsing{position:fixed;z-index:1000}.sidebar.sidebar-navigation.show{position:fixed;z-index:1000}.sidebar.sidebar-navigation{min-height:100%}nav.quarto-secondary-nav{background-color:#fff;border-bottom:1px solid #dee2e6}.quarto-banner nav.quarto-secondary-nav{background-color:#2c3e50;color:rgb(204.36,208.68,213);border-top:1px solid #dee2e6}.sidebar .sidebar-footer{visibility:visible;padding-top:1rem;position:inherit}.sidebar-tools-collapse{display:block}}#quarto-sidebar{transition:width .15s ease-in}#quarto-sidebar>*{padding-right:1em}@media(max-width: 991.98px){#quarto-sidebar .sidebar-menu-container{white-space:nowrap;min-width:225px}#quarto-sidebar.show{transition:width .15s ease-out}}@media(min-width: 992px){#quarto-sidebar{display:flex;flex-direction:column}.nav-page .nav-page-text,.sidebar-navigation .sidebar-section .sidebar-item{font-size:.875rem}.sidebar-navigation .sidebar-item{font-size:.925rem}.sidebar.sidebar-navigation{display:block;position:sticky}.sidebar-search{width:100%}.sidebar .sidebar-footer{visibility:visible}}@media(min-width: 992px){#quarto-sidebar-glass{display:none}}@media(max-width: 991.98px){#quarto-sidebar-glass{position:fixed;top:0;bottom:0;left:0;right:0;background-color:hsla(0,0%,100%,0);transition:background-color .15s ease-in;z-index:-1}#quarto-sidebar-glass.collapsing{z-index:1000}#quarto-sidebar-glass.show{transition:background-color .15s ease-out;background-color:hsla(0,0%,40%,.4);z-index:1000}}.sidebar .sidebar-footer{padding:.5rem 1rem;align-self:flex-end;color:#6c757d;width:100%}.quarto-page-breadcrumbs .breadcrumb-item+.breadcrumb-item,.quarto-page-breadcrumbs .breadcrumb-item{padding-right:.33em;padding-left:0}.quarto-page-breadcrumbs .breadcrumb-item::before{padding-right:.33em}.quarto-sidebar-footer{font-size:.875em}.sidebar-section .bi-chevron-right{vertical-align:middle}.sidebar-section .bi-chevron-right::before{font-size:.9em}.notransition{-webkit-transition:none !important;-moz-transition:none !important;-o-transition:none !important;transition:none !important}.btn:focus:not(:focus-visible){box-shadow:none}.page-navigation{display:flex;justify-content:space-between}.nav-page{padding-bottom:.75em}.nav-page .bi{font-size:1.8rem;vertical-align:middle}.nav-page .nav-page-text{padding-left:.25em;padding-right:.25em}.nav-page a{color:#6c757d;text-decoration:none;display:flex;align-items:center}.nav-page a:hover{color:rgb(19.2,150.4,124.8)}.nav-footer .toc-actions{padding-bottom:.5em;padding-top:.5em}.nav-footer .toc-actions a,.nav-footer .toc-actions a:hover{text-decoration:none}.nav-footer .toc-actions ul{display:flex;list-style:none}.nav-footer .toc-actions ul :first-child{margin-left:auto}.nav-footer .toc-actions ul :last-child{margin-right:auto}.nav-footer .toc-actions ul li{padding-right:1.5em}.nav-footer .toc-actions ul li i.bi{padding-right:.4em}.nav-footer .toc-actions ul li:last-of-type{padding-right:0}.nav-footer{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:baseline;text-align:center;padding-top:.5rem;padding-bottom:.5rem;background-color:#fff}body.nav-fixed{padding-top:82px}.nav-footer-contents{color:#6c757d;margin-top:.25rem}.nav-footer{min-height:3.5em;color:hsl(0,0%,46%)}.nav-footer a{color:hsl(0,0%,46%)}.nav-footer .nav-footer-left{font-size:.825em}.nav-footer .nav-footer-center{font-size:.825em}.nav-footer .nav-footer-right{font-size:.825em}.nav-footer-left .footer-items,.nav-footer-center .footer-items,.nav-footer-right .footer-items{display:inline-flex;padding-top:.3em;padding-bottom:.3em;margin-bottom:0em}.nav-footer-left .footer-items .nav-link,.nav-footer-center .footer-items .nav-link,.nav-footer-right .footer-items .nav-link{padding-left:.6em;padding-right:.6em}@media(min-width: 768px){.nav-footer-left{flex:1 1 0px;text-align:left}}@media(max-width: 575.98px){.nav-footer-left{margin-bottom:1em;flex:100%}}@media(min-width: 768px){.nav-footer-right{flex:1 1 0px;text-align:right}}@media(max-width: 575.98px){.nav-footer-right{margin-bottom:1em;flex:100%}}.nav-footer-center{text-align:center;min-height:3em}@media(min-width: 768px){.nav-footer-center{flex:1 1 0px}}.nav-footer-center .footer-items{justify-content:center}@media(max-width: 767.98px){.nav-footer-center{margin-bottom:1em;flex:100%}}@media(max-width: 767.98px){.nav-footer-center{margin-top:3em;order:10}}.navbar .quarto-reader-toggle.reader .quarto-reader-toggle-btn{background-color:rgb(204.36,208.68,213);border-radius:3px}@media(max-width: 991.98px){.quarto-reader-toggle{display:none}}.quarto-reader-toggle.reader.quarto-navigation-tool .quarto-reader-toggle-btn{background-color:hsl(0,0%,35%);border-radius:3px}.quarto-reader-toggle .quarto-reader-toggle-btn{display:inline-flex;padding-left:.2em;padding-right:.2em;margin-left:-0.2em;margin-right:-0.2em;text-align:center}.navbar .quarto-reader-toggle:not(.reader) .bi::before{background-image:url('data:image/svg+xml,')}.navbar .quarto-reader-toggle.reader .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-reader-toggle:not(.reader) .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-reader-toggle.reader .bi::before{background-image:url('data:image/svg+xml,')}#quarto-back-to-top{display:none;position:fixed;bottom:50px;background-color:#fff;border-radius:.25rem;box-shadow:0 .2rem .5rem #6c757d,0 0 .05rem #6c757d;color:#6c757d;text-decoration:none;font-size:.9em;text-align:center;left:50%;padding:.4rem .8rem;transform:translate(-50%, 0)}#quarto-announcement{padding:.5em;display:flex;justify-content:space-between;margin-bottom:0;font-size:.9em}#quarto-announcement .quarto-announcement-content{margin-right:auto}#quarto-announcement .quarto-announcement-content p{margin-bottom:0}#quarto-announcement .quarto-announcement-icon{margin-right:.5em;font-size:1.2em;margin-top:-0.15em}#quarto-announcement .quarto-announcement-action{cursor:pointer}.aa-DetachedSearchButtonQuery{display:none}.aa-DetachedOverlay ul.aa-List,#quarto-search-results ul.aa-List{list-style:none;padding-left:0}.aa-DetachedOverlay .aa-Panel,#quarto-search-results .aa-Panel{background-color:#fff;position:absolute;z-index:2000}#quarto-search-results .aa-Panel{max-width:400px}#quarto-search input{font-size:.925rem}@media(min-width: 992px){.navbar #quarto-search{margin-left:.25rem;order:999}}.navbar.navbar-expand-sm #quarto-search,.navbar.navbar-expand-md #quarto-search{order:999}@media(min-width: 992px){.navbar .quarto-navbar-tools{order:900}}@media(min-width: 992px){.navbar .quarto-navbar-tools.tools-end{margin-left:auto !important}}@media(max-width: 991.98px){#quarto-sidebar .sidebar-search{display:none}}#quarto-sidebar .sidebar-search .aa-Autocomplete{width:100%}.navbar .aa-Autocomplete .aa-Form{width:180px}.navbar #quarto-search.type-overlay .aa-Autocomplete{width:40px}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form{background-color:inherit;border:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form:focus-within{box-shadow:none;outline:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-InputWrapper{display:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-InputWrapper:focus-within{display:inherit}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-Label svg,.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-LoadingIndicator svg{width:26px;height:26px;color:rgb(204.36,208.68,213);opacity:1}.navbar #quarto-search.type-overlay .aa-Autocomplete svg.aa-SubmitIcon{width:26px;height:26px;color:rgb(204.36,208.68,213);opacity:1}.aa-Autocomplete .aa-Form,.aa-DetachedFormContainer .aa-Form{align-items:center;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;color:#212529;display:flex;line-height:1em;margin:0;position:relative;width:100%}.aa-Autocomplete .aa-Form:focus-within,.aa-DetachedFormContainer .aa-Form:focus-within{box-shadow:rgba(44,62,80,.6) 0 0 0 1px;outline:currentColor none medium}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix{align-items:center;display:flex;flex-shrink:0;order:1}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-Label,.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-Label,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator{cursor:initial;flex-shrink:0;padding:0;text-align:left}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-Label svg,.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-Label svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator svg{color:#212529;opacity:.5}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-SubmitButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-SubmitButton{appearance:none;background:none;border:0;margin:0}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator{align-items:center;display:flex;justify-content:center}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator[hidden]{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapper,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper{order:3;position:relative;width:100%}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input{appearance:none;background:none;border:0;color:#212529;font:inherit;height:calc(1.5em + .1rem + 2px);padding:0;width:100%}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::placeholder,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::placeholder{color:#212529;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input:focus{border-color:none;box-shadow:none;outline:none}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-decoration,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-cancel-button,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-button,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-decoration,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-decoration,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-cancel-button,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-button,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-decoration{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix{align-items:center;display:flex;order:4}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton{align-items:center;background:none;border:0;color:#212529;opacity:.8;cursor:pointer;display:flex;margin:0;width:calc(1.5em + .1rem + 2px)}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:hover,.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:hover,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:focus{color:#212529;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton[hidden]{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton svg{width:calc(1.5em + 0.75rem + calc(1px * 2))}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton{border:none;align-items:center;background:none;color:#212529;opacity:.4;font-size:.7rem;cursor:pointer;display:none;margin:0;width:calc(1em + .1rem + 2px)}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:hover,.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:hover,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:focus{color:#212529;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton[hidden]{display:none}.aa-PanelLayout:empty{display:none}.quarto-search-no-results.no-query{display:none}.aa-Source:has(.no-query){display:none}#quarto-search-results .aa-Panel{border:solid #dee2e6 1px}#quarto-search-results .aa-SourceNoResults{width:398px}.aa-DetachedOverlay .aa-Panel,#quarto-search-results .aa-Panel{max-height:65vh;overflow-y:auto;font-size:.925rem}.aa-DetachedOverlay .aa-SourceNoResults,#quarto-search-results .aa-SourceNoResults{height:60px;display:flex;justify-content:center;align-items:center}.aa-DetachedOverlay .search-error,#quarto-search-results .search-error{padding-top:10px;padding-left:20px;padding-right:20px;cursor:default}.aa-DetachedOverlay .search-error .search-error-title,#quarto-search-results .search-error .search-error-title{font-size:1.1rem;margin-bottom:.5rem}.aa-DetachedOverlay .search-error .search-error-title .search-error-icon,#quarto-search-results .search-error .search-error-title .search-error-icon{margin-right:8px}.aa-DetachedOverlay .search-error .search-error-text,#quarto-search-results .search-error .search-error-text{font-weight:300}.aa-DetachedOverlay .search-result-text,#quarto-search-results .search-result-text{font-weight:300;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.2rem;max-height:2.4rem}.aa-DetachedOverlay .aa-SourceHeader .search-result-header,#quarto-search-results .aa-SourceHeader .search-result-header{font-size:.875rem;background-color:hsl(0,0%,95%);padding-left:14px;padding-bottom:4px;padding-top:4px}.aa-DetachedOverlay .aa-SourceHeader .search-result-header-no-results,#quarto-search-results .aa-SourceHeader .search-result-header-no-results{display:none}.aa-DetachedOverlay .aa-SourceFooter .algolia-search-logo,#quarto-search-results .aa-SourceFooter .algolia-search-logo{width:110px;opacity:.85;margin:8px;float:right}.aa-DetachedOverlay .search-result-section,#quarto-search-results .search-result-section{font-size:.925em}.aa-DetachedOverlay a.search-result-link,#quarto-search-results a.search-result-link{color:inherit;text-decoration:none}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item,#quarto-search-results li.aa-Item[aria-selected=true] .search-item{background-color:#2c3e50}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item.search-result-more,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-section,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-text,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-title-container,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-text-container,#quarto-search-results li.aa-Item[aria-selected=true] .search-item.search-result-more,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-section,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-text,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-title-container,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-text-container{color:#fff;background-color:#2c3e50}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item mark.search-match,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-match.mark,#quarto-search-results li.aa-Item[aria-selected=true] .search-item mark.search-match,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-match.mark{color:#fff;background-color:rgb(58.4774193548,82.4,106.3225806452)}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item,#quarto-search-results li.aa-Item[aria-selected=false] .search-item{background-color:#fff}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item.search-result-more,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-section,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-text,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-title-container,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-text-container,#quarto-search-results li.aa-Item[aria-selected=false] .search-item.search-result-more,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-section,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-text,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-title-container,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-text-container{color:#212529}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item mark.search-match,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-match.mark,#quarto-search-results li.aa-Item[aria-selected=false] .search-item mark.search-match,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-match.mark{color:inherit;background-color:hsl(210,29.0322580645%,66.3137254902%)}.aa-DetachedOverlay .aa-Item .search-result-doc:not(.document-selectable) .search-result-title-container,#quarto-search-results .aa-Item .search-result-doc:not(.document-selectable) .search-result-title-container{background-color:#fff;color:#212529}.aa-DetachedOverlay .aa-Item .search-result-doc:not(.document-selectable) .search-result-text-container,#quarto-search-results .aa-Item .search-result-doc:not(.document-selectable) .search-result-text-container{padding-top:0px}.aa-DetachedOverlay li.aa-Item .search-result-doc.document-selectable .search-result-text-container,#quarto-search-results li.aa-Item .search-result-doc.document-selectable .search-result-text-container{margin-top:-4px}.aa-DetachedOverlay .aa-Item,#quarto-search-results .aa-Item{cursor:pointer}.aa-DetachedOverlay .aa-Item .search-item,#quarto-search-results .aa-Item .search-item{border-left:none;border-right:none;border-top:none;background-color:#fff;border-color:#dee2e6;color:#212529}.aa-DetachedOverlay .aa-Item .search-item p,#quarto-search-results .aa-Item .search-item p{margin-top:0;margin-bottom:0}.aa-DetachedOverlay .aa-Item .search-item i.bi,#quarto-search-results .aa-Item .search-item i.bi{padding-left:8px;padding-right:8px;font-size:1.3em}.aa-DetachedOverlay .aa-Item .search-item .search-result-title,#quarto-search-results .aa-Item .search-item .search-result-title{margin-top:.3em;margin-bottom:0em}.aa-DetachedOverlay .aa-Item .search-item .search-result-crumbs,#quarto-search-results .aa-Item .search-item .search-result-crumbs{white-space:nowrap;text-overflow:ellipsis;font-size:.8em;font-weight:300;margin-right:1em}.aa-DetachedOverlay .aa-Item .search-item .search-result-crumbs:not(.search-result-crumbs-wrap),#quarto-search-results .aa-Item .search-item .search-result-crumbs:not(.search-result-crumbs-wrap){max-width:30%;margin-left:auto;margin-top:.5em;margin-bottom:.1rem}.aa-DetachedOverlay .aa-Item .search-item .search-result-crumbs.search-result-crumbs-wrap,#quarto-search-results .aa-Item .search-item .search-result-crumbs.search-result-crumbs-wrap{flex-basis:100%;margin-top:0em;margin-bottom:.2em;margin-left:37px}.aa-DetachedOverlay .aa-Item .search-result-title-container,#quarto-search-results .aa-Item .search-result-title-container{font-size:1em;display:flex;flex-wrap:wrap;padding:6px 4px 6px 4px}.aa-DetachedOverlay .aa-Item .search-result-text-container,#quarto-search-results .aa-Item .search-result-text-container{padding-bottom:8px;padding-right:8px;margin-left:42px}.aa-DetachedOverlay .aa-Item .search-result-doc-section,.aa-DetachedOverlay .aa-Item .search-result-more,#quarto-search-results .aa-Item .search-result-doc-section,#quarto-search-results .aa-Item .search-result-more{padding-top:8px;padding-bottom:8px;padding-left:44px}.aa-DetachedOverlay .aa-Item .search-result-more,#quarto-search-results .aa-Item .search-result-more{font-size:.8em;font-weight:400}.aa-DetachedOverlay .aa-Item .search-result-doc,#quarto-search-results .aa-Item .search-result-doc{border-top:1px solid #dee2e6}.aa-DetachedSearchButton{background:none;border:none}.aa-DetachedSearchButton .aa-DetachedSearchButtonPlaceholder{display:none}.navbar .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon{color:rgb(204.36,208.68,213)}.sidebar-tools-collapse #quarto-search,.sidebar-tools-main #quarto-search{display:inline}.sidebar-tools-collapse #quarto-search .aa-Autocomplete,.sidebar-tools-main #quarto-search .aa-Autocomplete{display:inline}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton{padding-left:4px;padding-right:4px}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon{color:hsl(0,0%,35%)}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon .aa-SubmitIcon,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon .aa-SubmitIcon{margin-top:-3px}.aa-DetachedContainer{background:hsla(0,0%,100%,.65);width:90%;bottom:0;box-shadow:rgba(222,226,230,.6) 0 0 0 1px;outline:currentColor none medium;display:flex;flex-direction:column;left:0;margin:0;overflow:hidden;padding:0;position:fixed;right:0;top:0;z-index:1101}.aa-DetachedContainer::after{height:32px}.aa-DetachedContainer .aa-SourceHeader{margin:var(--aa-spacing-half) 0 var(--aa-spacing-half) 2px}.aa-DetachedContainer .aa-Panel{background-color:#fff;border-radius:0;box-shadow:none;flex-grow:1;margin:0;padding:0;position:relative}.aa-DetachedContainer .aa-PanelLayout{bottom:0;box-shadow:none;left:0;margin:0;max-height:none;overflow-y:auto;position:absolute;right:0;top:0;width:100%}.aa-DetachedFormContainer{background-color:#fff;border-bottom:1px solid #dee2e6;display:flex;flex-direction:row;justify-content:space-between;margin:0;padding:.5em}.aa-DetachedCancelButton{background:none;font-size:.8em;border:0;border-radius:3px;color:#212529;cursor:pointer;margin:0 0 0 .5em;padding:0 .5em}.aa-DetachedCancelButton:hover,.aa-DetachedCancelButton:focus{box-shadow:rgba(44,62,80,.6) 0 0 0 1px;outline:currentColor none medium}.aa-DetachedContainer--modal{bottom:inherit;height:auto;margin:0 auto;position:absolute;top:100px;border-radius:6px;max-width:850px}@media(max-width: 575.98px){.aa-DetachedContainer--modal{width:100%;top:0px;border-radius:0px;border:none}}.aa-DetachedContainer--modal .aa-PanelLayout{max-height:var(--aa-detached-modal-max-height);padding-bottom:var(--aa-spacing-half);position:static}.aa-Detached{height:100vh;overflow:hidden}.aa-DetachedOverlay{background-color:rgba(33,37,41,.4);position:fixed;left:0;right:0;top:0;margin:0;padding:0;height:100vh;z-index:1100}.quarto-dashboard.nav-fixed.dashboard-sidebar #quarto-content.quarto-dashboard-content{padding:0em}.quarto-dashboard #quarto-content.quarto-dashboard-content{padding:1em}.quarto-dashboard #quarto-content.quarto-dashboard-content>*{padding-top:0}@media(min-width: 576px){.quarto-dashboard{height:100%}}.quarto-dashboard .card.valuebox.bslib-card.bg-primary{background-color:rgba(39,128,227,.7) !important}.quarto-dashboard .card.valuebox.bslib-card.bg-secondary{background-color:#6c757d !important}.quarto-dashboard .card.valuebox.bslib-card.bg-success{background-color:rgba(63,182,24,.7) !important}.quarto-dashboard .card.valuebox.bslib-card.bg-info{background-color:rgba(153,84,187,.7) !important}.quarto-dashboard .card.valuebox.bslib-card.bg-warning{background-color:rgba(255,117,24,.7) !important}.quarto-dashboard .card.valuebox.bslib-card.bg-danger{background-color:rgba(255,0,57,.7) !important}.quarto-dashboard .card.valuebox.bslib-card.bg-light{background-color:#ecf0f1 !important}.quarto-dashboard .card.valuebox.bslib-card.bg-dark{background-color:#7b8a8b !important}.quarto-dashboard.dashboard-fill{display:flex;flex-direction:column}.quarto-dashboard #quarto-appendix{display:none}.quarto-dashboard #quarto-header #quarto-dashboard-header{border-top:solid 1px rgb(62.0967741935,87.5,112.9032258065);border-bottom:solid 1px rgb(62.0967741935,87.5,112.9032258065)}.quarto-dashboard #quarto-header #quarto-dashboard-header>nav{padding-left:1em;padding-right:1em}.quarto-dashboard #quarto-header #quarto-dashboard-header>nav .navbar-brand-container{padding-left:0}.quarto-dashboard #quarto-header #quarto-dashboard-header .navbar-toggler{margin-right:0}.quarto-dashboard #quarto-header #quarto-dashboard-header .navbar-toggler-icon{height:1em;width:1em;background-image:url('data:image/svg+xml,')}.quarto-dashboard #quarto-header #quarto-dashboard-header .navbar-brand-container{padding-right:1em}.quarto-dashboard #quarto-header #quarto-dashboard-header .navbar-title{font-size:1.1em}.quarto-dashboard #quarto-header #quarto-dashboard-header .navbar-nav{font-size:.9em}.quarto-dashboard #quarto-dashboard-header .navbar{padding:0}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-container{padding-left:1em}.quarto-dashboard #quarto-dashboard-header .navbar.slim .navbar-brand-container .nav-link,.quarto-dashboard #quarto-dashboard-header .navbar.slim .navbar-nav .nav-link{padding:.7em}.quarto-dashboard #quarto-dashboard-header .navbar .quarto-color-scheme-toggle{order:9}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-toggler{margin-left:.5em;order:10}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-nav .nav-link{padding:.5em;height:100%;display:flex;align-items:center}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-nav .active{background-color:rgb(58.4774193548,82.4,106.3225806452)}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-brand-container{padding:.5em .5em .5em 0;display:flex;flex-direction:row;margin-right:2em;align-items:center}@media(max-width: 767.98px){.quarto-dashboard #quarto-dashboard-header .navbar .navbar-brand-container{margin-right:auto}}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-collapse{align-self:stretch}@media(min-width: 768px){.quarto-dashboard #quarto-dashboard-header .navbar .navbar-collapse{order:8}}@media(max-width: 767.98px){.quarto-dashboard #quarto-dashboard-header .navbar .navbar-collapse{order:1000;padding-bottom:.5em}}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-collapse .navbar-nav{align-self:stretch}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-title{font-size:1.25em;line-height:1.1em;display:flex;flex-direction:row;flex-wrap:wrap;align-items:baseline}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-title .navbar-title-text{margin-right:.4em}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-title a{text-decoration:none;color:inherit}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-subtitle,.quarto-dashboard #quarto-dashboard-header .navbar .navbar-author{font-size:.9rem;margin-right:.5em}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-author{margin-left:auto}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-logo{max-height:48px;min-height:30px;object-fit:cover;margin-right:1em}.quarto-dashboard #quarto-dashboard-header .navbar .quarto-dashboard-links{order:9;padding-right:1em}.quarto-dashboard #quarto-dashboard-header .navbar .quarto-dashboard-link-text{margin-left:.25em}.quarto-dashboard #quarto-dashboard-header .navbar .quarto-dashboard-link{padding-right:0em;padding-left:.7em;text-decoration:none;color:rgb(204.36,208.68,213)}.quarto-dashboard .page-layout-custom .tab-content{padding:0;border:none}.quarto-dashboard-img-contain{height:100%;width:100%;object-fit:contain}@media(max-width: 575.98px){.quarto-dashboard .bslib-grid{grid-template-rows:minmax(1em, max-content) !important}.quarto-dashboard .sidebar-content{height:inherit}.quarto-dashboard .page-layout-custom{min-height:100vh}}.quarto-dashboard.dashboard-toolbar>.page-layout-custom,.quarto-dashboard.dashboard-sidebar>.page-layout-custom{padding:0}.quarto-dashboard .quarto-dashboard-content.quarto-dashboard-pages{padding:0}.quarto-dashboard .callout{margin-bottom:0;margin-top:0}.quarto-dashboard .html-fill-container figure{overflow:hidden}.quarto-dashboard bslib-tooltip .rounded-pill{border:solid #6c757d 1px}.quarto-dashboard bslib-tooltip .rounded-pill .svg{fill:#212529}.quarto-dashboard .tabset .dashboard-card-no-title .nav-tabs{margin-left:0;margin-right:auto}.quarto-dashboard .tabset .tab-content{border:none}.quarto-dashboard .tabset .card-header .nav-link[role=tab]{margin-top:-6px;padding-top:6px;padding-bottom:6px}.quarto-dashboard .card.valuebox,.quarto-dashboard .card.bslib-value-box{min-height:3rem}.quarto-dashboard .card.valuebox .card-body,.quarto-dashboard .card.bslib-value-box .card-body{padding:0}.quarto-dashboard .bslib-value-box .value-box-value{font-size:clamp(.1em,15cqw,5em)}.quarto-dashboard .bslib-value-box .value-box-showcase .bi{font-size:clamp(.1em,max(18cqw,5.2cqh),5em);text-align:center;height:1em}.quarto-dashboard .bslib-value-box .value-box-showcase .bi::before{vertical-align:1em}.quarto-dashboard .bslib-value-box .value-box-area{margin-top:auto;margin-bottom:auto}.quarto-dashboard .card figure.quarto-float{display:flex;flex-direction:column;align-items:center}.quarto-dashboard .dashboard-scrolling{padding:1em}.quarto-dashboard .full-height{height:100%}.quarto-dashboard .showcase-bottom .value-box-grid{display:grid;grid-template-columns:1fr;grid-template-rows:1fr auto;grid-template-areas:"top" "bottom"}.quarto-dashboard .showcase-bottom .value-box-grid .value-box-showcase{grid-area:bottom;padding:0;margin:0}.quarto-dashboard .showcase-bottom .value-box-grid .value-box-showcase i.bi{font-size:4rem}.quarto-dashboard .showcase-bottom .value-box-grid .value-box-area{grid-area:top}.quarto-dashboard .tab-content{margin-bottom:0}.quarto-dashboard .bslib-card .bslib-navs-card-title{justify-content:stretch;align-items:end}.quarto-dashboard .card-header{display:flex;flex-wrap:wrap;justify-content:space-between}.quarto-dashboard .card-header .card-title{display:flex;flex-direction:column;justify-content:center;margin-bottom:0}.quarto-dashboard .tabset .card-toolbar{margin-bottom:1em}.quarto-dashboard .bslib-grid>.bslib-sidebar-layout{border:none;gap:var(--bslib-spacer, 1rem)}.quarto-dashboard .bslib-grid>.bslib-sidebar-layout>.main{padding:0}.quarto-dashboard .bslib-grid>.bslib-sidebar-layout>.sidebar{border-radius:.25rem;border:1px solid rgba(0,0,0,.175)}.quarto-dashboard .bslib-grid>.bslib-sidebar-layout>.collapse-toggle{display:none}@media(max-width: 767.98px){.quarto-dashboard .bslib-grid>.bslib-sidebar-layout{grid-template-columns:1fr;grid-template-rows:max-content 1fr}.quarto-dashboard .bslib-grid>.bslib-sidebar-layout>.main{grid-column:1;grid-row:2}.quarto-dashboard .bslib-grid>.bslib-sidebar-layout .sidebar{grid-column:1;grid-row:1}}.quarto-dashboard .sidebar-right .sidebar{padding-left:2.5em}.quarto-dashboard .sidebar-right .collapse-toggle{left:2px}.quarto-dashboard .quarto-dashboard .sidebar-right button.collapse-toggle:not(.transitioning){left:unset}.quarto-dashboard aside.sidebar{padding-left:1em;padding-right:1em;background-color:rgba(52,58,64,.25);color:#212529}.quarto-dashboard .bslib-sidebar-layout>div.main{padding:.7em}.quarto-dashboard .bslib-sidebar-layout button.collapse-toggle{margin-top:.3em}.quarto-dashboard .bslib-sidebar-layout .collapse-toggle{top:0}.quarto-dashboard .bslib-sidebar-layout.sidebar-collapsed:not(.transitioning):not(.sidebar-right) .collapse-toggle{left:2px}.quarto-dashboard .sidebar>section>.h3:first-of-type{margin-top:0em}.quarto-dashboard .sidebar .h3,.quarto-dashboard .sidebar .h4,.quarto-dashboard .sidebar .h5,.quarto-dashboard .sidebar .h6{margin-top:.5em}.quarto-dashboard .sidebar form{flex-direction:column;align-items:start;margin-bottom:1em}.quarto-dashboard .sidebar form div[class*=oi-][class$=-input]{flex-direction:column}.quarto-dashboard .sidebar form[class*=oi-][class$=-toggle]{flex-direction:row-reverse;align-items:center;justify-content:start}.quarto-dashboard .sidebar form input[type=range]{margin-top:.5em;margin-right:.8em;margin-left:1em}.quarto-dashboard .sidebar label{width:fit-content}.quarto-dashboard .sidebar .card-body{margin-bottom:2em}.quarto-dashboard .sidebar .shiny-input-container{margin-bottom:1em}.quarto-dashboard .sidebar .shiny-options-group{margin-top:0}.quarto-dashboard .sidebar .control-label{margin-bottom:.3em}.quarto-dashboard .card .card-body .quarto-layout-row{align-items:stretch}.quarto-dashboard .toolbar{font-size:.9em;display:flex;flex-direction:row;border-top:solid 1px hsl(208.2352941176,6.1371841155%,79.137254902%);padding:1em;flex-wrap:wrap;background-color:rgba(52,58,64,.25)}.quarto-dashboard .toolbar .cell-output-display{display:flex}.quarto-dashboard .toolbar .shiny-input-container{padding-bottom:.5em;margin-bottom:.5em;width:inherit}.quarto-dashboard .toolbar .shiny-input-container>.checkbox:first-child{margin-top:6px}.quarto-dashboard .toolbar>*:last-child{margin-right:0}.quarto-dashboard .toolbar>*>*{margin-right:1em;align-items:baseline}.quarto-dashboard .toolbar>*>*>a{text-decoration:none;margin-top:auto;margin-bottom:auto}.quarto-dashboard .toolbar .shiny-input-container{padding-bottom:0;margin-bottom:0}.quarto-dashboard .toolbar .shiny-input-container>*{flex-shrink:0;flex-grow:0}.quarto-dashboard .toolbar .form-group.shiny-input-container:not([role=group])>label{margin-bottom:0}.quarto-dashboard .toolbar .shiny-input-container.no-baseline{align-items:start;padding-top:6px}.quarto-dashboard .toolbar .shiny-input-container{display:flex;align-items:baseline}.quarto-dashboard .toolbar .shiny-input-container label{padding-right:.4em}.quarto-dashboard .toolbar .shiny-input-container .bslib-input-switch{margin-top:6px}.quarto-dashboard .toolbar input[type=text]{line-height:1;width:inherit}.quarto-dashboard .toolbar .input-daterange{width:inherit}.quarto-dashboard .toolbar .input-daterange input[type=text]{height:2.4em;width:10em}.quarto-dashboard .toolbar .input-daterange .input-group-addon{height:auto;padding:0;margin-left:-5px !important;margin-right:-5px}.quarto-dashboard .toolbar .input-daterange .input-group-addon .input-group-text{padding-top:0;padding-bottom:0;height:100%}.quarto-dashboard .toolbar span.irs.irs--shiny{width:10em}.quarto-dashboard .toolbar span.irs.irs--shiny .irs-line{top:9px}.quarto-dashboard .toolbar span.irs.irs--shiny .irs-min,.quarto-dashboard .toolbar span.irs.irs--shiny .irs-max,.quarto-dashboard .toolbar span.irs.irs--shiny .irs-from,.quarto-dashboard .toolbar span.irs.irs--shiny .irs-to,.quarto-dashboard .toolbar span.irs.irs--shiny .irs-single{top:20px}.quarto-dashboard .toolbar span.irs.irs--shiny .irs-bar{top:8px}.quarto-dashboard .toolbar span.irs.irs--shiny .irs-handle{top:0px}.quarto-dashboard .toolbar .shiny-input-checkboxgroup>label{margin-top:6px}.quarto-dashboard .toolbar .shiny-input-checkboxgroup>.shiny-options-group{margin-top:0;align-items:baseline}.quarto-dashboard .toolbar .shiny-input-radiogroup>label{margin-top:6px}.quarto-dashboard .toolbar .shiny-input-radiogroup>.shiny-options-group{align-items:baseline;margin-top:0}.quarto-dashboard .toolbar .shiny-input-radiogroup>.shiny-options-group>.radio{margin-right:.3em}.quarto-dashboard .toolbar .form-select{padding-top:.2em;padding-bottom:.2em}.quarto-dashboard .toolbar .shiny-input-select{min-width:6em}.quarto-dashboard .toolbar div.checkbox{margin-bottom:0px}.quarto-dashboard .toolbar>.checkbox:first-child{margin-top:6px}.quarto-dashboard .toolbar form{width:fit-content}.quarto-dashboard .toolbar form label{padding-top:.2em;padding-bottom:.2em;width:fit-content}.quarto-dashboard .toolbar form input[type=date]{width:fit-content}.quarto-dashboard .toolbar form input[type=color]{width:3em}.quarto-dashboard .toolbar form button{padding:.4em}.quarto-dashboard .toolbar form select{width:fit-content}.quarto-dashboard .toolbar>*{font-size:.9em;flex-grow:0}.quarto-dashboard .toolbar .shiny-input-container label{margin-bottom:1px}.quarto-dashboard .toolbar-bottom{margin-top:1em;margin-bottom:0 !important;order:2}.quarto-dashboard .quarto-dashboard-content>.dashboard-toolbar-container>.toolbar-content>.tab-content>.tab-pane>*:not(.bslib-sidebar-layout){padding:1em}.quarto-dashboard .quarto-dashboard-content>.dashboard-toolbar-container>.toolbar-content>*:not(.tab-content){padding:1em}.quarto-dashboard .quarto-dashboard-content>.tab-content>.dashboard-page>.dashboard-toolbar-container>.toolbar-content,.quarto-dashboard .quarto-dashboard-content>.tab-content>.dashboard-page:not(.dashboard-sidebar-container)>*:not(.dashboard-toolbar-container){padding:1em}.quarto-dashboard .toolbar-content{padding:0}.quarto-dashboard .quarto-dashboard-content.quarto-dashboard-pages .tab-pane>.dashboard-toolbar-container .toolbar{border-radius:0;margin-bottom:0}.quarto-dashboard .dashboard-toolbar-container.toolbar-toplevel .toolbar{border-bottom:1px solid rgba(0,0,0,.175)}.quarto-dashboard .dashboard-toolbar-container.toolbar-toplevel .toolbar-bottom{margin-top:0}.quarto-dashboard .dashboard-toolbar-container:not(.toolbar-toplevel) .toolbar{margin-bottom:1em;border-top:none;border-radius:.25rem;border:1px solid rgba(0,0,0,.175)}.quarto-dashboard .vega-embed.has-actions details{width:1.7em;height:2em;position:absolute !important;top:0;right:0}.quarto-dashboard .dashboard-toolbar-container{padding:0}.quarto-dashboard .card .card-header p:last-child,.quarto-dashboard .card .card-footer p:last-child{margin-bottom:0}.quarto-dashboard .card .card-body>.h4:first-child{margin-top:0}.quarto-dashboard .card .card-body{z-index:4}@media(max-width: 767.98px){.quarto-dashboard .card .card-body .itables div.dataTables_wrapper div.dataTables_length,.quarto-dashboard .card .card-body .itables div.dataTables_wrapper div.dataTables_info,.quarto-dashboard .card .card-body .itables div.dataTables_wrapper div.dataTables_paginate{text-align:initial}.quarto-dashboard .card .card-body .itables div.dataTables_wrapper div.dataTables_filter{text-align:right}.quarto-dashboard .card .card-body .itables div.dataTables_wrapper div.dataTables_paginate ul.pagination{justify-content:initial}}.quarto-dashboard .card .card-body .itables .dataTables_wrapper{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;padding-top:0}.quarto-dashboard .card .card-body .itables .dataTables_wrapper table{flex-shrink:0}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dt-buttons{margin-bottom:.5em;margin-left:auto;width:fit-content;float:right}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dt-buttons.btn-group{background:#fff;border:none}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dt-buttons .btn-secondary{background-color:#fff;background-image:none;border:solid #dee2e6 1px;padding:.2em .7em}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dt-buttons .btn span{font-size:.8em;color:#212529}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_info{margin-left:.5em;margin-bottom:.5em;padding-top:0}@media(min-width: 768px){.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_info{font-size:.875em}}@media(max-width: 767.98px){.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_info{font-size:.8em}}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_filter{margin-bottom:.5em;font-size:.875em}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_filter input[type=search]{padding:1px 5px 1px 5px;font-size:.875em}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_length{flex-basis:1 1 50%;margin-bottom:.5em;font-size:.875em}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_length select{padding:.4em 3em .4em .5em;font-size:.875em;margin-left:.2em;margin-right:.2em}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_paginate{flex-shrink:0}@media(min-width: 768px){.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_paginate{margin-left:auto}}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_paginate ul.pagination .paginate_button .page-link{font-size:.8em}.quarto-dashboard .card .card-footer{font-size:.9em}.quarto-dashboard .card .card-toolbar{display:flex;flex-grow:1;flex-direction:row;width:100%;flex-wrap:wrap}.quarto-dashboard .card .card-toolbar>*{font-size:.8em;flex-grow:0}.quarto-dashboard .card .card-toolbar>.card-title{font-size:1em;flex-grow:1;align-self:flex-start;margin-top:.1em}.quarto-dashboard .card .card-toolbar .cell-output-display{display:flex}.quarto-dashboard .card .card-toolbar .shiny-input-container{padding-bottom:.5em;margin-bottom:.5em;width:inherit}.quarto-dashboard .card .card-toolbar .shiny-input-container>.checkbox:first-child{margin-top:6px}.quarto-dashboard .card .card-toolbar>*:last-child{margin-right:0}.quarto-dashboard .card .card-toolbar>*>*{margin-right:1em;align-items:baseline}.quarto-dashboard .card .card-toolbar>*>*>a{text-decoration:none;margin-top:auto;margin-bottom:auto}.quarto-dashboard .card .card-toolbar form{width:fit-content}.quarto-dashboard .card .card-toolbar form label{padding-top:.2em;padding-bottom:.2em;width:fit-content}.quarto-dashboard .card .card-toolbar form input[type=date]{width:fit-content}.quarto-dashboard .card .card-toolbar form input[type=color]{width:3em}.quarto-dashboard .card .card-toolbar form button{padding:.4em}.quarto-dashboard .card .card-toolbar form select{width:fit-content}.quarto-dashboard .card .card-toolbar .cell-output-display{display:flex}.quarto-dashboard .card .card-toolbar .shiny-input-container{padding-bottom:.5em;margin-bottom:.5em;width:inherit}.quarto-dashboard .card .card-toolbar .shiny-input-container>.checkbox:first-child{margin-top:6px}.quarto-dashboard .card .card-toolbar>*:last-child{margin-right:0}.quarto-dashboard .card .card-toolbar>*>*{margin-right:1em;align-items:baseline}.quarto-dashboard .card .card-toolbar>*>*>a{text-decoration:none;margin-top:auto;margin-bottom:auto}.quarto-dashboard .card .card-toolbar .shiny-input-container{padding-bottom:0;margin-bottom:0}.quarto-dashboard .card .card-toolbar .shiny-input-container>*{flex-shrink:0;flex-grow:0}.quarto-dashboard .card .card-toolbar .form-group.shiny-input-container:not([role=group])>label{margin-bottom:0}.quarto-dashboard .card .card-toolbar .shiny-input-container.no-baseline{align-items:start;padding-top:6px}.quarto-dashboard .card .card-toolbar .shiny-input-container{display:flex;align-items:baseline}.quarto-dashboard .card .card-toolbar .shiny-input-container label{padding-right:.4em}.quarto-dashboard .card .card-toolbar .shiny-input-container .bslib-input-switch{margin-top:6px}.quarto-dashboard .card .card-toolbar input[type=text]{line-height:1;width:inherit}.quarto-dashboard .card .card-toolbar .input-daterange{width:inherit}.quarto-dashboard .card .card-toolbar .input-daterange input[type=text]{height:2.4em;width:10em}.quarto-dashboard .card .card-toolbar .input-daterange .input-group-addon{height:auto;padding:0;margin-left:-5px !important;margin-right:-5px}.quarto-dashboard .card .card-toolbar .input-daterange .input-group-addon .input-group-text{padding-top:0;padding-bottom:0;height:100%}.quarto-dashboard .card .card-toolbar span.irs.irs--shiny{width:10em}.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-line{top:9px}.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-min,.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-max,.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-from,.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-to,.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-single{top:20px}.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-bar{top:8px}.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-handle{top:0px}.quarto-dashboard .card .card-toolbar .shiny-input-checkboxgroup>label{margin-top:6px}.quarto-dashboard .card .card-toolbar .shiny-input-checkboxgroup>.shiny-options-group{margin-top:0;align-items:baseline}.quarto-dashboard .card .card-toolbar .shiny-input-radiogroup>label{margin-top:6px}.quarto-dashboard .card .card-toolbar .shiny-input-radiogroup>.shiny-options-group{align-items:baseline;margin-top:0}.quarto-dashboard .card .card-toolbar .shiny-input-radiogroup>.shiny-options-group>.radio{margin-right:.3em}.quarto-dashboard .card .card-toolbar .form-select{padding-top:.2em;padding-bottom:.2em}.quarto-dashboard .card .card-toolbar .shiny-input-select{min-width:6em}.quarto-dashboard .card .card-toolbar div.checkbox{margin-bottom:0px}.quarto-dashboard .card .card-toolbar>.checkbox:first-child{margin-top:6px}.quarto-dashboard .card-body>table>thead{border-top:none}.quarto-dashboard .card-body>.table>:not(caption)>*>*,.quarto-dashboard .doc-reference section.card-body.doc-group>dl>:not(caption)>*>*,.doc-reference .quarto-dashboard section.card-body.doc-group>dl>:not(caption)>*>*{background-color:#fff}.tableFloatingHeaderOriginal{background-color:#fff;position:sticky !important;top:0 !important}.dashboard-data-table{margin-top:-1px}div.value-box-area span.observablehq--number{font-size:calc(clamp(.1em,15cqw,5em)*1.25);line-height:1.2;color:inherit;font-family:var(--bs-body-font-family)}.quarto-listing{padding-bottom:1em}.listing-pagination{padding-top:.5em}ul.pagination{float:right;padding-left:8px;padding-top:.5em}ul.pagination li{padding-right:.75em}ul.pagination li.disabled a,ul.pagination li.active a{color:#fff;text-decoration:none}ul.pagination li:last-of-type{padding-right:0}.listing-actions-group{display:flex}.quarto-listing-filter{margin-bottom:1em;width:200px;margin-left:auto}.quarto-listing-sort{margin-bottom:1em;margin-right:auto;width:auto}.quarto-listing-sort .input-group-text{font-size:.8em}.input-group-text{border-right:none}.quarto-listing-sort select.form-select{font-size:.8em}.listing-no-matching{text-align:center;padding-top:2em;padding-bottom:3em;font-size:1em}#quarto-margin-sidebar .quarto-listing-category{padding-top:0;font-size:1rem}#quarto-margin-sidebar .quarto-listing-category-title{cursor:pointer;font-weight:600;font-size:1rem}.quarto-listing-category .category{cursor:pointer}.quarto-listing-category .category.active{font-weight:600}.quarto-listing-category.category-cloud{display:flex;flex-wrap:wrap;align-items:baseline}.quarto-listing-category.category-cloud .category{padding-right:5px}.quarto-listing-category.category-cloud .category-cloud-1{font-size:.75em}.quarto-listing-category.category-cloud .category-cloud-2{font-size:.95em}.quarto-listing-category.category-cloud .category-cloud-3{font-size:1.15em}.quarto-listing-category.category-cloud .category-cloud-4{font-size:1.35em}.quarto-listing-category.category-cloud .category-cloud-5{font-size:1.55em}.quarto-listing-category.category-cloud .category-cloud-6{font-size:1.75em}.quarto-listing-category.category-cloud .category-cloud-7{font-size:1.95em}.quarto-listing-category.category-cloud .category-cloud-8{font-size:2.15em}.quarto-listing-category.category-cloud .category-cloud-9{font-size:2.35em}.quarto-listing-category.category-cloud .category-cloud-10{font-size:2.55em}.quarto-listing-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-1{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-2{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-3{grid-template-columns:repeat(3, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-3{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-3{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-4{grid-template-columns:repeat(4, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-4{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-4{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-5{grid-template-columns:repeat(5, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-5{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-5{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-6{grid-template-columns:repeat(6, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-6{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-6{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-7{grid-template-columns:repeat(7, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-7{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-7{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-8{grid-template-columns:repeat(8, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-8{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-8{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-9{grid-template-columns:repeat(9, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-9{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-9{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-10{grid-template-columns:repeat(10, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-10{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-10{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-11{grid-template-columns:repeat(11, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-11{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-11{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-12{grid-template-columns:repeat(12, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-12{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-12{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-grid{gap:1.5em}.quarto-grid-item.borderless{border:none}.quarto-grid-item.borderless .listing-categories .listing-category:last-of-type,.quarto-grid-item.borderless .listing-categories .listing-category:first-of-type{padding-left:0}.quarto-grid-item.borderless .listing-categories .listing-category{border:0}.quarto-grid-link{text-decoration:none;color:inherit}.quarto-grid-link:hover{text-decoration:none;color:inherit}.quarto-grid-item h5.title,.quarto-grid-item .title.h5{margin-top:0;margin-bottom:0}.quarto-grid-item .card-footer{display:flex;justify-content:space-between;font-size:.8em}.quarto-grid-item .card-footer p{margin-bottom:0}.quarto-grid-item p.card-img-top{margin-bottom:0}.quarto-grid-item p.card-img-top>img{object-fit:cover}.quarto-grid-item .card-other-values{margin-top:.5em;font-size:.8em}.quarto-grid-item .card-other-values tr{margin-bottom:.5em}.quarto-grid-item .card-other-values tr>td:first-of-type{font-weight:600;padding-right:1em;padding-left:1em;vertical-align:top}.quarto-grid-item div.post-contents{display:flex;flex-direction:column;text-decoration:none;height:100%}.quarto-grid-item .listing-item-img-placeholder{background-color:rgba(52,58,64,.25);flex-shrink:0}.quarto-grid-item .card-attribution{padding-top:1em;display:flex;gap:1em;text-transform:uppercase;color:#6c757d;font-weight:500;flex-grow:10;align-items:flex-end}.quarto-grid-item .description{padding-bottom:1em}.quarto-grid-item .card-attribution .date{align-self:flex-end}.quarto-grid-item .card-attribution.justify{justify-content:space-between}.quarto-grid-item .card-attribution.start{justify-content:flex-start}.quarto-grid-item .card-attribution.end{justify-content:flex-end}.quarto-grid-item .card-title{margin-bottom:.1em}.quarto-grid-item .card-subtitle{padding-top:.25em}.quarto-grid-item .card-text{font-size:.9em}.quarto-grid-item .listing-reading-time{padding-bottom:.25em}.quarto-grid-item .card-text-small{font-size:.8em}.quarto-grid-item .card-subtitle.subtitle{font-size:.9em;font-weight:600;padding-bottom:.5em}.quarto-grid-item .listing-categories{display:flex;flex-wrap:wrap;padding-bottom:5px}.quarto-grid-item .listing-categories .listing-category{color:#6c757d;border:solid 1px #dee2e6;border-radius:.25rem;text-transform:uppercase;font-size:.65em;padding-left:.5em;padding-right:.5em;padding-top:.15em;padding-bottom:.15em;cursor:pointer;margin-right:4px;margin-bottom:4px}.quarto-grid-item.card-right{text-align:right}.quarto-grid-item.card-right .listing-categories{justify-content:flex-end}.quarto-grid-item.card-left{text-align:left}.quarto-grid-item.card-center{text-align:center}.quarto-grid-item.card-center .listing-description{text-align:justify}.quarto-grid-item.card-center .listing-categories{justify-content:center}table.quarto-listing-table td.image{padding:0px}table.quarto-listing-table td.image img{width:100%;max-width:50px;object-fit:contain}table.quarto-listing-table a{text-decoration:none;word-break:keep-all}table.quarto-listing-table th a{color:inherit}table.quarto-listing-table th a.asc:after{margin-bottom:-2px;margin-left:5px;display:inline-block;height:1rem;width:1rem;background-repeat:no-repeat;background-size:1rem 1rem;background-image:url('data:image/svg+xml,');content:""}table.quarto-listing-table th a.desc:after{margin-bottom:-2px;margin-left:5px;display:inline-block;height:1rem;width:1rem;background-repeat:no-repeat;background-size:1rem 1rem;background-image:url('data:image/svg+xml,');content:""}table.quarto-listing-table.table-hover td{cursor:pointer}.quarto-post.image-left{flex-direction:row}.quarto-post.image-right{flex-direction:row-reverse}@media(max-width: 767.98px){.quarto-post.image-right,.quarto-post.image-left{gap:0em;flex-direction:column}.quarto-post .metadata{padding-bottom:1em;order:2}.quarto-post .body{order:1}.quarto-post .thumbnail{order:3}}.list.quarto-listing-default div:last-of-type{border-bottom:none}@media(min-width: 992px){.quarto-listing-container-default{margin-right:2em}}div.quarto-post{display:flex;gap:2em;margin-bottom:1.5em;border-bottom:1px solid #dee2e6}@media(max-width: 767.98px){div.quarto-post{padding-bottom:1em}}div.quarto-post .metadata{flex-basis:20%;flex-grow:0;margin-top:.2em;flex-shrink:10}div.quarto-post .thumbnail{flex-basis:30%;flex-grow:0;flex-shrink:0}div.quarto-post .thumbnail img{margin-top:.4em;width:100%;object-fit:cover}div.quarto-post .body{flex-basis:45%;flex-grow:1;flex-shrink:0}div.quarto-post .body h3.listing-title,div.quarto-post .body .listing-title.h3{margin-top:0px;margin-bottom:0px;border-bottom:none}div.quarto-post .body .listing-subtitle{font-size:.875em;margin-bottom:.5em;margin-top:.2em}div.quarto-post .body .description{font-size:.9em}div.quarto-post .body pre code{white-space:pre-wrap}div.quarto-post a{color:#212529;text-decoration:none}div.quarto-post .metadata{display:flex;flex-direction:column;font-size:.8em;font-family:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";flex-basis:33%}div.quarto-post .listing-categories{display:flex;flex-wrap:wrap;padding-bottom:5px}div.quarto-post .listing-categories .listing-category{color:#6c757d;border:solid 1px #dee2e6;border-radius:.25rem;text-transform:uppercase;font-size:.65em;padding-left:.5em;padding-right:.5em;padding-top:.15em;padding-bottom:.15em;cursor:pointer;margin-right:4px;margin-bottom:4px}div.quarto-post .listing-description{margin-bottom:.5em}div.quarto-about-jolla{display:flex !important;flex-direction:column;align-items:center;margin-top:10%;padding-bottom:1em}div.quarto-about-jolla .about-image{object-fit:cover;margin-left:auto;margin-right:auto;margin-bottom:1.5em}div.quarto-about-jolla img.round{border-radius:50%}div.quarto-about-jolla img.rounded{border-radius:10px}div.quarto-about-jolla .quarto-title h1.title,div.quarto-about-jolla .quarto-title .title.h1{text-align:center}div.quarto-about-jolla .quarto-title .description{text-align:center}div.quarto-about-jolla h2,div.quarto-about-jolla .h2{border-bottom:none}div.quarto-about-jolla .about-sep{width:60%}div.quarto-about-jolla main{text-align:center}div.quarto-about-jolla .about-links{display:flex}@media(min-width: 992px){div.quarto-about-jolla .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-jolla .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-jolla .about-link{color:rgb(78.4864864865,88,97.5135135135);text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-jolla .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-jolla .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-jolla .about-link:hover{color:#18bc9c}div.quarto-about-jolla .about-link i.bi{margin-right:.15em}div.quarto-about-solana{display:flex !important;flex-direction:column;padding-top:3em !important;padding-bottom:1em}div.quarto-about-solana .about-entity{display:flex !important;align-items:start;justify-content:space-between}@media(min-width: 992px){div.quarto-about-solana .about-entity{flex-direction:row}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity{flex-direction:column-reverse;align-items:center;text-align:center}}div.quarto-about-solana .about-entity .entity-contents{display:flex;flex-direction:column}@media(max-width: 767.98px){div.quarto-about-solana .about-entity .entity-contents{width:100%}}div.quarto-about-solana .about-entity .about-image{object-fit:cover}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-image{margin-bottom:1.5em}}div.quarto-about-solana .about-entity img.round{border-radius:50%}div.quarto-about-solana .about-entity img.rounded{border-radius:10px}div.quarto-about-solana .about-entity .about-links{display:flex;justify-content:left;padding-bottom:1.2em}@media(min-width: 992px){div.quarto-about-solana .about-entity .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-solana .about-entity .about-link{color:rgb(78.4864864865,88,97.5135135135);text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-solana .about-entity .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-solana .about-entity .about-link:hover{color:#18bc9c}div.quarto-about-solana .about-entity .about-link i.bi{margin-right:.15em}div.quarto-about-solana .about-contents{padding-right:1.5em;flex-basis:0;flex-grow:1}div.quarto-about-solana .about-contents main.content{margin-top:0}div.quarto-about-solana .about-contents h2,div.quarto-about-solana .about-contents .h2{border-bottom:none}div.quarto-about-trestles{display:flex !important;flex-direction:row;padding-top:3em !important;padding-bottom:1em}@media(max-width: 991.98px){div.quarto-about-trestles{flex-direction:column;padding-top:0em !important}}div.quarto-about-trestles .about-entity{display:flex !important;flex-direction:column;align-items:center;text-align:center;padding-right:1em}@media(min-width: 992px){div.quarto-about-trestles .about-entity{flex:0 0 42%}}div.quarto-about-trestles .about-entity .about-image{object-fit:cover;margin-bottom:1.5em}div.quarto-about-trestles .about-entity img.round{border-radius:50%}div.quarto-about-trestles .about-entity img.rounded{border-radius:10px}div.quarto-about-trestles .about-entity .about-links{display:flex;justify-content:center}@media(min-width: 992px){div.quarto-about-trestles .about-entity .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-trestles .about-entity .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-trestles .about-entity .about-link{color:rgb(78.4864864865,88,97.5135135135);text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-trestles .about-entity .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-trestles .about-entity .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-trestles .about-entity .about-link:hover{color:#18bc9c}div.quarto-about-trestles .about-entity .about-link i.bi{margin-right:.15em}div.quarto-about-trestles .about-contents{flex-basis:0;flex-grow:1}div.quarto-about-trestles .about-contents h2,div.quarto-about-trestles .about-contents .h2{border-bottom:none}@media(min-width: 992px){div.quarto-about-trestles .about-contents{border-left:solid 1px #dee2e6;padding-left:1.5em}}div.quarto-about-trestles .about-contents main.content{margin-top:0}div.quarto-about-marquee{padding-bottom:1em}div.quarto-about-marquee .about-contents{display:flex;flex-direction:column}div.quarto-about-marquee .about-image{max-height:550px;margin-bottom:1.5em;object-fit:cover}div.quarto-about-marquee img.round{border-radius:50%}div.quarto-about-marquee img.rounded{border-radius:10px}div.quarto-about-marquee h2,div.quarto-about-marquee .h2{border-bottom:none}div.quarto-about-marquee .about-links{display:flex;justify-content:center;padding-top:1.5em}@media(min-width: 992px){div.quarto-about-marquee .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-marquee .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-marquee .about-link{color:rgb(78.4864864865,88,97.5135135135);text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-marquee .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-marquee .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-marquee .about-link:hover{color:#18bc9c}div.quarto-about-marquee .about-link i.bi{margin-right:.15em}@media(min-width: 992px){div.quarto-about-marquee .about-link{border:none}}div.quarto-about-broadside{display:flex;flex-direction:column;padding-bottom:1em}div.quarto-about-broadside .about-main{display:flex !important;padding-top:0 !important}@media(min-width: 992px){div.quarto-about-broadside .about-main{flex-direction:row;align-items:flex-start}}@media(max-width: 991.98px){div.quarto-about-broadside .about-main{flex-direction:column}}@media(max-width: 991.98px){div.quarto-about-broadside .about-main .about-entity{flex-shrink:0;width:100%;height:450px;margin-bottom:1.5em;background-size:cover;background-repeat:no-repeat}}@media(min-width: 992px){div.quarto-about-broadside .about-main .about-entity{flex:0 10 50%;margin-right:1.5em;width:100%;height:100%;background-size:100%;background-repeat:no-repeat}}div.quarto-about-broadside .about-main .about-contents{padding-top:14px;flex:0 0 50%}div.quarto-about-broadside h2,div.quarto-about-broadside .h2{border-bottom:none}div.quarto-about-broadside .about-sep{margin-top:1.5em;width:60%;align-self:center}div.quarto-about-broadside .about-links{display:flex;justify-content:center;column-gap:20px;padding-top:1.5em}@media(min-width: 992px){div.quarto-about-broadside .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-broadside .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-broadside .about-link{color:rgb(78.4864864865,88,97.5135135135);text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-broadside .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-broadside .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-broadside .about-link:hover{color:#18bc9c}div.quarto-about-broadside .about-link i.bi{margin-right:.15em}@media(min-width: 992px){div.quarto-about-broadside .about-link{border:none}}.tippy-box[data-theme~=quarto]{background-color:#fff;border:solid 1px #dee2e6;border-radius:.25rem;color:#212529;font-size:.875rem}.tippy-box[data-theme~=quarto]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=quarto]>.tippy-arrow:after,.tippy-box[data-theme~=quarto]>.tippy-svg-arrow:after{content:"";position:absolute;z-index:-1}.tippy-box[data-theme~=quarto]>.tippy-arrow:after{border-color:rgba(0,0,0,0);border-style:solid}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-6px}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-6px}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-6px}.tippy-box[data-placement^=left]>.tippy-arrow:before{right:-6px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-arrow:after{border-top-color:#dee2e6;border-width:7px 7px 0;top:17px;left:1px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-svg-arrow>svg{top:16px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-svg-arrow:after{top:17px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff;bottom:16px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-arrow:after{border-bottom-color:#dee2e6;border-width:0 7px 7px;bottom:17px;left:1px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-svg-arrow>svg{bottom:15px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-svg-arrow:after{bottom:17px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-arrow:after{border-left-color:#dee2e6;border-width:7px 0 7px 7px;left:17px;top:1px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-svg-arrow>svg{left:11px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-svg-arrow:after{left:12px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff;right:16px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-arrow:after{border-width:7px 7px 7px 0;right:17px;top:1px;border-right-color:#dee2e6}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-svg-arrow>svg{right:11px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-svg-arrow:after{right:12px}.tippy-box[data-theme~=quarto]>.tippy-svg-arrow{fill:#212529}.tippy-box[data-theme~=quarto]>.tippy-svg-arrow:after{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA2czEuNzk2LS4wMTMgNC42Ny0zLjYxNUM1Ljg1MS45IDYuOTMuMDA2IDggMGMxLjA3LS4wMDYgMi4xNDguODg3IDMuMzQzIDIuMzg1QzE0LjIzMyA2LjAwNSAxNiA2IDE2IDZIMHoiIGZpbGw9InJnYmEoMCwgOCwgMTYsIDAuMikiLz48L3N2Zz4=);background-size:16px 6px;width:16px;height:6px}.top-right{position:absolute;top:1em;right:1em}.visually-hidden{border:0;clip:rect(0 0 0 0);height:auto;margin:0;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.hidden{display:none !important}.zindex-bottom{z-index:-1 !important}figure.figure{display:block}.quarto-layout-panel{margin-bottom:1em}.quarto-layout-panel>figure{width:100%}.quarto-layout-panel>figure>figcaption,.quarto-layout-panel>.panel-caption{margin-top:10pt}.quarto-layout-panel>.table-caption{margin-top:0px}.table-caption p{margin-bottom:.5em}.quarto-layout-row{display:flex;flex-direction:row;align-items:flex-start}.quarto-layout-valign-top{align-items:flex-start}.quarto-layout-valign-bottom{align-items:flex-end}.quarto-layout-valign-center{align-items:center}.quarto-layout-cell{position:relative;margin-right:20px}.quarto-layout-cell:last-child{margin-right:0}.quarto-layout-cell figure,.quarto-layout-cell>p{margin:.2em}.quarto-layout-cell img{max-width:100%}.quarto-layout-cell .html-widget{width:100% !important}.quarto-layout-cell div figure p{margin:0}.quarto-layout-cell figure{display:block;margin-inline-start:0;margin-inline-end:0}.quarto-layout-cell table{display:inline-table}.quarto-layout-cell-subref figcaption,figure .quarto-layout-row figure figcaption{text-align:center;font-style:italic}.quarto-figure{position:relative;margin-bottom:1em}.quarto-figure>figure{width:100%;margin-bottom:0}.quarto-figure-left>figure>p,.quarto-figure-left>figure>div{text-align:left}.quarto-figure-center>figure>p,.quarto-figure-center>figure>div{text-align:center}.quarto-figure-right>figure>p,.quarto-figure-right>figure>div{text-align:right}.quarto-figure>figure>div.cell-annotation,.quarto-figure>figure>div code{text-align:left}figure>p:empty{display:none}figure>p:first-child{margin-top:0;margin-bottom:0}figure>figcaption.quarto-float-caption-bottom{margin-bottom:.5em}figure>figcaption.quarto-float-caption-top{margin-top:.5em}div[id^=tbl-]{position:relative}.quarto-figure>.anchorjs-link{position:absolute;top:.6em;right:.5em}div[id^=tbl-]>.anchorjs-link{position:absolute;top:.7em;right:.3em}.quarto-figure:hover>.anchorjs-link,div[id^=tbl-]:hover>.anchorjs-link,h2:hover>.anchorjs-link,.h2:hover>.anchorjs-link,h3:hover>.anchorjs-link,.h3:hover>.anchorjs-link,h4:hover>.anchorjs-link,.h4:hover>.anchorjs-link,h5:hover>.anchorjs-link,.h5:hover>.anchorjs-link,h6:hover>.anchorjs-link,.h6:hover>.anchorjs-link,.reveal-anchorjs-link>.anchorjs-link{opacity:1}#title-block-header{margin-block-end:1rem;position:relative;margin-top:-1px}#title-block-header .abstract{margin-block-start:1rem}#title-block-header .abstract .abstract-title{font-weight:600}#title-block-header a{text-decoration:none}#title-block-header .author,#title-block-header .date,#title-block-header .doi{margin-block-end:.2rem}#title-block-header .quarto-title-block>div{display:flex}#title-block-header .quarto-title-block>div>h1,#title-block-header .quarto-title-block>div>.h1{flex-grow:1}#title-block-header .quarto-title-block>div>button{flex-shrink:0;height:2.25rem;margin-top:0}@media(min-width: 992px){#title-block-header .quarto-title-block>div>button{margin-top:5px}}tr.header>th>p:last-of-type{margin-bottom:0px}table,table.table{margin-top:.5rem;margin-bottom:.5rem}caption,.table-caption{padding-top:.5rem;padding-bottom:.5rem;text-align:center}figure.quarto-float-tbl figcaption.quarto-float-caption-top{margin-top:.5rem;margin-bottom:.25rem;text-align:center}figure.quarto-float-tbl figcaption.quarto-float-caption-bottom{padding-top:.25rem;margin-bottom:.5rem;text-align:center}.utterances{max-width:none;margin-left:-8px}iframe{margin-bottom:1em}details{margin-bottom:1em}details[show]{margin-bottom:0}details>summary{color:#6c757d}details>summary>p:only-child{display:inline}div.code-copy-outer-scaffold{position:relative}dd code:not(.sourceCode),p code:not(.sourceCode){white-space:pre-wrap}code{white-space:pre}@media print{code{white-space:pre-wrap}}pre>code{display:block}pre>code.sourceCode{white-space:pre}pre>code.sourceCode>span>a:first-child::before{text-decoration:none}pre.code-overflow-wrap>code.sourceCode{white-space:pre-wrap}pre.code-overflow-scroll>code.sourceCode{white-space:pre}code a:any-link{color:inherit;text-decoration:none}code a:hover{color:inherit;text-decoration:underline}ul.task-list{padding-left:1em}[data-tippy-root]{display:inline-block}.tippy-content .footnote-back{display:none}.footnote-back{margin-left:.2em}.tippy-content{overflow-x:auto}.quarto-embedded-source-code{display:none}.quarto-unresolved-ref{font-weight:600}.quarto-cover-image{max-width:35%;float:right;margin-left:30px}.cell-output-display .widget-subarea{margin-bottom:1em}.cell-output-display:not(.no-overflow-x),.knitsql-table:not(.no-overflow-x){overflow-x:auto}.panel-input{margin-bottom:1em}.panel-input>div,.panel-input>div>div{display:inline-block;vertical-align:top;padding-right:12px}.panel-input>p:last-child{margin-bottom:0}.layout-sidebar{margin-bottom:1em}.layout-sidebar .tab-content{border:none}.tab-content>.page-columns.active{display:grid}div.sourceCode>iframe{width:100%;height:300px;margin-bottom:-0.5em}a{text-underline-offset:3px}.callout pre.sourceCode{padding-left:0}div.ansi-escaped-output{font-family:monospace;display:block}/*! +* +* ansi colors from IPython notebook's +* +* we also add `bright-[color]-` synonyms for the `-[color]-intense` classes since +* that seems to be what ansi_up emits +* +*/.ansi-black-fg{color:#3e424d}.ansi-black-bg{background-color:#3e424d}.ansi-black-intense-black,.ansi-bright-black-fg{color:#282c36}.ansi-black-intense-black,.ansi-bright-black-bg{background-color:#282c36}.ansi-red-fg{color:#e75c58}.ansi-red-bg{background-color:#e75c58}.ansi-red-intense-red,.ansi-bright-red-fg{color:#b22b31}.ansi-red-intense-red,.ansi-bright-red-bg{background-color:#b22b31}.ansi-green-fg{color:#00a250}.ansi-green-bg{background-color:#00a250}.ansi-green-intense-green,.ansi-bright-green-fg{color:#007427}.ansi-green-intense-green,.ansi-bright-green-bg{background-color:#007427}.ansi-yellow-fg{color:#ddb62b}.ansi-yellow-bg{background-color:#ddb62b}.ansi-yellow-intense-yellow,.ansi-bright-yellow-fg{color:#b27d12}.ansi-yellow-intense-yellow,.ansi-bright-yellow-bg{background-color:#b27d12}.ansi-blue-fg{color:#208ffb}.ansi-blue-bg{background-color:#208ffb}.ansi-blue-intense-blue,.ansi-bright-blue-fg{color:#0065ca}.ansi-blue-intense-blue,.ansi-bright-blue-bg{background-color:#0065ca}.ansi-magenta-fg{color:#d160c4}.ansi-magenta-bg{background-color:#d160c4}.ansi-magenta-intense-magenta,.ansi-bright-magenta-fg{color:#a03196}.ansi-magenta-intense-magenta,.ansi-bright-magenta-bg{background-color:#a03196}.ansi-cyan-fg{color:#60c6c8}.ansi-cyan-bg{background-color:#60c6c8}.ansi-cyan-intense-cyan,.ansi-bright-cyan-fg{color:#258f8f}.ansi-cyan-intense-cyan,.ansi-bright-cyan-bg{background-color:#258f8f}.ansi-white-fg{color:#c5c1b4}.ansi-white-bg{background-color:#c5c1b4}.ansi-white-intense-white,.ansi-bright-white-fg{color:#a1a6b2}.ansi-white-intense-white,.ansi-bright-white-bg{background-color:#a1a6b2}.ansi-default-inverse-fg{color:#fff}.ansi-default-inverse-bg{background-color:#000}.ansi-bold{font-weight:bold}.ansi-underline{text-decoration:underline}:root{--quarto-body-bg: #fff;--quarto-body-color: #212529;--quarto-text-muted: #6c757d;--quarto-border-color: #dee2e6;--quarto-border-width: 1px;--quarto-border-radius: 0.25rem}table.gt_table{color:var(--quarto-body-color);font-size:1em;width:100%;background-color:rgba(0,0,0,0);border-top-width:inherit;border-bottom-width:inherit;border-color:var(--quarto-border-color)}table.gt_table th.gt_column_spanner_outer{color:var(--quarto-body-color);background-color:rgba(0,0,0,0);border-top-width:inherit;border-bottom-width:inherit;border-color:var(--quarto-border-color)}table.gt_table th.gt_col_heading{color:var(--quarto-body-color);font-weight:bold;background-color:rgba(0,0,0,0)}table.gt_table thead.gt_col_headings{border-bottom:1px solid currentColor;border-top-width:inherit;border-top-color:var(--quarto-border-color)}table.gt_table thead.gt_col_headings:not(:first-child){border-top-width:1px;border-top-color:var(--quarto-border-color)}table.gt_table td.gt_row{border-bottom-width:1px;border-bottom-color:var(--quarto-border-color);border-top-width:0px}table.gt_table tbody.gt_table_body{border-top-width:1px;border-bottom-width:1px;border-bottom-color:var(--quarto-border-color);border-top-color:currentColor}div.columns{display:initial;gap:initial}div.column{display:inline-block;overflow-x:initial;vertical-align:top;width:50%}.code-annotation-tip-content{word-wrap:break-word}.code-annotation-container-hidden{display:none !important}dl.code-annotation-container-grid{display:grid;grid-template-columns:min-content auto}dl.code-annotation-container-grid dt{grid-column:1}dl.code-annotation-container-grid dd{grid-column:2}pre.sourceCode.code-annotation-code{padding-right:0}code.sourceCode .code-annotation-anchor{z-index:100;position:relative;float:right;background-color:rgba(0,0,0,0)}input[type=checkbox]{margin-right:.5ch}:root{--mermaid-bg-color: #fff;--mermaid-edge-color: #6c757d;--mermaid-node-fg-color: #212529;--mermaid-fg-color: #212529;--mermaid-fg-color--lighter: rgb(55.7432432432, 62.5, 69.2567567568);--mermaid-fg-color--lightest: rgb(78.4864864865, 88, 97.5135135135);--mermaid-font-family: Lato, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;--mermaid-label-bg-color: #fff;--mermaid-label-fg-color: #2c3e50;--mermaid-node-bg-color: rgba(44, 62, 80, 0.1);--mermaid-node-fg-color: #212529}@media print{:root{font-size:11pt}#quarto-sidebar,#TOC,.nav-page{display:none}.page-columns .content{grid-column-start:page-start}.fixed-top{position:relative}.panel-caption,.figure-caption,figcaption{color:#666}}body.quarto-light .dark-content{display:none !important}body.quarto-dark .light-content{display:none !important}.code-copy-button{position:absolute;top:0;right:0;border:0;margin-top:5px;margin-right:5px;background-color:rgba(0,0,0,0);z-index:3}.code-copy-button-tooltip{font-size:.75em}.code-copy-button>.bi::before{display:inline-block;height:1rem;width:1rem;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:1rem 1rem}.code-copy-button-checked>.bi::before{background-image:url('data:image/svg+xml,')}.code-copy-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}.code-copy-button-checked:hover>.bi::before{background-image:url('data:image/svg+xml,')}main ol ol,main ul ul,main ol ul,main ul ol{margin-bottom:1em}ul>li:not(:has(>p))>ul,ol>li:not(:has(>p))>ul,ul>li:not(:has(>p))>ol,ol>li:not(:has(>p))>ol{margin-bottom:0}ul>li:not(:has(>p))>ul>li:has(>p),ol>li:not(:has(>p))>ul>li:has(>p),ul>li:not(:has(>p))>ol>li:has(>p),ol>li:not(:has(>p))>ol>li:has(>p){margin-top:1rem}body{margin:0}main.page-columns>header>h1.title,main.page-columns>header>.title.h1{margin-bottom:0}@media(min-width: 992px){body .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.fullcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] 35px [page-end-inset page-end] 5fr [screen-end-inset] 1.5em}body.slimcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.listing:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 3em [body-end] 50px [body-end-outset] minmax(0px, 250px) [page-end-inset] minmax(50px, 100px) [page-end] 1fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 175px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 175px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] minmax(25px, 50px) [page-start-inset] minmax(50px, 150px) [body-start-outset] minmax(25px, 50px) [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] minmax(25px, 50px) [body-end-outset] minmax(50px, 150px) [page-end-inset] minmax(25px, 50px) [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(1000px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(50px, 100px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(1000px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 50px [page-start-inset] minmax(50px, 150px) [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(450px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(1000px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 50px [page-start-inset] minmax(50px, 150px) [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(450px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(50px, 150px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] minmax(25px, 50px) [page-start-inset] minmax(50px, 150px) [body-start-outset] minmax(25px, 50px) [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] minmax(25px, 50px) [body-end-outset] minmax(50px, 150px) [page-end-inset] minmax(25px, 50px) [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}}@media(max-width: 991.98px){body .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.fullcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.slimcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.listing:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(1250px - 3em)) [body-content-end body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 145px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 145px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1.5em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(75px, 150px) [page-end-inset] 25px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(1000px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 4fr [screen-end-inset] 1.5em [screen-end]}body.docked.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 4fr [screen-end-inset] 1.5em [screen-end]}body.floating.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(75px, 150px) [page-end-inset] 25px [page-end] 4fr [screen-end-inset] 1.5em [screen-end]}}@media(max-width: 767.98px){body .page-columns,body.fullcontent:not(.floating):not(.docked) .page-columns,body.slimcontent:not(.floating):not(.docked) .page-columns,body.docked .page-columns,body.docked.slimcontent .page-columns,body.docked.fullcontent .page-columns,body.floating .page-columns,body.floating.slimcontent .page-columns,body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}nav[role=doc-toc]{display:none}}body,.page-row-navigation{grid-template-rows:[page-top] max-content [contents-top] max-content [contents-bottom] max-content [page-bottom]}.page-rows-contents{grid-template-rows:[content-top] minmax(max-content, 1fr) [content-bottom] minmax(60px, max-content) [page-bottom]}.page-full{grid-column:screen-start/screen-end !important}.page-columns>*{grid-column:body-content-start/body-content-end}.page-columns.column-page>*{grid-column:page-start/page-end}.page-columns.column-page-left .page-columns.page-full>*,.page-columns.column-page-left>*{grid-column:page-start/body-content-end}.page-columns.column-page-right .page-columns.page-full>*,.page-columns.column-page-right>*{grid-column:body-content-start/page-end}.page-rows{grid-auto-rows:auto}.header{grid-column:screen-start/screen-end;grid-row:page-top/contents-top}#quarto-content{padding:0;grid-column:screen-start/screen-end;grid-row:contents-top/contents-bottom}body.floating .sidebar.sidebar-navigation{grid-column:page-start/body-start;grid-row:content-top/page-bottom}body.docked .sidebar.sidebar-navigation{grid-column:screen-start/body-start;grid-row:content-top/page-bottom}.sidebar.toc-left{grid-column:page-start/body-start;grid-row:content-top/page-bottom}.sidebar.margin-sidebar{grid-column:body-end/page-end;grid-row:content-top/page-bottom}.page-columns .content{grid-column:body-content-start/body-content-end;grid-row:content-top/content-bottom;align-content:flex-start}.page-columns .page-navigation{grid-column:body-content-start/body-content-end;grid-row:content-bottom/page-bottom}.page-columns .footer{grid-column:screen-start/screen-end;grid-row:contents-bottom/page-bottom}.page-columns .column-body{grid-column:body-content-start/body-content-end}.page-columns .column-body-fullbleed{grid-column:body-start/body-end}.page-columns .column-body-outset{grid-column:body-start-outset/body-end-outset;z-index:998;opacity:.999}.page-columns .column-body-outset table{background:#fff}.page-columns .column-body-outset-left{grid-column:body-start-outset/body-content-end;z-index:998;opacity:.999}.page-columns .column-body-outset-left table{background:#fff}.page-columns .column-body-outset-right{grid-column:body-content-start/body-end-outset;z-index:998;opacity:.999}.page-columns .column-body-outset-right table{background:#fff}.page-columns .column-page{grid-column:page-start/page-end;z-index:998;opacity:.999}.page-columns .column-page table{background:#fff}.page-columns .column-page-inset{grid-column:page-start-inset/page-end-inset;z-index:998;opacity:.999}.page-columns .column-page-inset table{background:#fff}.page-columns .column-page-inset-left{grid-column:page-start-inset/body-content-end;z-index:998;opacity:.999}.page-columns .column-page-inset-left table{background:#fff}.page-columns .column-page-inset-right{grid-column:body-content-start/page-end-inset;z-index:998;opacity:.999}.page-columns .column-page-inset-right figcaption table{background:#fff}.page-columns .column-page-left{grid-column:page-start/body-content-end;z-index:998;opacity:.999}.page-columns .column-page-left table{background:#fff}.page-columns .column-page-right{grid-column:body-content-start/page-end;z-index:998;opacity:.999}.page-columns .column-page-right figcaption table{background:#fff}#quarto-content.page-columns #quarto-margin-sidebar,#quarto-content.page-columns #quarto-sidebar{z-index:1}@media(max-width: 991.98px){#quarto-content.page-columns #quarto-margin-sidebar.collapse,#quarto-content.page-columns #quarto-sidebar.collapse,#quarto-content.page-columns #quarto-margin-sidebar.collapsing,#quarto-content.page-columns #quarto-sidebar.collapsing{z-index:1055}}#quarto-content.page-columns main.column-page,#quarto-content.page-columns main.column-page-right,#quarto-content.page-columns main.column-page-left{z-index:0}.page-columns .column-screen-inset{grid-column:screen-start-inset/screen-end-inset;z-index:998;opacity:.999}.page-columns .column-screen-inset table{background:#fff}.page-columns .column-screen-inset-left{grid-column:screen-start-inset/body-content-end;z-index:998;opacity:.999}.page-columns .column-screen-inset-left table{background:#fff}.page-columns .column-screen-inset-right{grid-column:body-content-start/screen-end-inset;z-index:998;opacity:.999}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:screen-start/screen-end;z-index:998;opacity:.999}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:screen-start/body-content-end;z-index:998;opacity:.999}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/screen-end;z-index:998;opacity:.999}.page-columns .column-screen-right table{background:#fff}.page-columns .column-screen-inset-shaded{grid-column:screen-start/screen-end;padding:1em;background:#ecf0f1;z-index:998;opacity:.999;margin-bottom:1em}.zindex-content{z-index:998;opacity:.999}.zindex-modal{z-index:1055;opacity:.999}.zindex-over-content{z-index:999;opacity:.999}img.img-fluid.column-screen,img.img-fluid.column-screen-inset-shaded,img.img-fluid.column-screen-inset,img.img-fluid.column-screen-inset-left,img.img-fluid.column-screen-inset-right,img.img-fluid.column-screen-left,img.img-fluid.column-screen-right{width:100%}@media(min-width: 992px){.margin-caption,div.aside,aside:not(.footnotes):not(.sidebar),.column-margin{grid-column:body-end/page-end !important;z-index:998}.column-sidebar{grid-column:page-start/body-start !important;z-index:998}.column-leftmargin{grid-column:screen-start-inset/body-start !important;z-index:998}.no-row-height{height:1em;overflow:visible}}@media(max-width: 991.98px){.margin-caption,div.aside,aside:not(.footnotes):not(.sidebar),.column-margin{grid-column:body-end/page-end !important;z-index:998}.no-row-height{height:1em;overflow:visible}.page-columns.page-full{overflow:visible}.page-columns.toc-left .margin-caption,.page-columns.toc-left div.aside,.page-columns.toc-left aside:not(.footnotes):not(.sidebar),.page-columns.toc-left .column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;opacity:.999}.page-columns.toc-left .no-row-height{height:initial;overflow:initial}}@media(max-width: 767.98px){.margin-caption,div.aside,aside:not(.footnotes):not(.sidebar),.column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;opacity:.999}.no-row-height{height:initial;overflow:initial}#quarto-margin-sidebar{display:none}#quarto-sidebar-toc-left{display:none}.hidden-sm{display:none}}.panel-grid{display:grid;grid-template-rows:repeat(1, 1fr);grid-template-columns:repeat(24, 1fr);gap:1em}.panel-grid .g-col-1{grid-column:auto/span 1}.panel-grid .g-col-2{grid-column:auto/span 2}.panel-grid .g-col-3{grid-column:auto/span 3}.panel-grid .g-col-4{grid-column:auto/span 4}.panel-grid .g-col-5{grid-column:auto/span 5}.panel-grid .g-col-6{grid-column:auto/span 6}.panel-grid .g-col-7{grid-column:auto/span 7}.panel-grid .g-col-8{grid-column:auto/span 8}.panel-grid .g-col-9{grid-column:auto/span 9}.panel-grid .g-col-10{grid-column:auto/span 10}.panel-grid .g-col-11{grid-column:auto/span 11}.panel-grid .g-col-12{grid-column:auto/span 12}.panel-grid .g-col-13{grid-column:auto/span 13}.panel-grid .g-col-14{grid-column:auto/span 14}.panel-grid .g-col-15{grid-column:auto/span 15}.panel-grid .g-col-16{grid-column:auto/span 16}.panel-grid .g-col-17{grid-column:auto/span 17}.panel-grid .g-col-18{grid-column:auto/span 18}.panel-grid .g-col-19{grid-column:auto/span 19}.panel-grid .g-col-20{grid-column:auto/span 20}.panel-grid .g-col-21{grid-column:auto/span 21}.panel-grid .g-col-22{grid-column:auto/span 22}.panel-grid .g-col-23{grid-column:auto/span 23}.panel-grid .g-col-24{grid-column:auto/span 24}.panel-grid .g-start-1{grid-column-start:1}.panel-grid .g-start-2{grid-column-start:2}.panel-grid .g-start-3{grid-column-start:3}.panel-grid .g-start-4{grid-column-start:4}.panel-grid .g-start-5{grid-column-start:5}.panel-grid .g-start-6{grid-column-start:6}.panel-grid .g-start-7{grid-column-start:7}.panel-grid .g-start-8{grid-column-start:8}.panel-grid .g-start-9{grid-column-start:9}.panel-grid .g-start-10{grid-column-start:10}.panel-grid .g-start-11{grid-column-start:11}.panel-grid .g-start-12{grid-column-start:12}.panel-grid .g-start-13{grid-column-start:13}.panel-grid .g-start-14{grid-column-start:14}.panel-grid .g-start-15{grid-column-start:15}.panel-grid .g-start-16{grid-column-start:16}.panel-grid .g-start-17{grid-column-start:17}.panel-grid .g-start-18{grid-column-start:18}.panel-grid .g-start-19{grid-column-start:19}.panel-grid .g-start-20{grid-column-start:20}.panel-grid .g-start-21{grid-column-start:21}.panel-grid .g-start-22{grid-column-start:22}.panel-grid .g-start-23{grid-column-start:23}@media(min-width: 576px){.panel-grid .g-col-sm-1{grid-column:auto/span 1}.panel-grid .g-col-sm-2{grid-column:auto/span 2}.panel-grid .g-col-sm-3{grid-column:auto/span 3}.panel-grid .g-col-sm-4{grid-column:auto/span 4}.panel-grid .g-col-sm-5{grid-column:auto/span 5}.panel-grid .g-col-sm-6{grid-column:auto/span 6}.panel-grid .g-col-sm-7{grid-column:auto/span 7}.panel-grid .g-col-sm-8{grid-column:auto/span 8}.panel-grid .g-col-sm-9{grid-column:auto/span 9}.panel-grid .g-col-sm-10{grid-column:auto/span 10}.panel-grid .g-col-sm-11{grid-column:auto/span 11}.panel-grid .g-col-sm-12{grid-column:auto/span 12}.panel-grid .g-col-sm-13{grid-column:auto/span 13}.panel-grid .g-col-sm-14{grid-column:auto/span 14}.panel-grid .g-col-sm-15{grid-column:auto/span 15}.panel-grid .g-col-sm-16{grid-column:auto/span 16}.panel-grid .g-col-sm-17{grid-column:auto/span 17}.panel-grid .g-col-sm-18{grid-column:auto/span 18}.panel-grid .g-col-sm-19{grid-column:auto/span 19}.panel-grid .g-col-sm-20{grid-column:auto/span 20}.panel-grid .g-col-sm-21{grid-column:auto/span 21}.panel-grid .g-col-sm-22{grid-column:auto/span 22}.panel-grid .g-col-sm-23{grid-column:auto/span 23}.panel-grid .g-col-sm-24{grid-column:auto/span 24}.panel-grid .g-start-sm-1{grid-column-start:1}.panel-grid .g-start-sm-2{grid-column-start:2}.panel-grid .g-start-sm-3{grid-column-start:3}.panel-grid .g-start-sm-4{grid-column-start:4}.panel-grid .g-start-sm-5{grid-column-start:5}.panel-grid .g-start-sm-6{grid-column-start:6}.panel-grid .g-start-sm-7{grid-column-start:7}.panel-grid .g-start-sm-8{grid-column-start:8}.panel-grid .g-start-sm-9{grid-column-start:9}.panel-grid .g-start-sm-10{grid-column-start:10}.panel-grid .g-start-sm-11{grid-column-start:11}.panel-grid .g-start-sm-12{grid-column-start:12}.panel-grid .g-start-sm-13{grid-column-start:13}.panel-grid .g-start-sm-14{grid-column-start:14}.panel-grid .g-start-sm-15{grid-column-start:15}.panel-grid .g-start-sm-16{grid-column-start:16}.panel-grid .g-start-sm-17{grid-column-start:17}.panel-grid .g-start-sm-18{grid-column-start:18}.panel-grid .g-start-sm-19{grid-column-start:19}.panel-grid .g-start-sm-20{grid-column-start:20}.panel-grid .g-start-sm-21{grid-column-start:21}.panel-grid .g-start-sm-22{grid-column-start:22}.panel-grid .g-start-sm-23{grid-column-start:23}}@media(min-width: 768px){.panel-grid .g-col-md-1{grid-column:auto/span 1}.panel-grid .g-col-md-2{grid-column:auto/span 2}.panel-grid .g-col-md-3{grid-column:auto/span 3}.panel-grid .g-col-md-4{grid-column:auto/span 4}.panel-grid .g-col-md-5{grid-column:auto/span 5}.panel-grid .g-col-md-6{grid-column:auto/span 6}.panel-grid .g-col-md-7{grid-column:auto/span 7}.panel-grid .g-col-md-8{grid-column:auto/span 8}.panel-grid .g-col-md-9{grid-column:auto/span 9}.panel-grid .g-col-md-10{grid-column:auto/span 10}.panel-grid .g-col-md-11{grid-column:auto/span 11}.panel-grid .g-col-md-12{grid-column:auto/span 12}.panel-grid .g-col-md-13{grid-column:auto/span 13}.panel-grid .g-col-md-14{grid-column:auto/span 14}.panel-grid .g-col-md-15{grid-column:auto/span 15}.panel-grid .g-col-md-16{grid-column:auto/span 16}.panel-grid .g-col-md-17{grid-column:auto/span 17}.panel-grid .g-col-md-18{grid-column:auto/span 18}.panel-grid .g-col-md-19{grid-column:auto/span 19}.panel-grid .g-col-md-20{grid-column:auto/span 20}.panel-grid .g-col-md-21{grid-column:auto/span 21}.panel-grid .g-col-md-22{grid-column:auto/span 22}.panel-grid .g-col-md-23{grid-column:auto/span 23}.panel-grid .g-col-md-24{grid-column:auto/span 24}.panel-grid .g-start-md-1{grid-column-start:1}.panel-grid .g-start-md-2{grid-column-start:2}.panel-grid .g-start-md-3{grid-column-start:3}.panel-grid .g-start-md-4{grid-column-start:4}.panel-grid .g-start-md-5{grid-column-start:5}.panel-grid .g-start-md-6{grid-column-start:6}.panel-grid .g-start-md-7{grid-column-start:7}.panel-grid .g-start-md-8{grid-column-start:8}.panel-grid .g-start-md-9{grid-column-start:9}.panel-grid .g-start-md-10{grid-column-start:10}.panel-grid .g-start-md-11{grid-column-start:11}.panel-grid .g-start-md-12{grid-column-start:12}.panel-grid .g-start-md-13{grid-column-start:13}.panel-grid .g-start-md-14{grid-column-start:14}.panel-grid .g-start-md-15{grid-column-start:15}.panel-grid .g-start-md-16{grid-column-start:16}.panel-grid .g-start-md-17{grid-column-start:17}.panel-grid .g-start-md-18{grid-column-start:18}.panel-grid .g-start-md-19{grid-column-start:19}.panel-grid .g-start-md-20{grid-column-start:20}.panel-grid .g-start-md-21{grid-column-start:21}.panel-grid .g-start-md-22{grid-column-start:22}.panel-grid .g-start-md-23{grid-column-start:23}}@media(min-width: 992px){.panel-grid .g-col-lg-1{grid-column:auto/span 1}.panel-grid .g-col-lg-2{grid-column:auto/span 2}.panel-grid .g-col-lg-3{grid-column:auto/span 3}.panel-grid .g-col-lg-4{grid-column:auto/span 4}.panel-grid .g-col-lg-5{grid-column:auto/span 5}.panel-grid .g-col-lg-6{grid-column:auto/span 6}.panel-grid .g-col-lg-7{grid-column:auto/span 7}.panel-grid .g-col-lg-8{grid-column:auto/span 8}.panel-grid .g-col-lg-9{grid-column:auto/span 9}.panel-grid .g-col-lg-10{grid-column:auto/span 10}.panel-grid .g-col-lg-11{grid-column:auto/span 11}.panel-grid .g-col-lg-12{grid-column:auto/span 12}.panel-grid .g-col-lg-13{grid-column:auto/span 13}.panel-grid .g-col-lg-14{grid-column:auto/span 14}.panel-grid .g-col-lg-15{grid-column:auto/span 15}.panel-grid .g-col-lg-16{grid-column:auto/span 16}.panel-grid .g-col-lg-17{grid-column:auto/span 17}.panel-grid .g-col-lg-18{grid-column:auto/span 18}.panel-grid .g-col-lg-19{grid-column:auto/span 19}.panel-grid .g-col-lg-20{grid-column:auto/span 20}.panel-grid .g-col-lg-21{grid-column:auto/span 21}.panel-grid .g-col-lg-22{grid-column:auto/span 22}.panel-grid .g-col-lg-23{grid-column:auto/span 23}.panel-grid .g-col-lg-24{grid-column:auto/span 24}.panel-grid .g-start-lg-1{grid-column-start:1}.panel-grid .g-start-lg-2{grid-column-start:2}.panel-grid .g-start-lg-3{grid-column-start:3}.panel-grid .g-start-lg-4{grid-column-start:4}.panel-grid .g-start-lg-5{grid-column-start:5}.panel-grid .g-start-lg-6{grid-column-start:6}.panel-grid .g-start-lg-7{grid-column-start:7}.panel-grid .g-start-lg-8{grid-column-start:8}.panel-grid .g-start-lg-9{grid-column-start:9}.panel-grid .g-start-lg-10{grid-column-start:10}.panel-grid .g-start-lg-11{grid-column-start:11}.panel-grid .g-start-lg-12{grid-column-start:12}.panel-grid .g-start-lg-13{grid-column-start:13}.panel-grid .g-start-lg-14{grid-column-start:14}.panel-grid .g-start-lg-15{grid-column-start:15}.panel-grid .g-start-lg-16{grid-column-start:16}.panel-grid .g-start-lg-17{grid-column-start:17}.panel-grid .g-start-lg-18{grid-column-start:18}.panel-grid .g-start-lg-19{grid-column-start:19}.panel-grid .g-start-lg-20{grid-column-start:20}.panel-grid .g-start-lg-21{grid-column-start:21}.panel-grid .g-start-lg-22{grid-column-start:22}.panel-grid .g-start-lg-23{grid-column-start:23}}@media(min-width: 1200px){.panel-grid .g-col-xl-1{grid-column:auto/span 1}.panel-grid .g-col-xl-2{grid-column:auto/span 2}.panel-grid .g-col-xl-3{grid-column:auto/span 3}.panel-grid .g-col-xl-4{grid-column:auto/span 4}.panel-grid .g-col-xl-5{grid-column:auto/span 5}.panel-grid .g-col-xl-6{grid-column:auto/span 6}.panel-grid .g-col-xl-7{grid-column:auto/span 7}.panel-grid .g-col-xl-8{grid-column:auto/span 8}.panel-grid .g-col-xl-9{grid-column:auto/span 9}.panel-grid .g-col-xl-10{grid-column:auto/span 10}.panel-grid .g-col-xl-11{grid-column:auto/span 11}.panel-grid .g-col-xl-12{grid-column:auto/span 12}.panel-grid .g-col-xl-13{grid-column:auto/span 13}.panel-grid .g-col-xl-14{grid-column:auto/span 14}.panel-grid .g-col-xl-15{grid-column:auto/span 15}.panel-grid .g-col-xl-16{grid-column:auto/span 16}.panel-grid .g-col-xl-17{grid-column:auto/span 17}.panel-grid .g-col-xl-18{grid-column:auto/span 18}.panel-grid .g-col-xl-19{grid-column:auto/span 19}.panel-grid .g-col-xl-20{grid-column:auto/span 20}.panel-grid .g-col-xl-21{grid-column:auto/span 21}.panel-grid .g-col-xl-22{grid-column:auto/span 22}.panel-grid .g-col-xl-23{grid-column:auto/span 23}.panel-grid .g-col-xl-24{grid-column:auto/span 24}.panel-grid .g-start-xl-1{grid-column-start:1}.panel-grid .g-start-xl-2{grid-column-start:2}.panel-grid .g-start-xl-3{grid-column-start:3}.panel-grid .g-start-xl-4{grid-column-start:4}.panel-grid .g-start-xl-5{grid-column-start:5}.panel-grid .g-start-xl-6{grid-column-start:6}.panel-grid .g-start-xl-7{grid-column-start:7}.panel-grid .g-start-xl-8{grid-column-start:8}.panel-grid .g-start-xl-9{grid-column-start:9}.panel-grid .g-start-xl-10{grid-column-start:10}.panel-grid .g-start-xl-11{grid-column-start:11}.panel-grid .g-start-xl-12{grid-column-start:12}.panel-grid .g-start-xl-13{grid-column-start:13}.panel-grid .g-start-xl-14{grid-column-start:14}.panel-grid .g-start-xl-15{grid-column-start:15}.panel-grid .g-start-xl-16{grid-column-start:16}.panel-grid .g-start-xl-17{grid-column-start:17}.panel-grid .g-start-xl-18{grid-column-start:18}.panel-grid .g-start-xl-19{grid-column-start:19}.panel-grid .g-start-xl-20{grid-column-start:20}.panel-grid .g-start-xl-21{grid-column-start:21}.panel-grid .g-start-xl-22{grid-column-start:22}.panel-grid .g-start-xl-23{grid-column-start:23}}@media(min-width: 1400px){.panel-grid .g-col-xxl-1{grid-column:auto/span 1}.panel-grid .g-col-xxl-2{grid-column:auto/span 2}.panel-grid .g-col-xxl-3{grid-column:auto/span 3}.panel-grid .g-col-xxl-4{grid-column:auto/span 4}.panel-grid .g-col-xxl-5{grid-column:auto/span 5}.panel-grid .g-col-xxl-6{grid-column:auto/span 6}.panel-grid .g-col-xxl-7{grid-column:auto/span 7}.panel-grid .g-col-xxl-8{grid-column:auto/span 8}.panel-grid .g-col-xxl-9{grid-column:auto/span 9}.panel-grid .g-col-xxl-10{grid-column:auto/span 10}.panel-grid .g-col-xxl-11{grid-column:auto/span 11}.panel-grid .g-col-xxl-12{grid-column:auto/span 12}.panel-grid .g-col-xxl-13{grid-column:auto/span 13}.panel-grid .g-col-xxl-14{grid-column:auto/span 14}.panel-grid .g-col-xxl-15{grid-column:auto/span 15}.panel-grid .g-col-xxl-16{grid-column:auto/span 16}.panel-grid .g-col-xxl-17{grid-column:auto/span 17}.panel-grid .g-col-xxl-18{grid-column:auto/span 18}.panel-grid .g-col-xxl-19{grid-column:auto/span 19}.panel-grid .g-col-xxl-20{grid-column:auto/span 20}.panel-grid .g-col-xxl-21{grid-column:auto/span 21}.panel-grid .g-col-xxl-22{grid-column:auto/span 22}.panel-grid .g-col-xxl-23{grid-column:auto/span 23}.panel-grid .g-col-xxl-24{grid-column:auto/span 24}.panel-grid .g-start-xxl-1{grid-column-start:1}.panel-grid .g-start-xxl-2{grid-column-start:2}.panel-grid .g-start-xxl-3{grid-column-start:3}.panel-grid .g-start-xxl-4{grid-column-start:4}.panel-grid .g-start-xxl-5{grid-column-start:5}.panel-grid .g-start-xxl-6{grid-column-start:6}.panel-grid .g-start-xxl-7{grid-column-start:7}.panel-grid .g-start-xxl-8{grid-column-start:8}.panel-grid .g-start-xxl-9{grid-column-start:9}.panel-grid .g-start-xxl-10{grid-column-start:10}.panel-grid .g-start-xxl-11{grid-column-start:11}.panel-grid .g-start-xxl-12{grid-column-start:12}.panel-grid .g-start-xxl-13{grid-column-start:13}.panel-grid .g-start-xxl-14{grid-column-start:14}.panel-grid .g-start-xxl-15{grid-column-start:15}.panel-grid .g-start-xxl-16{grid-column-start:16}.panel-grid .g-start-xxl-17{grid-column-start:17}.panel-grid .g-start-xxl-18{grid-column-start:18}.panel-grid .g-start-xxl-19{grid-column-start:19}.panel-grid .g-start-xxl-20{grid-column-start:20}.panel-grid .g-start-xxl-21{grid-column-start:21}.panel-grid .g-start-xxl-22{grid-column-start:22}.panel-grid .g-start-xxl-23{grid-column-start:23}}main{margin-top:1em;margin-bottom:1em}h1,.h1,h2,.h2{color:inherit;margin-top:2rem;margin-bottom:1rem;font-weight:600}h1.title,.title.h1{margin-top:0}main.content>p:has(+section){margin-bottom:2rem}main.content>section:first-of-type>h2:nth-child(1),main.content>section:first-of-type>.h2:nth-child(1){margin-top:0}h2,.h2{border-bottom:1px solid #dee2e6;padding-bottom:.5rem}h3,.h3{font-weight:600}h3,.h3,h4,.h4{opacity:.9;margin-top:1.5rem}h5,.h5,h6,.h6{opacity:.9}.header-section-number{color:hsl(210,10.8108108108%,39.5098039216%)}.nav-link.active .header-section-number{color:inherit}mark,.mark{padding:0em}.panel-caption,.figure-caption,.subfigure-caption,.table-caption,figcaption,caption{font-size:.9rem;color:hsl(210,10.8108108108%,39.5098039216%)}.quarto-layout-cell[data-ref-parent] caption{color:hsl(210,10.8108108108%,39.5098039216%)}.column-margin figcaption,.margin-caption,div.aside,aside,.column-margin{color:hsl(210,10.8108108108%,39.5098039216%);font-size:.825rem}.panel-caption.margin-caption{text-align:inherit}.column-margin.column-container p{margin-bottom:0}.column-margin.column-container>*:not(.collapse):first-child{padding-bottom:.5em;display:block}.column-margin.column-container>*:not(.collapse):not(:first-child){padding-top:.5em;padding-bottom:.5em;display:block}body.quarto-dark .column-margin.column-container>.light-content+.dark-content{padding-top:0}.column-margin.column-container>*.collapse:not(.show){display:none}@media(min-width: 768px){.column-margin.column-container .callout-margin-content:first-child{margin-top:4.5em}.column-margin.column-container .callout-margin-content-simple:first-child{margin-top:3.5em}}.margin-caption>*{padding-top:.5em;padding-bottom:.5em}@media(max-width: 767.98px){.quarto-layout-row{flex-direction:column}}.nav-tabs .nav-item{margin-top:1px;cursor:pointer}.tab-content{margin-top:0px;border-left:#ecf0f1 1px solid;border-right:#ecf0f1 1px solid;border-bottom:#ecf0f1 1px solid;margin-left:0;padding:1em;margin-bottom:1em}@media(max-width: 767.98px){.layout-sidebar{margin-left:0;margin-right:0}}.panel-sidebar,.panel-sidebar .form-control,.panel-input,.panel-input .form-control,.selectize-dropdown{font-size:.9rem}.panel-sidebar .form-control,.panel-input .form-control{padding-top:.1rem}.tab-pane div.sourceCode{margin-top:0px}.tab-pane>p{padding-top:0}.tab-pane>p:nth-child(1){padding-top:0}.tab-pane>p:last-child{margin-bottom:0}.tab-pane>pre:last-child{margin-bottom:0}.tab-content>.tab-pane:not(.active){display:none !important}div.sourceCode{background-color:rgba(236,240,241,.65);border:1px solid rgba(236,240,241,.65);border-radius:.25rem}pre.sourceCode{background-color:rgba(0,0,0,0)}pre.sourceCode{border:none;font-size:.875em;overflow-y:visible !important;padding:.4em}div.sourceCode{overflow-y:hidden}.callout div.sourceCode{margin-left:initial}.blockquote{font-size:inherit;padding-left:1rem;padding-right:1.5rem;color:hsl(210,10.8108108108%,39.5098039216%)}.blockquote h1:first-child,.blockquote .h1:first-child,.blockquote h2:first-child,.blockquote .h2:first-child,.blockquote h3:first-child,.blockquote .h3:first-child,.blockquote h4:first-child,.blockquote .h4:first-child,.blockquote h5:first-child,.blockquote .h5:first-child{margin-top:0}pre{background-color:initial;padding:initial;border:initial}p code.sourceCode,li code.sourceCode,td code.sourceCode{background-color:rgba(236,240,241,.65)}p pre code:not(.sourceCode),li pre code:not(.sourceCode),pre code:not(.sourceCode){background-color:initial}p code:not(.sourceCode),li code:not(.sourceCode),td code:not(.sourceCode){background-color:rgba(236,240,241,.65);padding:.2em}nav p code:not(.sourceCode),nav li code:not(.sourceCode),nav td code:not(.sourceCode){background-color:rgba(0,0,0,0);padding:0}td code:not(.sourceCode){white-space:pre-wrap}#quarto-embedded-source-code-modal>.modal-dialog{max-width:1000px;padding-left:1.75rem;padding-right:1.75rem}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-body{padding:0}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-body div.sourceCode{margin:0;padding:.2rem .2rem;border-radius:0px;border:none}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-header{padding:.7rem}.code-tools-button{font-size:1rem;padding:.15rem .15rem;margin-left:5px;color:#6c757d;background-color:rgba(0,0,0,0);transition:initial;cursor:pointer}.code-tools-button>.bi::before{display:inline-block;height:1rem;width:1rem;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:1rem 1rem}.code-tools-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}#quarto-embedded-source-code-modal .code-copy-button>.bi::before{background-image:url('data:image/svg+xml,')}#quarto-embedded-source-code-modal .code-copy-button-checked>.bi::before{background-image:url('data:image/svg+xml,')}.sidebar{will-change:top;transition:top 200ms linear;position:sticky;overflow-y:auto;padding-top:1.2em;max-height:100vh}.sidebar.toc-left,.sidebar.margin-sidebar{top:0px;padding-top:1em}.sidebar.quarto-banner-title-block-sidebar>*{padding-top:1.65em}figure .quarto-notebook-link{margin-top:.5em}.quarto-notebook-link{font-size:.75em;color:#6c757d;margin-bottom:1em;text-decoration:none;display:block}.quarto-notebook-link:hover{text-decoration:underline;color:#18bc9c}.quarto-notebook-link::before{display:inline-block;height:.75rem;width:.75rem;margin-bottom:0em;margin-right:.25em;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:.75rem .75rem}.toc-actions i.bi,.quarto-code-links i.bi,.quarto-other-links i.bi,.quarto-alternate-notebooks i.bi,.quarto-alternate-formats i.bi{margin-right:.4em;font-size:.8rem}.quarto-other-links-text-target .quarto-code-links i.bi,.quarto-other-links-text-target .quarto-other-links i.bi{margin-right:.2em}.quarto-other-formats-text-target .quarto-alternate-formats i.bi{margin-right:.1em}.toc-actions i.bi.empty,.quarto-code-links i.bi.empty,.quarto-other-links i.bi.empty,.quarto-alternate-notebooks i.bi.empty,.quarto-alternate-formats i.bi.empty{padding-left:1em}.quarto-notebook h2,.quarto-notebook .h2{border-bottom:none}.quarto-notebook .cell-container{display:flex}.quarto-notebook .cell-container .cell{flex-grow:4}.quarto-notebook .cell-container .cell-decorator{padding-top:1.5em;padding-right:1em;text-align:right}.quarto-notebook .cell-container.code-fold .cell-decorator{padding-top:3em}.quarto-notebook .cell-code code{white-space:pre-wrap}.quarto-notebook .cell .cell-output-stderr pre code,.quarto-notebook .cell .cell-output-stdout pre code{white-space:pre-wrap;overflow-wrap:anywhere}.toc-actions,.quarto-alternate-formats,.quarto-other-links,.quarto-code-links,.quarto-alternate-notebooks{padding-left:0em}.sidebar .toc-actions a,.sidebar .quarto-alternate-formats a,.sidebar .quarto-other-links a,.sidebar .quarto-code-links a,.sidebar .quarto-alternate-notebooks a,.sidebar nav[role=doc-toc] a{text-decoration:none}.sidebar .toc-actions a:hover,.sidebar .quarto-other-links a:hover,.sidebar .quarto-code-links a:hover,.sidebar .quarto-alternate-formats a:hover,.sidebar .quarto-alternate-notebooks a:hover{color:#18bc9c}.sidebar .toc-actions h2,.sidebar .toc-actions .h2,.sidebar .quarto-code-links h2,.sidebar .quarto-code-links .h2,.sidebar .quarto-other-links h2,.sidebar .quarto-other-links .h2,.sidebar .quarto-alternate-notebooks h2,.sidebar .quarto-alternate-notebooks .h2,.sidebar .quarto-alternate-formats h2,.sidebar .quarto-alternate-formats .h2,.sidebar nav[role=doc-toc]>h2,.sidebar nav[role=doc-toc]>.h2{font-weight:500;margin-bottom:.2rem;margin-top:.3rem;font-family:inherit;border-bottom:0;padding-bottom:0;padding-top:0px}.sidebar .toc-actions>h2,.sidebar .toc-actions>.h2,.sidebar .quarto-code-links>h2,.sidebar .quarto-code-links>.h2,.sidebar .quarto-other-links>h2,.sidebar .quarto-other-links>.h2,.sidebar .quarto-alternate-notebooks>h2,.sidebar .quarto-alternate-notebooks>.h2,.sidebar .quarto-alternate-formats>h2,.sidebar .quarto-alternate-formats>.h2{font-size:.8rem}.sidebar nav[role=doc-toc]>h2,.sidebar nav[role=doc-toc]>.h2{font-size:.875rem}.sidebar nav[role=doc-toc]>ul a{border-left:1px solid #ecf0f1;padding-left:.6rem}.sidebar .toc-actions h2>ul a,.sidebar .toc-actions .h2>ul a,.sidebar .quarto-code-links h2>ul a,.sidebar .quarto-code-links .h2>ul a,.sidebar .quarto-other-links h2>ul a,.sidebar .quarto-other-links .h2>ul a,.sidebar .quarto-alternate-notebooks h2>ul a,.sidebar .quarto-alternate-notebooks .h2>ul a,.sidebar .quarto-alternate-formats h2>ul a,.sidebar .quarto-alternate-formats .h2>ul a{border-left:none;padding-left:.6rem}.sidebar .toc-actions ul a:empty,.sidebar .quarto-code-links ul a:empty,.sidebar .quarto-other-links ul a:empty,.sidebar .quarto-alternate-notebooks ul a:empty,.sidebar .quarto-alternate-formats ul a:empty,.sidebar nav[role=doc-toc]>ul a:empty{display:none}.sidebar .toc-actions ul,.sidebar .quarto-code-links ul,.sidebar .quarto-other-links ul,.sidebar .quarto-alternate-notebooks ul,.sidebar .quarto-alternate-formats ul{padding-left:0;list-style:none}.sidebar nav[role=doc-toc] ul{list-style:none;padding-left:0;list-style:none}.sidebar nav[role=doc-toc]>ul{margin-left:.45em}.quarto-margin-sidebar nav[role=doc-toc]{padding-left:.5em}.sidebar .toc-actions>ul,.sidebar .quarto-code-links>ul,.sidebar .quarto-other-links>ul,.sidebar .quarto-alternate-notebooks>ul,.sidebar .quarto-alternate-formats>ul{font-size:.8rem}.sidebar nav[role=doc-toc]>ul{font-size:.875rem}.sidebar .toc-actions ul li a,.sidebar .quarto-code-links ul li a,.sidebar .quarto-other-links ul li a,.sidebar .quarto-alternate-notebooks ul li a,.sidebar .quarto-alternate-formats ul li a,.sidebar nav[role=doc-toc]>ul li a{line-height:1.1rem;padding-bottom:.2rem;padding-top:.2rem;color:inherit}.sidebar nav[role=doc-toc] ul>li>ul>li>a{padding-left:1.2em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>a{padding-left:2.4em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>a{padding-left:3.6em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>ul>li>a{padding-left:4.8em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>ul>li>ul>li>a{padding-left:6em}.sidebar nav[role=doc-toc] ul>li>a.active,.sidebar nav[role=doc-toc] ul>li>ul>li>a.active{border-left:1px solid #18bc9c;color:#18bc9c !important}.sidebar nav[role=doc-toc] ul>li>a:hover,.sidebar nav[role=doc-toc] ul>li>ul>li>a:hover{color:#18bc9c !important}kbd,.kbd{color:#212529;background-color:#f8f9fa;border:1px solid;border-radius:5px;border-color:#dee2e6}.quarto-appendix-contents div.hanging-indent{margin-left:0em}.quarto-appendix-contents div.hanging-indent div.csl-entry{margin-left:1em;text-indent:-1em}.citation a,.footnote-ref{text-decoration:none}.footnotes ol{padding-left:1em}.tippy-content>*{margin-bottom:.7em}.tippy-content>*:last-child{margin-bottom:0}.callout{margin-top:1.25rem;margin-bottom:1.25rem;border-radius:.25rem;overflow-wrap:break-word}.callout .callout-title-container{overflow-wrap:anywhere}.callout.callout-style-simple{padding:.4em .7em;border-left:5px solid;border-right:1px solid #dee2e6;border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.callout.callout-style-default{border-left:5px solid;border-right:1px solid #dee2e6;border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.callout .callout-body-container{flex-grow:1}.callout.callout-style-simple .callout-body{font-size:.9rem;font-weight:400;margin-bottom:-0.4em;margin-top:.5em}.callout.callout-style-default .callout-body{font-size:.9rem;font-weight:400}.callout:not(.no-icon).callout-titled.callout-style-simple .callout-body{padding-left:1.6em}.callout.callout-titled>.callout-header{padding-top:.2em;margin-bottom:-0.2em}.callout.callout-empty-content>.callout-header{margin-bottom:0em;border-bottom-right-radius:calc(0.25rem + -1px)}.callout>.callout-header.collapsed{border-bottom-right-radius:calc(0.25rem + -1px)}.callout.callout-style-simple>div.callout-header{border-bottom:none;font-size:.9rem;font-weight:600;opacity:75%}.callout.callout-style-default>div.callout-header{border-bottom:none;font-weight:600;opacity:85%;font-size:.9rem;padding-left:.5em;padding-right:.5em;border-top-right-radius:calc(0.25rem + -1px)}.callout.callout-style-default .callout-body{padding-left:.5em;padding-right:.5em}.callout.callout-style-default .callout-body>:first-child{padding-top:.5rem;margin-top:0}.callout>div.callout-header[data-bs-toggle=collapse]{cursor:pointer}.callout.callout-style-default .callout-header[aria-expanded=false],.callout.callout-style-default .callout-header[aria-expanded=true]{padding-top:0px;margin-bottom:0px;align-items:center}.callout.callout-titled .callout-body>:last-child:not(.sourceCode),.callout.callout-titled .callout-body>div>:last-child:not(.sourceCode){padding-bottom:.5rem;margin-bottom:0}.callout:not(.callout-titled) .callout-body>:first-child,.callout:not(.callout-titled) .callout-body>div>:first-child{margin-top:.25rem}.callout:not(.callout-titled) .callout-body>:last-child,.callout:not(.callout-titled) .callout-body>div>:last-child{margin-bottom:.2rem}.callout.callout-style-simple:not(.callout-titled) .callout-body>:last-child,.callout.callout-style-simple:not(.callout-titled) .callout-body>div>:last-child{margin-bottom:.5em}.callout.callout-style-simple .callout-icon::before,.callout.callout-style-simple .callout-toggle::before{height:1rem;width:1rem;display:inline-block;content:"";background-repeat:no-repeat;background-size:1rem 1rem}.callout.callout-style-default .callout-icon::before,.callout.callout-style-default .callout-toggle::before{height:.9rem;width:.9rem;display:inline-block;content:"";background-repeat:no-repeat;background-size:.9rem .9rem}.callout.callout-style-default .callout-toggle::before{margin-top:5px}.callout .callout-btn-toggle .callout-toggle::before{transition:transform .2s linear}.callout .callout-header[aria-expanded=false] .callout-toggle::before{transform:rotate(-90deg)}.callout .callout-header[aria-expanded=true] .callout-toggle::before{transform:none}.callout.callout-style-simple:not(.no-icon) div.callout-icon-container{padding-top:.2em;padding-right:.55em}.callout.callout-style-default:not(.no-icon) div.callout-icon-container{padding-top:.1em;padding-right:.35em}.callout.callout-style-default:not(.no-icon) div.callout-title-container{margin-top:-1px}.callout.callout-style-default.callout-caution:not(.no-icon) div.callout-icon-container{padding-top:.3em;padding-right:.35em}.callout>.callout-body>.callout-icon-container>.no-icon,.callout>.callout-header>.callout-icon-container>.no-icon{display:none}div.callout.callout{border-left-color:#6c757d}div.callout.callout-style-default>.callout-header{background-color:#6c757d}div.callout-note.callout{border-left-color:#2c3e50}div.callout-note.callout-style-default>.callout-header{background-color:rgb(233.9,235.7,237.5)}div.callout-note:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-note.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-note .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-tip.callout{border-left-color:#18bc9c}div.callout-tip.callout-style-default>.callout-header{background-color:rgb(231.9,248.3,245.1)}div.callout-tip:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-tip.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-tip .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-warning.callout{border-left-color:#f39c12}div.callout-warning.callout-style-default>.callout-header{background-color:rgb(253.8,245.1,231.3)}div.callout-warning:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-warning.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-warning .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-caution.callout{border-left-color:#fd7e14}div.callout-caution.callout-style-default>.callout-header{background-color:rgb(254.8,242.1,231.5)}div.callout-caution:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-caution.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-caution .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-important.callout{border-left-color:#e74c3c}div.callout-important.callout-style-default>.callout-header{background-color:rgb(252.6,237.1,235.5)}div.callout-important:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-important.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-important .callout-toggle::before{background-image:url('data:image/svg+xml,')}.quarto-toggle-container{display:flex;align-items:center}.quarto-reader-toggle .bi::before,.quarto-color-scheme-toggle .bi::before{display:inline-block;height:1rem;width:1rem;content:"";background-repeat:no-repeat;background-size:1rem 1rem}.sidebar-navigation{padding-left:20px}.navbar{background-color:#2c3e50;color:rgb(204.36,208.68,213)}.navbar .quarto-color-scheme-toggle:not(.alternate) .bi::before{background-image:url('data:image/svg+xml,')}.navbar .quarto-color-scheme-toggle.alternate .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-color-scheme-toggle:not(.alternate) .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-color-scheme-toggle.alternate .bi::before{background-image:url('data:image/svg+xml,')}.quarto-sidebar-toggle{border-color:#dee2e6;border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem;border-style:solid;border-width:1px;overflow:hidden;border-top-width:0px;padding-top:0px !important}.quarto-sidebar-toggle-title{cursor:pointer;padding-bottom:2px;margin-left:.25em;text-align:center;font-weight:400;font-size:.775em}#quarto-content .quarto-sidebar-toggle{background:hsl(0,0%,98%)}#quarto-content .quarto-sidebar-toggle-title{color:#212529}.quarto-sidebar-toggle-icon{color:#dee2e6;margin-right:.5em;float:right;transition:transform .2s ease}.quarto-sidebar-toggle-icon::before{padding-top:5px}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-icon{transform:rotate(-180deg)}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-title{border-bottom:solid #dee2e6 1px}.quarto-sidebar-toggle-contents{background-color:#fff;padding-right:10px;padding-left:10px;margin-top:0px !important;transition:max-height .5s ease}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-contents{padding-top:1em;padding-bottom:10px}@media(max-width: 767.98px){.sidebar-menu-container{padding-bottom:5em}}.quarto-sidebar-toggle:not(.expanded) .quarto-sidebar-toggle-contents{padding-top:0px !important;padding-bottom:0px}nav[role=doc-toc]{z-index:1020}#quarto-sidebar>*,nav[role=doc-toc]>*{transition:opacity .1s ease,border .1s ease}#quarto-sidebar.slow>*,nav[role=doc-toc].slow>*{transition:opacity .4s ease,border .4s ease}.quarto-color-scheme-toggle:not(.alternate).top-right .bi::before{background-image:url('data:image/svg+xml,')}.quarto-color-scheme-toggle.alternate.top-right .bi::before{background-image:url('data:image/svg+xml,')}#quarto-appendix.default{border-top:1px solid #dee2e6}#quarto-appendix.default{background-color:#fff;padding-top:1.5em;margin-top:2em;z-index:998}#quarto-appendix.default .quarto-appendix-heading{margin-top:0;line-height:1.4em;font-weight:600;opacity:.9;border-bottom:none;margin-bottom:0}#quarto-appendix.default .footnotes ol,#quarto-appendix.default .footnotes ol li>p:last-of-type,#quarto-appendix.default .quarto-appendix-contents>p:last-of-type{margin-bottom:0}#quarto-appendix.default .footnotes ol{margin-left:.5em}#quarto-appendix.default .quarto-appendix-secondary-label{margin-bottom:.4em}#quarto-appendix.default .quarto-appendix-bibtex{font-size:.7em;padding:1em;border:solid 1px #dee2e6;margin-bottom:1em}#quarto-appendix.default .quarto-appendix-bibtex code.sourceCode{white-space:pre-wrap}#quarto-appendix.default .quarto-appendix-citeas{font-size:.9em;padding:1em;border:solid 1px #dee2e6;margin-bottom:1em}#quarto-appendix.default .quarto-appendix-heading{font-size:1em !important}#quarto-appendix.default *[role=doc-endnotes]>ol,#quarto-appendix.default .quarto-appendix-contents>*:not(h2):not(.h2){font-size:.9em}#quarto-appendix.default section{padding-bottom:1.5em}#quarto-appendix.default section *[role=doc-endnotes],#quarto-appendix.default section>*:not(a){opacity:.9;word-wrap:break-word}.btn.btn-quarto,div.cell-output-display .btn-quarto{--bs-btn-color: rgb(253.53, 253.62, 253.7);--bs-btn-bg: #6c757d;--bs-btn-border-color: #6c757d;--bs-btn-hover-color: rgb(253.53, 253.62, 253.7);--bs-btn-hover-bg: rgb(130.05, 137.7, 144.5);--bs-btn-hover-border-color: rgb(122.7, 130.8, 138);--bs-btn-focus-shadow-rgb: 130, 137, 144;--bs-btn-active-color: #fff;--bs-btn-active-bg: rgb(137.4, 144.6, 151);--bs-btn-active-border-color: rgb(122.7, 130.8, 138);--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #6c757d;--bs-btn-disabled-border-color: #6c757d}nav.quarto-secondary-nav.color-navbar{background-color:#2c3e50;color:rgb(204.36,208.68,213)}nav.quarto-secondary-nav.color-navbar h1,nav.quarto-secondary-nav.color-navbar .h1,nav.quarto-secondary-nav.color-navbar .quarto-btn-toggle{color:rgb(204.36,208.68,213)}@media(max-width: 991.98px){body.nav-sidebar .quarto-title-banner{margin-bottom:0;padding-bottom:1em}body.nav-sidebar #title-block-header{margin-block-end:0}}p.subtitle{margin-top:.25em;margin-bottom:.5em}code a:any-link{color:inherit;text-decoration-color:#6c757d}/*! light */div.observablehq table thead tr th{background-color:var(--bs-body-bg)}input,button,select,optgroup,textarea{background-color:var(--bs-body-bg)}.code-annotated .code-copy-button{margin-right:1.25em;margin-top:0;padding-bottom:0;padding-top:3px}.code-annotation-gutter-bg{background-color:#fff}.code-annotation-gutter{background-color:rgba(236,240,241,.65)}.code-annotation-gutter,.code-annotation-gutter-bg{height:100%;width:calc(20px + .5em);position:absolute;top:0;right:0}dl.code-annotation-container-grid dt{margin-right:1em;margin-top:.25rem}dl.code-annotation-container-grid dt{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;color:rgb(55.7432432432,62.5,69.2567567568);border:solid rgb(55.7432432432,62.5,69.2567567568) 1px;border-radius:50%;height:22px;width:22px;line-height:22px;font-size:11px;text-align:center;vertical-align:middle;text-decoration:none}dl.code-annotation-container-grid dt[data-target-cell]{cursor:pointer}dl.code-annotation-container-grid dt[data-target-cell].code-annotation-active{color:#fff;border:solid #aaa 1px;background-color:#aaa}pre.code-annotation-code{padding-top:0;padding-bottom:0}pre.code-annotation-code code{z-index:3}#code-annotation-line-highlight-gutter{width:100%;border-top:solid rgba(170,170,170,.2666666667) 1px;border-bottom:solid rgba(170,170,170,.2666666667) 1px;z-index:2;background-color:rgba(170,170,170,.1333333333)}#code-annotation-line-highlight{margin-left:-4em;width:calc(100% + 4em);border-top:solid rgba(170,170,170,.2666666667) 1px;border-bottom:solid rgba(170,170,170,.2666666667) 1px;z-index:2;background-color:rgba(170,170,170,.1333333333)}code.sourceCode .code-annotation-anchor.code-annotation-active{background-color:var(--quarto-hl-normal-color, #aaaaaa);border:solid var(--quarto-hl-normal-color, #aaaaaa) 1px;color:#ecf0f1;font-weight:bolder}code.sourceCode .code-annotation-anchor{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;color:var(--quarto-hl-co-color);border:solid var(--quarto-hl-co-color) 1px;border-radius:50%;height:18px;width:18px;font-size:9px;margin-top:2px}code.sourceCode button.code-annotation-anchor{padding:2px;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none}code.sourceCode a.code-annotation-anchor{line-height:18px;text-align:center;vertical-align:middle;cursor:default;text-decoration:none}@media print{.page-columns .column-screen-inset{grid-column:page-start-inset/page-end-inset;z-index:998;opacity:.999}.page-columns .column-screen-inset table{background:#fff}.page-columns .column-screen-inset-left{grid-column:page-start-inset/body-content-end;z-index:998;opacity:.999}.page-columns .column-screen-inset-left table{background:#fff}.page-columns .column-screen-inset-right{grid-column:body-content-start/page-end-inset;z-index:998;opacity:.999}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:page-start/page-end;z-index:998;opacity:.999}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:page-start/body-content-end;z-index:998;opacity:.999}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/page-end;z-index:998;opacity:.999}.page-columns .column-screen-right table{background:#fff}.page-columns .column-screen-inset-shaded{grid-column:page-start-inset/page-end-inset;padding:1em;background:#ecf0f1;z-index:998;opacity:.999;margin-bottom:1em}}.quarto-video{margin-bottom:1em}.table,.doc-reference section.doc-group>dl{border-top:1px solid rgb(210.6,211.4,212.2);border-bottom:1px solid rgb(210.6,211.4,212.2)}.table>thead,.doc-reference section.doc-group>dl>thead{border-top-width:0;border-bottom:1px solid #909294}.table a,.doc-reference section.doc-group>dl a{word-break:break-word}.table>:not(caption)>*>*,.doc-reference section.doc-group>dl>:not(caption)>*>*{background-color:unset;color:unset}#quarto-document-content .crosstalk-input .checkbox input[type=checkbox],#quarto-document-content .crosstalk-input .checkbox-inline input[type=checkbox]{position:unset;margin-top:unset;margin-left:unset}#quarto-document-content .row{margin-left:unset;margin-right:unset}.quarto-xref{white-space:nowrap}#quarto-draft-alert{margin-top:0px;margin-bottom:0px;padding:.3em;text-align:center;font-size:.9em}#quarto-draft-alert i{margin-right:.3em}#quarto-back-to-top{z-index:1000}pre{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:0.875em;font-weight:400}pre code{font-family:inherit;font-size:inherit;font-weight:inherit}code{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:0.875em;font-weight:400}a{background-color:rgba(0,0,0,0);font-weight:400;text-decoration:underline}.screen-reader-only{position:absolute;clip:rect(0 0 0 0);border:0;height:1px;margin:-1px;overflow:hidden;padding:0;width:1px}a.external:after{content:"";background-image:url('data:image/svg+xml,');background-size:contain;background-repeat:no-repeat;background-position:center center;margin-left:.2em;padding-right:.75em}div.sourceCode code a.external:after{content:none}a.external:after:hover{cursor:pointer}.quarto-ext-icon{display:inline-block;font-size:.75em;padding-left:.3em}.code-with-filename .code-with-filename-file{margin-bottom:0;padding-bottom:2px;padding-top:2px;padding-left:.7em;border:var(--quarto-border-width) solid var(--quarto-border-color);border-radius:var(--quarto-border-radius);border-bottom:0;border-bottom-left-radius:0%;border-bottom-right-radius:0%}.code-with-filename div.sourceCode,.reveal .code-with-filename div.sourceCode{margin-top:0;border-top-left-radius:0%;border-top-right-radius:0%}.code-with-filename .code-with-filename-file pre{margin-bottom:0}.code-with-filename .code-with-filename-file{background-color:rgba(219,219,219,.8)}.quarto-dark .code-with-filename .code-with-filename-file{background-color:#555}.code-with-filename .code-with-filename-file strong{font-weight:400}.quarto-title-banner{margin-bottom:1em;color:rgb(204.36,208.68,213);background:#2c3e50}.quarto-title-banner a{color:rgb(204.36,208.68,213)}.quarto-title-banner h1,.quarto-title-banner .h1,.quarto-title-banner h2,.quarto-title-banner .h2{color:rgb(204.36,208.68,213)}.quarto-title-banner .code-tools-button{color:hsl(210,9.3264248705%,61.8352941176%)}.quarto-title-banner .code-tools-button:hover{color:rgb(204.36,208.68,213)}.quarto-title-banner .code-tools-button>.bi::before{background-image:url('data:image/svg+xml,')}.quarto-title-banner .code-tools-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}.quarto-title-banner .quarto-title .title{font-weight:600}.quarto-title-banner .quarto-categories{margin-top:.75em}@media(min-width: 992px){.quarto-title-banner{padding-top:2.5em;padding-bottom:2.5em}}@media(max-width: 991.98px){.quarto-title-banner{padding-top:1em;padding-bottom:1em}}@media(max-width: 767.98px){body.hypothesis-enabled #title-block-header>*{padding-right:20px}}main.quarto-banner-title-block>section:first-child>h2,main.quarto-banner-title-block>section:first-child>.h2,main.quarto-banner-title-block>section:first-child>h3,main.quarto-banner-title-block>section:first-child>.h3,main.quarto-banner-title-block>section:first-child>h4,main.quarto-banner-title-block>section:first-child>.h4{margin-top:0}.quarto-title .quarto-categories{display:flex;flex-wrap:wrap;row-gap:.5em;column-gap:.4em;padding-bottom:.5em;margin-top:.75em}.quarto-title .quarto-categories .quarto-category{padding:.25em .75em;font-size:.65em;text-transform:uppercase;border:solid 1px;border-radius:.25rem;opacity:.6}.quarto-title .quarto-categories .quarto-category a{color:inherit}.quarto-title-meta-container{display:grid;grid-template-columns:1fr auto}.quarto-title-meta-column-end{display:flex;flex-direction:column;padding-left:1em}.quarto-title-meta-column-end a .bi{margin-right:.3em}#title-block-header.quarto-title-block.default .quarto-title-meta{display:grid;grid-template-columns:repeat(2, 1fr);grid-column-gap:1em}#title-block-header.quarto-title-block.default .quarto-title .title{margin-bottom:0}#title-block-header.quarto-title-block.default .quarto-title-author-orcid img{margin-top:-0.2em;height:.8em;width:.8em}#title-block-header.quarto-title-block.default .quarto-title-author-email{opacity:.7}#title-block-header.quarto-title-block.default .quarto-description p:last-of-type{margin-bottom:0}#title-block-header.quarto-title-block.default .quarto-title-meta-contents p,#title-block-header.quarto-title-block.default .quarto-title-authors p,#title-block-header.quarto-title-block.default .quarto-title-affiliations p{margin-bottom:.1em}#title-block-header.quarto-title-block.default .quarto-title-meta-heading{text-transform:uppercase;margin-top:1em;font-size:.8em;opacity:.8;font-weight:400}#title-block-header.quarto-title-block.default .quarto-title-meta-contents{font-size:.9em}#title-block-header.quarto-title-block.default .quarto-title-meta-contents p.affiliation:last-of-type{margin-bottom:.1em}#title-block-header.quarto-title-block.default p.affiliation{margin-bottom:.1em}#title-block-header.quarto-title-block.default .keywords,#title-block-header.quarto-title-block.default .description,#title-block-header.quarto-title-block.default .abstract{margin-top:0}#title-block-header.quarto-title-block.default .keywords>p,#title-block-header.quarto-title-block.default .description>p,#title-block-header.quarto-title-block.default .abstract>p{font-size:.9em}#title-block-header.quarto-title-block.default .keywords>p:last-of-type,#title-block-header.quarto-title-block.default .description>p:last-of-type,#title-block-header.quarto-title-block.default .abstract>p:last-of-type{margin-bottom:0}#title-block-header.quarto-title-block.default .keywords .block-title,#title-block-header.quarto-title-block.default .description .block-title,#title-block-header.quarto-title-block.default .abstract .block-title{margin-top:1em;text-transform:uppercase;font-size:.8em;opacity:.8;font-weight:400}#title-block-header.quarto-title-block.default .quarto-title-meta-author{display:grid;grid-template-columns:minmax(max-content, 1fr) 1fr;grid-column-gap:1em}.quarto-title-tools-only{display:flex;justify-content:right}.bg-primary .navbar-nav .show>.nav-link,.bg-primary .navbar-nav .nav-link.active,.bg-primary .navbar-nav .nav-link:hover,.bg-primary .navbar-nav .nav-link:focus{color:#18bc9c !important}.nav-tabs .nav-link.active,.nav-tabs .nav-link.active:focus,.nav-tabs .nav-link.active:hover,.nav-tabs .nav-item.open .nav-link,.nav-tabs .nav-item.open .nav-link:focus,.nav-tabs .nav-item.open .nav-link:hover{color:#2c3e50}.pagination a:hover{text-decoration:none}.badge.bg-light{color:#7b8a8b}.alert{color:#fff;border:none}.alert a,.alert .alert-link{color:#fff;text-decoration:underline}.alert-default{background-color:#6c757d}.alert-primary{background-color:#2c3e50}.alert-secondary{background-color:#6c757d}.alert-success{background-color:#18bc9c}.alert-info{background-color:#3498db}.alert-warning{background-color:#f39c12}.alert-danger{background-color:#e74c3c}.alert-light{background-color:#ecf0f1}.alert-dark{background-color:#7b8a8b}.alert-light,.alert-light a,.alert-light .alert-link{color:#212529}.modal .btn-close,.toast .btn-close,.offcanvas .btn-close{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e")}a{text-decoration:none}a.gdls-link{text-decoration:underline;text-underline-offset:.25em;text-decoration-thickness:.125em}a.gdls-code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:.875em}h1.title,.title.h1{font-weight:600 !important}@media(min-width: 992px){h1.title,.title.h1{font-size:2.3rem}}h2,.h2{border-bottom:none;padding-bottom:0}h1.changelog-version,.changelog-version.h1,h2.changelog-version,.changelog-version.h2{display:flex;align-items:center;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1.6rem}h1.changelog-version::before,.changelog-version.h1::before,h2.changelog-version::before,.changelog-version.h2::before{content:"";width:1.15em;height:1.15em;flex:0 0 1.15em;transform:translateY(0.08em);background-color:currentColor;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.59 13.41 11 3H4v7l9.59 9.59a2 2 0 0 0 2.82 0l4.18-4.18a2 2 0 0 0 0-2.82Z'/%3E%3Cline x1='7' y1='7' x2='7.01' y2='7'/%3E%3C/svg%3E") no-repeat center/contain;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.59 13.41 11 3H4v7l9.59 9.59a2 2 0 0 0 2.82 0l4.18-4.18a2 2 0 0 0 0-2.82Z'/%3E%3Cline x1='7' y1='7' x2='7.01' y2='7'/%3E%3C/svg%3E") no-repeat center/contain}.description{font-style:italic}@media(max-width: 767.98px){.description{padding-bottom:1em}}table.gd-summary-table{border:none;margin:1em 0}table.gd-summary-table thead{display:none}table.gd-summary-table td,table.gd-summary-table th{border:none;padding:.5em .75em;vertical-align:top}table.gd-summary-table td{border-top:1px solid var(--bs-border-color, #dee2e6)}table.gd-summary-table tr:first-child td{border-top:none}table.gd-summary-table td:first-child{width:40%;font-weight:500;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}table.gd-summary-table td:first-child a{color:var(--bs-body-color);text-decoration:underline;text-underline-offset:.2em}table.gd-summary-table td:first-child a:hover{color:var(--bs-link-color)}table.gd-summary-table td:last-child{color:var(--bs-secondary-color, #6c757d);font-family:"Open Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}body.quarto-dark table.gd-summary-table td:last-child{color:var(--bs-body-color)}.table>tbody,.doc-reference section.doc-group>dl>tbody{border-bottom-color:#dee2e6}.navbar .dropdown-item{color:#343a40}.doc-reference section.doc-group>dl{border-top-style:dashed;border-bottom-style:dashed;padding-top:.5em}.doc-reference section.doc-group>dl>dt{margin-left:0px !important}.doc-reference dd>p:last-child{margin-bottom:0}.doc-reference dt a{color:inherit;text-decoration:underline;font-weight:bold;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:.875em;text-underline-offset:.25em;text-decoration-thickness:.125em;word-break:initial}.doc-api-page .badge{position:relative;top:-3px}h2.doc-parameters,.doc-parameters.h2,h2.doc-returns,.doc-returns.h2,h2.doc-attributes,.doc-attributes.h2,h2.doc-functions,.doc-functions.h2,h2.doc-methods,.doc-methods.h2,h2.doc-classes,.doc-classes.h2,h2.doc-group,.doc-group.h2{font-size:22px;border-bottom:none;padding-bottom:0}header span.doc-object-name,h1 span.doc-object-name,.h1 span.doc-object-name,h2 span.doc-object-name,.h2 span.doc-object-name,h3 span.doc-object-name,.h3 span.doc-object-name,h4 span.doc-object-name,.h4 span.doc-object-name{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1.25rem}.doc-object span.doc-object-name:not(h1.title>span):not(.title.h1>span){opacity:.85}.doc-subject>p{font-style:italic}.content code.doc-symbol{font-size:.9rem}.doc-usage-source{display:flex;justify-content:space-between;align-items:baseline}.doc-usage-source p{margin-bottom:0rem;font-size:.7rem;text-transform:uppercase}.doc-usage-source>p:first-child{color:#aaa}.doc-usage-source a{color:#4682b4 !important;text-decoration:underline;font-weight:600}.doc-signature div.sourceCode{margin-top:.15rem;border-radius:0 !important}.doc-signature>div:first-child{background-color:rgb(241.6288,242.3344,243.04)}.doc-signature code{max-height:20rem;overflow:auto}.doc-signature>p:first-child{border-radius:.25rem}.doc-signature>p:first-child code{display:block}.doc-signature>p:first-child code a{color:#2c3e50}.doc-text:has(+section){margin-bottom:2rem}section:has(>h2.doc-warnings,>.doc-warnings.h2,>h3.doc-warnings,>.doc-warnings.h3){border-left:4px solid #d97706;background-color:#fffbeb;padding:.75rem 1rem;border-radius:4px;margin-top:1rem;margin-bottom:1rem;color:#1f2937}section:has(>h2.doc-warnings,>.doc-warnings.h2,>h3.doc-warnings,>.doc-warnings.h3)>:is(h2,.h2,h3,.h3){font-size:.875rem;font-weight:600;color:#1f2937;margin-top:0;margin-bottom:.25rem}section:has(>h2.doc-warnings,>.doc-warnings.h2,>h3.doc-warnings,>.doc-warnings.h3)>:is(h2,.h2,h3,.h3)::before{content:"⚠️"}section:has(>h2.doc-warnings,>.doc-warnings.h2,>h3.doc-warnings,>.doc-warnings.h3)>p{margin-bottom:0;color:#1f2937}section:has(>h2.doc-notes,>.doc-notes.h2,>h3.doc-notes,>.doc-notes.h3){border-left:4px solid #3b82f6;background-color:#eff6ff;padding:.75rem 1rem;border-radius:4px;margin-top:1rem;margin-bottom:1rem;color:#1f2937}section:has(>h2.doc-notes,>.doc-notes.h2,>h3.doc-notes,>.doc-notes.h3)>:is(h2,.h2,h3,.h3){font-size:.875rem;font-weight:600;color:#1f2937;margin-top:0;margin-bottom:.25rem}section:has(>h2.doc-notes,>.doc-notes.h2,>h3.doc-notes,>.doc-notes.h3)>:is(h2,.h2,h3,.h3)::before{content:"ℹ️"}section:has(>h2.doc-notes,>.doc-notes.h2,>h3.doc-notes,>.doc-notes.h3)>p{margin-bottom:0;color:#1f2937}:is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dl>dt{font-weight:normal}:is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dl>dd>table{min-width:33%;width:0}:is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dl>dd>table>thead{border-top:0rem solid #dee2e6;border-bottom:.15em solid #dee2e6}:is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dt code,.doc-signature>p>code{display:block;font-weight:normal}.doc-text dt code{font-weight:normal}:is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dt code a,.doc-signature>p>code a{color:inherit;text-decoration:none}section.doc-attributes>section.doc-attribute,section.doc-methods>section.doc-method{border-left:.025rem solid #adb5bd;backgroud-color:aqua}:is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) .doc-parameter-name{font-weight:bold}h2:is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples),.h2:is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples){font-size:1.295rem}#toc-title{font-weight:600 !important;font-size:15px;color:dimgray;text-transform:uppercase}.sidebar nav li>a>code{color:#7d12ba;background-color:#f8f9fa;padding:.075rem .075rem}.gd-ref-sidebar #quarto-sidebar .sidebar-item-text{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}span.doc-object-name:is(.doc-class-name,.doc-method-name,.doc-module-name,.doc-function-name,.doc-alias-name,.doc-attribute-name,.doc-type-name,.doc-typevar)::before{font-size:.9rem;font-family:monospace;margin-right:.5rem;border-radius:.25rem}.sidebar span.doc-object-name:is(.doc-class-name,.doc-method-name,.doc-module-name,.doc-function-name,.doc-alias-name,.doc-attribute-name,.doc-type-name,.doc-typevar)::before{font-size:.55rem}.content span.doc-label::after{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:.785rem;padding:.125rem .25rem;margin-left:1rem;vertical-align:middle;border-radius:.25rem;border-width:1px;border-style:solid}.content span.doc-label-class::after{content:"class"}.content span.doc-label-dataclass::after{content:"dataclass"}.content span.doc-label-namedtuple::after{content:"namedtuple"}.content span.doc-label-typeddict::after{content:"typeddict"}.content span.doc-label-protocol::after{content:"protocol"}.content span.doc-label-abc::after{content:"abc"}.content span.doc-label-enum::after{content:"enum"}.content span.doc-label-method::after{content:"method"}.content span.doc-label-classmethod::after{content:"classmethod"}.content span.doc-label-staticmethod::after{content:"staticmethod"}.content span.doc-label-function::after{content:"function"}.content span.doc-label-async::after{content:"async"}.content span.doc-label-exception::after{content:"exception"}.content span.doc-label-property::after{content:"property"}.content span.doc-label-constant::after{content:"constant"}.content span.doc-label-typealias::after{content:"typealias"}.content span.doc-label-cli::after{content:"cli"}.content span.doc-label-cli-group::after{content:"cli-group"}.content span.doc-label-mcp-tool::after{content:"mcp-tool"}.content span.doc-label-mcp-resource::after{content:"mcp-resource"}.content span.doc-label-mcp-resource-template::after{content:"mcp-resource-template"}.content span.doc-label-mcp-prompt::after{content:"mcp-prompt"}.content span.doc-label-mcp::after{content:"mcp"}.content span.doc-label-class::after{color:rgb(90.4,25.2,209.6);border-color:rgb(90.4,25.2,209.6);background-color:rgb(246.77,243.51,252.73)}.content span.doc-label-dataclass::after{color:rgb(90.4,25.2,209.6);border-color:rgb(90.4,25.2,209.6);background-color:rgb(246.77,243.51,252.73)}.content span.doc-label-namedtuple::after{color:rgb(90.4,25.2,209.6);border-color:rgb(90.4,25.2,209.6);background-color:rgb(246.77,243.51,252.73)}.content span.doc-label-typeddict::after{color:rgb(90.4,25.2,209.6);border-color:rgb(90.4,25.2,209.6);background-color:rgb(246.77,243.51,252.73)}.content span.doc-label-protocol::after{color:rgb(90.4,25.2,209.6);border-color:rgb(90.4,25.2,209.6);background-color:rgb(246.77,243.51,252.73)}.content span.doc-label-abc::after{color:rgb(90.4,25.2,209.6);border-color:rgb(90.4,25.2,209.6);background-color:rgb(246.77,243.51,252.73)}.content span.doc-label-enum::after{color:rgb(90.4,25.2,209.6);border-color:rgb(90.4,25.2,209.6);background-color:rgb(246.77,243.51,252.73)}.content span.doc-label-method::after{color:rgb(42.08,109.68,156.16);border-color:rgb(42.08,109.68,156.16);background-color:rgb(244.354,247.734,250.058)}.content span.doc-label-classmethod::after{color:rgb(42.08,109.68,156.16);border-color:rgb(42.08,109.68,156.16);background-color:rgb(244.354,247.734,250.058)}.content span.doc-label-staticmethod::after{color:rgb(42.08,109.68,156.16);border-color:rgb(42.08,109.68,156.16);background-color:rgb(244.354,247.734,250.058)}.content span.doc-label-function::after,.content span.doc-label-async::after{color:rgb(120.16,42.16,83.2);border-color:rgb(120.16,42.16,83.2);background-color:rgb(248.258,244.358,246.41)}.content span.doc-label-property::after{color:rgb(29.28,141.04,112.64);border-color:rgb(29.28,141.04,112.64);background-color:rgb(243.714,249.302,247.882)}.content span.doc-label-constant::after{color:rgb(211.2,113.2,32);border-color:rgb(211.2,113.2,32);background-color:rgb(252.81,247.91,243.85)}.content span.doc-label-typealias::after{color:rgb(203.2,137.2,30.4);border-color:rgb(203.2,137.2,30.4);background-color:rgb(252.41,249.11,243.77)}.content span.doc-label-cli::after{color:rgb(24.16,132.72,115.84);border-color:rgb(24.16,132.72,115.84);background-color:rgb(243.458,248.886,248.042)}.content span.doc-label-cli-group::after{content:"cli-group";color:rgb(24.16,132.72,115.84);border-color:rgb(24.16,132.72,115.84);background-color:rgb(243.458,248.886,248.042)}.content span.doc-label-mcp-tool::after{content:"tool";color:#e6194b;border-color:#e6194b;background-color:rgb(253.75,243.5,246)}.content span.doc-label-mcp-resource::after{content:"resource";color:#3cb44b;border-color:#3cb44b;background-color:rgb(245.25,251.25,246)}.content span.doc-label-mcp-resource-template::after{content:"resource template";color:#f032e6;border-color:#f032e6;background-color:rgb(254.25,244.75,253.75)}.content span.doc-label-mcp-prompt::after{content:"prompt";color:#4363d8;border-color:#4363d8;background-color:rgb(245.6,247.2,253.05)}.content span.doc-label-mcp::after{content:"mcp";color:rgb(79.84,54.64,139.52);border-color:rgb(79.84,54.64,139.52);background-color:rgb(246.242,244.982,249.226)}.mcp-capability-tiles{max-width:28rem;margin-bottom:1.5rem}.mcp-capability-tiles>p{display:grid;grid-template-columns:1fr 1fr;gap:.5rem;margin:0;padding-top:10px}.mcp-tile{display:flex;align-items:center;justify-content:space-between;padding:.5rem .85rem;border-radius:.375rem;font-size:.875rem;font-weight:500;border:1px solid}.mcp-tile-label{flex:1}.mcp-tile-count{font-weight:700;font-size:1rem;margin-left:.5rem}.mcp-tile-tools{color:#e6194b;border-color:#e6194b;background-color:rgb(253,236.6,240.6)}.mcp-tile-resources{color:#3cb44b;border-color:#3cb44b;background-color:rgb(239.4,249,240.6)}.mcp-tile-templates{color:#f032e6;border-color:#f032e6;background-color:rgb(253.8,238.6,253)}.mcp-tile-prompts{color:#4363d8;border-color:#4363d8;background-color:rgb(239.96,242.52,251.88)}.mcp-tile-instructions{color:#f58231;border-color:#f58231;background-color:rgb(254.2,245,238.52)}.mcp-tile-completions{color:#911eb4;border-color:#911eb4;background-color:rgb(246.2,237,249)}span.doc-method-name::after,dt a.doc-method-name::after{content:"()"}[data-bs-theme=dark] .sidebar nav li>a>code{color:inherit;background-color:rgba(0,0,0,0)}[data-bs-theme=dark] :is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dt code{color:#e2e8f0 !important;background-color:#2d3748 !important}[data-bs-theme=dark] :is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dt code span{color:#e2e8f0 !important}[data-bs-theme=dark] :is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dt code .doc-parameter-name{color:#f7fafc !important}[data-bs-theme=dark] :is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dt code .doc-parameter-annotation,[data-bs-theme=dark] :is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dt code .doc-parameter-annotation-sep,[data-bs-theme=dark] :is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dt code .doc-parameter-default,[data-bs-theme=dark] :is(.doc-parameters,.doc-other-parameters,.doc-returns,.doc-yields,.doc-receives,.doc-raises,.doc-warns,.doc-attributes,.doc-parameter-attributes,.doc-init-parameters,.doc-see-also,.doc-examples) dt code .doc-parameter-default-sep{color:#cbd5e0 !important}[data-bs-theme=dark] .doc-signature div.sourceCode{background-color:#2d3748 !important}[data-bs-theme=dark] .doc-signature code{color:#e2e8f0 !important}[data-bs-theme=dark] .doc-signature code span:not(.sig-class,.sig-name,.cn-none,.cn-bool,.op){color:#e2e8f0 !important}[data-bs-theme=dark] .doc-signature.doc-attribute code{background-color:#2d3748 !important;color:#e2e8f0 !important}[data-bs-theme=dark] .doc-signature.doc-attribute .doc-parameter-name,[data-bs-theme=dark] .doc-signature.doc-attribute .doc-parameter-annotation-sep,[data-bs-theme=dark] .doc-signature.doc-attribute .doc-parameter-annotation{color:#fff !important}[data-bs-theme=dark] section:has(>h2.doc-warnings,>.doc-warnings.h2,>h3.doc-warnings,>.doc-warnings.h3){background-color:#422006 !important;border-color:#d97706 !important;color:#fef3c7 !important}[data-bs-theme=dark] section:has(>h2.doc-warnings,>.doc-warnings.h2,>h3.doc-warnings,>.doc-warnings.h3)>:is(h2,.h2,h3,.h3){color:#fbbf24 !important}[data-bs-theme=dark] section:has(>h2.doc-warnings,>.doc-warnings.h2,>h3.doc-warnings,>.doc-warnings.h3)>p{color:#fef3c7 !important}[data-bs-theme=dark] section:has(>h2.doc-notes,>.doc-notes.h2,>h3.doc-notes,>.doc-notes.h3){background-color:#1e3a5f !important;border-color:#3b82f6 !important;color:#dbeafe !important}[data-bs-theme=dark] section:has(>h2.doc-notes,>.doc-notes.h2,>h3.doc-notes,>.doc-notes.h3)>:is(h2,.h2,h3,.h3){color:#93c5fd !important}[data-bs-theme=dark] section:has(>h2.doc-notes,>.doc-notes.h2,>h3.doc-notes,>.doc-notes.h3)>p{color:#dbeafe !important}[data-bs-theme=dark] .callout{color:var(--bs-body-color) !important}[data-bs-theme=dark] .callout .callout-title-container{color:var(--bs-body-color) !important}[data-bs-theme=dark] .callout .callout-body p{color:var(--bs-body-color) !important}[data-bs-theme=dark] .quarto-post .listing-date,[data-bs-theme=dark] .quarto-post .listing-author{color:var(--bs-body-color)}[data-bs-theme=dark] .quarto-post .listing-title a{color:var(--bs-body-color)}html.theme-loading{visibility:hidden}html.theme-loading body{visibility:hidden}h2.title,.title.h2{margin-top:.5rem;border-bottom:none;padding-bottom:0}.table a,.doc-reference section.doc-group>dl a{text-underline-offset:4px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;color:inherit;font-weight:bold;font-size:.875em;word-break:initial;text-decoration-thickness:2px}code span.sig-class{color:#0e84b5;font-weight:600}code span.sig-name{color:#4758ab;font-weight:600}code span.cn-none{color:#7d4e9e;font-weight:500}code span.cn-bool{color:#07a;font-weight:600}#cb1 code span.op{color:#d14d00;font-weight:500}#cb1 code span.overload-spacer{display:block;height:.35em;user-select:none}.navbar-brand img{max-height:45px;padding-right:0px;margin-left:5px;margin-right:12px;transition:transform .3s ease}.navbar-brand img:hover{transform:scale(1.15)}body{background-color:var(--gd-bg-primary, #FCFEFF)}p a{color:#000;text-decoration:underline;text-underline-offset:4px}li a{color:#000;text-decoration:underline;text-underline-offset:4px}.citation a[role=doc-biblioref]{color:var(--gd-citation-color);text-decoration:underline dotted;text-decoration-thickness:1px;text-underline-offset:3px}.citation a[role=doc-biblioref]:hover{color:var(--gd-citation-color);text-decoration-style:solid}section.level1:has(>#refs){margin-top:2rem;padding-top:1.5rem;border-top:1px solid var(--gd-border-color)}section.level1:has(>#refs)>:first-child{margin-top:0}#refs:not(section>#refs){margin-top:2.5rem;padding-top:1.5rem;border-top:1px solid var(--gd-border-color)}html.quarto-dark #quarto-appendix.default,body.quarto-dark #quarto-appendix.default{background-color:rgba(0,0,0,0);border-top-color:var(--gd-border-color)}#quarto-appendix #quarto-bibliography>.quarto-appendix-heading{font-size:1.85rem !important;font-weight:500;margin-bottom:1rem}#refs{font-size:.9em;color:var(--gd-text-secondary)}#refs .csl-entry{margin-bottom:.6rem}#refs .csl-entry:last-child{margin-bottom:0}#refs.hanging-indent{margin-left:0}#refs.hanging-indent .csl-entry{margin-left:1em;text-indent:-1em}.column-margin a:has(.bi),.column-margin a:has(.fa-brands),.column-margin a:has(.ror-sidebar-icon){color:#495057;text-decoration:none}.column-margin a:has(.bi):hover,.column-margin a:has(.fa-brands):hover,.column-margin a:has(.ror-sidebar-icon):hover{color:#212529}@media(min-width: 992px){body.nav-sidebar.floating.fullcontent .page-columns{grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] minmax(25px, 50px) [page-start-inset] minmax(50px, 150px) [body-start-outset] minmax(25px, 50px) [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] minmax(25px, 50px) [body-end-outset] minmax(50px, 150px) [page-end-inset] minmax(25px, 50px) [page-end] 5fr [screen-end-inset] 1.5em [screen-end] !important}main.content:has(.gd-meta-sidebar){position:relative;overflow:visible}.gd-meta-sidebar{position:absolute;top:0;left:100%;margin-left:1.5em;width:200px}.gd-meta-sidebar h3,.gd-meta-sidebar .h3,.gd-meta-sidebar h4,.gd-meta-sidebar .h4{font-size:.9em;font-weight:600;margin-top:.8em;margin-bottom:.25em;border-bottom:none;padding-bottom:0}.gd-meta-sidebar h3:first-child,.gd-meta-sidebar .h3:first-child,.gd-meta-sidebar h4:first-child,.gd-meta-sidebar .h4:first-child{margin-top:0}}@media(max-width: 991.98px){.gd-meta-sidebar{border-top:1px solid var(--bs-border-color, #dee2e6);padding-top:1em;margin-top:2em}}dt{min-height:32px;overflow-x:visible;margin-left:-4px}dd{padding-left:1.5rem}dd>p+ul,dd>p+ol{margin-top:-0.5em}dd>ul>li::marker,dd>ol>li::marker{color:#9ca3af}h2.doc-section,.doc-section.h2{font-size:22px;border-bottom:none;padding-bottom:0}.doc-section-parameters dd{padding-left:1.5rem;margin-left:0}.doc-section-parameters dd p{margin-left:0}.doc-section-warnings>h2,.doc-section-warnings>.h2{color:crimson;font-weight:600;margin-bottom:.5rem;border-left:none;border-bottom:none;padding-left:0}.doc-section-warnings>h2::before,.doc-section-warnings>.h2::before{content:"⚠️ "}.doc-section-warnings>p{margin:.5rem 0;padding:.75rem 1rem;background-color:#fef2f2;border-left:4px solid #dc2626;border-radius:4px;font-size:.9rem}.table td,.doc-reference section.doc-group>dl td{padding-left:.5rem;text-indent:0}code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:.875em;color:#121212}.blockquote{font-size:13px;background-color:#e8e8e8;border-left-color:#4682b4}p,h1,.h1,h2,.h2,h3,.h3,#toc-title,#toc-function-reference,.nav-link,.table,.doc-reference section.doc-group>dl{font-family:"Open Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}.gt_table p,.gt_table li,.gt_table dd,.gt_table dt{font-family:inherit}.cell-output.cell-output-stdout{border-style:solid;border-width:1px;border-color:rgba(161,161,161,.3960784314);border-radius:4px;padding:.4em;background-color:rgba(247,241,235,.3960784314);margin-bottom:12px}summary::marker{font-size:1.5em}.parameter-name{margin-right:-10px}#toc-title>ul{font-size:14px}#TOC>ul.collapse{display:block !important;visibility:visible !important}#quarto-margin-sidebar{margin-left:20px;padding-top:30px}#quarto-margin-sidebar nav ul li{padding-top:3px;color:#595959}#quarto-margin-sidebar nav ul li a{color:#595959}#quarto-margin-sidebar nav ul li a:hover{color:#333}#quarto-margin-sidebar nav ul li a.active{color:#0d6efd;font-weight:500}#navbarCollapse>ul.navbar-nav.navbar-nav-scroll.me-auto>li>a:hover{background-color:#f07000;color:#fff;border-radius:5px}#navbarCollapse>ul.navbar-nav.navbar-nav-scroll.me-auto>li>a{color:var(--gd-navbar-text);font-weight:bold}a.sidebar-item-text.sidebar-link.text-start[data-bs-toggle=collapse]{pointer-events:none;cursor:default}a.sidebar-item-toggle.text-start{display:none !important}#quarto-sidebar ul.collapse.sidebar-section{display:block !important;visibility:visible !important;height:auto !important}div.sidebar-item-container{cursor:default !important}#quarto-sidebar .sidebar-link[href]{position:relative}#quarto-sidebar .sidebar-link[href]::before{content:"";position:absolute;inset:-3px -8px -3px -10px;border-radius:6px;opacity:0;transition:opacity .15s ease;pointer-events:none;background-color:rgba(0,0,0,.04);box-shadow:0 1px 4px rgba(0,0,0,.1)}#quarto-sidebar .sidebar-link[href]:hover::before{opacity:1}#quarto-sidebar a.sidebar-item-text.sidebar-link.active{color:#f47900;text-decoration:underline;text-decoration-thickness:3px;text-decoration-color:rgba(101,180,237,.75);text-underline-offset:3px}#api-reference>h1,#api-reference>.h1{margin:0}.navbar-title{font-family:Inter,Roboto,"Helvetica Neue","Arial Nova","Nimbus Sans",Arial,sans-serif;font-weight:bold;color:var(--gd-navbar-text);border-style:solid;border-width:2px;border-radius:8px;padding-left:10px;padding-right:10px;padding-top:3px;padding-bottom:4px}.version-badge{font-size:.65em;font-weight:500;color:rgba(0,0,0,.55);background-color:rgba(0,0,0,.08);border-radius:4px;padding:1px 6px;margin-left:6px;vertical-align:middle;letter-spacing:.02em;cursor:default}#quarto-sidebar{background-color:rgba(250,250,253,.3137254902)}@media(max-width: 991.98px){#quarto-sidebar{background-color:#fafafd}#quarto-sidebar.show{bottom:0;min-height:0;overflow-y:auto}#quarto-sidebar.sidebar-navigation.collapsing{transition:width .3s cubic-bezier(0.4, 0, 0.2, 1) !important;overflow:hidden}#quarto-sidebar.sidebar-navigation.collapsing>.sidebar-menu-container{min-width:280px}}@media(min-width: 992px){body.gd-section-no-sidebar #quarto-content{grid-template-columns:[screen-start] 1.5em [screen-start-inset] 4.65fr [page-start page-start-inset body-start-outset body-start] 1.5em [body-content-start] minmax(500px, calc(1050px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end] !important}}#quarto-sidebar .sidebar-item-text{font-family:"Open Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:.85em;display:block;max-width:100%;white-space:normal;hyphens:none}a.sidebar-item-text.sidebar-link.text-start>span{text-transform:uppercase;font-weight:600;color:dimgray;font-family:"Open Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:1em;hyphens:none}.sidebar-menu-container{border-bottom-style:solid;border-bottom-width:3px;border-bottom-color:#e7eaf6}#quarto-sidebar .sidebar-item .menu-text{font-size:15px}.gd-ref-sidebar #quarto-sidebar .sidebar-item .menu-text{font-size:12px}.sidebar-item-section{padding-bottom:8px}body.doc-cli-reference #quarto-sidebar .sidebar-item-section>.sidebar-item-container>.sidebar-item-text .menu-text{display:inline-block;text-transform:uppercase;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:.7rem;letter-spacing:.04em;line-height:1.2;padding:.1rem .4rem;border-radius:.25rem;border:1px solid rgb(24.16,132.72,115.84);color:rgb(24.16,132.72,115.84);background-color:rgb(231.916,242.772,241.084)}body.doc-cli-reference #quarto-sidebar .sidebar-item-section{margin-top:.4rem}body.doc-cli-reference #quarto-sidebar li.sidebar-item:not(.sidebar-item-section)+li.sidebar-item-section{margin-top:.9rem}@media(min-width: 992px){#quarto-sidebar.gd-sidebar-float{display:flex;flex-direction:column;overflow:hidden !important;position:sticky;transition:top .15s ease,max-height .15s ease;margin-right:-12px;align-self:start}#quarto-sidebar.gd-sidebar-float .sidebar-menu-container{border-bottom:none}#quarto-sidebar.gd-sidebar-float .sidebar-menu-container>ul{margin-bottom:0}#quarto-sidebar.gd-sidebar-float .sidebar-menu-container>ul>li:last-child{padding-bottom:7px}#quarto-sidebar.gd-sidebar-float .sidebar-item{margin-top:.1rem;margin-bottom:.1em}#quarto-sidebar.gd-sidebar-float .sidebar-link[href]::before{display:none !important;content:none !important}#quarto-sidebar.gd-sidebar-float .sidebar-link[href]{border-radius:6px;padding-left:8px;padding-right:8px;padding-top:3px;padding-bottom:3px;margin-left:-8px;margin-right:0;transition:background-color .15s ease,box-shadow .15s ease}#quarto-sidebar.gd-sidebar-float .sidebar-link[href]:hover{background-color:rgba(0,0,0,.04);box-shadow:0 1px 4px rgba(0,0,0,.1)}#quarto-sidebar.gd-sidebar-float.sidebar-navigation>*{padding-top:.4em}#quarto-sidebar.gd-sidebar-float>*{padding-right:0}}.gd-sidebar-float-body{display:none}@media(min-width: 992px){.gd-sidebar-float-body{display:block;flex:1 1 auto;overflow-y:auto;overscroll-behavior:contain;position:relative;scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.15) rgba(0,0,0,0)}.gd-sidebar-float-body::-webkit-scrollbar{width:5px}.gd-sidebar-float-body::-webkit-scrollbar-track{background:rgba(0,0,0,0)}.gd-sidebar-float-body::-webkit-scrollbar-thumb{background:rgba(0,0,0,.12);border-radius:4px}}.gd-sidebar-scroll-indicator{display:none}@media(min-width: 992px){.gd-sidebar-scroll-indicator{display:flex;align-items:center;justify-content:center;position:sticky;left:0;right:0;min-height:32px;margin-top:-32px;pointer-events:none;opacity:0;transition:opacity .2s ease;z-index:3}.gd-sidebar-scroll-indicator.visible{opacity:1;pointer-events:auto;cursor:pointer}.gd-sidebar-scroll-top{top:0;background:linear-gradient(to bottom, rgba(250, 250, 253, 0.92) 0%, transparent 100%)}.gd-sidebar-scroll-bottom{bottom:0;position:sticky;margin-top:0;margin-bottom:-32px;background:linear-gradient(to top, rgba(250, 250, 253, 0.92) 0%, transparent 100%)}.gd-sidebar-scroll-arrow{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;background:rgba(0,0,0,.06);color:#6c757d;font-size:.65rem;line-height:1;transition:background .15s ease,color .15s ease}.gd-sidebar-scroll-indicator:hover .gd-sidebar-scroll-arrow{background:rgba(0,0,0,.12);color:#343a40}}@media(min-width: 992px){body.quarto-dark #quarto-sidebar.gd-sidebar-float{background:rgba(30,30,30,.55);border-color:hsla(0,0%,100%,.1);box-shadow:0 1px 6px rgba(0,0,0,.25)}body.quarto-dark .gd-sidebar-float-body{scrollbar-color:hsla(0,0%,100%,.15) rgba(0,0,0,0)}body.quarto-dark .gd-sidebar-float-body::-webkit-scrollbar-thumb{background:hsla(0,0%,100%,.12)}body.quarto-dark #quarto-sidebar.gd-sidebar-float .sidebar-link[href]:hover{background-color:hsla(0,0%,100%,.08);box-shadow:inset 0 0 0 1px hsla(0,0%,100%,.12)}body.quarto-dark .gd-sidebar-scroll-top{background:linear-gradient(to bottom, rgba(30, 30, 30, 0.92) 0%, transparent 100%)}body.quarto-dark .gd-sidebar-scroll-bottom{background:linear-gradient(to top, rgba(30, 30, 30, 0.92) 0%, transparent 100%)}body.quarto-dark .gd-sidebar-scroll-arrow{background:hsla(0,0%,100%,.08);color:#ced4da}body.quarto-dark .gd-sidebar-scroll-indicator:hover .gd-sidebar-scroll-arrow{background:hsla(0,0%,100%,.15);color:#ecf0f1}}@media print{.gd-sidebar-scroll-indicator{display:none !important}}#quarto-header>nav>div{margin-left:2%;margin-right:2%}.navbar{background:var(--gd-navbar-bg);border-bottom:1px solid rgba(0,0,0,.08)}.nav-link.active{text-decoration:underline;text-decoration-thickness:2px;text-decoration-color:rgba(101,180,237,.75);text-underline-offset:4px}body.quarto-light .navbar .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(0,0,0,0.65)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}#gd-navbar-widgets{display:flex;align-items:center;justify-content:flex-end;gap:6px;min-width:fit-content;flex-wrap:nowrap}@media(max-width: 991.98px){.navbar{padding-top:0;padding-bottom:0}.navbar .container-fluid,.navbar .container-sm,.navbar .container-md,.navbar .container-lg,.navbar .container-xl,.navbar .container-xxl{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;position:relative;row-gap:6px;padding-top:6px;padding-bottom:6px}.navbar .navbar-toggler{position:absolute;left:10px;top:15px;margin:0;z-index:3}.navbar .navbar-brand-container.mx-auto{order:1;flex:0 0 100%;margin:0;display:flex;justify-content:center;max-width:100%}.navbar .navbar-brand-container.mx-auto .navbar-brand{margin:0;padding-top:0;padding-bottom:0;padding-right:0;max-width:100%;min-width:0}.navbar .navbar-title{display:block;max-width:calc(100vw - 132px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.navbar .quarto-navbar-tools{order:2;flex:0 0 100%;display:flex;justify-content:center;margin:0;padding:0}.navbar #gd-navbar-widgets{justify-content:center;flex:0 1 auto;width:auto;margin:0}.navbar #navbarCollapse{order:3;flex:0 0 100%}}#gd-navbar-widgets>#dark-mode-toggle-container,#gd-navbar-widgets>#gd-keyboard-btn-container{display:flex;align-items:center;justify-content:center;margin:0}#gd-navbar-widgets #quarto-search{margin-left:0;order:unset}#gd-navbar-widgets #quarto-search.type-overlay .aa-Autocomplete{width:34px}#quarto-search .aa-DetachedSearchButton{display:flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;background:rgba(0,0,0,.06);border:1px solid rgba(0,0,0,.15);border-radius:6px;color:var(--gd-navbar-text);cursor:pointer;transition:all .2s ease}#quarto-search .aa-DetachedSearchButton:hover{background:rgba(0,0,0,.1);border-color:rgba(0,0,0,.25)}#quarto-search .aa-DetachedSearchButton:focus{outline:none;box-shadow:0 0 0 2px rgba(0,0,0,.15)}#quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon{display:flex;align-items:center;justify-content:center}.navbar #quarto-search.type-overlay .aa-Autocomplete svg.aa-SubmitIcon{width:20px;height:20px;margin:0;color:currentColor}#quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonPlaceholder{display:none}body.quarto-light .navbar .aa-DetachedSearchButton svg,body.quarto-light .navbar .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon,body.quarto-light .navbar .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon svg,body.quarto-light .navbar .aa-DetachedSearchButton .aa-SearchIcon,html.quarto-light .navbar .aa-DetachedSearchButton svg,html.quarto-light .navbar .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon,html.quarto-light .navbar .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon svg,html.quarto-light .navbar .aa-DetachedSearchButton .aa-SearchIcon,:root[data-bs-theme=light] .navbar .aa-DetachedSearchButton svg,:root[data-bs-theme=light] .navbar .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon,:root[data-bs-theme=light] .navbar .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon svg,:root[data-bs-theme=light] .navbar .aa-DetachedSearchButton .aa-SearchIcon,body.quarto-light .navbar .aa-SubmitButton,body.quarto-light .navbar .aa-SubmitButton svg{color:var(--gd-navbar-text) !important;fill:var(--gd-navbar-text)}body.quarto-light .navbar .quarto-navbar-tools button,body.quarto-light .navbar .quarto-navbar-tools .quarto-navigation-tool{display:flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;background:rgba(0,0,0,.06);border:1px solid rgba(0,0,0,.15);border-radius:6px;color:var(--gd-navbar-text);cursor:pointer;transition:all .2s ease}body.quarto-light .navbar .quarto-navbar-tools button:hover,body.quarto-light .navbar .quarto-navbar-tools .quarto-navigation-tool:hover{background:rgba(0,0,0,.1);border-color:rgba(0,0,0,.25)}body.quarto-light .navbar .nav-item.compact .nav-link,body.quarto-light .navbar .gd-navbar-icon{display:flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;background:rgba(0,0,0,.06);border:1px solid rgba(0,0,0,.15);border-radius:6px;color:var(--gd-navbar-text);cursor:pointer;transition:all .2s ease}body.quarto-light .navbar .nav-item.compact .nav-link:hover,body.quarto-light .navbar .gd-navbar-icon:hover{background:rgba(0,0,0,.1);border-color:rgba(0,0,0,.25)}#navbarCollapse>ul.navbar-nav.navbar-nav-scroll.ms-auto>li{padding-right:5px}.shrink-example .cell-output table{zoom:60%}.cell-output table.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-striped-bg: transparent}.scale-to-fit{width:100%;position:relative}.scale-to-fit .gd-scale-wrapper{transform-origin:top left}.scale-to-fit.gd-scale-scrollable{overflow-x:auto;-webkit-overflow-scrolling:touch}footer.footer .nav-footer{margin-top:10px}.nav-footer{position:relative;z-index:1;border-top-style:solid;border-top-width:1px;border-top-color:rgba(170,170,170,.2509803922)}.nav-footer-left{color:#303030}.nav-footer-center{color:#303030;text-wrap:balance;padding-bottom:20px}.nav-footer-right{color:#303030}@media(min-width: 992px){.nav-footer{padding-left:calc((100vw - 900px)/2);padding-right:calc((100vw - 900px)/2)}.nav-footer-center{margin-top:.5rem}}@media(min-width: 1200px){.nav-footer{padding-left:calc((100vw - 1100px)/2);padding-right:calc((100vw - 1100px)/2)}}@media(min-width: 1400px){.nav-footer{padding-left:calc((100vw - 1300px)/2);padding-right:calc((100vw - 1300px)/2)}}.nav-footer-center a{color:inherit;text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px}.nav-footer-center a:hover{text-decoration-thickness:2px}.nav-page.nav-page-previous a,.nav-page.nav-page-next a{border-style:solid;padding-left:.5rem;border-radius:8px;padding-right:.5rem;border-width:1px;margin-left:.5rem;margin-right:.5rem}.nav-page-text{font-size:.875em;position:relative;top:-1px}@media(max-width: 576px){.page-navigation{flex-direction:column;align-items:center;gap:.5rem}.nav-page.nav-page-previous,.nav-page.nav-page-next{width:auto;text-align:center}}.source-link{font-size:12px;font-weight:600;color:#4682b4 !important;text-decoration:underline !important;text-underline-offset:3px;text-decoration-thickness:1.5px;letter-spacing:.5px;transition:color .2s ease}.source-link:hover{color:#2a5f8a !important;text-decoration-thickness:2px}.usage-source-row{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:-14px}.code-copy-outer-scaffold>.usage-source-row{position:relative;z-index:1}.code-copy-outer-scaffold{position:relative}div.sourceCode{overflow:visible;position:relative}div.sourceCode>pre{overflow-x:auto}.gd-code-nav{position:absolute;top:0;right:0;z-index:3;padding:.35rem}.gd-code-copy{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid rgba(0,0,0,0);border-radius:4px;background:rgba(0,0,0,0);color:#6c757d;cursor:pointer;opacity:.25;transition:opacity .15s ease,background-color .15s ease,color .15s ease,border-color .15s ease}.code-copy-outer-scaffold:hover .gd-code-copy,div.sourceCode:hover>.gd-code-nav .gd-code-copy,.gd-code-copy:focus-visible{opacity:1}.gd-code-copy:hover{background-color:rgba(0,0,0,.06);border-color:rgba(0,0,0,.1);color:#495057}.gd-code-copy.gd-code-copied{opacity:1;color:#198754}.code-copy-button{display:none !important}@media(max-width: 991.98px){#quarto-header>.navbar .container-fluid.d-flex,#quarto-header>.navbar .d-flex.container-sm,#quarto-header>.navbar .d-flex.container-md,#quarto-header>.navbar .d-flex.container-lg,#quarto-header>.navbar .d-flex.container-xl,#quarto-header>.navbar .d-flex.container-xxl{margin-left:0;padding-left:5px}.quarto-secondary-nav .container-fluid.d-flex,.quarto-secondary-nav .d-flex.container-sm,.quarto-secondary-nav .d-flex.container-md,.quarto-secondary-nav .d-flex.container-lg,.quarto-secondary-nav .d-flex.container-xl,.quarto-secondary-nav .d-flex.container-xxl{align-items:center;padding-left:1rem}.quarto-secondary-nav-title{padding-top:0;margin-bottom:.5rem;padding-left:.5rem}.gd-ref-title{display:flex;align-items:center;gap:0;padding-top:0;padding-left:.5rem;color:#212529;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gd-ref-title-prefix{font-weight:600;color:#495057;flex-shrink:0}.gd-ref-title-sep{margin:0 .4em;color:#adb5bd;flex-shrink:0}.gd-ref-title-name{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:18px;color:#495057;overflow:hidden;text-overflow:ellipsis;position:relative;top:2px}body.quarto-dark .gd-ref-title{color:#868e96}body.quarto-dark .gd-ref-title-prefix,body.quarto-dark .gd-ref-title-name{color:#ced4da}body.quarto-dark .gd-ref-title-sep{color:#6c757d}.quarto-secondary-nav .quarto-btn-toggle{display:flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;background:rgba(0,0,0,.06);border:1px solid rgba(0,0,0,.15);border-radius:6px;color:#495057;cursor:pointer;transition:all .2s ease;margin-right:6px;flex-shrink:0}.quarto-secondary-nav .quarto-btn-toggle .bi{font-size:1.15rem;line-height:1}.quarto-secondary-nav .quarto-btn-toggle:hover{background:rgba(0,0,0,.1);border-color:rgba(0,0,0,.25)}.quarto-secondary-nav .quarto-btn-toggle:focus{outline:none;box-shadow:0 0 0 2px rgba(0,0,0,.15)}body.quarto-dark .quarto-secondary-nav .quarto-btn-toggle{background:hsla(0,0%,100%,.08);border-color:hsla(0,0%,100%,.18);color:#dee2e6}body.quarto-dark .quarto-secondary-nav .quarto-btn-toggle:hover{background:hsla(0,0%,100%,.14);border-color:hsla(0,0%,100%,.28)}body.quarto-dark .quarto-secondary-nav .quarto-btn-toggle:focus{box-shadow:0 0 0 2px hsla(0,0%,100%,.2)}#quarto-document-content{display:flex;flex-direction:column}.column-margin{order:2;margin-top:2rem;padding:.75rem 1.5rem 1.5rem 1.5rem;background-color:#f8f9fa;border-radius:8px;border:1px solid #e9ecef}.column-margin>div>section:first-child>h3,.column-margin>div>section:first-child>.h3{margin-top:.5em}.column-margin,.column-margin>*,.column-margin section,.column-margin p,.column-margin code{background-color:#f8f9fa}#quarto-document-content>*:not(.column-margin){order:1}.column-margin h4,.column-margin .h4{font-size:.9rem;color:#495057;border-bottom:1px solid #dee2e6;padding-bottom:.5rem;margin-top:1rem}.column-margin h4:first-child,.column-margin .h4:first-child{margin-top:0}#quarto-content{padding-left:12px;padding-right:12px}}#github-widget{position:relative;display:inline-flex;align-items:center}.gh-widget-trigger{display:flex;align-items:center;gap:6px;padding:6px 10px;background:rgba(0,0,0,.06);border:1px solid rgba(0,0,0,.15);border-radius:6px;color:var(--gd-navbar-text);cursor:pointer;transition:all .2s ease;font-size:13px}.gh-widget-trigger:hover{background:rgba(0,0,0,.1);border-color:rgba(0,0,0,.25)}.gh-widget-open .gh-widget-trigger{background:rgba(0,0,0,.12);border-color:rgba(0,0,0,.25)}.gh-icon{flex-shrink:0}.gh-stats{display:flex;align-items:center;gap:10px;margin-left:4px}.gh-stat{display:flex;align-items:center;gap:3px;font-weight:500}.gh-stat svg{opacity:.85}.gh-count{min-width:16px;text-align:center}.gh-dropdown-arrow{margin-left:2px;opacity:.7;transition:transform .2s ease}.gh-widget-open .gh-dropdown-arrow{transform:rotate(180deg)}.gh-dropdown{position:absolute;top:calc(100% + 6px);right:0;min-width:180px;background:#fff;border:1px solid #d0d7de;border-radius:8px;box-shadow:0 8px 24px rgba(31,35,40,.12);opacity:0;visibility:hidden;transform:translateY(-8px);transition:all .2s ease;z-index:1000;overflow:hidden}.gh-widget-open .gh-dropdown{opacity:1;visibility:visible;transform:translateY(0)}.gh-dropdown-item{display:flex;align-items:center;gap:10px;padding:10px 14px;color:#24292f !important;text-decoration:none !important;font-size:14px;font-weight:500;transition:background .15s ease}.gh-dropdown-item:hover{background:#f6f8fa;text-decoration:none !important}.gh-dropdown-item svg{color:#57606a;flex-shrink:0}.gh-dropdown-divider{height:1px;margin:4px 0;background:#d8dee4}.gh-badge{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;margin-left:auto;background:#ddf4ff;color:#0969da;border-radius:10px;font-size:12px;font-weight:600}.gd-version-selector{position:relative;display:flex;align-items:center}.gd-vs-trigger{display:flex;align-items:center;gap:6px;padding:6px 10px;background:rgba(0,0,0,.06);border:1px solid rgba(0,0,0,.15);border-radius:6px;color:var(--gd-navbar-text);cursor:pointer;transition:all .2s ease;font-size:13px;font-weight:500;white-space:nowrap}.gd-vs-trigger:hover{background:rgba(0,0,0,.1);border-color:rgba(0,0,0,.25)}.gd-vs-open .gd-vs-trigger{background:rgba(0,0,0,.12);border-color:rgba(0,0,0,.25)}.gd-vs-icon{flex-shrink:0;width:20px;height:20px}.gd-vs-label{line-height:1}.gd-vs-arrow{margin-left:2px;opacity:.7;transition:transform .2s ease}.gd-vs-open .gd-vs-arrow{transform:rotate(180deg)}.gd-vs-dropdown{position:absolute;top:calc(100% + 6px);right:0;min-width:170px;background:#fff;border:1px solid #d0d7de;border-radius:8px;box-shadow:0 8px 24px rgba(31,35,40,.12);opacity:0;visibility:hidden;transform:translateY(-8px);transition:all .2s ease;z-index:1000;overflow:hidden}.gd-vs-open .gd-vs-dropdown{opacity:1;visibility:visible;transform:translateY(0)}.gd-vs-item{display:flex;align-items:center;gap:8px;padding:8px 14px;color:#24292f !important;text-decoration:none !important;font-size:14px;font-weight:500;transition:background .15s ease}.gd-vs-item:hover{background:#f6f8fa}.gd-vs-item-active{background:#f0f6ff;font-weight:600}.gd-vs-badge{display:inline-flex;align-items:center;justify-content:center;width:16px;font-size:12px;flex-shrink:0}.gd-vs-badge-spacer{display:inline-block;width:16px;flex-shrink:0}.gd-vs-badge-pre{color:#9a6700}.gd-vs-badge-eol{color:#cf222e}.gd-vs-check{margin-left:auto;color:#1a7f37;font-size:12px;flex-shrink:0}@media(max-width: 991.98px){.gd-vs-label{display:none}}.gd-version-banner{padding:10px 20px;font-size:14px;text-align:center;font-weight:500;border-bottom:1px solid}.gd-version-banner a{font-weight:600;text-decoration:underline;margin-left:4px}.gd-version-banner-old{background:#fff8c5;color:#4d2d00;border-color:#d4a72c}.gd-version-banner-old a{color:#4d2d00}.gd-version-banner-pre{background:#ddf4ff;color:#0550ae;border-color:#54aeff}.gd-version-banner-pre a{color:#0550ae}.gd-version-banner-eol{background:#ffebe9;color:#82071e;border-color:#ff8182}.gd-version-banner-eol a{color:#82071e}body.quarto-dark .gd-vs-trigger,html.quarto-dark .gd-vs-trigger,:root[data-bs-theme=dark] .gd-vs-trigger{background:hsla(0,0%,100%,.08);border-color:hsla(0,0%,100%,.15)}body.quarto-dark .gd-vs-trigger:hover,html.quarto-dark .gd-vs-trigger:hover,:root[data-bs-theme=dark] .gd-vs-trigger:hover{background:hsla(0,0%,100%,.14);border-color:hsla(0,0%,100%,.25)}body.quarto-dark .gd-vs-dropdown,html.quarto-dark .gd-vs-dropdown,:root[data-bs-theme=dark] .gd-vs-dropdown{background:var(--gd-bg-secondary);border-color:var(--gd-border-color);box-shadow:0 8px 24px rgba(0,0,0,.4)}body.quarto-dark .gd-vs-item,html.quarto-dark .gd-vs-item,:root[data-bs-theme=dark] .gd-vs-item{color:#adbac7 !important}body.quarto-dark .gd-vs-item:hover,html.quarto-dark .gd-vs-item:hover,:root[data-bs-theme=dark] .gd-vs-item:hover{background:#373e47}body.quarto-dark .gd-vs-item-active,html.quarto-dark .gd-vs-item-active,:root[data-bs-theme=dark] .gd-vs-item-active{background:#1c3049}body.quarto-dark .gd-vs-check,html.quarto-dark .gd-vs-check,:root[data-bs-theme=dark] .gd-vs-check{color:#57ab5a}body.quarto-dark .gd-version-banner-old,html.quarto-dark .gd-version-banner-old,:root[data-bs-theme=dark] .gd-version-banner-old{background:#3d2e00;color:#e3b341;border-color:#5c4400}body.quarto-dark .gd-version-banner-old a,html.quarto-dark .gd-version-banner-old a,:root[data-bs-theme=dark] .gd-version-banner-old a{color:#e3b341}body.quarto-dark .gd-version-banner-pre,html.quarto-dark .gd-version-banner-pre,:root[data-bs-theme=dark] .gd-version-banner-pre{background:#0d2137;color:#539bf5;border-color:#1b3a57}body.quarto-dark .gd-version-banner-pre a,html.quarto-dark .gd-version-banner-pre a,:root[data-bs-theme=dark] .gd-version-banner-pre a{color:#539bf5}body.quarto-dark .gd-version-banner-eol,html.quarto-dark .gd-version-banner-eol,:root[data-bs-theme=dark] .gd-version-banner-eol{background:#3c1118;color:#f47067;border-color:#5c1a23}body.quarto-dark .gd-version-banner-eol a,html.quarto-dark .gd-version-banner-eol a,:root[data-bs-theme=dark] .gd-version-banner-eol a{color:#f47067}.gd-badge{display:inline-block;font-size:.7em;font-weight:600;line-height:1;padding:3px 8px;border-radius:10px;vertical-align:middle;margin-left:6px;white-space:nowrap;letter-spacing:.01em}.gd-badge-new{background:#dafbe1;color:#1a7f37;border:1px solid #a6e3b0}.gd-badge-changed{background:#ddf4ff;color:#0550ae;border:1px solid #80ccff}.gd-badge-deprecated{background:#ffebe9;color:#82071e;border:1px solid #ffb8b0}body.quarto-dark .gd-badge-new,html.quarto-dark .gd-badge-new,:root[data-bs-theme=dark] .gd-badge-new{background:#0d3117;color:#57ab5a;border-color:#1b4b27}body.quarto-dark .gd-badge-changed,html.quarto-dark .gd-badge-changed,:root[data-bs-theme=dark] .gd-badge-changed{background:#0d2137;color:#539bf5;border-color:#1b3a57}body.quarto-dark .gd-badge-deprecated,html.quarto-dark .gd-badge-deprecated,:root[data-bs-theme=dark] .gd-badge-deprecated{background:#3c1118;color:#f47067;border-color:#5c1a23}@media(max-width: 991.98px){#quarto-header>nav>div{margin-left:0%;margin-right:0%}.container,.container-fluid,.container-sm,.container-md,.container-lg,.container-xl,.container-xxl{padding-right:calc(var(--bs-gutter-x)*.15);padding-left:calc(var(--bs-gutter-x)*.15)}.navbar-expand-lg .navbar-nav .nav-link{padding-left:.4rem;padding-right:.6rem;margin-left:-0.2rem}#gd-navbar-widgets{gap:4px;margin-left:auto}.gh-widget-trigger{width:100%;justify-content:flex-start}}@media(max-width: 991.98px){#supported-by-posit{display:none !important}}@media(max-width: 767.98px){body .page-columns{grid-template-columns:[screen-start] .5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] .5em [screen-end] !important}}@media(max-width: 768px){.gh-stats{display:none}.gh-widget-trigger{padding:6px 8px}.gh-dropdown{right:0;min-width:160px}}#quarto-header,#quarto-header nav,#quarto-header .navbar,#quarto-header .container-fluid,#quarto-header .container-sm,#quarto-header .container-md,#quarto-header .container-lg,#quarto-header .container-xl,#quarto-header .container-xxl,.navbar-nav.ms-auto,.navbar-nav.ms-auto>li,.navbar-nav.ms-auto>li>.nav-link{overflow:visible !important}#navbarCollapse>ul.navbar-nav.navbar-nav-scroll.me-auto{text-wrap:nowrap;overflow-x:auto !important}@media print{#github-widget{display:none}}.reference-switcher-container{margin-left:0;margin-right:.6rem;margin-bottom:.2rem;padding-top:.5rem;padding-bottom:.6rem;border-bottom:1px solid rgba(0,0,0,.06);background:rgba(0,0,0,0)}.reference-switcher{display:flex;gap:.25rem;background:#f0f0f0;border-radius:6px;padding:.2rem}.reference-switcher-btn{flex:1;display:flex;align-items:center;justify-content:center;gap:.35rem;padding:.35rem .5rem;border:none;border-radius:4px;background:rgba(0,0,0,0);color:#666;font-size:.8rem;font-weight:500;cursor:pointer;transition:all .15s ease}.reference-switcher-btn:hover{background:hsla(0,0%,100%,.5);color:#333}.reference-switcher-btn.active{background:#fff;color:#333;box-shadow:0 1px 3px rgba(0,0,0,.1)}.reference-switcher-btn i{font-size:.9rem}body.quarto-dark .reference-switcher{background:#2a2a2a}body.quarto-dark .reference-switcher-btn{color:#999}body.quarto-dark .reference-switcher-btn:hover{background:hsla(0,0%,100%,.1);color:#ccc}body.quarto-dark .reference-switcher-btn.active{background:#3a3a3a;color:#fff;box-shadow:0 1px 3px rgba(0,0,0,.3)}.reference-switcher-dropdown{position:relative}.reference-switcher-dropdown-toggle{display:flex;align-items:center;gap:.4rem;width:100%;padding:.4rem .6rem;border:1px solid rgba(0,0,0,.1);border-radius:6px;background:#f8f8f8;color:#333;font-size:.8rem;font-weight:500;cursor:pointer;transition:border-color .15s ease,background .15s ease}.reference-switcher-dropdown-toggle:hover{border-color:rgba(0,0,0,.2);background:#f0f0f0}.reference-switcher-dropdown-toggle i{font-size:.9rem;opacity:.7}.reference-switcher-dropdown-label{flex:1;text-align:left}.reference-switcher-chevron{opacity:.5;transition:transform .15s ease}.reference-switcher-dropdown-toggle[aria-expanded=true] .reference-switcher-chevron{transform:rotate(180deg)}.reference-switcher-dropdown-menu{display:none;position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:100;margin:0;padding:.25rem;list-style:none;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,.1)}.reference-switcher-dropdown-menu.show{display:block}.reference-switcher-dropdown-item{display:flex;align-items:center;gap:.4rem;padding:.4rem .6rem;border-radius:4px;font-size:.8rem;font-weight:500;color:#555;cursor:pointer;transition:background .1s ease,color .1s ease}.reference-switcher-dropdown-item:hover{background:#f0f0f0;color:#333}.reference-switcher-dropdown-item.active{background:#e8f0fe;color:#1a73e8}.reference-switcher-dropdown-item i{font-size:.9rem;opacity:.7}body.quarto-dark .reference-switcher-dropdown-toggle{background:#2a2a2a;border-color:hsla(0,0%,100%,.1);color:#e0e0e0}body.quarto-dark .reference-switcher-dropdown-toggle:hover{background:#333;border-color:hsla(0,0%,100%,.2)}body.quarto-dark .reference-switcher-dropdown-menu{background:#2a2a2a;border-color:hsla(0,0%,100%,.1);box-shadow:0 4px 12px rgba(0,0,0,.4)}body.quarto-dark .reference-switcher-dropdown-item{color:#999}body.quarto-dark .reference-switcher-dropdown-item:hover{background:hsla(0,0%,100%,.08);color:#e0e0e0}body.quarto-dark .reference-switcher-dropdown-item.active{background:rgba(138,180,248,.15);color:#8ab4f8}.sidebar-filter-container{padding:.35rem .65rem .65rem 0rem;border-bottom:1px solid rgba(0,0,0,.05);background:rgba(0,0,0,0);position:sticky;top:0;z-index:10}.sidebar-filter-wrapper{position:relative;display:flex;align-items:center}.sidebar-filter-input{width:100%;padding:.3rem 1.75rem .3rem 1.85rem;font-size:.8rem;border:1px solid #e9e9e9;border-radius:4px;background-color:#fff;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out,background-color .15s ease-in-out}.sidebar-filter-input:focus{outline:none;border-color:#86b7fe;box-shadow:0 0 0 .15rem rgba(13,110,253,.12);background-color:#fff}.sidebar-filter-input::placeholder{color:#999;opacity:1}.sidebar-filter-icon{position:absolute;left:.55rem;top:50%;transform:translateY(-50%);color:#999;pointer-events:none;font-size:.75rem;display:flex;align-items:center;justify-content:center}.sidebar-filter-clear{position:absolute;right:.35rem;top:50%;transform:translateY(-50%);background:none;border:none;color:#999;cursor:pointer;padding:.15rem;line-height:1;border-radius:3px;transition:color .15s ease,background-color .15s ease;font-size:.7rem}.sidebar-filter-clear:hover{color:#666;background-color:rgba(0,0,0,.04)}.sidebar-filter-count{font-size:.7rem;color:#888;text-align:center;margin-top:.25rem;padding:.1rem .4rem;background:rgba(0,0,0,0);border-radius:3px}.sidebar-filter-count .filter-count-num{font-weight:600;color:#666}.sidebar-item.sidebar-filter-match .sidebar-link{background-color:rgba(255,243,205,.5)}.sidebar-item{transition:opacity .15s ease}@media(max-width: 991.98px){.sidebar-filter-container{padding:.4rem .65rem}.sidebar-filter-input{font-size:.85rem;padding:.35rem 1.75rem .35rem 1.85rem}}body.quarto-dark .sidebar-filter-container{background:rgba(0,0,0,0);border-bottom-color:hsla(0,0%,100%,.08)}body.quarto-dark .sidebar-filter-input{background-color:#2a2a2a;border-color:#3d3d3d;color:#e0e0e0}body.quarto-dark .sidebar-filter-input:focus{border-color:#6ea8fe;box-shadow:0 0 0 .15rem rgba(13,110,253,.25);background-color:#333}body.quarto-dark .sidebar-filter-input::placeholder{color:#9e9e9e}body.quarto-dark .sidebar-filter-icon,body.quarto-dark .sidebar-filter-clear{color:#9e9e9e}body.quarto-dark .sidebar-filter-clear:hover{color:#e0e0e0;background-color:hsla(0,0%,100%,.1)}body.quarto-dark .sidebar-filter-count{color:#9e9e9e}body.quarto-dark .sidebar-filter-count .filter-count-num{color:#e0e0e0}body.quarto-dark .sidebar-item.sidebar-filter-match .sidebar-link{background-color:rgba(255,193,7,.2)}h1.title.cli-title,.title.cli-title.h1{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1.25rem;font-weight:600}.cli-manpage{width:100%}.cli-manpage pre{font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13px;line-height:1.6;background:#012b15;color:#d4d4d4;border:none;border-radius:6px;padding:1.25rem 1.5rem;overflow-x:auto;white-space:pre;margin-bottom:1rem;max-width:100%}.cli-manpage pre code{font-family:inherit;font-size:inherit;background:rgba(0,0,0,0);color:inherit;padding:0;white-space:pre}[data-bs-theme=light] .cli-manpage pre{background:#1e1e1e;color:#d4d4d4}@media(min-width: 992px)and (max-width: 1199.98px){.cli-manpage{margin-top:1.5rem}}@media(min-width: 1200px){.cli-manpage{margin-top:1.5rem}}@media(min-width: 768px)and (max-width: 991.98px){.cli-manpage{margin-top:1.5rem}.cli-manpage pre{font-size:12px;padding:1rem 1.25rem;border-radius:4px}h1.title.cli-title,.title.cli-title.h1{font-size:1.1rem}}@media(max-width: 767.98px){.cli-manpage{margin-top:1.5rem}.cli-manpage pre{font-size:11px;padding:.875rem 1rem;line-height:1.5}h1.title.cli-title,.title.cli-title.h1{font-size:1rem}}@media(max-width: 575.98px){.cli-manpage{margin-top:1.5rem}.cli-manpage pre{font-size:10px;padding:.75rem .875rem;border-radius:3px}h1.title.cli-title,.title.cli-title.h1{font-size:.95rem}}.nav-item:has(#gd-keyboard-btn-container){display:flex;align-items:center}#gd-keyboard-btn-container{display:flex;align-items:center;justify-content:center;margin-right:2px}.gd-keyboard-btn{display:flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;background:rgba(0,0,0,.06);border:1px solid rgba(0,0,0,.15);border-radius:6px;color:var(--gd-navbar-text);cursor:pointer;transition:all .2s ease}.gd-keyboard-btn:hover{background:rgba(0,0,0,.1);border-color:rgba(0,0,0,.25)}.gd-keyboard-btn:focus{outline:none;box-shadow:0 0 0 2px rgba(0,0,0,.15)}.gd-keyboard-btn svg{display:block}@media(max-width: 991.98px){#gd-navbar-widgets>#gd-keyboard-btn-container,#gd-keyboard-btn-container{display:none}}body.quarto-dark .gd-keyboard-btn{background:hsla(0,0%,100%,.08);border-color:hsla(0,0%,100%,.18);color:#f8f9fa}body.quarto-dark .gd-keyboard-btn:hover{background:hsla(0,0%,100%,.14);border-color:hsla(0,0%,100%,.28)}body.quarto-dark .gd-keyboard-btn:focus{box-shadow:0 0 0 2px hsla(0,0%,100%,.2)}.nav-item:has(#dark-mode-toggle-container){display:flex;align-items:center}#dark-mode-toggle-container{display:flex;align-items:center;justify-content:center;margin-right:0}.dark-mode-toggle{display:flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;background:rgba(0,0,0,.06);border:1px solid rgba(0,0,0,.15);border-radius:6px;color:var(--gd-navbar-text);cursor:pointer;transition:all .2s ease}.dark-mode-toggle:hover{background:rgba(0,0,0,.1);border-color:rgba(0,0,0,.25)}.dark-mode-toggle:focus{outline:none;box-shadow:0 0 0 2px rgba(0,0,0,.15)}.dark-mode-toggle svg{display:block}.theme-icon-light,.theme-icon-dark{display:flex;align-items:center;justify-content:center}:root{--gd-bg-primary: #FCFEFF;--gd-bg-secondary: #FAFAFD;--gd-bg-tertiary: #F7F1EB;--gd-text-primary: rgb(18, 18, 18);--gd-text-secondary: #333;--gd-text-muted: #666;--gd-border-color: #e9e9e9;--gd-border-light: #E7EAF6;--gd-link-color: black;--gd-code-bg: #f8f9fa;--gd-code-color: rgb(18, 18, 18);--gd-blockquote-bg: #E8E8E8;--gd-sidebar-bg: #FAFAFD;--gd-navbar-bg: #f0f0f0;--gd-navbar-text: #2d2d2d;--gd-footer-text: rgb(48, 48, 48);--gd-highlight-color: rgba(255, 243, 205, 0.5);--gd-active-link: rgb(244, 121, 0);--gd-accent-blue: rgba(101, 180, 237, 0.75);--gd-citation-color: #1a6cae;--gd-syn-class: #0e84b5;--gd-syn-name: #4758AB;--gd-syn-none: #7D4E9E;--gd-syn-bool: #0077AA;--gd-syn-operator: #D14D00;--gd-syn-keyword: #008000;--gd-syn-string: #BA2121;--gd-syn-number: #666666;--gd-syn-comment: #408080;--gd-syn-function: #0000FF;--gd-syn-builtin: #008000}html.quarto-dark,body.quarto-dark{--gd-bg-primary: #1a1a1a;--gd-bg-secondary: #222222;--gd-bg-tertiary: #2a2a2a;--gd-text-primary: #e0e0e0;--gd-text-secondary: #c8c8c8;--gd-text-muted: #999;--gd-border-color: #3d3d3d;--gd-border-light: #333;--gd-link-color: #7cb8e8;--gd-code-bg: #2a2a2a;--gd-code-color: #e0e0e0;--gd-blockquote-bg: #2a2a2a;--gd-sidebar-bg: #1e1e1e;--gd-navbar-bg: #1a1a1a;--gd-navbar-text: #e0e0e0;--gd-footer-text: #b0b0b0;--gd-highlight-color: rgba(255, 193, 7, 0.2);--gd-active-link: #ff9f43;--gd-accent-blue: rgba(101, 180, 237, 0.6);--gd-citation-color: #7cb8e8;--gd-syn-class: #56c8ff;--gd-syn-name: #8cb4ff;--gd-syn-none: #c792ea;--gd-syn-bool: #56c8ff;--gd-syn-operator: #ff9f43;--gd-syn-keyword: #c792ea;--gd-syn-string: #c3e88d;--gd-syn-number: #f78c6c;--gd-syn-comment: #8891b3;--gd-syn-function: #82aaff;--gd-syn-builtin: #ffcb6b}body.quarto-dark{background-color:var(--gd-bg-primary);color:var(--gd-text-primary)}body.quarto-dark .quarto-body-content{background-color:var(--gd-bg-primary)}body.quarto-dark #quarto-content{background-color:var(--gd-bg-primary)}body.quarto-dark #quarto-document-content{background-color:var(--gd-bg-primary)}body.quarto-dark main.content{background-color:var(--gd-bg-primary)}body.quarto-dark .page-columns{background-color:var(--gd-bg-primary)}body.quarto-dark .page-rows-contents{background-color:var(--gd-bg-primary)}body.quarto-dark .column-body{background-color:var(--gd-bg-primary)}body.quarto-dark .column-page{background-color:var(--gd-bg-primary)}body.quarto-dark article{background-color:var(--gd-bg-primary)}body.quarto-dark section{background-color:var(--gd-bg-primary)}html.quarto-dark{background-color:var(--gd-bg-primary)}body.quarto-dark h1,body.quarto-dark .h1,body.quarto-dark h2,body.quarto-dark .h2,body.quarto-dark h3,body.quarto-dark .h3,body.quarto-dark h4,body.quarto-dark .h4,body.quarto-dark h5,body.quarto-dark .h5,body.quarto-dark h6,body.quarto-dark .h6{color:var(--gd-text-primary)}body.quarto-dark p,body.quarto-dark li,body.quarto-dark dd,body.quarto-dark dt{color:var(--gd-text-primary)}body.quarto-dark p a,body.quarto-dark li a{color:var(--gd-link-color)}body.quarto-dark p a:hover,body.quarto-dark li a:hover{color:#9dcaf0}body.quarto-dark .column-margin a:has(.bi),body.quarto-dark .column-margin a:has(.fa-brands),body.quarto-dark .column-margin a:has(.ror-sidebar-icon){color:#adb5bd}body.quarto-dark .column-margin a:has(.bi):hover,body.quarto-dark .column-margin a:has(.fa-brands):hover,body.quarto-dark .column-margin a:has(.ror-sidebar-icon):hover{color:#dee2e6}body.quarto-dark .table a,body.quarto-dark .doc-reference section.doc-group>dl a,.doc-reference body.quarto-dark section.doc-group>dl a{color:var(--gd-link-color)}body.quarto-dark code{color:var(--gd-code-color);background-color:var(--gd-code-bg)}body.quarto-dark pre{background-color:var(--gd-bg-tertiary);border-color:var(--gd-border-color)}body.quarto-dark pre code{background-color:rgba(0,0,0,0);color:var(--gd-text-primary)}body.quarto-dark .sourceCode span,body.quarto-dark pre.sourceCode code span{color:var(--gd-text-primary)}body.quarto-dark pre.bash code,body.quarto-dark pre.sh code,body.quarto-dark pre.shell code,body.quarto-dark .sourceCode.bash code,body.quarto-dark .sourceCode.sh code,body.quarto-dark div.sourceCode[data-language=bash] code,body.quarto-dark div.sourceCode[data-language=sh] code{color:var(--gd-text-primary)}body.quarto-dark .sourceCode.bash span,body.quarto-dark .sourceCode.sh span,body.quarto-dark div.sourceCode[data-language=bash] span,body.quarto-dark div.sourceCode[data-language=sh] span{color:var(--gd-text-primary) !important}body.quarto-dark :not(pre)>code{color:#f0a0a0;background-color:var(--gd-code-bg)}body.quarto-dark .gt_table p,body.quarto-dark .gt_table li,body.quarto-dark .gt_table dd,body.quarto-dark .gt_table dt{color:inherit}body.quarto-dark .gt_table code,body.quarto-dark .gt_table :not(pre)>code{color:inherit;background-color:rgba(0,0,0,0)}body.quarto-dark code span.sig-class{color:var(--gd-syn-class) !important}body.quarto-dark code span.sig-name{color:var(--gd-syn-name) !important}body.quarto-dark code span.cn-none{color:var(--gd-syn-none) !important}body.quarto-dark code span.cn-bool{color:var(--gd-syn-bool) !important}body.quarto-dark #cb1 code span.op{color:var(--gd-syn-operator) !important}body.quarto-dark #cb1 code span.overload-spacer{display:block;height:.35em;user-select:none}body.quarto-dark .sourceCode span.kw,body.quarto-dark .highlight span.k{color:var(--gd-syn-keyword)}body.quarto-dark .sourceCode span.cf{color:var(--gd-syn-keyword)}body.quarto-dark .sourceCode span.op{color:var(--gd-syn-operator)}body.quarto-dark .sourceCode span.st,body.quarto-dark .highlight span.s,body.quarto-dark .highlight span.s1,body.quarto-dark .highlight span.s2{color:var(--gd-syn-string)}body.quarto-dark .sourceCode span.dv,body.quarto-dark .sourceCode span.fl,body.quarto-dark .sourceCode span.bn,body.quarto-dark .highlight span.mi,body.quarto-dark .highlight span.mf{color:var(--gd-syn-number)}body.quarto-dark .sourceCode span.co,body.quarto-dark .highlight span.c,body.quarto-dark .highlight span.c1,body.quarto-dark .highlight span.cm{color:var(--gd-syn-comment);font-style:italic}body.quarto-dark .sourceCode span.fu,body.quarto-dark .highlight span.nf{color:var(--gd-syn-function)}body.quarto-dark .sourceCode span.bu,body.quarto-dark .highlight span.nb{color:var(--gd-syn-builtin)}body.quarto-dark .sourceCode span.va,body.quarto-dark .sourceCode span.at,body.quarto-dark .highlight span.n{color:var(--gd-text-primary)}body.quarto-dark .sourceCode span.sc{color:var(--gd-syn-string)}body.quarto-dark .sourceCode span.ss{color:var(--gd-syn-string)}body.quarto-dark .sourceCode span.im{color:var(--gd-syn-keyword)}body.quarto-dark .sourceCode span.cn{color:var(--gd-syn-none)}body.quarto-dark .sourceCode span.dt{color:var(--gd-syn-class)}body.quarto-dark .sourceCode span.an{color:var(--gd-syn-comment)}body.quarto-dark .sourceCode span.pp{color:var(--gd-syn-keyword)}body.quarto-dark .sourceCode span.ex{color:var(--gd-syn-function)}body.quarto-dark .sourceCode span.do{color:var(--gd-syn-comment);font-style:italic}body.quarto-dark .sourceCode span.al{color:#f55;font-weight:bold}body.quarto-dark .sourceCode span.er{color:#f55}body.quarto-dark .sourceCode span.wa{color:#ffb86c}body.quarto-dark .sourceCode span.in{color:var(--gd-syn-comment)}body.quarto-dark dt code{color:var(--gd-text-primary);background-color:var(--gd-code-bg)}body.quarto-dark dt code span{color:var(--gd-text-primary)}body.quarto-dark .parameter-name{color:#82aaff}body.quarto-dark .parameter-name strong{color:#82aaff}body.quarto-dark .parameter-annotation{color:#c792ea}body.quarto-dark .parameter-annotation-sep{color:var(--gd-text-muted)}body.quarto-dark .parameter-default{color:#c3e88d}body.quarto-dark .parameter-default-sep{color:var(--gd-text-muted)}body.quarto-dark .doc-section dt{color:var(--gd-text-primary)}body.quarto-dark .doc-section dd{color:var(--gd-text-primary)}body.quarto-dark .doc-section-parameters dt code{color:var(--gd-text-primary)}body.quarto-dark .doc-section-warnings>h2,body.quarto-dark .doc-section-warnings>.h2{color:#fca5a5}body.quarto-dark .doc-section-warnings>p{background-color:rgba(220,38,38,.1);border-left-color:#ef4444;color:var(--gd-text-primary)}body.quarto-dark .cell-output.cell-output-stdout{background-color:var(--gd-bg-tertiary);border-color:var(--gd-border-color);color:var(--gd-text-primary)}body.quarto-dark .cell-output.cell-output-stderr{background-color:rgba(255,85,85,.1);border-color:rgba(255,85,85,.3)}body.quarto-dark .blockquote,body.quarto-dark blockquote{background-color:var(--gd-blockquote-bg);border-left-color:var(--gd-accent-blue);color:var(--gd-text-secondary)}body.quarto-dark #quarto-sidebar{background-color:var(--gd-sidebar-bg);border-right-color:var(--gd-border-color)}body.quarto-dark .sidebar-menu-container{border-bottom-color:var(--gd-border-color)}body.quarto-dark #quarto-sidebar .sidebar-item-text{color:var(--gd-text-secondary)}body.quarto-dark #quarto-sidebar .sidebar-item-text:hover{color:var(--gd-text-primary)}body.quarto-dark #quarto-sidebar .sidebar-link[href]::before{background-color:hsla(0,0%,100%,.04);box-shadow:inset 0 0 0 1px hsla(0,0%,100%,.15)}body.quarto-dark #quarto-sidebar a.sidebar-item-text.sidebar-link.active{color:var(--gd-active-link)}body.quarto-dark a.sidebar-item-text.sidebar-link.text-start>span{color:#9e9e9e}body.quarto-dark .sidebar-tools-collapse{color:var(--gd-text-muted)}body.quarto-dark .navbar{background:var(--gd-navbar-bg) !important;border-bottom:1px solid var(--gd-border-color)}body.quarto-dark .navbar-title{color:var(--gd-navbar-text)}body.quarto-dark .version-badge{color:rgba(224,224,224,.75);background-color:hsla(0,0%,100%,.1)}body.quarto-dark #navbarCollapse>ul.navbar-nav.navbar-nav-scroll.me-auto>li>a{color:#e0e0e0}body.quarto-dark #navbarCollapse>ul.navbar-nav.navbar-nav-scroll.me-auto>li>a:hover{background-color:#f07000;color:#fff}body.quarto-dark .dark-mode-toggle{background:hsla(0,0%,100%,.08);border-color:hsla(0,0%,100%,.15);color:#e0e0e0}body.quarto-dark .dark-mode-toggle:hover{background:hsla(0,0%,100%,.12);border-color:hsla(0,0%,100%,.25)}body.quarto-dark #quarto-margin-sidebar{color:var(--gd-text-secondary)}body.quarto-dark #quarto-margin-sidebar nav a{color:var(--gd-text-muted)}body.quarto-dark #quarto-margin-sidebar nav a:hover{color:var(--gd-text-primary)}body.quarto-dark #quarto-margin-sidebar nav a.active{color:var(--gd-active-link)}body.quarto-dark #toc-title{color:var(--gd-text-primary)}body.quarto-dark .nav-footer{background-color:var(--gd-bg-secondary);border-top:1px solid var(--gd-border-color)}body.quarto-dark .nav-footer-left,body.quarto-dark .nav-footer-right,body.quarto-dark .nav-footer-center{color:var(--gd-footer-text)}body.quarto-dark .nav-footer a{color:var(--gd-link-color)}body.quarto-dark .table,body.quarto-dark .doc-reference section.doc-group>dl,.doc-reference body.quarto-dark section.doc-group>dl{color:var(--gd-text-primary);border-color:var(--gd-border-color)}body.quarto-dark .table th,body.quarto-dark .doc-reference section.doc-group>dl th,.doc-reference body.quarto-dark section.doc-group>dl th{background-color:var(--gd-bg-secondary);border-color:var(--gd-border-color)}body.quarto-dark .table td,body.quarto-dark .doc-reference section.doc-group>dl td,.doc-reference body.quarto-dark section.doc-group>dl td{border-color:var(--gd-border-color)}body.quarto-dark .table-striped>tbody>tr:nth-of-type(odd)>*{background-color:var(--gd-bg-tertiary)}body.quarto-dark .table-hover>tbody>tr:hover>*{background-color:hsla(0,0%,100%,.05)}body.quarto-dark .card{background-color:var(--gd-bg-secondary);border-color:var(--gd-border-color)}body.quarto-dark .card-header{background-color:var(--gd-bg-tertiary);border-color:var(--gd-border-color)}body.quarto-dark .callout{background-color:var(--gd-bg-secondary);border-color:var(--gd-border-color);color:var(--gd-text-primary)}body.quarto-dark .callout .callout-header{background-color:var(--gd-bg-secondary) !important}body.quarto-dark .callout .callout-icon::before{filter:invert(1)}body.quarto-dark .callout .callout-title-container{color:var(--gd-text-primary)}body.quarto-dark .callout .callout-body p{color:var(--gd-text-primary)}body.quarto-dark .callout-note{border-left-color:#6ea8fe}body.quarto-dark .callout-warning{border-left-color:#ffb86c}body.quarto-dark .callout-important{border-left-color:#f55}body.quarto-dark .callout-tip{border-left-color:#50fa7b}body.quarto-dark input,body.quarto-dark textarea,body.quarto-dark select{background-color:var(--gd-bg-tertiary);border-color:var(--gd-border-color);color:var(--gd-text-primary)}body.quarto-dark input:focus,body.quarto-dark textarea:focus,body.quarto-dark select:focus{border-color:#6ea8fe;box-shadow:0 0 0 .15rem rgba(110,168,254,.25)}body.quarto-dark input::placeholder{color:var(--gd-text-muted)}body.quarto-dark #quarto-search,html.quarto-dark #quarto-search,:root[data-bs-theme=dark] #quarto-search{background-color:rgba(0,0,0,0)}body.quarto-dark #quarto-search input,html.quarto-dark #quarto-search input,:root[data-bs-theme=dark] #quarto-search input{background-color:var(--gd-bg-tertiary);border-color:var(--gd-border-color);color:var(--gd-text-primary) !important}body.quarto-dark #quarto-search .aa-SubmitButton,html.quarto-dark #quarto-search .aa-SubmitButton,:root[data-bs-theme=dark] #quarto-search .aa-SubmitButton{background-color:rgba(0,0,0,0);color:var(--gd-text-muted) !important}body.quarto-dark #quarto-search .aa-DetachedSearchButton{background:hsla(0,0%,100%,.08);border-color:hsla(0,0%,100%,.15);color:#e0e0e0}body.quarto-dark #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon,body.quarto-dark #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon svg,body.quarto-dark #quarto-search .aa-DetachedSearchButton .aa-SearchIcon,html.quarto-dark #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon,html.quarto-dark #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon svg,html.quarto-dark #quarto-search .aa-DetachedSearchButton .aa-SearchIcon,:root[data-bs-theme=dark] #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon,:root[data-bs-theme=dark] #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon svg,:root[data-bs-theme=dark] #quarto-search .aa-DetachedSearchButton .aa-SearchIcon{color:#e0e0e0 !important;fill:#e0e0e0 !important}body.quarto-dark #quarto-search .aa-DetachedSearchButton:hover{background:hsla(0,0%,100%,.12);border-color:hsla(0,0%,100%,.25)}body.quarto-dark #quarto-search .aa-DetachedSearchButton:focus{outline:none;box-shadow:0 0 0 2px hsla(0,0%,100%,.15)}body.quarto-dark .navbar .quarto-navbar-tools button,body.quarto-dark .navbar .quarto-navbar-tools .quarto-navigation-tool{display:flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;background:hsla(0,0%,100%,.08);border:1px solid hsla(0,0%,100%,.15);border-radius:6px;color:#e0e0e0;cursor:pointer;transition:all .2s ease}body.quarto-dark .navbar .quarto-navbar-tools button:hover,body.quarto-dark .navbar .quarto-navbar-tools .quarto-navigation-tool:hover{background:hsla(0,0%,100%,.12);border-color:hsla(0,0%,100%,.25)}body.quarto-dark .navbar .nav-item.compact .nav-link,body.quarto-dark .navbar .gd-navbar-icon{display:flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;background:hsla(0,0%,100%,.08);border:1px solid hsla(0,0%,100%,.15);border-radius:6px;color:#e0e0e0;cursor:pointer;transition:all .2s ease}body.quarto-dark .navbar .nav-item.compact .nav-link:hover,body.quarto-dark .navbar .gd-navbar-icon:hover{background:hsla(0,0%,100%,.12);border-color:hsla(0,0%,100%,.25)}body.quarto-dark .navbar .navbar-toggler{border:none;--bs-navbar-toggler-focus-width: 0}body.quarto-dark .navbar .navbar-toggler:focus{box-shadow:none;outline:none}body.quarto-dark .navbar .navbar-toggler .navbar-toggler-icon{--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23e0e0e0' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}body.quarto-dark .aa-Panel{background-color:var(--gd-bg-secondary);border-color:var(--gd-border-color)}body.quarto-dark .aa-Item{color:var(--gd-text-primary)}body.quarto-dark .aa-Item:hover,body.quarto-dark .aa-Item[aria-selected=true]{background-color:var(--gd-bg-tertiary)}body.quarto-dark .search-result-title,body.quarto-dark p.search-result-title,body.quarto-dark .aa-Panel .search-result-title,body.quarto-dark #quarto-search-results .search-result-title,html.quarto-dark .search-result-title,html.quarto-dark p.search-result-title{color:var(--gd-text-primary) !important}body.quarto-dark .search-result-header,body.quarto-dark div.search-result-header,body.quarto-dark .aa-Panel .search-result-header,body.quarto-dark #quarto-search-results .search-result-header,html.quarto-dark .search-result-header,html.quarto-dark div.search-result-header{color:var(--gd-text-secondary) !important}body.quarto-dark .search-result-text{color:var(--gd-text-secondary)}body.quarto-dark .search-result-doc-title{color:var(--gd-text-primary)}body.quarto-dark .search-result-section{color:var(--gd-text-muted)}body.quarto-dark .aa-SourceHeader{color:var(--gd-text-muted);border-bottom-color:var(--gd-border-color)}body.quarto-dark .aa-SourceNoResults{color:var(--gd-text-muted)}body.quarto-dark .quarto-search-results{background-color:var(--gd-bg-secondary)}body.quarto-dark .search-result-link{color:var(--gd-link-color)}body.quarto-dark .search-result-link:hover{color:#9dcaf0}body.quarto-dark .aa-Autocomplete{background-color:rgba(0,0,0,0)}body.quarto-dark .aa-Form,html.quarto-dark .aa-Form,:root[data-bs-theme=dark] .aa-Form{background-color:var(--gd-bg-tertiary);border-color:var(--gd-border-color)}body.quarto-dark .aa-Input,html.quarto-dark .aa-Input,:root[data-bs-theme=dark] .aa-Input{color:var(--gd-text-primary) !important;background-color:rgba(0,0,0,0)}body.quarto-dark .aa-InputWrapperPrefix,body.quarto-dark .aa-InputWrapperSuffix,html.quarto-dark .aa-InputWrapperPrefix,html.quarto-dark .aa-InputWrapperSuffix,:root[data-bs-theme=dark] .aa-InputWrapperPrefix,:root[data-bs-theme=dark] .aa-InputWrapperSuffix{color:var(--gd-text-muted)}body.quarto-dark .aa-SubmitButton,html.quarto-dark .aa-SubmitButton,:root[data-bs-theme=dark] .aa-SubmitButton,body.quarto-dark .aa-SubmitIcon,html.quarto-dark .aa-SubmitIcon,:root[data-bs-theme=dark] .aa-SubmitIcon,body.quarto-dark svg.aa-SubmitIcon,html.quarto-dark svg.aa-SubmitIcon,:root[data-bs-theme=dark] svg.aa-SubmitIcon{color:var(--gd-text-muted) !important;fill:var(--gd-text-muted) !important}body.quarto-dark .aa-ClearButton,html.quarto-dark .aa-ClearButton,:root[data-bs-theme=dark] .aa-ClearButton,body.quarto-dark .aa-ClearIcon,html.quarto-dark .aa-ClearIcon,:root[data-bs-theme=dark] .aa-ClearIcon,body.quarto-dark svg.aa-ClearIcon,html.quarto-dark svg.aa-ClearIcon,:root[data-bs-theme=dark] svg.aa-ClearIcon{color:var(--gd-text-muted) !important;fill:var(--gd-text-muted) !important}body.quarto-dark .aa-ClearButton:hover,html.quarto-dark .aa-ClearButton:hover,:root[data-bs-theme=dark] .aa-ClearButton:hover,body.quarto-dark .aa-ClearButton:hover svg.aa-ClearIcon,html.quarto-dark .aa-ClearButton:hover svg.aa-ClearIcon,:root[data-bs-theme=dark] .aa-ClearButton:hover svg.aa-ClearIcon{color:var(--gd-text-primary) !important;fill:var(--gd-text-primary) !important}body.quarto-dark .gh-widget-trigger{background:hsla(0,0%,100%,.08);border-color:hsla(0,0%,100%,.15);color:#e0e0e0}body.quarto-dark .gh-widget-trigger:hover{background:hsla(0,0%,100%,.12);border-color:hsla(0,0%,100%,.25)}body.quarto-dark .nav-item:has(#github-widget)>a:hover,body.quarto-dark .nav-item:has(#github-widget) .nav-link:hover{background:rgba(0,0,0,0) !important;background-color:rgba(0,0,0,0) !important;box-shadow:none !important}body.quarto-dark .gh-dropdown{background:var(--gd-bg-secondary);border-color:var(--gd-border-color);box-shadow:0 8px 24px rgba(0,0,0,.4)}body.quarto-dark .gh-dropdown-item{color:var(--gd-text-primary) !important}body.quarto-dark .gh-dropdown-item:hover{background:var(--gd-bg-tertiary)}body.quarto-dark .gh-dropdown-item svg{color:var(--gd-text-muted)}body.quarto-dark .gh-dropdown-divider{background:var(--gd-border-color)}body.quarto-dark .gh-badge{background:rgba(110,168,254,.2);color:#6ea8fe}body.quarto-dark .source-link{color:#7cb8e8 !important}body.quarto-dark .source-link:hover{color:#9dcaf0 !important}@media(max-width: 991.98px){body.quarto-dark .column-margin{background-color:var(--gd-bg-secondary);border-color:var(--gd-border-color)}body.quarto-dark .column-margin,body.quarto-dark .column-margin>*,body.quarto-dark .column-margin section,body.quarto-dark .column-margin p,body.quarto-dark .column-margin code{background-color:var(--gd-bg-secondary)}body.quarto-dark .column-margin h4,body.quarto-dark .column-margin .h4{color:var(--gd-text-secondary);border-bottom-color:var(--gd-border-color)}body.quarto-dark .quarto-secondary-nav{background-color:var(--gd-bg-secondary);border-bottom-color:var(--gd-border-color)}body.quarto-dark header.headroom--unpinned .quarto-secondary-nav{box-shadow:0 1px 4px rgba(0,0,0,.3)}}body.quarto-dark .gd-code-copy{color:var(--gd-text-muted)}body.quarto-dark .gd-code-copy:hover{background-color:hsla(0,0%,100%,.08);border-color:hsla(0,0%,100%,.15);color:var(--gd-text-primary)}body.quarto-dark .gd-code-copy.gd-code-copied{color:#75b798}body.quarto-dark .code-with-filename .code-with-filename-file{background-color:var(--gd-bg-tertiary);border-color:var(--gd-border-color)}body.quarto-dark .code-with-filename .code-with-filename-file pre{background-color:var(--gd-bg-tertiary);color:var(--gd-text-primary)}body.quarto-dark .code-with-filename .code-with-filename-file pre strong{color:var(--gd-text-primary)}body.quarto-dark .code-with-filename-file{background-color:var(--gd-bg-tertiary)}body.quarto-dark .code-with-filename-file pre{background-color:rgba(0,0,0,0);color:var(--gd-text-primary);margin:0}body.quarto-dark ::-webkit-scrollbar{width:10px;height:10px}body.quarto-dark ::-webkit-scrollbar-track{background:var(--gd-bg-secondary)}body.quarto-dark ::-webkit-scrollbar-thumb{background:var(--gd-border-color);border-radius:5px}body.quarto-dark ::-webkit-scrollbar-thumb:hover{background:#555}body,.navbar,#quarto-sidebar,.nav-footer,.card,pre,code,.table,.doc-reference section.doc-group>dl,input,textarea,.gh-dropdown,.dark-mode-toggle{transition:background-color .2s ease,border-color .2s ease,color .2s ease}.section-cards{display:grid;gap:1rem;margin-top:.5rem}.section-cards-2col{grid-template-columns:repeat(auto-fill, minmax(300px, 1fr))}.section-cards-1col{grid-template-columns:1fr}.section-cards-list{grid-template-columns:1fr}.section-card{display:block;padding:1.25rem 1.5rem;border:1px solid var(--bs-border-color, #dee2e6);border-radius:.5rem;color:inherit;text-decoration:none;transition:box-shadow .2s ease-out,border-color .2s ease-out,transform .2s ease-out}.section-card:hover{border-color:var(--bs-primary, #0d6efd);box-shadow:0 4px 12px rgba(0,0,0,.1);transform:translateY(-2px);color:inherit;text-decoration:none}.section-card-img{width:100%;border-radius:.375rem;margin-bottom:.75rem}.section-card-title{font-size:1.1rem;font-weight:600;margin-bottom:.35rem;color:var(--bs-primary, #0d6efd)}.section-card-desc{font-size:.9rem;color:var(--bs-secondary-color, #6c757d);line-height:1.45}body.quarto-dark .section-card{border-color:var(--bs-border-color, #495057)}body.quarto-dark .section-card:hover{box-shadow:0 4px 12px rgba(0,0,0,.3)}body.quarto-dark .section-card-title{color:#599cff !important}body.quarto-dark .section-card-desc{color:#9ca3af !important}body.quarto-dark .section-card:hover{border-color:#599cff}html:not(.theme-loaded) *,html:not(.theme-loaded) *::before,html:not(.theme-loaded) *::after{transition:none !important}@media(min-width: 992px){body[data-page=index] #quarto-document-content>section:not(.column-margin),body[data-page=index] #quarto-document-content>.gd-hero,body[data-page=index] #quarto-document-content>p,body[data-page=index] #quarto-document-content>.cell,body[data-page=index] #quarto-document-content>details{grid-column:page-start-inset/body-content-end !important}body[data-page=index] .column-margin{grid-column:body-end/page-end !important}body.gd-homepage.quarto-dark #quarto-content,body.gd-homepage.quarto-dark main.content,body.gd-homepage.quarto-dark #quarto-document-content,body.gd-homepage.quarto-dark .quarto-body-content,body.gd-homepage.quarto-dark .page-columns,body.gd-homepage.quarto-dark .page-rows-contents,body.gd-homepage.quarto-dark .column-body,body.gd-homepage.quarto-dark article,body.gd-homepage.quarto-dark section{background-color:rgba(0,0,0,0)}}.gd-homepage{overflow-x:clip}.gd-hero{text-align:center;padding:2.5rem 1rem 2rem;position:relative;overflow:visible}#gd-starfield{position:fixed;top:0;left:0;width:100vw;height:100vh;pointer-events:none;z-index:0;transition:opacity .15s ease-out;mask-image:linear-gradient(to bottom, black 35%, transparent 85%);-webkit-mask-image:linear-gradient(to bottom, black 35%, transparent 85%)}.gd-hero>*:not(#gd-starfield){position:relative;z-index:1}main.content.page-columns.page-full>*{grid-column:body-content-start/body-content-end}.gd-homepage main.page-columns>*:not(.column-margin){grid-column:page-start-inset/body-content-end}.gd-hero-logo{display:block;width:auto;max-width:80%;margin-left:auto;margin-right:auto;margin-bottom:1.25rem}.gd-hero-name{font-size:2.5rem;font-weight:600;margin-bottom:.3rem;line-height:1.15}.gd-hero-tagline{font-size:1.35rem;max-width:600px;margin:0 auto 1rem;color:var(--bs-secondary-color, #6c757d);line-height:1.3;text-wrap:balance}.gd-hero-badges{display:flex;justify-content:center;flex-wrap:wrap;gap:.35rem}.gd-hero-badges img{height:20px}.gd-hero .gd-only-dark{display:none !important}[data-bs-theme=dark] .gd-hero .gd-only-light{display:none !important}[data-bs-theme=dark] .gd-hero .gd-only-dark{display:block !important;margin-left:auto;margin-right:auto}html[data-bs-theme=dark] .navbar-logo.light-content{display:none !important}html[data-bs-theme=dark] .navbar-logo.dark-content{display:inline !important}.gd-hero+section.level1>h1:first-child,.gd-hero+section.level1>.h1:first-child,.gd-hero+section.level2>h2:first-child,.gd-hero+section.level2>.h2:first-child{margin-top:.5rem !important}.gd-cta-grid{display:grid;grid-template-columns:repeat(3, 1fr);gap:1.25rem;margin:1.5rem 0 2rem}.gd-cta-card{display:flex;flex-direction:column;align-items:flex-start;padding:1.5rem;border-radius:12px;border:1px solid rgba(0,0,0,.08);background:linear-gradient(135deg, rgba(255, 255, 255, 0.9), rgba(248, 249, 250, 0.7));text-decoration:none !important;color:inherit !important;transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease;position:relative;overflow:hidden}.gd-cta-card:hover{transform:translateY(-3px);box-shadow:0 8px 24px rgba(0,0,0,.1);border-color:rgba(0,0,0,.15)}.gd-cta-card:hover .gd-cta-arrow{transform:translateX(4px);opacity:1}.gd-cta-icon{font-size:2rem;margin-bottom:.75rem;line-height:1}.gd-cta-title{font-size:1.15rem;font-weight:600;margin-bottom:.4rem;line-height:1.3}.gd-cta-desc{font-size:.9rem;line-height:1.5;color:#6c757d;flex-grow:1}.gd-cta-arrow{font-size:1.25rem;margin-top:.75rem;opacity:.4;transition:transform .2s ease,opacity .2s ease;font-weight:600}body.quarto-dark .gd-cta-card{border-color:hsla(0,0%,100%,.1);background:linear-gradient(135deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.02))}body.quarto-dark .gd-cta-card:hover{border-color:hsla(0,0%,100%,.2);box-shadow:0 8px 24px rgba(0,0,0,.3)}body.quarto-dark .gd-cta-desc{color:#adb5bd}@media(max-width: 768px){.gd-cta-grid{grid-template-columns:1fr;gap:1rem}}.gd-feature-wall{margin:3rem 0 2rem;hyphens:auto;-webkit-hyphens:auto;overflow-wrap:break-word}.gd-fw-heading{text-align:center;font-weight:700;margin-bottom:1.5rem;letter-spacing:-0.01em}.gd-fw-large,.gd-fw-medium,.gd-fw-small{text-align:justify;text-justify:inter-word}.gd-fw-large{font-size:1.65rem;line-height:1.45;margin-bottom:.6rem;letter-spacing:-0.01em}.gd-fw-medium{font-size:1.15rem;line-height:1.55;margin-bottom:.5rem}.gd-fw-small{font-size:.88rem;line-height:1.65}.gd-feature-wall b{font-weight:650}@media(max-width: 768px){.gd-fw-large{font-size:1.35rem}.gd-fw-medium{font-size:1.05rem}.gd-fw-small{font-size:.82rem}}:root{--gd-palette-sky: #0077b6;--gd-palette-peach: #e07a3a;--gd-palette-prism: #6d28d9;--gd-palette-lilac: #a855f7;--gd-palette-slate: #64748b;--gd-palette-honey: #d97706;--gd-palette-dusk: #4338ca;--gd-palette-mint: #0d9488;--gd-palette-accent: var(--gd-accent, #6366f1)}html[data-bs-theme=dark]{--gd-palette-sky: #38bdf8;--gd-palette-peach: #fb923c;--gd-palette-prism: #a78bfa;--gd-palette-lilac: #c084fc;--gd-palette-slate: #94a3b8;--gd-palette-honey: #fbbf24;--gd-palette-dusk: #818cf8;--gd-palette-mint: #2dd4bf;--gd-palette-accent: var(--gd-accent, #818cf8)}.gd-hr{--gd-hr-color: var(--gd-accent, #6366f1);--gd-hr-thickness: 2px;--gd-hr-width: 100%;--gd-hr-spacing: 2rem;border:none;height:var(--gd-hr-thickness);width:var(--gd-hr-width);max-width:100%;margin:var(--gd-hr-spacing) auto;background:var(--gd-hr-color);opacity:.7;display:block}.gd-hr--dotted{background:none;border-top:var(--gd-hr-thickness) dotted var(--gd-hr-color);height:0}.gd-hr--dashed{background:none;border-top:var(--gd-hr-thickness) dashed var(--gd-hr-color);height:0}.gd-hr--double{background:none;border-top:calc(var(--gd-hr-thickness)*.5) double var(--gd-hr-color);height:0;border-top-width:calc(var(--gd-hr-thickness) + 2px)}.gd-hr--left{margin-left:0;margin-right:auto}.gd-hr--right{margin-left:auto;margin-right:0}.gd-hr--with-text{display:flex;align-items:center;gap:1rem;height:auto;background:none;border:none;width:var(--gd-hr-width);max-width:100%;margin:var(--gd-hr-spacing) auto;opacity:1}.gd-hr--with-text.gd-hr--left{margin-left:0;margin-right:auto}.gd-hr--with-text.gd-hr--right{margin-left:auto;margin-right:0}.gd-hr-line{flex:1;height:var(--gd-hr-thickness, 2px);background:var(--gd-hr-color);opacity:.7}.gd-hr-text{font-size:.9rem;font-weight:500;color:var(--gd-hr-color);white-space:nowrap;user-select:none;line-height:1}.gd-hr-text--sm{font-size:.75rem}.gd-hr-text--lg{font-size:1.2rem}.gd-hr--gradient-shimmer{background:linear-gradient(90deg, transparent, var(--gd-hr-color, var(--gd-accent, #6366f1)) 25%, var(--gd-accent-secondary, #a855f7) 50%, var(--gd-hr-color, var(--gd-accent, #6366f1)) 75%, transparent);background-size:200% 100%;animation:gd-hr-shimmer 4s ease-in-out infinite;border:none;height:var(--gd-hr-thickness)}@keyframes gd-hr-shimmer{0%{background-position:100% 0}50%{background-position:0% 0}100%{background-position:100% 0}}.gd-hr--gradient-static{background:linear-gradient(90deg, transparent, var(--gd-hr-color, var(--gd-accent, #6366f1)) 25%, var(--gd-accent-secondary, #a855f7) 50%, var(--gd-hr-color, var(--gd-accent, #6366f1)) 75%, transparent);border:none;height:var(--gd-hr-thickness)}.gd-hr--fade{background:linear-gradient(90deg, transparent, var(--gd-hr-color) 20%, var(--gd-hr-color) 80%, transparent);border:none;height:var(--gd-hr-thickness)}.gd-hr--fade-edges{background:radial-gradient(ellipse at center, var(--gd-hr-color) 0%, transparent 70%);border:none;height:var(--gd-hr-thickness)}.gd-hr--dots{background:none;border:none;height:auto;text-align:center;opacity:1}.gd-hr--dots::after{content:"· · ·";font-size:1.5rem;letter-spacing:.3em;color:var(--gd-hr-color);opacity:.8}.gd-hr--diamond{background:none;border:none;height:auto;display:flex;align-items:center;gap:.75rem;opacity:1}.gd-hr--diamond::before,.gd-hr--diamond::after{content:"";flex:1;height:1px;background:var(--gd-hr-color);opacity:.5}.gd-hr--diamond::before{content:""}hr.gd-hr--diamond{display:flex}hr.gd-hr--diamond::before{content:"";flex:1;height:1px;background:linear-gradient(90deg, transparent, var(--gd-hr-color))}hr.gd-hr--diamond::after{content:"◇";flex:none;height:auto;background:none;font-size:1rem;color:var(--gd-hr-color);opacity:.8;padding:0 .5rem}.gd-hr--ornament{background:none;border:none;height:auto;display:flex;align-items:center;opacity:1}hr.gd-hr--ornament::before{content:"";flex:1;height:1px;background:linear-gradient(90deg, transparent, var(--gd-hr-color))}hr.gd-hr--ornament::after{content:"❧";flex:none;height:auto;background:none;font-size:1.2rem;color:var(--gd-hr-color);opacity:.7;padding:0 .75rem}.gd-hr--wave{background:repeating-linear-gradient(135deg, var(--gd-hr-color) 0px, var(--gd-hr-color) 2px, transparent 2px, transparent 6px);border:none;height:var(--gd-hr-thickness);opacity:.6}.gd-hr--double-line{background:none;border:none;height:calc(var(--gd-hr-thickness)*2 + 3px);position:relative;opacity:.7}.gd-hr--double-line::before,.gd-hr--double-line::after{content:"";position:absolute;left:0;right:0;height:var(--gd-hr-thickness);background:var(--gd-hr-color)}.gd-hr--double-line::before{top:0}.gd-hr--double-line::after{bottom:0}body.quarto-dark .gd-hr{opacity:.6}body.quarto-dark .gd-hr--with-text{opacity:1}body.quarto-dark .gd-hr-line{opacity:.5}body.quarto-dark .gd-hr-text{opacity:.85}body.quarto-dark .gd-hr--dots::after{opacity:.6}@media(prefers-reduced-motion: reduce){.gd-hr--gradient-shimmer{animation:none}}@media(max-width: 768px){.gd-hr{--gd-hr-spacing: 1.5rem}}.gd-fw-rule{border:none;height:2px;margin:3rem auto 2rem;max-width:30rem;background:linear-gradient(90deg, transparent, var(--gd-accent, #6366f1) 25%, var(--gd-accent-secondary, #a855f7) 50%, var(--gd-accent, #6366f1) 75%, transparent);background-size:200% 100%;animation:gd-rule-shimmer 4s ease-in-out infinite;opacity:.7}@keyframes gd-rule-shimmer{0%{background-position:100% 0}50%{background-position:0% 0}100%{background-position:100% 0}}.gd-fw-closing{text-align:center;padding:0 1.5rem 2.5rem;max-width:38rem;margin:0 auto;position:relative;z-index:1}.gd-fw-closing p{font-size:1.05rem;line-height:1.7;color:#6b7280;margin:0}body.quarto-dark .gd-fw-closing p{color:#9ca3af}.gd-fw-closing a{color:var(--gd-accent, #6366f1);text-decoration:none;font-weight:600;border-bottom:1px solid rgba(0,0,0,0);transition:border-color .2s ease}.gd-fw-closing a:hover{border-bottom-color:var(--gd-accent, #6366f1)}@media(max-width: 768px){.gd-fw-rule{max-width:80%;margin:2rem auto 1.5rem}.gd-fw-closing p{font-size:.95rem}}@media(max-width: 768px){.gd-hero{padding:1.5rem .75rem 1.25rem}.gd-hero-logo{max-height:140px !important}.gd-hero-name{font-size:2.25rem}.gd-hero-tagline{font-size:1.1rem}}.gd-copy-page{float:right;display:flex;gap:4px;margin-top:4px;margin-left:12px;position:relative;z-index:5}.gd-copy-page-btn{display:inline-flex;align-items:center;gap:5px;padding:3px 8px;border:1px solid #d0d7de;border-radius:6px;background:#f6f8fa;color:#57606a;font-size:12px;font-family:inherit;line-height:1.4;cursor:pointer;text-decoration:none;transition:background .15s,border-color .15s,color .15s;white-space:nowrap}.gd-copy-page-btn:hover{background:#eaeef2;border-color:#b8bfc6;color:#24292f;text-decoration:none}.gd-copy-page-btn:active{background:#d8dee4}.gd-copy-page-btn.gd-copy-success{border-color:#2da44e;color:#1a7f37;background:#dafbe1}a.gd-view-md-btn{color:#57606a}a.gd-view-md-btn:hover{color:#24292f}html[data-bs-theme=dark] .gd-copy-page-btn{background:#21262d;border-color:#30363d;color:#8b949e}html[data-bs-theme=dark] .gd-copy-page-btn:hover{background:#30363d;border-color:#484f58;color:#c9d1d9}html[data-bs-theme=dark] .gd-copy-page-btn:active{background:#3a424a}html[data-bs-theme=dark] .gd-copy-page-btn.gd-copy-success{border-color:#238636;color:#3fb950;background:#0d1117}html[data-bs-theme=dark] a.gd-view-md-btn{color:#8b949e}html[data-bs-theme=dark] a.gd-view-md-btn:hover{color:#c9d1d9}@media(max-width: 768px){.gd-copy-page{float:none;margin-left:0;margin-bottom:10px}.gd-copy-page-label{display:none}.gd-copy-page-btn{padding:4px 6px}}.gd-announcement-banner{font-family:var(--bs-body-font-family, system-ui, -apple-system, sans-serif);line-height:1.5;letter-spacing:.01em;text-wrap:balance}.gd-announcement-banner a{font-weight:600;text-decoration:underline;color:inherit}.gd-announcement-banner a:hover{opacity:.85;text-decoration:underline}html[data-bs-theme=dark] .gd-announcement-info{background:#1a5bb5 !important}html[data-bs-theme=dark] .gd-announcement-warning{background:#d4a800 !important}html[data-bs-theme=dark] .gd-announcement-success{background:#126b3d !important}html[data-bs-theme=dark] .gd-announcement-danger{background:#b02a37 !important}@keyframes gd-gradient-shift{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}}.gd-gradient-sky,.gd-gradient-peach,.gd-gradient-prism,.gd-gradient-lilac,.gd-gradient-slate,.gd-gradient-honey,.gd-gradient-dusk,.gd-gradient-mint{background-size:400% 400% !important;animation:gd-gradient-shift 15s ease infinite;border-bottom-color:rgba(0,0,0,.08) !important}html[data-bs-theme=dark] .gd-gradient-sky,html[data-bs-theme=dark] .gd-gradient-peach,html[data-bs-theme=dark] .gd-gradient-prism,html[data-bs-theme=dark] .gd-gradient-lilac,html[data-bs-theme=dark] .gd-gradient-slate,html[data-bs-theme=dark] .gd-gradient-honey,html[data-bs-theme=dark] .gd-gradient-dusk,html[data-bs-theme=dark] .gd-gradient-mint{color:#fff !important;border-bottom-color:hsla(0,0%,100%,.15) !important}.gd-gradient-sky{background:linear-gradient(-45deg, #d0ecf9, #e0f4ff, #c5e8f7, #b8e0f5) !important}html[data-bs-theme=dark] .gd-gradient-sky{background:linear-gradient(-45deg, #023e8a, #0077b6, #005f73, #0096c7) !important}.gd-gradient-peach{background:linear-gradient(-45deg, #ffddc1, #ffe4cc, #fdd0d8, #fbc4d4) !important}html[data-bs-theme=dark] .gd-gradient-peach{background:linear-gradient(-45deg, #cc4a1a, #c7760f, #b84a5f, #a33560) !important}.gd-gradient-prism{background:linear-gradient(-45deg, #c4f0e0, #d0e8f5, #e4d4f4, #d8cef0) !important}html[data-bs-theme=dark] .gd-gradient-prism{background:linear-gradient(-45deg, #048a65, #0c6a8a, #52077d, #2a0978) !important}.gd-gradient-lilac{background:linear-gradient(-45deg, #e8d0f0, #f5d0e0, #f0d4f8, #eac8ee) !important}html[data-bs-theme=dark] .gd-gradient-lilac{background:linear-gradient(-45deg, #561e64, #8b1140, #a02db3, #6e1a7d) !important}.gd-gradient-slate{background:linear-gradient(-45deg, #e0e4e8, #eceff1, #dde2e6, #d5dadf) !important}html[data-bs-theme=dark] .gd-gradient-slate{background:linear-gradient(-45deg, #37474f, #455a64, #3e525e, #263238) !important}.gd-gradient-honey{background:linear-gradient(-45deg, #ffe0c2, #ffedcc, #ffe5b4, #ffd6a8) !important}html[data-bs-theme=dark] .gd-gradient-honey{background:linear-gradient(-45deg, #bf360c, #e65100, #ef6c00, #b71c1c) !important}.gd-gradient-dusk{background:linear-gradient(-45deg, #d8daf0, #dddff5, #d4d0ee, #dad4f2) !important}html[data-bs-theme=dark] .gd-gradient-dusk{background:linear-gradient(-45deg, #0d1244, #141b55, #1a0f52, #261560) !important}.gd-gradient-mint{background:linear-gradient(-45deg, #ccece8, #d5f0ec, #c4e8e4, #d0f2ee) !important}html[data-bs-theme=dark] .gd-gradient-mint{background:linear-gradient(-45deg, #00695c, #00796b, #004d40, #00897b) !important}html[data-bs-theme=dark] .navbar[class*=gd-gradient-]{border-bottom:1px solid hsla(0,0%,100%,.15) !important}html[data-bs-theme=dark] .navbar[class*=gd-gradient-] .nav-link,html[data-bs-theme=dark] .navbar[class*=gd-gradient-] .navbar-brand .navbar-title{color:#fff !important}html[data-bs-theme=dark] .navbar[class*=gd-gradient-] .nav-link:hover{background-color:hsla(0,0%,100%,.2) !important;color:#fff !important}html[data-bs-theme=dark] .navbar[class*=gd-gradient-] .nav-item:has(#github-widget) .nav-link:hover{background-color:rgba(0,0,0,0) !important}html[data-bs-theme=dark] .navbar[class*=gd-gradient-] .nav-item.compact .nav-link,html[data-bs-theme=dark] .navbar[class*=gd-gradient-] .gd-navbar-icon{background:hsla(0,0%,100%,.08) !important;border:1px solid hsla(0,0%,100%,.15);border-radius:6px;width:34px;height:34px;display:flex;align-items:center;justify-content:center;padding:0}html[data-bs-theme=dark] .navbar[class*=gd-gradient-] .nav-item.compact .nav-link:hover,html[data-bs-theme=dark] .navbar[class*=gd-gradient-] .gd-navbar-icon:hover{background:hsla(0,0%,100%,.12) !important;border-color:hsla(0,0%,100%,.25)}html[data-bs-theme=dark] .navbar[class*=gd-gradient-] .nav-link.active{text-decoration-color:hsla(0,0%,100%,.75) !important}html[data-bs-theme=dark] .navbar[class*=gd-gradient-] .navbar-toggler{border:none !important;color:#e0e0e0 !important}html[data-bs-theme=dark] .navbar[class*=gd-gradient-] .navbar-toggler-icon{filter:none}html[data-bs-theme=dark] .navbar[class*=gd-gradient-] .bi{color:#fff !important}html[data-bs-theme=dark] .gd-announcement-banner[class*=gd-gradient-] a{color:#fff !important}html[data-bs-theme=dark] .gd-announcement-banner[class*=gd-gradient-] button{color:#fff !important}@keyframes gd-glow-drift-1{0%{transform:translateX(0%) scale(1);opacity:.6}25%{transform:translateX(5%) scale(1.08);opacity:.42}50%{transform:translateX(-3%) scale(1.02);opacity:.55}75%{transform:translateX(2%) scale(1.05);opacity:.38}100%{transform:translateX(0%) scale(1);opacity:.6}}@keyframes gd-glow-drift-2{0%{transform:translateX(0%) scale(1);opacity:.45}30%{transform:translateX(-6%) scale(1.1);opacity:.58}60%{transform:translateX(4%) scale(0.96);opacity:.35}100%{transform:translateX(0%) scale(1);opacity:.45}}@keyframes gd-glow-drift-3{0%{transform:translateX(0%) scale(1);opacity:.35}35%{transform:translateX(3%) scale(1.12);opacity:.52}70%{transform:translateX(-5%) scale(1.04);opacity:.28}100%{transform:translateX(0%) scale(1);opacity:.35}}.gd-content-glow{position:fixed;top:0;left:0;right:0;height:600px;pointer-events:none;z-index:0;mask-image:linear-gradient(to bottom, rgb(0, 0, 0) 0%, rgba(0, 0, 0, 0) 100%);-webkit-mask-image:linear-gradient(to bottom, rgb(0, 0, 0) 0%, rgba(0, 0, 0, 0) 100%)}.gd-glow-pulse{position:absolute;inset:0}.gd-glow-pulse-1{background:radial-gradient(ellipse 65% 55% at 28% 0%, var(--gd-glow-color), transparent);animation:gd-glow-drift-1 23s ease-in-out infinite;opacity:.6}.gd-glow-pulse-2{background:radial-gradient(ellipse 50% 45% at 62% 5%, var(--gd-glow-color), transparent);animation:gd-glow-drift-2 19s ease-in-out infinite;opacity:.45}.gd-glow-pulse-3{background:radial-gradient(ellipse 45% 50% at 85% 0%, var(--gd-glow-color), transparent);animation:gd-glow-drift-3 27s ease-in-out infinite;opacity:.35}.gd-content-glow-sky{--gd-glow-color: #c5e8f7}.gd-content-glow-peach{--gd-glow-color: #ffddc1}.gd-content-glow-prism{--gd-glow-color: #d0e8f5}.gd-content-glow-lilac{--gd-glow-color: #e8d0f0}.gd-content-glow-slate{--gd-glow-color: #dde2e6}.gd-content-glow-honey{--gd-glow-color: #ffe0c2}.gd-content-glow-dusk{--gd-glow-color: #d8daf0}.gd-content-glow-mint{--gd-glow-color: #ccece8}html[data-bs-theme=dark] .gd-content-glow-sky{--gd-glow-color: #023e8a}html[data-bs-theme=dark] .gd-content-glow-peach{--gd-glow-color: #cc4a1a}html[data-bs-theme=dark] .gd-content-glow-prism{--gd-glow-color: #0c6a8a}html[data-bs-theme=dark] .gd-content-glow-lilac{--gd-glow-color: #561e64}html[data-bs-theme=dark] .gd-content-glow-slate{--gd-glow-color: #37474f}html[data-bs-theme=dark] .gd-content-glow-honey{--gd-glow-color: #bf360c}html[data-bs-theme=dark] .gd-content-glow-dusk{--gd-glow-color: #141b55}html[data-bs-theme=dark] .gd-content-glow-mint{--gd-glow-color: #00695c}@media(min-width: 992px){header.headroom--unpinned{transform:translateY(0%) !important}}@media(max-width: 991.98px){.quarto-secondary-nav{position:relative;z-index:1;transition:transform 200ms linear,box-shadow 200ms linear}header.headroom--unpinned .quarto-secondary-nav{transform:translateY(100%);box-shadow:0 1px 4px rgba(0,0,0,.12)}}.gd-skills-install{border:1px solid rgb(191.7,197.1,202.5);border-radius:.5rem;margin-bottom:2rem;overflow:hidden;width:100%}.gd-skills-install-toggle{display:flex;align-items:center;gap:.5rem;width:100%;padding:.75rem 1.25rem;border:none;background:rgb(240.23,241.49,242.75);color:#2c3e50;font-weight:600;font-size:1rem;cursor:pointer;text-align:left;transition:background .15s ease}.gd-skills-install-toggle:hover{background:rgb(227.57,229.91,232.25)}.gd-skills-install-toggle[aria-expanded=true]{border-bottom:1px solid rgb(191.7,197.1,202.5)}.gd-skills-install-icon{display:inline-block;font-size:.65rem;transition:transform .25s ease;line-height:1}.gd-skills-install-toggle[aria-expanded=true] .gd-skills-install-icon{transform:rotate(90deg)}.gd-skills-install-body{display:grid;grid-template-rows:0fr;transition:grid-template-rows .35s ease;background:rgb(248.67,249.21,249.75)}.gd-skills-install-body>*{overflow:hidden;min-height:0}.gd-skills-install-body.gd-skills-install-open{grid-template-rows:1fr}.gd-skills-install-body .gd-skills-install-pad{padding:1rem 1.25rem .75rem}.gd-skills-install-body .sourceCode{margin:.35rem 0 .75rem}.gd-skills-install-body .gd-code-copy{opacity:1 !important}.gd-skills-install-body pre.sourceCode{padding:.5rem 2.5rem .5rem .75rem;font-size:.88rem}.gd-skills-install-body pre.sourceCode code{padding:0 !important}.gd-skills-install-body p{margin:.25rem 0;font-size:.92rem;line-height:1.55}.gd-skills-install-body p a{text-decoration:underline;cursor:pointer}.gd-skills-install-body strong{color:rgb(37.4,52.7,68)}html[data-bs-theme=dark] .gd-skills-install{border-color:#161f28}html[data-bs-theme=dark] .gd-skills-install-toggle{background:rgb(8.8,12.4,16);color:rgb(149.5,158.5,167.5)}html[data-bs-theme=dark] .gd-skills-install-toggle:hover{background:rgb(12.32,17.36,22.4)}html[data-bs-theme=dark] .gd-skills-install-toggle[aria-expanded=true]{border-bottom-color:#161f28}html[data-bs-theme=dark] .gd-skills-install-body{background:rgb(5.28,7.44,9.6)}html[data-bs-theme=dark] .gd-skills-install-body strong{color:rgb(128.4,139.2,150)}html[data-bs-theme=dark] .gd-skills-install-body .code-copy-outer-scaffold,html[data-bs-theme=dark] .gd-skills-install-body .sourceCode,html[data-bs-theme=dark] .gd-skills-install-body pre.sourceCode{background:rgba(0,0,0,0)}body.gd-skills-page .content.column-page{grid-column:page-start/page-end !important;max-width:100%}body.gd-license-page .content.column-page{grid-column:page-start/page-end !important;max-width:100%}body.gd-blog-index .content.column-page{grid-column:page-start/page-end !important;max-width:100%}.gd-skills-raw{background:#f8f9fa;color:#343a40;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:.85rem;line-height:1.7;padding:1.25rem 1.5rem;border-radius:.5rem;border:1px solid #dee2e6;overflow-x:auto;white-space:pre-wrap;word-wrap:break-word;margin:0;max-width:100%}.gd-skills-raw .sourceCode{background:rgba(0,0,0,0) !important;border:none !important;margin:0;padding:0}.gd-skills-raw code{background:rgba(0,0,0,0);color:inherit;padding:0;font-size:inherit;white-space:pre-wrap}.gd-skills-raw pre{background:rgba(0,0,0,0) !important;border:none !important;margin:0;padding:0;color:inherit}html[data-bs-theme=dark] .gd-skills-raw{background:#212529;border-color:#7b8a8b;color:#ecf0f1}.gd-skills-tree{background:#f8f9fa;color:#7b8a8b;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:.88rem;line-height:1.8;padding:1rem 1.25rem;border-radius:.5rem;border:1px solid #dee2e6;margin:0 0 1.5rem;white-space:pre;overflow-x:auto}.gd-skills-tree a{color:#2c3e50;text-decoration:none}.gd-skills-tree a:hover{text-decoration:underline}html[data-bs-theme=dark] .gd-skills-tree{background:#212529;border-color:#7b8a8b;color:#ced4da}html[data-bs-theme=dark] .gd-skills-tree a{color:rgb(128.4,139.2,150)}.gd-skills-section-heading{font-size:.8rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#adb5bd;margin:0 0 .5rem;padding:0}html[data-bs-theme=dark] .gd-skills-section-heading{color:#ced4da}.gd-skills-file-heading{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:.95rem;font-weight:600;color:#7b8a8b;margin:1.5rem 0 .35rem;padding:0}.gd-skills-file-heading:first-of-type{margin-top:0}html[data-bs-theme=dark] .gd-skills-file-heading{color:#dee2e6}.gd-skill-switcher-sentinel{height:0}.gd-skill-switcher{display:flex;align-items:center;gap:.35rem;padding:.5rem .75rem;margin:0 0 1.75rem;background:#f8f9fa;border:1px solid #dee2e6;border-radius:.5rem;overflow-x:auto;z-index:1019;transition:box-shadow .2s ease,border-radius .2s ease}.gd-skill-switcher--stuck{position:fixed;left:0;right:0;margin:0;border-radius:0;border-left:none;border-right:none;box-shadow:0 2px 8px rgba(0,0,0,.08);padding-left:max(.75rem,env(safe-area-inset-left));padding-right:max(.75rem,env(safe-area-inset-right));transition:top 200ms linear,box-shadow .2s ease,border-radius .2s ease}.gd-skill-pill{display:inline-flex;align-items:center;gap:.4rem;padding:.4rem 1rem;border:1px solid rgba(0,0,0,0);border-radius:999px;background:rgba(0,0,0,0);color:#6c757d;font-size:.88rem;font-weight:500;white-space:nowrap;cursor:pointer;transition:background .15s ease,color .15s ease,border-color .15s ease;line-height:1.4}.gd-skill-pill:hover{background:rgb(233.9,235.7,237.5);color:#2c3e50}.gd-skill-pill--active,.gd-skill-pill[aria-selected=true]{background:#fff;color:#2c3e50;border-color:rgb(160.05,168.15,176.25);font-weight:600;box-shadow:0 1px 3px rgba(0,0,0,.06)}.gd-skill-pill__icon{width:1em;height:1em;flex-shrink:0}.gd-skill-panel[hidden]{display:none !important}html[data-bs-theme=dark] .gd-skill-switcher{background:#212529;border-color:#7b8a8b}html[data-bs-theme=dark] .gd-skill-switcher--stuck{box-shadow:0 2px 8px rgba(0,0,0,.35)}html[data-bs-theme=dark] .gd-skill-pill{color:#ced4da}html[data-bs-theme=dark] .gd-skill-pill:hover{background:rgb(11,15.5,20);color:rgb(138.95,148.85,158.75)}html[data-bs-theme=dark] .gd-skill-pill--active,html[data-bs-theme=dark] .gd-skill-pill[aria-selected=true]{background:#343a40;color:rgb(138.95,148.85,158.75);border-color:rgb(24.2,34.1,44)}.gd-page-metadata{border-top:1px solid #dee2e6;padding-top:1rem;margin-top:2rem;margin-bottom:1rem;color:#6c757d;font-size:.875rem;line-height:1.5;display:flex;align-items:center;gap:1.25rem;flex-wrap:wrap}.gd-page-metadata .gd-metadata-dates{display:flex;align-items:center;gap:1rem}.gd-page-metadata .gd-metadata-item{display:flex;align-items:center;gap:.35rem}.gd-page-metadata .gd-icon{display:inline-flex;align-items:center;opacity:.65}.gd-page-metadata .gd-icon svg{vertical-align:middle}.gd-page-metadata .gd-metadata-separator{color:#ced4da;font-weight:300}.gd-page-metadata .gd-metadata-authors{display:flex;align-items:center;gap:.4rem}.gd-page-metadata .gd-author-link{display:inline-flex;text-decoration:none}.gd-page-metadata .gd-author-avatar{width:26px;height:26px;border-radius:50%;object-fit:cover;flex-shrink:0;border:2px solid #dee2e6;transition:border-color .15s ease}.gd-page-metadata .gd-author-avatar:hover{border-color:#2c3e50}.gd-page-metadata .gd-author-initials{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:50%;background:#2c3e50;color:#fff;font-weight:600;font-size:.7rem;flex-shrink:0;border:2px solid rgba(0,0,0,0);transition:border-color .15s ease}.gd-page-metadata .gd-author-initials:hover{border-color:rgb(35.2,49.6,64)}html[data-bs-theme=dark] .gd-page-metadata{border-top-color:#7b8a8b;color:#ced4da}html[data-bs-theme=dark] .gd-page-metadata .gd-icon{opacity:.6}html[data-bs-theme=dark] .gd-page-metadata .gd-metadata-separator{color:#6c757d}html[data-bs-theme=dark] .gd-page-metadata .gd-author-avatar{border-color:#6c757d}html[data-bs-theme=dark] .gd-page-metadata .gd-author-avatar:hover{border-color:rgb(107.3,119.9,132.5)}html[data-bs-theme=dark] .gd-page-metadata .gd-author-initials{background:rgb(86.2,100.6,115)}html[data-bs-theme=dark] .gd-page-metadata .gd-author-initials:hover{border-color:rgb(128.4,139.2,150)}.tippy-box{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:.8125rem;line-height:1.4;border-radius:6px;font-weight:500;overflow:hidden}.tippy-box[data-theme~=gd-material]{background-color:#343a40;color:#fff;box-shadow:0 4px 14px -2px rgba(0,0,0,.2),0 2px 4px -1px rgba(0,0,0,.1)}.tippy-box[data-theme~=gd-material]::before{content:"";position:absolute;inset:0;background:linear-gradient(135deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 50%);pointer-events:none;opacity:0;transition:opacity 150ms ease-in-out}.tippy-box[data-theme~=gd-material][data-state=visible]::before{opacity:1}.tippy-box[data-theme~=gd-material]>.tippy-arrow{color:#343a40}.tippy-box[data-theme~=gd-material]>.tippy-arrow::before{filter:drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15))}.tippy-box[data-theme~=gd-material]>.tippy-content{padding:6px 10px;position:relative;z-index:1}.tippy-box[data-theme~=gd-material-dark]{background-color:#ecf0f1;color:#212529;box-shadow:0 4px 14px -2px rgba(0,0,0,.35),0 2px 4px -1px rgba(0,0,0,.2)}.tippy-box[data-theme~=gd-material-dark]::before{content:"";position:absolute;inset:0;background:linear-gradient(135deg, rgba(0, 0, 0, 0.06) 0%, rgba(0, 0, 0, 0) 50%);pointer-events:none;opacity:0;transition:opacity 150ms ease-in-out}.tippy-box[data-theme~=gd-material-dark][data-state=visible]::before{opacity:1}.tippy-box[data-theme~=gd-material-dark]>.tippy-arrow{color:#ecf0f1}.tippy-box[data-theme~=gd-material-dark]>.tippy-arrow::before{filter:drop-shadow(0 1px 3px rgba(0, 0, 0, 0.25))}.tippy-box[data-theme~=gd-material-dark]>.tippy-content{padding:6px 10px;position:relative;z-index:1}html.quarto-dark .tippy-box[data-theme~=quarto],body.quarto-dark .tippy-box[data-theme~=quarto]{background-color:var(--gd-bg-secondary);color:var(--gd-text-primary);border:1px solid var(--gd-border-color)}html.quarto-dark .tippy-box[data-theme~=quarto] .csl-entry,body.quarto-dark .tippy-box[data-theme~=quarto] .csl-entry{color:var(--gd-text-primary)}html.quarto-dark .tippy-box[data-theme~=quarto] a,body.quarto-dark .tippy-box[data-theme~=quarto] a{color:var(--gd-citation-color)}html.quarto-dark .tippy-box[data-theme~=quarto]>.tippy-arrow,body.quarto-dark .tippy-box[data-theme~=quarto]>.tippy-arrow{color:var(--gd-bg-secondary)}html.quarto-dark .tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-arrow::before,body.quarto-dark .tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-arrow::before{border-top-color:var(--gd-bg-secondary)}html.quarto-dark .tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-arrow::before,body.quarto-dark .tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-arrow::before{border-bottom-color:var(--gd-bg-secondary)}html.quarto-dark .tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-arrow::before,body.quarto-dark .tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-arrow::before{border-left-color:var(--gd-bg-secondary)}html.quarto-dark .tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-arrow::before,body.quarto-dark .tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-arrow::before{border-right-color:var(--gd-bg-secondary)}.tippy-box[data-animation=shift-away][data-state=hidden]{opacity:0}.tippy-box[data-animation=shift-away][data-state=hidden][data-placement^=top]{transform:translateY(6px)}.tippy-box[data-animation=shift-away][data-state=hidden][data-placement^=bottom]{transform:translateY(-6px)}.tippy-box[data-animation=shift-away][data-state=hidden][data-placement^=left]{transform:translateX(6px)}.tippy-box[data-animation=shift-away][data-state=hidden][data-placement^=right]{transform:translateX(-6px)}.gd-tooltip-mounted .tippy-box::before{animation:gd-tooltip-fill 200ms ease-out forwards}@keyframes gd-tooltip-fill{from{opacity:0;transform:scale(0.95)}to{opacity:1;transform:scale(1)}}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:-5px}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:-5px}.tippy-box[data-placement^=left]>.tippy-arrow{right:-5px}.tippy-box[data-placement^=right]>.tippy-arrow{left:-5px}.tippy-popper,[data-tippy-root]{z-index:9999 !important}.tippy-box[data-theme~=gd-material] a,.tippy-box[data-theme~=gd-material-dark] a{color:inherit;text-decoration:underline;text-underline-offset:2px}.tippy-box[data-theme~=gd-material] a:hover,.tippy-box[data-theme~=gd-material-dark] a:hover{opacity:.85}[data-tippy-content]{title:none}.cell:has(.mermaid-js),.cell:has(.mermaid){display:block}.cell-output-display:has(.mermaid-js),.cell-output-display:has(.mermaid){display:flex;justify-content:center;width:100%}.cell-output-display figure.figure:has(.mermaid-js),.cell-output-display figure.figure:has(.mermaid){display:flex;justify-content:center;margin:1.5rem auto;width:100%}.cell-output-display figure.figure>div:has(>.mermaid-js),.cell-output-display figure.figure>div:has(>svg.mermaid-js){display:flex;justify-content:center;width:100%}svg.mermaid-js{display:block;margin:0 auto}pre.mermaid{background:rgba(0,0,0,0);padding:.5rem;border-radius:6px;text-align:center}.cell-output-display:has(.mermaid-js),.cell-output-display:has(.mermaid){border:1px solid #dee2e6;border-radius:8px;padding:1rem;margin:.5rem 0}body.quarto-dark .cell-output-display:has(.mermaid-js),html.quarto-dark .cell-output-display:has(.mermaid-js){background:#f8f9fa;border-color:#dee2e6;border-radius:8px;padding:1rem;margin:.5rem 0}body.quarto-dark svg.mermaid-js p,html.quarto-dark svg.mermaid-js p,body.quarto-dark svg[id^=mermaid-] p,html.quarto-dark svg[id^=mermaid-] p{color:#333 !important}body.quarto-dark svg.mermaid-js span,html.quarto-dark svg.mermaid-js span,body.quarto-dark svg[id^=mermaid-] span,html.quarto-dark svg[id^=mermaid-] span{color:#333 !important}body.quarto-dark svg.mermaid-js div,html.quarto-dark svg.mermaid-js div,body.quarto-dark svg[id^=mermaid-] div,html.quarto-dark svg[id^=mermaid-] div{color:#333 !important}body.quarto-dark svg.mermaid-js .nodeLabel,html.quarto-dark svg.mermaid-js .nodeLabel,body.quarto-dark svg[id^=mermaid-] .nodeLabel,html.quarto-dark svg[id^=mermaid-] .nodeLabel{color:#333 !important}body.quarto-dark svg.mermaid-js .edgeLabel,html.quarto-dark svg.mermaid-js .edgeLabel,body.quarto-dark svg[id^=mermaid-] .edgeLabel,html.quarto-dark svg[id^=mermaid-] .edgeLabel{color:#333 !important}body.quarto-dark svg.mermaid-js foreignObject *,html.quarto-dark svg.mermaid-js foreignObject *,body.quarto-dark svg[id^=mermaid-] foreignObject *,html.quarto-dark svg[id^=mermaid-] foreignObject *{color:#333 !important}.mermaid-diagram{text-align:center;margin:1rem 0}.mermaid-diagram img{max-width:100%;height:auto}.light-mode-only{display:block !important}.dark-mode-only{display:none !important}body.quarto-dark .light-mode-only,html.quarto-dark .light-mode-only{display:none !important}body.quarto-dark .dark-mode-only,html.quarto-dark .dark-mode-only{display:block !important}.gd-table-responsive{position:relative;width:100%;margin-bottom:1rem}.gd-table-scroll{width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.gd-table-scroll:focus{outline:2px solid #2c3e50;outline-offset:2px}.gd-table-scroll:focus:not(:focus-visible){outline:none}.gd-table-scroll>table{margin-bottom:0;width:max-content;min-width:100%}.gd-table-scroll-indicator{position:absolute;top:0;bottom:0;width:40px;display:flex;align-items:center;justify-content:center;pointer-events:none;opacity:0;transition:opacity .2s ease;z-index:2}.gd-table-scroll-indicator.visible{opacity:1;pointer-events:auto;cursor:pointer}.gd-table-scroll-left{left:0;background:linear-gradient(to right, rgba(255, 255, 255, 0.95) 0%, transparent 100%);padding-left:4px}.gd-table-scroll-right{right:0;background:linear-gradient(to left, rgba(255, 255, 255, 0.95) 0%, transparent 100%);padding-right:4px}.gd-scroll-arrow{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;background:rgba(0,0,0,.06);color:#6c757d;font-size:1.25rem;font-weight:300;line-height:1;transition:background .15s ease,color .15s ease}.gd-table-scroll-indicator:hover .gd-scroll-arrow{background:rgba(0,0,0,.12);color:#343a40}@media(max-width: 767.98px){.gd-table-scroll>table{font-size:.85em}}@media(max-width: 575.98px){.gd-table-scroll>table{font-size:.8em}}body.quarto-dark .gd-table-scroll-left,html[data-bs-theme=dark] .gd-table-scroll-left{background:linear-gradient(to right, rgba(26, 26, 26, 0.95) 0%, transparent 100%)}body.quarto-dark .gd-table-scroll-right,html[data-bs-theme=dark] .gd-table-scroll-right{background:linear-gradient(to left, rgba(26, 26, 26, 0.95) 0%, transparent 100%)}body.quarto-dark .gd-scroll-arrow,html[data-bs-theme=dark] .gd-scroll-arrow{background:hsla(0,0%,100%,.08);color:#ced4da}.gd-table-scroll-indicator:hover body.quarto-dark .gd-scroll-arrow,.gd-table-scroll-indicator:hover html[data-bs-theme=dark] .gd-scroll-arrow{background:hsla(0,0%,100%,.15);color:#ecf0f1}@media print{.gd-table-scroll{overflow:visible}.gd-table-scroll-indicator{display:none}}td>p:has(>svg.gd-icon){margin:0;line-height:inherit}.gd-keys{display:inline-block;font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;font-size:.8em;font-weight:500;line-height:1;padding:.15em .45em;min-width:1.6em;text-align:center;white-space:nowrap;vertical-align:baseline;color:#1f2328;background:linear-gradient(180deg, #f6f8fa 0%, #eaeef2 100%);border:1px solid #d0d7de;border-bottom-width:2px;border-radius:5px;box-shadow:0 1px 0 rgba(27,31,36,.04),inset 0 1px 0 hsla(0,0%,100%,.25)}.gd-keys-sep{display:inline-block;margin:0 .15em;font-size:.85em;color:#656d76;vertical-align:baseline;user-select:none}.gd-keys-fn{font-size:.7em;font-weight:600;letter-spacing:.04em;padding:.25em .45em;text-transform:uppercase;position:relative;top:-1.1px}body.quarto-dark .gd-keys,html.quarto-dark .gd-keys,:root[data-bs-theme=dark] .gd-keys{color:#e6edf3;background:linear-gradient(180deg, #2d333b 0%, #22272e 100%);border-color:#444c56;box-shadow:0 1px 0 rgba(0,0,0,.3),inset 0 1px 0 hsla(0,0%,100%,.04)}body.quarto-dark .gd-keys-sep,html.quarto-dark .gd-keys-sep,:root[data-bs-theme=dark] .gd-keys-sep{color:#8b949e}.quarto-video{border:1px solid rgba(0,0,0,.15);border-radius:6px;overflow:hidden}body.quarto-dark .quarto-video,html[data-bs-theme=dark] .quarto-video{border-color:hsla(0,0%,100%,.15)}.gd-keyboard-overlay{position:fixed;inset:0;z-index:1090;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.45);opacity:0;visibility:hidden;transition:opacity .2s ease,visibility .2s ease}.gd-keyboard-overlay-visible{opacity:1;visibility:visible}.gd-keyboard-overlay-inner{width:90%;max-width:520px;max-height:80vh;overflow-y:auto;background:#fff;border-radius:.75rem;box-shadow:0 8px 32px rgba(0,0,0,.18);padding:1.5rem 2rem 2rem;transform:translateY(12px);transition:transform .2s ease}.gd-keyboard-overlay-visible .gd-keyboard-overlay-inner{transform:translateY(0)}.gd-keyboard-overlay-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.25rem}.gd-keyboard-overlay-header h2,.gd-keyboard-overlay-header .h2{margin:0;font-size:1.15rem;font-weight:600;color:#212529}.gd-keyboard-overlay-close{display:flex;align-items:center;justify-content:center;width:30px;height:30px;padding:0;border:none;border-radius:50%;background:rgba(0,0,0,0);color:#6c757d;cursor:pointer;transition:background-color .15s ease,color .15s ease}.gd-keyboard-overlay-close:hover{background:rgba(0,0,0,.06);color:#212529}.gd-keyboard-overlay-close:focus-visible{outline:2px solid #2c3e50;outline-offset:2px}.gd-keyboard-overlay-body{display:flex;flex-direction:column;gap:1.25rem}.gd-keyboard-group h3,.gd-keyboard-group .h3{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:#868e96;margin:0 0 .5rem}.gd-keyboard-group dl{margin:0}.gd-keyboard-row{display:flex;align-items:center;justify-content:space-between;padding:.35rem 0;border-bottom:1px solid rgba(0,0,0,.05)}.gd-keyboard-row:last-child{border-bottom:none}.gd-keyboard-row dt{display:flex;align-items:center;gap:.35rem;font-weight:normal;margin:0}.gd-keyboard-row dd{margin:0;color:#495057;font-size:.9rem}.gd-keyboard-or{font-size:.75rem;color:#adb5bd}kbd{display:inline-flex;align-items:center;justify-content:center;min-width:1.6em;padding:.15em .45em;font-family:inherit;font-size:.8rem;font-weight:500;line-height:1;color:#495057;background:#f8f9fa;border:1px solid #dee2e6;border-radius:.3rem;box-shadow:0 1px 0 rgba(0,0,0,.08)}[data-bs-theme=dark] .gd-keyboard-overlay{background:rgba(0,0,0,.6)}[data-bs-theme=dark] .gd-keyboard-overlay-inner{background:#2b3035;box-shadow:0 8px 32px rgba(0,0,0,.4)}[data-bs-theme=dark] .gd-keyboard-overlay-header h2,[data-bs-theme=dark] .gd-keyboard-overlay-header .h2{color:#f8f9fa}[data-bs-theme=dark] .gd-keyboard-overlay-close{color:#adb5bd}[data-bs-theme=dark] .gd-keyboard-overlay-close:hover{background:hsla(0,0%,100%,.08);color:#f8f9fa}[data-bs-theme=dark] .gd-keyboard-group h3,[data-bs-theme=dark] .gd-keyboard-group .h3{color:#868e96}[data-bs-theme=dark] .gd-keyboard-row{border-bottom-color:hsla(0,0%,100%,.06)}[data-bs-theme=dark] .gd-keyboard-row dd{color:#ced4da}[data-bs-theme=dark] kbd{color:#ced4da;background:#343a40;border-color:#495057;box-shadow:0 1px 0 rgba(0,0,0,.2)}@media(prefers-reduced-motion: reduce){.gd-keyboard-overlay,.gd-keyboard-overlay-inner{transition:none}}.gd-menu-overlay{position:fixed;inset:0;z-index:1090;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.45);opacity:0;visibility:hidden;transition:opacity .2s ease,visibility .2s ease}.gd-menu-overlay-visible{opacity:1;visibility:visible}.gd-menu-overlay-inner{width:90%;max-width:420px;max-height:80vh;overflow-y:auto;background:#fff;border-radius:.75rem;box-shadow:0 8px 32px rgba(0,0,0,.18);padding:1.25rem 1.5rem 1.5rem;transform:translateY(12px);transition:transform .2s ease}.gd-menu-overlay-visible .gd-menu-overlay-inner{transform:translateY(0)}.gd-menu-overlay-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:1rem}.gd-menu-overlay-header h2,.gd-menu-overlay-header .h2{margin:0;font-size:1.05rem;font-weight:600;color:#212529}.gd-menu-overlay-close{display:flex;align-items:center;justify-content:center;width:30px;height:30px;padding:0;border:none;border-radius:50%;background:rgba(0,0,0,0);color:#6c757d;cursor:pointer;transition:background-color .15s ease,color .15s ease}.gd-menu-overlay-close:hover{background:rgba(0,0,0,.06);color:#212529}.gd-menu-overlay-close:focus-visible{outline:2px solid #2c3e50;outline-offset:2px}.gd-menu-list{list-style:none;margin:0;padding:0}.gd-menu-section{font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:#868e96;padding:.65rem .75rem .25rem;cursor:default}.gd-menu-section:first-child{padding-top:0}.gd-menu-item{display:flex;align-items:center;padding:.45rem .75rem;border-radius:.4rem;color:#495057;font-size:.9rem;text-decoration:none;transition:background-color .12s ease,color .12s ease}.gd-menu-item:hover{background:rgba(0,0,0,.04);color:#212529;text-decoration:none}.gd-menu-item:focus-visible{outline:2px solid #2c3e50;outline-offset:-2px;background:rgba(0,0,0,.03)}.gd-menu-item-label{flex:1 1 auto;min-width:0}.gd-menu-item-label .gd-nav-icon{flex-shrink:0;width:15px;height:15px;margin-right:.4em;vertical-align:-0.15em;opacity:.7}.gd-menu-item-label .gd-sidebar-status-badge{margin-left:4px;vertical-align:middle}.gd-menu-item:hover .gd-nav-icon,.gd-menu-item-active .gd-nav-icon{opacity:1}.gd-menu-item>.gd-sidebar-upcoming{flex-shrink:0;margin-left:auto;padding-left:6px}.gd-menu-section .gd-nav-icon{width:14px;height:14px;margin-right:.35em;vertical-align:-0.1em;opacity:.6}.gd-menu-item-active{font-weight:600;color:#2c3e50;background:rgba(44,62,80,.06)}.gd-menu-item-focused{background:rgba(0,0,0,.06);color:#212529;outline:2px solid #2c3e50;outline-offset:-2px}[data-bs-theme=dark] .gd-menu-overlay{background:rgba(0,0,0,.6)}[data-bs-theme=dark] .gd-menu-overlay-inner{background:#2b3035;box-shadow:0 8px 32px rgba(0,0,0,.4)}[data-bs-theme=dark] .gd-menu-overlay-header h2,[data-bs-theme=dark] .gd-menu-overlay-header .h2{color:#f8f9fa}[data-bs-theme=dark] .gd-menu-overlay-close{color:#adb5bd}[data-bs-theme=dark] .gd-menu-overlay-close:hover{background:hsla(0,0%,100%,.08);color:#f8f9fa}[data-bs-theme=dark] .gd-menu-section{color:#868e96}[data-bs-theme=dark] .gd-menu-item{color:#ced4da}[data-bs-theme=dark] .gd-menu-item:hover{background:hsla(0,0%,100%,.06);color:#f8f9fa}[data-bs-theme=dark] .gd-menu-item-active{color:hsl(210,29.0322580645%,39.3137254902%);background:rgba(44,62,80,.12)}[data-bs-theme=dark] .gd-menu-item-focused{background:hsla(0,0%,100%,.08);color:#f8f9fa;outline:2px solid hsl(210,29.0322580645%,39.3137254902%);outline-offset:-2px}@media(prefers-reduced-motion: reduce){.gd-menu-overlay,.gd-menu-overlay-inner{transition:none}}body.gd-menu-open{overflow:hidden}@media(max-width: 991.98px){#quarto-sidebar{display:none !important}#quarto-sidebar-glass{display:none !important}.gd-menu-overlay{-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}body.gd-menu-open #quarto-header{z-index:1091}body.gd-menu-open #quarto-header>.navbar{position:relative;z-index:-1}.gd-menu-overlay-inner{width:calc(100% - 2rem);max-width:420px;max-height:calc(100vh - 5rem - 35px);margin-top:15px;margin-bottom:20px;display:flex;flex-direction:column}.gd-menu-overlay-body{flex:1 1 auto;overflow-y:auto;-webkit-overflow-scrolling:touch;margin:0 -1.5rem -1.5rem;padding:0 1.5rem 1.5rem}.gd-menu-overlay-header{flex-shrink:0}}.gd-menu-overlay .gd-menu-ref-switcher{display:flex;gap:.25rem;background:#f0f0f0;border-radius:6px;padding:.2rem;margin-bottom:.75rem}.gd-menu-overlay .gd-menu-ref-switcher-btn{flex:1;display:flex;align-items:center;justify-content:center;gap:.35rem;padding:.45rem .5rem;border:none;border-radius:4px;background:rgba(0,0,0,0);color:#666;font-size:.85rem;font-weight:500;cursor:pointer;transition:all .15s ease}.gd-menu-overlay .gd-menu-ref-switcher-btn:hover{background:hsla(0,0%,100%,.5);color:#333}.gd-menu-overlay .gd-menu-ref-switcher-btn.active{background:#fff;color:#333;box-shadow:0 1px 3px rgba(0,0,0,.1)}.gd-menu-overlay .gd-menu-ref-filter{position:relative;margin-bottom:.5rem}.gd-menu-overlay .gd-menu-ref-filter-input{width:100%;padding:.4rem .75rem .4rem 2rem;font-size:16px;border:1px solid #e9e9e9;border-radius:6px;background-color:#fff;transition:border-color .15s ease,box-shadow .15s ease}.gd-menu-overlay .gd-menu-ref-filter-input:focus{outline:none;border-color:#86b7fe;box-shadow:0 0 0 .15rem rgba(13,110,253,.12)}.gd-menu-overlay .gd-menu-ref-filter-input::placeholder{color:#999}.gd-menu-overlay .gd-menu-ref-filter-icon{position:absolute;left:.6rem;top:50%;transform:translateY(-50%);color:#999;pointer-events:none;font-size:.8rem}[data-bs-theme=dark] .gd-menu-overlay .gd-menu-ref-switcher{background:#2a2a2a}[data-bs-theme=dark] .gd-menu-overlay .gd-menu-ref-switcher-btn{color:#999}[data-bs-theme=dark] .gd-menu-overlay .gd-menu-ref-switcher-btn:hover{background:hsla(0,0%,100%,.1);color:#ccc}[data-bs-theme=dark] .gd-menu-overlay .gd-menu-ref-switcher-btn.active{background:#3a3a3a;color:#fff;box-shadow:0 1px 3px rgba(0,0,0,.3)}[data-bs-theme=dark] .gd-menu-overlay .gd-menu-ref-filter-input{background-color:#2a2a2a;border-color:#3d3d3d;color:#e0e0e0}[data-bs-theme=dark] .gd-menu-overlay .gd-menu-ref-filter-input:focus{border-color:#6ea8fe;box-shadow:0 0 0 .15rem rgba(13,110,253,.25)}[data-bs-theme=dark] .gd-menu-overlay .gd-menu-ref-filter-icon{color:#9e9e9e}.gd-ref-sidebar .gd-menu-overlay .gd-menu-item{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:.8rem}.gd-back-to-top{position:fixed;bottom:2rem;right:2rem;z-index:1040;display:flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:1px solid rgba(0,0,0,.12);border-radius:50%;background:hsla(0,0%,100%,.92);color:#495057;cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,.12);opacity:0;visibility:hidden;transition:opacity .25s ease,visibility .25s ease,bottom .25s ease,background-color .15s ease,color .15s ease,box-shadow .15s ease}.gd-back-to-top:hover{background:#fff;color:#212529;box-shadow:0 4px 12px rgba(0,0,0,.18)}.gd-back-to-top:focus-visible{outline:2px solid #2c3e50;outline-offset:2px}.gd-back-to-top svg{display:block}.gd-back-to-top-visible{opacity:1;visibility:visible}[data-bs-theme=dark] .gd-back-to-top{background:rgba(52,58,64,.92);color:#dee2e6;border-color:hsla(0,0%,100%,.12);box-shadow:0 2px 8px rgba(0,0,0,.3)}[data-bs-theme=dark] .gd-back-to-top:hover{background:#495057;color:#f8f9fa;box-shadow:0 4px 12px rgba(0,0,0,.4)}@media(prefers-reduced-motion: reduce){.gd-back-to-top{transition:none}}@media(max-width: 767.98px){.gd-back-to-top{bottom:1.25rem;right:1.25rem;width:36px;height:36px}}.gd-otp-btn{position:fixed;bottom:4.5rem;right:1.25rem;z-index:1040;display:none;align-items:center;justify-content:center;width:36px;height:36px;padding:0;border:1px solid rgba(0,0,0,.12);border-radius:50%;background:hsla(0,0%,100%,.92);color:#495057;cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,.12);transition:opacity .25s ease,bottom .25s ease,background-color .15s ease,color .15s ease,box-shadow .15s ease}.gd-otp-btn:hover,.gd-otp-btn.gd-otp-btn-active{background:#fff;color:#212529;box-shadow:0 4px 12px rgba(0,0,0,.18)}.gd-otp-btn:focus-visible{outline:2px solid #2c3e50;outline-offset:2px}.gd-otp-btn svg{display:block}.gd-otp-backdrop{position:fixed;inset:0;z-index:1041;background:rgba(0,0,0,.25);opacity:0;visibility:hidden;transition:opacity .2s ease,visibility .2s ease}.gd-otp-backdrop-visible{opacity:1;visibility:visible}.gd-otp-panel{position:fixed;bottom:6rem;right:1.25rem;z-index:1042;width:min(280px,100vw - 2.5rem);max-height:min(360px,60vh);overflow-y:scroll;overscroll-behavior:contain;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:12px;box-shadow:0 8px 24px rgba(0,0,0,.16);opacity:0;visibility:hidden;transform:translateY(12px) scale(0.95);transform-origin:bottom right;transition:opacity .2s ease,visibility .2s ease,transform .2s ease;-webkit-overflow-scrolling:touch}.gd-otp-panel-visible{opacity:1;visibility:visible;transform:translateY(0) scale(1)}.gd-otp-panel-heading{padding:.75rem 1rem .375rem;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:#6c757d;border-bottom:1px solid rgba(0,0,0,.06)}.gd-otp-panel-list{list-style:none;margin:0;padding:.375rem 0}.gd-otp-panel-list li{margin:0;padding:0}.gd-otp-panel-list li.gd-otp-nested{padding-left:.75rem}.gd-otp-panel-link{display:block;padding:.5rem 1rem;font-size:.85rem;line-height:1.35;color:#343a40;text-decoration:none;border-radius:0;transition:background-color .1s ease}.gd-otp-panel-link:hover{background:rgba(0,0,0,.04);color:#212529;text-decoration:none}.gd-otp-panel-link:active{background:rgba(0,0,0,.08)}[data-bs-theme=dark] .gd-otp-btn{background:rgba(52,58,64,.92);color:#dee2e6;border-color:hsla(0,0%,100%,.12);box-shadow:0 2px 8px rgba(0,0,0,.3)}[data-bs-theme=dark] .gd-otp-btn:hover,[data-bs-theme=dark] .gd-otp-btn.gd-otp-btn-active{background:#495057;color:#f8f9fa;box-shadow:0 4px 12px rgba(0,0,0,.4)}[data-bs-theme=dark] .gd-otp-backdrop{background:rgba(0,0,0,.45)}[data-bs-theme=dark] .gd-otp-panel{background:#2b3035;border-color:hsla(0,0%,100%,.1);box-shadow:0 8px 24px rgba(0,0,0,.35)}[data-bs-theme=dark] .gd-otp-panel-heading{color:#adb5bd;border-bottom-color:hsla(0,0%,100%,.08)}[data-bs-theme=dark] .gd-otp-panel-link{color:#dee2e6}[data-bs-theme=dark] .gd-otp-panel-link:hover{background:hsla(0,0%,100%,.06);color:#f8f9fa}[data-bs-theme=dark] .gd-otp-panel-link:active{background:hsla(0,0%,100%,.1)}@media(prefers-reduced-motion: reduce){.gd-otp-btn,.gd-otp-panel,.gd-otp-backdrop{transition:none}}.gd-license-features{border:1px solid rgb(191.7,197.1,202.5);border-radius:.5rem;margin-bottom:1.5rem;overflow:hidden;width:100%}.gd-license-features-toggle{display:flex;align-items:center;gap:.5rem;width:100%;padding:.75rem 1.25rem;border:none;background:rgb(240.23,241.49,242.75);color:#2c3e50;font-weight:600;font-size:1rem;cursor:pointer;text-align:left;transition:background .15s ease}.gd-license-features-toggle:hover{background:rgb(227.57,229.91,232.25)}.gd-license-features-toggle[aria-expanded=true]{border-bottom:1px solid rgb(191.7,197.1,202.5)}.gd-license-features-icon{display:inline-block;font-size:.65rem;transition:transform .25s ease;line-height:1}.gd-license-features-toggle[aria-expanded=true] .gd-license-features-icon{transform:rotate(90deg)}.gd-license-features-body{display:grid;grid-template-rows:0fr;transition:grid-template-rows .35s ease;background:rgb(248.67,249.21,249.75)}.gd-license-features-body>*{overflow:hidden;min-height:0}.gd-license-features-body.gd-license-features-open{grid-template-rows:1fr}.gd-license-features-body .gd-license-features-pad{padding:.6rem 1.25rem .6rem;display:flex;flex-direction:column;gap:.25rem}.license-feature-group h4,.license-feature-group .h4{font-size:.8rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;margin-bottom:.3rem;color:var(--bs-secondary-color, #6c757d)}.license-feature-group:first-child h4,.license-feature-group:first-child .h4{margin-top:0}.license-badges{display:flex;flex-wrap:wrap;gap:.375rem}.license-badge{display:inline-block;padding:.25rem .6rem;font-size:.8rem;font-weight:500;border-radius:1rem;line-height:1.4;white-space:nowrap}.license-badge-permission{background:rgba(25,135,84,.12);color:#146c43;border:1px solid rgba(25,135,84,.25)}.license-badge-condition{background:rgba(13,110,253,.12);color:#0a58ca;border:1px solid rgba(13,110,253,.25)}.license-badge-limitation{background:rgba(220,53,69,.12);color:#b02a37;border:1px solid rgba(220,53,69,.25)}.gd-spdx-badge{display:inline-block;padding:.05rem .35rem;padding-bottom:0;font-size:.72rem;font-weight:600;font-family:var(--bs-font-monospace);border-radius:.2rem;background:var(--bs-tertiary-bg, #f8f9fa);border:1px solid var(--bs-border-color, #dee2e6);color:var(--bs-body-color);text-decoration:none;cursor:default;vertical-align:middle;line-height:1.3;transition:background .15s,border-color .15s}.gd-spdx-badge:hover{background:var(--bs-secondary-bg, #e9ecef);border-color:var(--bs-secondary-color, #6c757d);text-decoration:none;color:var(--bs-body-color)}html[data-bs-theme=dark] .gd-license-features{border-color:#161f28}html[data-bs-theme=dark] .gd-license-features-toggle{background:rgb(8.8,12.4,16);color:rgb(149.5,158.5,167.5)}html[data-bs-theme=dark] .gd-license-features-toggle:hover{background:rgb(12.32,17.36,22.4)}html[data-bs-theme=dark] .gd-license-features-toggle[aria-expanded=true]{border-bottom-color:#161f28}html[data-bs-theme=dark] .gd-license-features-body{background:rgb(5.28,7.44,9.6)}html[data-bs-theme=dark] .license-badge-permission{background:rgba(25,135,84,.2);color:#75b798;border-color:rgba(25,135,84,.35)}html[data-bs-theme=dark] .license-badge-condition{background:rgba(13,110,253,.2);color:#6ea8fe;border-color:rgba(13,110,253,.35)}html[data-bs-theme=dark] .license-badge-limitation{background:rgba(220,53,69,.2);color:#ea868f;border-color:rgba(220,53,69,.35)}.gd-nav-icon{flex-shrink:0;margin-right:.4em;vertical-align:-0.15em;opacity:.7;transition:opacity .15s ease}.navbar .nav-link>.menu-text>.gd-nav-icon{width:16px;height:16px}.navbar .nav-link:hover>.menu-text>.gd-nav-icon{opacity:1}#quarto-sidebar .menu-text>.gd-nav-icon,#quarto-sidebar .sidebar-item-text>.gd-nav-icon{width:15px;height:15px}#quarto-sidebar .sidebar-item:hover .gd-nav-icon{opacity:1}#quarto-sidebar .sidebar-link.active>.menu-text>.gd-nav-icon,#quarto-sidebar a.sidebar-item-text.sidebar-link.active>.gd-nav-icon{opacity:1}#quarto-sidebar .sidebar-item-section>.sidebar-item-container .gd-nav-icon{width:16px;height:16px}.gd-page-tags{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:.35rem;margin-bottom:.8rem}.gd-tag-pill{display:inline-flex;align-items:center;gap:.2rem;padding:.15rem .55rem;font-size:.75rem;font-weight:500;line-height:1.4;color:rgb(39.6,52,64.4);background-color:rgb(233.9,235.7,237.5);border:1px solid rgb(202.25,206.75,211.25);border-radius:1rem;text-decoration:none;transition:background-color .15s ease,border-color .15s ease;white-space:nowrap}.gd-tag-pill:hover,.gd-tag-pill:focus-visible{background-color:rgb(212.8,216.4,220);border-color:rgb(170.6,177.8,185);color:rgb(39.6,55.8,72);text-decoration:none}.gd-tag-pill .gd-tag-icon{display:inline-flex;align-items:center;margin-right:.15rem;opacity:.7}.gd-tag-heading{margin-top:1.5rem;margin-bottom:.35rem}.gd-tag-heading .gd-tag-pill{cursor:default;pointer-events:none}.gd-tag-indent-1{margin-left:2rem}.gd-tag-indent-2{margin-left:4rem}.gd-tag-pages{margin-bottom:.75rem}.gd-tag-page-link{padding:.15rem 0;padding-left:1.25rem}.gd-tag-page-link a{color:#212529;text-decoration:underline}.gd-tag-page-link a:hover{color:#2c3e50}.gd-tag-pill-segmented{padding:0;overflow:hidden;gap:0}.gd-tag-pill-segmented .gd-tag-pill-segment{display:inline-flex;align-items:center;padding:.15rem .55rem}.gd-tag-pill-segmented .gd-tag-pill-parent{background-color:rgb(233.9,235.7,237.5)}.gd-tag-pill-segmented .gd-tag-pill-segment:not(.gd-tag-pill-parent){background-color:rgb(244.45,245.35,246.25)}.gd-tag-pill-segmented .gd-tag-pill-sep{display:inline-block;width:1px;align-self:stretch;background-color:rgb(170.6,177.8,185)}.gd-tag-section{display:inline-block;font-size:.7rem;font-weight:500;color:#6c757d;background-color:#f8f9fa;padding:.05rem .4rem;border-radius:.25rem;margin-left:.4rem;vertical-align:middle}body.quarto-dark .gd-tag-pill{color:rgb(191.7,197.1,202.5);background-color:rgba(44,62,80,.15);border-color:rgba(44,62,80,.3)}body.quarto-dark .gd-tag-pill:hover,body.quarto-dark .gd-tag-pill:focus-visible{background-color:rgba(44,62,80,.25);border-color:rgba(44,62,80,.5);color:rgb(223.35,226.05,228.75)}body.quarto-dark .gd-tag-section{color:#ced4da;background-color:#343a40}body.quarto-dark .gd-tag-pill-sep{background-color:rgba(44,62,80,.4)}body.quarto-dark .gd-tag-pill-segmented .gd-tag-pill-parent{background-color:rgba(44,62,80,.15)}body.quarto-dark .gd-tag-pill-segmented .gd-tag-pill-segment:not(.gd-tag-pill-parent){background-color:rgba(44,62,80,.08)}body.quarto-dark .gd-tag-page-link a{color:#dee2e6}.gd-page-status{display:inline-flex;align-items:center;gap:.35rem;padding:.25rem .65rem;margin-top:.3rem;margin-bottom:.6rem;font-size:14px;font-weight:500;line-height:1.4;border-radius:.35rem;color:var(--gd-status-color, #6c757d);background-color:color-mix(in srgb, var(--gd-status-color, #6c757d) 8%, transparent);border:1px solid color-mix(in srgb, var(--gd-status-color, #6c757d) 25%, transparent)}.gd-page-status .gd-status-badge-icon{display:inline-flex;align-items:center;opacity:.85}.gd-page-status .gd-status-badge-icon svg{width:14px;height:14px}.gd-page-status .gd-status-badge-label{font-weight:600}.gd-page-status .gd-status-badge-desc{font-weight:400;opacity:.8}.gd-sidebar-status-badge{display:inline-flex;align-items:center;justify-content:center;margin-left:4px;padding:.05rem .35rem;font-size:.65rem;font-weight:600;line-height:1.3;border-radius:.75rem;color:var(--gd-status-color, #6c757d);background-color:color-mix(in srgb, var(--gd-status-color, #6c757d) 10%, transparent);white-space:nowrap;flex-shrink:0}.gd-sidebar-status-badge svg{width:11px;height:11px}#quarto-sidebar.sidebar-navigation .sidebar-item .sidebar-link{display:flex;align-items:center}body.quarto-dark .gd-page-status{background-color:color-mix(in srgb, var(--gd-status-color, #6c757d) 12%, transparent);border-color:color-mix(in srgb, var(--gd-status-color, #6c757d) 30%, transparent)}body.quarto-dark .gd-sidebar-status-badge{background-color:color-mix(in srgb, var(--gd-status-color, #6c757d) 15%, transparent)}.gd-upcoming-title{background:linear-gradient(90deg, #e63946, #eab308, #2a9d8f, #e63946);background-size:300% auto;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:rgba(0,0,0,0);animation:gd-upcoming-gradient 5s ease-in-out infinite}@keyframes gd-upcoming-gradient{0%{background-position:0% center}50%{background-position:100% center}100%{background-position:0% center}}.gd-upcoming-icon{display:inline-flex;align-items:center;margin-left:.4em;color:#e63946;-webkit-text-fill-color:#e63946;cursor:help;vertical-align:middle}h1.quarto-secondary-nav-title .gd-upcoming-icon svg,.quarto-secondary-nav-title.h1 .gd-upcoming-icon svg{width:16px;height:16px}.gd-sidebar-upcoming{display:inline-flex;align-items:center;margin-left:auto;cursor:help}.gd-color-swatch{margin:1.5rem 0;border-radius:12px}.gd-color-swatch--bordered{border:1px solid var(--bs-border-color)}.gd-color-swatch--circles{padding:1.25rem}.gd-color-swatch--rectangles{overflow:hidden;padding:0}.gd-cs-title{width:100%;font-weight:600;font-size:1rem;margin-bottom:.5rem;color:var(--bs-body-color)}.gd-cs-description{width:100%;font-size:.9375rem;color:var(--bs-secondary-color);margin-bottom:1rem;line-height:1.6}.gd-cs-swatches{display:grid;grid-template-columns:repeat(auto-fill, minmax(var(--gd-cs-size, 56px), 1fr));gap:1.25rem}.gd-swatch{display:flex;flex-direction:column;align-items:center;gap:.375rem;cursor:pointer;transition:transform .15s ease}.gd-swatch:hover{transform:translateY(-2px)}.gd-swatch:active{transform:translateY(0)}.gd-swatch:focus-visible{outline:2px solid var(--bs-primary);outline-offset:4px;border-radius:4px}.gd-swatch-color{width:var(--gd-cs-size, 56px);height:var(--gd-cs-size, 56px);border-radius:50%;position:relative;box-shadow:0 2px 8px rgba(0,0,0,.1);transition:box-shadow .15s ease}.gd-swatch-color:hover{box-shadow:0 4px 16px rgba(0,0,0,.15)}.gd-swatch-color[data-needs-ring=true]{box-shadow:inset 0 0 0 1px var(--gd-ring-color),0 2px 8px rgba(0,0,0,.1)}.gd-swatch-name{font-size:.8125rem;font-weight:500;color:var(--bs-body-color);text-align:center;overflow-wrap:break-word;word-break:break-word;line-height:1.3}.gd-swatch-hex{font-family:var(--bs-font-monospace);font-size:.6875rem;color:var(--bs-secondary-color);text-align:center}.gd-swatch-contrast{font-family:var(--bs-font-monospace);font-size:.625rem;color:var(--bs-secondary-color);text-align:center}.gd-swatch-rect{display:flex;align-items:center;padding:.875rem 1.25rem;cursor:pointer;transition:filter .15s ease;min-height:56px;position:relative}.gd-swatch-rect:hover{filter:brightness(0.95)}.gd-swatch-rect:not(:last-child){border-bottom:1px solid rgba(0,0,0,.06)}.gd-swatch-rect:focus-visible{outline:2px solid var(--bs-primary);outline-offset:-2px}.gd-swatch-rect-name{font-weight:600;flex:1}.gd-swatch-rect-hex{font-family:var(--bs-font-monospace);font-size:.875rem;margin-right:1.5rem}.gd-swatch-contrast-samples{display:flex;gap:.5rem}.gd-swatch-aa-sample{font-weight:700;font-size:.875rem;padding:.125rem .375rem;border-radius:4px}.gd-cs-pass{color:#16a34a}.gd-cs-fail{color:#dc2626}.gd-swatch-copy-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.35);border-radius:inherit;opacity:0;transition:opacity .3s ease;pointer-events:none}.gd-swatch-copy-overlay svg{color:#fff;width:24px;height:24px;filter:drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3))}.gd-cs-tooltip{display:flex;gap:.625rem;padding:.25rem;font-size:.8125rem;min-width:200px}.gd-cs-tooltip-swatch{width:32px;aspect-ratio:1;border-radius:6px;flex-shrink:0;margin-top:2px}.gd-cs-tooltip-name{font-weight:600;margin-bottom:.25rem}.gd-cs-tooltip-table{width:100%;border-collapse:collapse;font-size:.75rem}.gd-cs-tooltip-table td{padding:1px 0}.gd-cs-tooltip-table td:first-child{color:hsla(0,0%,100%,.55);padding-right:.75rem;white-space:nowrap}.gd-cs-tooltip-table code{font-size:.75rem;background:none;padding:0}.gd-cs-tooltip-sep{border-top:1px solid var(--bs-border-color-translucent);padding-top:4px !important}.gd-cs-tooltip-copy{background:none;border:none;cursor:pointer;padding:0 .25rem;font-size:.75rem;opacity:.6;transition:opacity .15s ease}.gd-cs-tooltip-copy:hover{opacity:1}html[data-bs-theme=dark] .gd-swatch-color{box-shadow:0 2px 8px rgba(0,0,0,.3)}html[data-bs-theme=dark] .gd-swatch-color:hover{box-shadow:0 4px 16px rgba(0,0,0,.4)}html[data-bs-theme=dark] .gd-swatch-color[data-needs-ring=true]{box-shadow:inset 0 0 0 1px var(--gd-ring-color),0 2px 8px rgba(0,0,0,.3)}html[data-bs-theme=dark] .gd-swatch-rect:not(:last-child){border-bottom-color:hsla(0,0%,100%,.08)}html[data-bs-theme=dark] .gd-swatch-rect:hover{filter:brightness(1.1)}html[data-bs-theme=dark] .gd-swatch-copy-overlay{background:hsla(0,0%,100%,.25)}html[data-bs-theme=dark] .gd-cs-pass{color:#4ade80}html[data-bs-theme=dark] .gd-cs-fail{color:#f87171}@media(prefers-reduced-motion: reduce){.gd-swatch:hover{transform:none}.gd-swatch-copy-overlay{transition:none}}@media(max-width: 575.98px){.gd-cs-swatches{gap:.75rem;grid-template-columns:repeat(auto-fill, minmax(44px, 1fr))}.gd-swatch-color{width:44px !important;height:44px !important}.gd-swatch-rect{flex-wrap:wrap;gap:.5rem}.gd-swatch-rect-hex{margin-right:0}}.gd-output-title-container{border:1px solid rgba(0,0,0,.1);border-radius:.375rem;margin-top:.5rem;margin-bottom:1rem;overflow:hidden}.gd-output-title-header{background:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.1);padding:.35rem .75rem;font-size:.8rem;font-weight:600;color:rgba(0,0,0,.55);letter-spacing:.02em}.gd-output-title-body{padding:.5rem .75rem}.gd-output-title-body .cell-output{margin:0;padding:0}.gd-output-title-body .cell-output pre{margin:0;border:none;background:rgba(0,0,0,0);padding:0}.gd-output-title-container:has(.gd-output-title-body .cell-output-display>div){border:none}.gd-output-title-container:has(.gd-output-title-body .cell-output-display>div) .gd-output-title-header{background:rgba(0,0,0,0);border-bottom:none;padding-left:0}.gd-output-title-container:has(.gd-output-title-body .cell-output-display>div) .gd-output-title-body{padding:0}body.quarto-dark .gd-output-title-container{border-color:hsla(0,0%,100%,.12)}body.quarto-dark .gd-output-title-header{background:hsla(0,0%,100%,.04);border-bottom-color:hsla(0,0%,100%,.12);color:hsla(0,0%,100%,.55)}.gd-details{border:1px solid rgb(191.7,197.1,202.5);border-radius:.5rem;margin-bottom:1rem;overflow:hidden;transition:height .3s ease}.gd-details>summary{list-style:none}.gd-details>summary::-webkit-details-marker{display:none}.gd-details>summary::marker{display:none}.gd-details-summary{display:flex;align-items:center;gap:.5rem;width:100%;padding:.75rem .75rem;background:rgb(240.23,241.49,242.75);color:#2c3e50;font-weight:600;font-size:1rem;cursor:pointer;user-select:none;transition:background .15s ease}.gd-details-summary:hover{background:rgb(227.57,229.91,232.25)}.gd-details[open] .gd-details-summary{border-bottom:1px solid rgb(191.7,197.1,202.5)}.gd-details-chevron{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:1rem;height:1rem;transition:transform .25s ease}.gd-details-chevron::before{content:"";display:block;width:.45rem;height:.45rem;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(-45deg);transition:transform .25s ease}.gd-details[open] .gd-details-chevron::before,.gd-details--open .gd-details-chevron::before{transform:rotate(45deg)}.gd-details-icon-wrap{display:inline-flex;align-items:center;flex-shrink:0;line-height:1}.gd-details-icon{width:1em;height:1em}.gd-details-title{flex:1 1 auto}.gd-details-body{padding:.75rem 1rem .75rem;background:rgb(248.67,249.21,249.75)}.gd-details-body>:last-child{margin-bottom:0}.gd-details-body .sourceCode{margin:.35rem 0 .75rem}.gd-details-body pre.sourceCode{padding:.5rem 2.5rem .5rem .75rem;font-size:.88rem}.gd-details-body pre.sourceCode code{padding:0 !important}.gd-details--animating{overflow:hidden;transition:height .3s ease}.gd-details--note{border-color:#3b82f6}.gd-details--note .gd-details-summary{background:rgb(235.4,242.5,254.1);color:rgb(47.2,104,196.8)}.gd-details--note .gd-details-summary:hover{background:rgb(221.68,233.75,253.47)}.gd-details--note .gd-details[open]>.gd-details-summary,.gd-details--note[open]>.gd-details-summary{border-bottom-color:rgb(196.2,217.5,252.3)}.gd-details--note .gd-details-body{background:rgb(247.16,250,254.64)}.gd-details--warning{border-color:#f59e0b}.gd-details--warning .gd-details-summary{background:rgb(254,245.3,230.6);color:rgb(171.5,110.6,7.7)}.gd-details--warning .gd-details-summary:hover{background:rgb(253.3,238.51,213.52)}.gd-details--warning[open]>.gd-details-summary{border-bottom-color:rgb(252,225.9,181.8)}.gd-details--warning .gd-details-body{background:rgb(254.6,251.12,245.24)}.gd-details--tip{border-color:#10b981}.gd-details--tip .gd-details-summary{background:rgb(231.1,248,242.4);color:rgb(12.8,148,103.2)}.gd-details--tip .gd-details-summary:hover{background:rgb(214.37,243.1,233.58)}.gd-details--tip[open]>.gd-details-summary{border-bottom-color:rgb(183.3,234,217.2)}.gd-details--tip .gd-details-body{background:rgb(245.44,252.2,249.96)}.gd-details--danger{border-color:#ef4444}.gd-details--danger .gd-details-summary{background:rgb(253.4,236.3,236.3);color:rgb(191.2,54.4,54.4)}.gd-details--danger .gd-details-summary:hover{background:rgb(252.28,223.21,223.21)}.gd-details--danger[open]>.gd-details-summary{border-bottom-color:rgb(250.2,198.9,198.9)}.gd-details--danger .gd-details-body{background:rgb(254.36,247.52,247.52)}.gd-details--gradient{border-color:color-mix(in srgb, var(--gd-accent, #6366f1) 40%, transparent)}.gd-details--gradient .gd-details-summary{background:linear-gradient(-45deg, color-mix(in srgb, var(--gd-accent, #6366f1) 15%, white), color-mix(in srgb, var(--gd-accent-secondary, #a855f7) 12%, white), color-mix(in srgb, var(--gd-accent, #6366f1) 10%, white), color-mix(in srgb, var(--gd-accent-secondary, #a855f7) 15%, white));background-size:400% 400%;animation:gd-gradient-shift 15s ease infinite;color:color-mix(in srgb, var(--gd-accent, #6366f1) 85%, black)}.gd-details--gradient .gd-details-summary:hover{background:linear-gradient(-45deg, color-mix(in srgb, var(--gd-accent, #6366f1) 22%, white), color-mix(in srgb, var(--gd-accent-secondary, #a855f7) 18%, white), color-mix(in srgb, var(--gd-accent, #6366f1) 15%, white), color-mix(in srgb, var(--gd-accent-secondary, #a855f7) 22%, white));background-size:400% 400%;animation:gd-gradient-shift 15s ease infinite}.gd-details--gradient[open]>.gd-details-summary{border-bottom-color:color-mix(in srgb, var(--gd-accent, #6366f1) 30%, transparent)}.gd-details--gradient .gd-details-body{background:linear-gradient(-45deg, color-mix(in srgb, var(--gd-accent, #6366f1) 4%, white), color-mix(in srgb, var(--gd-accent-secondary, #a855f7) 3%, white), color-mix(in srgb, var(--gd-accent, #6366f1) 2%, white), color-mix(in srgb, var(--gd-accent-secondary, #a855f7) 4%, white));background-size:400% 400%;animation:gd-gradient-shift 15s ease infinite}.gd-details--gradient-sky .gd-details-summary,.gd-details--gradient-sky .gd-details-body,.gd-details--gradient-peach .gd-details-summary,.gd-details--gradient-peach .gd-details-body,.gd-details--gradient-prism .gd-details-summary,.gd-details--gradient-prism .gd-details-body,.gd-details--gradient-lilac .gd-details-summary,.gd-details--gradient-lilac .gd-details-body,.gd-details--gradient-slate .gd-details-summary,.gd-details--gradient-slate .gd-details-body,.gd-details--gradient-honey .gd-details-summary,.gd-details--gradient-honey .gd-details-body,.gd-details--gradient-dusk .gd-details-summary,.gd-details--gradient-dusk .gd-details-body,.gd-details--gradient-mint .gd-details-summary,.gd-details--gradient-mint .gd-details-body{background-size:400% 400%;animation:gd-gradient-shift 15s ease infinite}.gd-details--gradient-sky{border-color:#90cdf4}.gd-details--gradient-sky .gd-details-summary{background:linear-gradient(-45deg, #d0ecf9, #e0f4ff, #c5e8f7, #b8e0f5);color:#023e8a}.gd-details--gradient-sky .gd-details-summary:hover{filter:brightness(0.96)}.gd-details--gradient-sky[open]>.gd-details-summary{border-bottom-color:#90cdf4}.gd-details--gradient-sky .gd-details-body{background:linear-gradient(-45deg, #edf7fd, #f2faff, #eaf6fc, #e7f4fb)}.gd-details--gradient-peach{border-color:#f9b89a}.gd-details--gradient-peach .gd-details-summary{background:linear-gradient(-45deg, #ffddc1, #ffe4cc, #fdd0d8, #fbc4d4);color:#7c2d12}.gd-details--gradient-peach .gd-details-summary:hover{filter:brightness(0.96)}.gd-details--gradient-peach[open]>.gd-details-summary{border-bottom-color:#f9b89a}.gd-details--gradient-peach .gd-details-body{background:linear-gradient(-45deg, #fff4ec, #fff7f0, #fef0f2, #fdedf3)}.gd-details--gradient-prism{border-color:#a7d8c8}.gd-details--gradient-prism .gd-details-summary{background:linear-gradient(-45deg, #c4f0e0, #d0e8f5, #e4d4f4, #d8cef0);color:#1e3a5f}.gd-details--gradient-prism .gd-details-summary:hover{filter:brightness(0.96)}.gd-details--gradient-prism[open]>.gd-details-summary{border-bottom-color:#a7d8c8}.gd-details--gradient-prism .gd-details-body{background:linear-gradient(-45deg, #ecfaf4, #eff5fb, #f5eefc, #f2eefa)}.gd-details--gradient-lilac{border-color:#d8a8e8}.gd-details--gradient-lilac .gd-details-summary{background:linear-gradient(-45deg, #e8d0f0, #f5d0e0, #f0d4f8, #eac8ee);color:#4a1462}.gd-details--gradient-lilac .gd-details-summary:hover{filter:brightness(0.96)}.gd-details--gradient-lilac[open]>.gd-details-summary{border-bottom-color:#d8a8e8}.gd-details--gradient-lilac .gd-details-body{background:linear-gradient(-45deg, #f7eefc, #fdf0f5, #faeefb, #f8ecf9)}.gd-details--gradient-slate{border-color:#b0b8c1}.gd-details--gradient-slate .gd-details-summary{background:linear-gradient(-45deg, #e0e4e8, #eceff1, #dde2e6, #d5dadf);color:#263238}.gd-details--gradient-slate .gd-details-summary:hover{filter:brightness(0.96)}.gd-details--gradient-slate[open]>.gd-details-summary{border-bottom-color:#b0b8c1}.gd-details--gradient-slate .gd-details-body{background:linear-gradient(-45deg, #f4f5f7, #f8f9fa, #f3f4f6, #f1f2f4)}.gd-details--gradient-honey{border-color:#f5c97a}.gd-details--gradient-honey .gd-details-summary{background:linear-gradient(-45deg, #ffe0c2, #ffedcc, #ffe5b4, #ffd6a8);color:#7c2d12}.gd-details--gradient-honey .gd-details-summary:hover{filter:brightness(0.96)}.gd-details--gradient-honey[open]>.gd-details-summary{border-bottom-color:#f5c97a}.gd-details--gradient-honey .gd-details-body{background:linear-gradient(-45deg, #fff6ec, #fffaf0, #fff5e6, #fff2e0)}.gd-details--gradient-dusk{border-color:#b0b4d8}.gd-details--gradient-dusk .gd-details-summary{background:linear-gradient(-45deg, #d8daf0, #dddff5, #d4d0ee, #dad4f2);color:#1a1050}.gd-details--gradient-dusk .gd-details-summary:hover{filter:brightness(0.96)}.gd-details--gradient-dusk[open]>.gd-details-summary{border-bottom-color:#b0b4d8}.gd-details--gradient-dusk .gd-details-body{background:linear-gradient(-45deg, #f0f1fa, #f2f3fc, #eeedf9, #f0eefb)}.gd-details--gradient-mint{border-color:#80cbc4}.gd-details--gradient-mint .gd-details-summary{background:linear-gradient(-45deg, #ccece8, #d5f0ec, #c4e8e4, #d0f2ee);color:#004d40}.gd-details--gradient-mint .gd-details-summary:hover{filter:brightness(0.96)}.gd-details--gradient-mint[open]>.gd-details-summary{border-bottom-color:#80cbc4}.gd-details--gradient-mint .gd-details-body{background:linear-gradient(-45deg, #ebf8f6, #eff9f8, #e9f7f5, #ecfaf8)}.gd-details .gd-details{margin:.5rem 0;border-radius:.375rem}.gd-details .gd-details .gd-details-summary{padding:.5rem 1rem;font-size:.92rem}.gd-details .gd-details .gd-details-body{padding:.75rem 1rem .5rem}html[data-bs-theme=dark] .gd-details{border-color:#161f28}html[data-bs-theme=dark] .gd-details-summary{background:rgb(8.8,12.4,16);color:rgb(149.5,158.5,167.5)}html[data-bs-theme=dark] .gd-details-summary:hover{background:rgb(12.32,17.36,22.4)}html[data-bs-theme=dark] .gd-details[open]>.gd-details-summary{border-bottom-color:#161f28}html[data-bs-theme=dark] .gd-details-body{background:rgb(5.28,7.44,9.6)}html[data-bs-theme=dark] .gd-details-body .code-copy-outer-scaffold,html[data-bs-theme=dark] .gd-details-body .sourceCode,html[data-bs-theme=dark] .gd-details-body pre.sourceCode{background:rgba(0,0,0,0)}html[data-bs-theme=dark] .gd-details--note{border-color:rgb(35.4,78,147.6)}html[data-bs-theme=dark] .gd-details--note .gd-details-summary{background:rgb(14.75,32.5,61.5);color:rgb(166.8,198.75,250.95)}html[data-bs-theme=dark] .gd-details--note .gd-details-summary:hover{background:rgb(20.65,45.5,86.1)}html[data-bs-theme=dark] .gd-details--note[open]>.gd-details-summary{border-bottom-color:rgb(35.4,78,147.6)}html[data-bs-theme=dark] .gd-details--note .gd-details-body{background:rgb(7.08,15.6,29.52)}html[data-bs-theme=dark] .gd-details--warning{border-color:rgb(122.5,79,5.5)}html[data-bs-theme=dark] .gd-details--warning .gd-details-summary{background:rgb(61.25,39.5,2.75);color:rgb(250.5,211.35,145.2)}html[data-bs-theme=dark] .gd-details--warning .gd-details-summary:hover{background:rgb(85.75,55.3,3.85)}html[data-bs-theme=dark] .gd-details--warning[open]>.gd-details-summary{border-bottom-color:rgb(122.5,79,5.5)}html[data-bs-theme=dark] .gd-details--warning .gd-details-body{background:rgb(29.4,18.96,1.32)}html[data-bs-theme=dark] .gd-details--tip{border-color:rgb(8,92.5,64.5)}html[data-bs-theme=dark] .gd-details--tip .gd-details-summary{background:rgb(4,46.25,32.25);color:rgb(147.45,223.5,198.3)}html[data-bs-theme=dark] .gd-details--tip .gd-details-summary:hover{background:rgb(5.6,64.75,45.15)}html[data-bs-theme=dark] .gd-details--tip[open]>.gd-details-summary{border-bottom-color:rgb(8,92.5,64.5)}html[data-bs-theme=dark] .gd-details--tip .gd-details-body{background:rgb(1.92,22.2,15.48)}html[data-bs-theme=dark] .gd-details--danger{border-color:rgb(119.5,34,34)}html[data-bs-theme=dark] .gd-details--danger .gd-details-summary{background:rgb(59.75,17,17);color:rgb(247.8,170.85,170.85)}html[data-bs-theme=dark] .gd-details--danger .gd-details-summary:hover{background:rgb(83.65,23.8,23.8)}html[data-bs-theme=dark] .gd-details--danger[open]>.gd-details-summary{border-bottom-color:rgb(119.5,34,34)}html[data-bs-theme=dark] .gd-details--danger .gd-details-body{background:rgb(28.68,8.16,8.16)}html[data-bs-theme=dark] .gd-details--gradient{border-color:color-mix(in srgb, var(--gd-accent, #818cf8) 35%, transparent)}html[data-bs-theme=dark] .gd-details--gradient .gd-details-summary{background:linear-gradient(-45deg, color-mix(in srgb, var(--gd-accent, #818cf8) 25%, black), color-mix(in srgb, var(--gd-accent-secondary, #c084fc) 20%, black), color-mix(in srgb, var(--gd-accent, #818cf8) 18%, black), color-mix(in srgb, var(--gd-accent-secondary, #c084fc) 25%, black));background-size:400% 400%;animation:gd-gradient-shift 15s ease infinite;color:#fff}html[data-bs-theme=dark] .gd-details--gradient .gd-details-summary:hover{background:linear-gradient(-45deg, color-mix(in srgb, var(--gd-accent, #818cf8) 32%, black), color-mix(in srgb, var(--gd-accent-secondary, #c084fc) 28%, black), color-mix(in srgb, var(--gd-accent, #818cf8) 25%, black), color-mix(in srgb, var(--gd-accent-secondary, #c084fc) 32%, black));background-size:400% 400%;animation:gd-gradient-shift 15s ease infinite}html[data-bs-theme=dark] .gd-details--gradient[open]>.gd-details-summary{border-bottom-color:color-mix(in srgb, var(--gd-accent, #818cf8) 25%, transparent)}html[data-bs-theme=dark] .gd-details--gradient .gd-details-body{background:linear-gradient(-45deg, color-mix(in srgb, var(--gd-accent, #818cf8) 8%, black), color-mix(in srgb, var(--gd-accent-secondary, #c084fc) 6%, black), color-mix(in srgb, var(--gd-accent, #818cf8) 5%, black), color-mix(in srgb, var(--gd-accent-secondary, #c084fc) 8%, black));background-size:400% 400%;animation:gd-gradient-shift 15s ease infinite}html[data-bs-theme=dark] .gd-details--gradient-sky{border-color:#0077b6}html[data-bs-theme=dark] .gd-details--gradient-sky .gd-details-summary{background:linear-gradient(-45deg, #023e8a, #0077b6, #005f73, #0096c7);color:#fff}html[data-bs-theme=dark] .gd-details--gradient-sky .gd-details-summary:hover{filter:brightness(1.15)}html[data-bs-theme=dark] .gd-details--gradient-sky[open]>.gd-details-summary{border-bottom-color:#005f73}html[data-bs-theme=dark] .gd-details--gradient-sky .gd-details-body{background:linear-gradient(-45deg, #021c3d, #012e4a, #012a38, #01374b)}html[data-bs-theme=dark] .gd-details--gradient-peach{border-color:#cc4a1a}html[data-bs-theme=dark] .gd-details--gradient-peach .gd-details-summary{background:linear-gradient(-45deg, #cc4a1a, #c7760f, #b84a5f, #a33560);color:#fff}html[data-bs-theme=dark] .gd-details--gradient-peach .gd-details-summary:hover{filter:brightness(1.15)}html[data-bs-theme=dark] .gd-details--gradient-peach[open]>.gd-details-summary{border-bottom-color:#a33560}html[data-bs-theme=dark] .gd-details--gradient-peach .gd-details-body{background:linear-gradient(-45deg, #3d160a, #3b2405, #37161d, #31101d)}html[data-bs-theme=dark] .gd-details--gradient-prism{border-color:#048a65}html[data-bs-theme=dark] .gd-details--gradient-prism .gd-details-summary{background:linear-gradient(-45deg, #048a65, #0c6a8a, #52077d, #2a0978);color:#fff}html[data-bs-theme=dark] .gd-details--gradient-prism .gd-details-summary:hover{filter:brightness(1.15)}html[data-bs-theme=dark] .gd-details--gradient-prism[open]>.gd-details-summary{border-bottom-color:#0c6a8a}html[data-bs-theme=dark] .gd-details--gradient-prism .gd-details-body{background:linear-gradient(-45deg, #02291e, #042029, #180225, #0d0224)}html[data-bs-theme=dark] .gd-details--gradient-lilac{border-color:#561e64}html[data-bs-theme=dark] .gd-details--gradient-lilac .gd-details-summary{background:linear-gradient(-45deg, #561e64, #8b1140, #a02db3, #6e1a7d);color:#fff}html[data-bs-theme=dark] .gd-details--gradient-lilac .gd-details-summary:hover{filter:brightness(1.15)}html[data-bs-theme=dark] .gd-details--gradient-lilac[open]>.gd-details-summary{border-bottom-color:#8b1140}html[data-bs-theme=dark] .gd-details--gradient-lilac .gd-details-body{background:linear-gradient(-45deg, #1a091e, #290613, #300e35, #210826)}html[data-bs-theme=dark] .gd-details--gradient-slate{border-color:#455a64}html[data-bs-theme=dark] .gd-details--gradient-slate .gd-details-summary{background:linear-gradient(-45deg, #37474f, #455a64, #3e525e, #263238);color:#fff}html[data-bs-theme=dark] .gd-details--gradient-slate .gd-details-summary:hover{filter:brightness(1.15)}html[data-bs-theme=dark] .gd-details--gradient-slate[open]>.gd-details-summary{border-bottom-color:#3e525e}html[data-bs-theme=dark] .gd-details--gradient-slate .gd-details-body{background:linear-gradient(-45deg, #111518, #15191e, #13181b, #0c0f11)}html[data-bs-theme=dark] .gd-details--gradient-honey{border-color:#bf360c}html[data-bs-theme=dark] .gd-details--gradient-honey .gd-details-summary{background:linear-gradient(-45deg, #bf360c, #e65100, #ef6c00, #b71c1c);color:#fff}html[data-bs-theme=dark] .gd-details--gradient-honey .gd-details-summary:hover{filter:brightness(1.15)}html[data-bs-theme=dark] .gd-details--gradient-honey[open]>.gd-details-summary{border-bottom-color:#e65100}html[data-bs-theme=dark] .gd-details--gradient-honey .gd-details-body{background:linear-gradient(-45deg, #391004, #441800, #482000, #370808)}html[data-bs-theme=dark] .gd-details--gradient-dusk{border-color:#1a0f52}html[data-bs-theme=dark] .gd-details--gradient-dusk .gd-details-summary{background:linear-gradient(-45deg, #0d1244, #141b55, #1a0f52, #261560);color:#fff}html[data-bs-theme=dark] .gd-details--gradient-dusk .gd-details-summary:hover{filter:brightness(1.15)}html[data-bs-theme=dark] .gd-details--gradient-dusk[open]>.gd-details-summary{border-bottom-color:#141b55}html[data-bs-theme=dark] .gd-details--gradient-dusk .gd-details-body{background:linear-gradient(-45deg, #040514, #060819, #080518, #0b061c)}html[data-bs-theme=dark] .gd-details--gradient-mint{border-color:#00695c}html[data-bs-theme=dark] .gd-details--gradient-mint .gd-details-summary{background:linear-gradient(-45deg, #00695c, #00796b, #004d40, #00897b);color:#fff}html[data-bs-theme=dark] .gd-details--gradient-mint .gd-details-summary:hover{filter:brightness(1.15)}html[data-bs-theme=dark] .gd-details--gradient-mint[open]>.gd-details-summary{border-bottom-color:#004d40}html[data-bs-theme=dark] .gd-details--gradient-mint .gd-details-body{background:linear-gradient(-45deg, #001f1b, #002420, #001713, #002924)}.gd-details--gleam{--gd-gleam-color: rgb(86.2, 100.6, 115);--gd-gleam-angle: 0deg;border:2px solid rgba(0,0,0,0);background:linear-gradient(var(--gd-gleam-bg, var(--bs-body-bg, #ffffff)), var(--gd-gleam-bg, var(--bs-body-bg, #ffffff))) padding-box,conic-gradient(from var(--gd-gleam-angle), var(--gd-gleam-color) 0%, var(--gd-gleam-color) 60%, white 75%, white 82%, var(--gd-gleam-color) 92%, var(--gd-gleam-color) 100%) border-box}.gd-details--gleam.gd-details--gradient-sky{--gd-gleam-color: #38bdf8}.gd-details--gleam.gd-details--gradient-peach{--gd-gleam-color: #fb923c}.gd-details--gleam.gd-details--gradient-prism{--gd-gleam-color: #a78bfa}.gd-details--gleam.gd-details--gradient-lilac{--gd-gleam-color: #c084fc}.gd-details--gleam.gd-details--gradient-slate{--gd-gleam-color: #94a3b8}.gd-details--gleam.gd-details--gradient-honey{--gd-gleam-color: #fbbf24}.gd-details--gleam.gd-details--gradient-dusk{--gd-gleam-color: #818cf8}.gd-details--gleam.gd-details--gradient-mint{--gd-gleam-color: #2dd4bf}.gd-details--gleam.gd-details--gradient{--gd-gleam-color: var(--gd-accent, #6366f1)}.gd-details--gleam.gd-details--note{--gd-gleam-color: #60a5fa}.gd-details--gleam.gd-details--warning{--gd-gleam-color: #fbbf24}.gd-details--gleam.gd-details--tip{--gd-gleam-color: #34d399}.gd-details--gleam.gd-details--danger{--gd-gleam-color: #f87171}html[data-bs-theme=dark] .gd-details--gleam{--gd-gleam-color: rgb(160.05, 168.15, 176.25);border-color:rgba(0,0,0,0);background:linear-gradient(var(--bs-body-bg, #212529), var(--bs-body-bg, #212529)) padding-box,conic-gradient(from var(--gd-gleam-angle), transparent 0%, transparent 60%, var(--gd-gleam-color) 75%, color-mix(in srgb, var(--gd-gleam-color) 60%, white) 80%, var(--gd-gleam-color) 85%, transparent 95%, transparent 100%) border-box}html[data-bs-theme=dark] .gd-details--gleam.gd-details--gradient-sky{--gd-gleam-color: #7dd3fc}html[data-bs-theme=dark] .gd-details--gleam.gd-details--gradient-peach{--gd-gleam-color: #fdba74}html[data-bs-theme=dark] .gd-details--gleam.gd-details--gradient-prism{--gd-gleam-color: #c4b5fd}html[data-bs-theme=dark] .gd-details--gleam.gd-details--gradient-lilac{--gd-gleam-color: #d8b4fe}html[data-bs-theme=dark] .gd-details--gleam.gd-details--gradient-slate{--gd-gleam-color: #cbd5e1}html[data-bs-theme=dark] .gd-details--gleam.gd-details--gradient-honey{--gd-gleam-color: #fde68a}html[data-bs-theme=dark] .gd-details--gleam.gd-details--gradient-dusk{--gd-gleam-color: #a5b4fc}html[data-bs-theme=dark] .gd-details--gleam.gd-details--gradient-mint{--gd-gleam-color: #5eead4}html[data-bs-theme=dark] .gd-details--gleam.gd-details--gradient{--gd-gleam-color: var(--gd-accent, #818cf8)}html[data-bs-theme=dark] .gd-details--gleam.gd-details--note{--gd-gleam-color: #93c5fd}html[data-bs-theme=dark] .gd-details--gleam.gd-details--warning{--gd-gleam-color: #fde68a}html[data-bs-theme=dark] .gd-details--gleam.gd-details--tip{--gd-gleam-color: #6ee7b7}html[data-bs-theme=dark] .gd-details--gleam.gd-details--danger{--gd-gleam-color: #fca5a5}@media(prefers-reduced-motion: reduce){.gd-details{transition:none}.gd-details--animating{transition:none}.gd-details-chevron::before{transition:none}.gd-details-summary{transition:none}.gd-details--gradient .gd-details-summary,.gd-details--gradient .gd-details-body,.gd-details--gradient-sky .gd-details-summary,.gd-details--gradient-sky .gd-details-body,.gd-details--gradient-peach .gd-details-summary,.gd-details--gradient-peach .gd-details-body,.gd-details--gradient-prism .gd-details-summary,.gd-details--gradient-prism .gd-details-body,.gd-details--gradient-lilac .gd-details-summary,.gd-details--gradient-lilac .gd-details-body,.gd-details--gradient-slate .gd-details-summary,.gd-details--gradient-slate .gd-details-body,.gd-details--gradient-honey .gd-details-summary,.gd-details--gradient-honey .gd-details-body,.gd-details--gradient-dusk .gd-details-summary,.gd-details--gradient-dusk .gd-details-body,.gd-details--gradient-mint .gd-details-summary,.gd-details--gradient-mint .gd-details-body{animation:none}}@keyframes gd-sparkle-color{0%{color:#e74c3c}33%{color:#f39c12}67%{color:#3498db}100%{color:#e74c3c}}@keyframes gd-sparkle-pulse{0%,100%{transform:scale(1);opacity:.85}50%{transform:scale(1.3);opacity:1}}@keyframes gd-sparkle-curated-pulse{0%,100%{transform:scale(1) rotate(0deg);opacity:.9}25%{transform:scale(1.5) rotate(10deg);opacity:1}50%{transform:scale(1.1) rotate(-5deg);opacity:.95}75%{transform:scale(1.6) rotate(8deg);opacity:1}}.gd-sparkle{display:inline-block;animation:gd-sparkle-color 3s ease-in-out infinite,gd-sparkle-pulse 2s ease-in-out infinite}.gd-sparkle-curated{display:inline-block;animation:gd-sparkle-color 1.8s ease-in-out infinite,gd-sparkle-curated-pulse 1.4s ease-in-out infinite;filter:drop-shadow(0 0 2px currentColor)}@media(prefers-reduced-motion: reduce){.gd-sparkle,.gd-sparkle-curated{animation:gd-sparkle-color 6s ease-in-out infinite;filter:none}}:root{--quarto-scss-export-gray-300: #dee2e6;--quarto-scss-export-gray-500: #adb5bd;--quarto-scss-export-gray-600: #6c757d;--quarto-scss-export-gray-800: #343a40;--quarto-scss-export-card-cap-bg: rgba(52, 58, 64, 0.25);--quarto-scss-export-border-color: #dee2e6;--quarto-scss-export-text-muted: #6c757d;--quarto-scss-export-white: #fff;--quarto-scss-export-gray-100: #f8f9fa;--quarto-scss-export-gray-200: #ecf0f1;--quarto-scss-export-gray-400: #ced4da;--quarto-scss-export-gray-700: #7b8a8b;--quarto-scss-export-gray-900: #212529;--quarto-scss-export-black: #000;--quarto-scss-export-blue: #2c3e50;--quarto-scss-export-indigo: #6610f2;--quarto-scss-export-purple: #6f42c1;--quarto-scss-export-pink: #e83e8c;--quarto-scss-export-red: #e74c3c;--quarto-scss-export-orange: #fd7e14;--quarto-scss-export-yellow: #f39c12;--quarto-scss-export-green: #18bc9c;--quarto-scss-export-teal: #20c997;--quarto-scss-export-cyan: #3498db;--quarto-scss-export-primary: #2c3e50;--quarto-scss-export-secondary: #6c757d;--quarto-scss-export-success: #18bc9c;--quarto-scss-export-info: #3498db;--quarto-scss-export-warning: #f39c12;--quarto-scss-export-danger: #e74c3c;--quarto-scss-export-light: #ecf0f1;--quarto-scss-export-dark: #7b8a8b;--quarto-scss-export-link-color: #18bc9c;--quarto-scss-export-dropdown-link-color: #7b8a8b;--quarto-scss-export-dropdown-link-hover-color: #fff;--quarto-scss-export-dropdown-link-hover-bg: #2c3e50;--quarto-scss-export-nav-link-disabled-color: #6c757d;--quarto-scss-export-nav-tabs-border-color: #ecf0f1;--quarto-scss-export-pagination-color: #fff;--quarto-scss-export-pagination-bg: #18bc9c;--quarto-scss-export-pagination-border-color: transparent;--quarto-scss-export-pagination-hover-color: #fff;--quarto-scss-export-pagination-hover-bg: rgb(15.3396226415, 120.1603773585, 99.7075471698);--quarto-scss-export-pagination-hover-border-color: transparent;--quarto-scss-export-pagination-active-bg: rgb(15.3396226415, 120.1603773585, 99.7075471698);--quarto-scss-export-pagination-active-border-color: transparent;--quarto-scss-export-pagination-disabled-color: #ecf0f1;--quarto-scss-export-pagination-disabled-bg: rgb(58.5754716981, 229.9245283019, 196.4905660377);--quarto-scss-export-pagination-disabled-border-color: transparent;--quarto-scss-export-list-group-hover-bg: #ecf0f1;--quarto-scss-export-list-group-disabled-bg: #ecf0f1;--quarto-scss-export-btn-close-color: #fff;--quarto-scss-export-title-banner-color: ;--quarto-scss-export-title-banner-bg: ;--quarto-scss-export-btn-code-copy-color: #5E5E5E;--quarto-scss-export-btn-code-copy-color-active: #4758AB;--quarto-scss-export-sidebar-bg: #fff;--quarto-scss-export-link-color-bg: transparent;--quarto-scss-export-code-color: #7d12ba;--quarto-scss-export-code-bg: #f8f9fa;--quarto-scss-export-toc-color: #18bc9c;--quarto-scss-export-toc-active-border: #18bc9c;--quarto-scss-export-toc-inactive-border: #ecf0f1;--quarto-scss-export-navbar-default: #2c3e50;--quarto-scss-export-navbar-hl-override: false;--quarto-scss-export-navbar-bg: #2c3e50;--quarto-scss-export-btn-bg: #6c757d;--quarto-scss-export-btn-fg: rgb(253.53, 253.62, 253.7);--quarto-scss-export-body-contrast-bg: #fff;--quarto-scss-export-body-contrast-color: #212529;--quarto-scss-export-navbar-fg: rgb(204.36, 208.68, 213);--quarto-scss-export-navbar-hl: #fff;--quarto-scss-export-navbar-brand: rgb(204.36, 208.68, 213);--quarto-scss-export-navbar-brand-hl: #fff;--quarto-scss-export-navbar-toggler-border-color: rgba(204.36, 208.68, 213, 0);--quarto-scss-export-navbar-hover-color: rgba(255, 255, 255, 0.8);--quarto-scss-export-navbar-disabled-color: rgba(204.36, 208.68, 213, 0.75);--quarto-scss-export-sidebar-fg: rgb(89.25, 89.25, 89.25);--quarto-scss-export-title-block-color: #212529;--quarto-scss-export-title-block-contast-color: #fff;--quarto-scss-export-footer-bg: #fff;--quarto-scss-export-footer-fg: rgb(117.3, 117.3, 117.3);--quarto-scss-export-popover-bg: #fff;--quarto-scss-export-input-bg: #fff;--quarto-scss-export-input-border-color: #dee2e6;--quarto-scss-export-code-annotation-higlight-color: rgba(170, 170, 170, 0.2666666667);--quarto-scss-export-code-annotation-higlight-bg: rgba(170, 170, 170, 0.1333333333);--quarto-scss-export-table-group-separator-color: #909294;--quarto-scss-export-table-group-separator-color-lighter: rgb(210.6, 211.4, 212.2);--quarto-scss-export-link-decoration: underline;--quarto-scss-export-table-border-color: #dee2e6;--quarto-scss-export-sidebar-glass-bg: rgba(102, 102, 102, 0.4);--quarto-scss-export-color-contrast-dark: #000;--quarto-scss-export-color-contrast-light: #fff;--quarto-scss-export-blue-100: rgb(212.8, 216.4, 220);--quarto-scss-export-blue-200: rgb(170.6, 177.8, 185);--quarto-scss-export-blue-300: rgb(128.4, 139.2, 150);--quarto-scss-export-blue-400: rgb(86.2, 100.6, 115);--quarto-scss-export-blue-500: #2c3e50;--quarto-scss-export-blue-600: rgb(35.2, 49.6, 64);--quarto-scss-export-blue-700: rgb(26.4, 37.2, 48);--quarto-scss-export-blue-800: rgb(17.6, 24.8, 32);--quarto-scss-export-blue-900: rgb(8.8, 12.4, 16);--quarto-scss-export-indigo-100: rgb(224.4, 207.2, 252.4);--quarto-scss-export-indigo-200: rgb(193.8, 159.4, 249.8);--quarto-scss-export-indigo-300: rgb(163.2, 111.6, 247.2);--quarto-scss-export-indigo-400: rgb(132.6, 63.8, 244.6);--quarto-scss-export-indigo-500: #6610f2;--quarto-scss-export-indigo-600: rgb(81.6, 12.8, 193.6);--quarto-scss-export-indigo-700: rgb(61.2, 9.6, 145.2);--quarto-scss-export-indigo-800: rgb(40.8, 6.4, 96.8);--quarto-scss-export-indigo-900: rgb(20.4, 3.2, 48.4);--quarto-scss-export-purple-100: rgb(226.2, 217.2, 242.6);--quarto-scss-export-purple-200: rgb(197.4, 179.4, 230.2);--quarto-scss-export-purple-300: rgb(168.6, 141.6, 217.8);--quarto-scss-export-purple-400: rgb(139.8, 103.8, 205.4);--quarto-scss-export-purple-500: #6f42c1;--quarto-scss-export-purple-600: rgb(88.8, 52.8, 154.4);--quarto-scss-export-purple-700: rgb(66.6, 39.6, 115.8);--quarto-scss-export-purple-800: rgb(44.4, 26.4, 77.2);--quarto-scss-export-purple-900: rgb(22.2, 13.2, 38.6);--quarto-scss-export-pink-100: rgb(250.4, 216.4, 232);--quarto-scss-export-pink-200: rgb(245.8, 177.8, 209);--quarto-scss-export-pink-300: rgb(241.2, 139.2, 186);--quarto-scss-export-pink-400: rgb(236.6, 100.6, 163);--quarto-scss-export-pink-500: #e83e8c;--quarto-scss-export-pink-600: rgb(185.6, 49.6, 112);--quarto-scss-export-pink-700: rgb(139.2, 37.2, 84);--quarto-scss-export-pink-800: rgb(92.8, 24.8, 56);--quarto-scss-export-pink-900: rgb(46.4, 12.4, 28);--quarto-scss-export-red-100: rgb(250.2, 219.2, 216);--quarto-scss-export-red-200: rgb(245.4, 183.4, 177);--quarto-scss-export-red-300: rgb(240.6, 147.6, 138);--quarto-scss-export-red-400: rgb(235.8, 111.8, 99);--quarto-scss-export-red-500: #e74c3c;--quarto-scss-export-red-600: rgb(184.8, 60.8, 48);--quarto-scss-export-red-700: rgb(138.6, 45.6, 36);--quarto-scss-export-red-800: rgb(92.4, 30.4, 24);--quarto-scss-export-red-900: rgb(46.2, 15.2, 12);--quarto-scss-export-orange-100: rgb(254.6, 229.2, 208);--quarto-scss-export-orange-200: rgb(254.2, 203.4, 161);--quarto-scss-export-orange-300: rgb(253.8, 177.6, 114);--quarto-scss-export-orange-400: rgb(253.4, 151.8, 67);--quarto-scss-export-orange-500: #fd7e14;--quarto-scss-export-orange-600: rgb(202.4, 100.8, 16);--quarto-scss-export-orange-700: rgb(151.8, 75.6, 12);--quarto-scss-export-orange-800: rgb(101.2, 50.4, 8);--quarto-scss-export-orange-900: rgb(50.6, 25.2, 4);--quarto-scss-export-yellow-100: rgb(252.6, 235.2, 207.6);--quarto-scss-export-yellow-200: rgb(250.2, 215.4, 160.2);--quarto-scss-export-yellow-300: rgb(247.8, 195.6, 112.8);--quarto-scss-export-yellow-400: rgb(245.4, 175.8, 65.4);--quarto-scss-export-yellow-500: #f39c12;--quarto-scss-export-yellow-600: rgb(194.4, 124.8, 14.4);--quarto-scss-export-yellow-700: rgb(145.8, 93.6, 10.8);--quarto-scss-export-yellow-800: rgb(97.2, 62.4, 7.2);--quarto-scss-export-yellow-900: rgb(48.6, 31.2, 3.6);--quarto-scss-export-green-100: rgb(208.8, 241.6, 235.2);--quarto-scss-export-green-200: rgb(162.6, 228.2, 215.4);--quarto-scss-export-green-300: rgb(116.4, 214.8, 195.6);--quarto-scss-export-green-400: rgb(70.2, 201.4, 175.8);--quarto-scss-export-green-500: #18bc9c;--quarto-scss-export-green-600: rgb(19.2, 150.4, 124.8);--quarto-scss-export-green-700: rgb(14.4, 112.8, 93.6);--quarto-scss-export-green-800: rgb(9.6, 75.2, 62.4);--quarto-scss-export-green-900: rgb(4.8, 37.6, 31.2);--quarto-scss-export-teal-100: rgb(210.4, 244.2, 234.2);--quarto-scss-export-teal-200: rgb(165.8, 233.4, 213.4);--quarto-scss-export-teal-300: rgb(121.2, 222.6, 192.6);--quarto-scss-export-teal-400: rgb(76.6, 211.8, 171.8);--quarto-scss-export-teal-500: #20c997;--quarto-scss-export-teal-600: rgb(25.6, 160.8, 120.8);--quarto-scss-export-teal-700: rgb(19.2, 120.6, 90.6);--quarto-scss-export-teal-800: rgb(12.8, 80.4, 60.4);--quarto-scss-export-teal-900: rgb(6.4, 40.2, 30.2);--quarto-scss-export-cyan-100: rgb(214.4, 234.4, 247.8);--quarto-scss-export-cyan-200: rgb(173.8, 213.8, 240.6);--quarto-scss-export-cyan-300: rgb(133.2, 193.2, 233.4);--quarto-scss-export-cyan-400: rgb(92.6, 172.6, 226.2);--quarto-scss-export-cyan-500: #3498db;--quarto-scss-export-cyan-600: rgb(41.6, 121.6, 175.2);--quarto-scss-export-cyan-700: rgb(31.2, 91.2, 131.4);--quarto-scss-export-cyan-800: rgb(20.8, 60.8, 87.6);--quarto-scss-export-cyan-900: rgb(10.4, 30.4, 43.8);--quarto-scss-export-default: #6c757d;--quarto-scss-export-primary-text-emphasis: rgb(17.6, 24.8, 32);--quarto-scss-export-secondary-text-emphasis: rgb(43.2, 46.8, 50);--quarto-scss-export-success-text-emphasis: rgb(9.6, 75.2, 62.4);--quarto-scss-export-info-text-emphasis: rgb(20.8, 60.8, 87.6);--quarto-scss-export-warning-text-emphasis: rgb(97.2, 62.4, 7.2);--quarto-scss-export-danger-text-emphasis: rgb(92.4, 30.4, 24);--quarto-scss-export-light-text-emphasis: #7b8a8b;--quarto-scss-export-dark-text-emphasis: #7b8a8b;--quarto-scss-export-primary-bg-subtle: rgb(212.8, 216.4, 220);--quarto-scss-export-secondary-bg-subtle: rgb(225.6, 227.4, 229);--quarto-scss-export-success-bg-subtle: rgb(208.8, 241.6, 235.2);--quarto-scss-export-info-bg-subtle: rgb(214.4, 234.4, 247.8);--quarto-scss-export-warning-bg-subtle: rgb(252.6, 235.2, 207.6);--quarto-scss-export-danger-bg-subtle: rgb(250.2, 219.2, 216);--quarto-scss-export-light-bg-subtle: rgb(251.5, 252, 252.5);--quarto-scss-export-dark-bg-subtle: #ced4da;--quarto-scss-export-primary-border-subtle: rgb(170.6, 177.8, 185);--quarto-scss-export-secondary-border-subtle: rgb(196.2, 199.8, 203);--quarto-scss-export-success-border-subtle: rgb(162.6, 228.2, 215.4);--quarto-scss-export-info-border-subtle: rgb(173.8, 213.8, 240.6);--quarto-scss-export-warning-border-subtle: rgb(250.2, 215.4, 160.2);--quarto-scss-export-danger-border-subtle: rgb(245.4, 183.4, 177);--quarto-scss-export-light-border-subtle: #ecf0f1;--quarto-scss-export-dark-border-subtle: #adb5bd;--quarto-scss-export-body-text-align: ;--quarto-scss-export-body-color: #212529;--quarto-scss-export-body-bg: #fff;--quarto-scss-export-body-secondary-color: rgba(33, 37, 41, 0.75);--quarto-scss-export-body-secondary-bg: #ecf0f1;--quarto-scss-export-body-tertiary-color: rgba(33, 37, 41, 0.5);--quarto-scss-export-body-tertiary-bg: #f8f9fa;--quarto-scss-export-body-emphasis-color: #000;--quarto-scss-export-link-hover-color: rgb(19.2, 150.4, 124.8);--quarto-scss-export-link-hover-decoration: ;--quarto-scss-export-border-color-translucent: rgba(0, 0, 0, 0.175);--quarto-scss-export-component-active-bg: #2c3e50;--quarto-scss-export-component-active-color: #fff;--quarto-scss-export-focus-ring-color: rgba(44, 62, 80, 0.25);--quarto-scss-export-headings-font-family: ;--quarto-scss-export-headings-font-style: ;--quarto-scss-export-display-font-family: ;--quarto-scss-export-display-font-style: ;--quarto-scss-export-blockquote-footer-color: #6c757d;--quarto-scss-export-blockquote-border-color: #ecf0f1;--quarto-scss-export-hr-bg-color: ;--quarto-scss-export-hr-height: ;--quarto-scss-export-hr-border-color: ;--quarto-scss-export-legend-font-weight: ;--quarto-scss-export-mark-bg: rgb(252.6, 235.2, 207.6);--quarto-scss-export-table-color: #212529;--quarto-scss-export-table-bg: #fff;--quarto-scss-export-table-accent-bg: transparent;--quarto-scss-export-table-th-font-weight: ;--quarto-scss-export-table-striped-color: #212529;--quarto-scss-export-table-striped-bg: rgba(0, 0, 0, 0.05);--quarto-scss-export-table-active-color: #212529;--quarto-scss-export-table-active-bg: rgba(0, 0, 0, 0.1);--quarto-scss-export-table-hover-color: #212529;--quarto-scss-export-table-hover-bg: rgba(0, 0, 0, 0.075);--quarto-scss-export-table-caption-color: rgba(33, 37, 41, 0.75);--quarto-scss-export-input-btn-font-family: ;--quarto-scss-export-input-btn-focus-color: rgba(44, 62, 80, 0.25);--quarto-scss-export-btn-color: #212529;--quarto-scss-export-btn-font-family: ;--quarto-scss-export-btn-white-space: ;--quarto-scss-export-btn-link-color: #18bc9c;--quarto-scss-export-btn-link-hover-color: rgb(19.2, 150.4, 124.8);--quarto-scss-export-btn-link-disabled-color: #6c757d;--quarto-scss-export-form-text-font-style: ;--quarto-scss-export-form-text-font-weight: ;--quarto-scss-export-form-text-color: rgba(33, 37, 41, 0.75);--quarto-scss-export-form-label-font-size: ;--quarto-scss-export-form-label-font-style: ;--quarto-scss-export-form-label-font-weight: ;--quarto-scss-export-form-label-color: ;--quarto-scss-export-input-font-family: ;--quarto-scss-export-input-disabled-color: ;--quarto-scss-export-input-disabled-bg: #ecf0f1;--quarto-scss-export-input-disabled-border-color: ;--quarto-scss-export-input-color: #212529;--quarto-scss-export-input-focus-bg: #fff;--quarto-scss-export-input-focus-border-color: rgb(149.5, 158.5, 167.5);--quarto-scss-export-input-focus-color: #212529;--quarto-scss-export-input-placeholder-color: rgba(33, 37, 41, 0.75);--quarto-scss-export-input-plaintext-color: #212529;--quarto-scss-export-form-check-label-color: ;--quarto-scss-export-form-check-transition: ;--quarto-scss-export-form-check-input-bg: #fff;--quarto-scss-export-form-check-input-focus-border: rgb(149.5, 158.5, 167.5);--quarto-scss-export-form-check-input-checked-color: #fff;--quarto-scss-export-form-check-input-checked-bg-color: #2c3e50;--quarto-scss-export-form-check-input-checked-border-color: #2c3e50;--quarto-scss-export-form-check-input-indeterminate-color: #fff;--quarto-scss-export-form-check-input-indeterminate-bg-color: #2c3e50;--quarto-scss-export-form-check-input-indeterminate-border-color: #2c3e50;--quarto-scss-export-form-switch-color: rgba(0, 0, 0, 0.25);--quarto-scss-export-form-switch-focus-color: rgb(149.5, 158.5, 167.5);--quarto-scss-export-form-switch-checked-color: #fff;--quarto-scss-export-input-group-addon-color: #212529;--quarto-scss-export-input-group-addon-bg: #f8f9fa;--quarto-scss-export-input-group-addon-border-color: #dee2e6;--quarto-scss-export-form-select-font-family: ;--quarto-scss-export-form-select-color: #212529;--quarto-scss-export-form-select-bg: #fff;--quarto-scss-export-form-select-disabled-color: ;--quarto-scss-export-form-select-disabled-bg: #ecf0f1;--quarto-scss-export-form-select-disabled-border-color: ;--quarto-scss-export-form-select-indicator-color: #343a40;--quarto-scss-export-form-select-border-color: #dee2e6;--quarto-scss-export-form-select-focus-border-color: rgb(149.5, 158.5, 167.5);--quarto-scss-export-form-range-track-bg: #f8f9fa;--quarto-scss-export-form-range-thumb-bg: #2c3e50;--quarto-scss-export-form-range-thumb-active-bg: rgb(191.7, 197.1, 202.5);--quarto-scss-export-form-range-thumb-disabled-bg: rgba(33, 37, 41, 0.75);--quarto-scss-export-form-file-button-color: #212529;--quarto-scss-export-form-file-button-bg: #f8f9fa;--quarto-scss-export-form-file-button-hover-bg: #ecf0f1;--quarto-scss-export-form-floating-label-disabled-color: #6c757d;--quarto-scss-export-form-feedback-font-style: ;--quarto-scss-export-form-feedback-valid-color: #18bc9c;--quarto-scss-export-form-feedback-invalid-color: #e74c3c;--quarto-scss-export-form-feedback-icon-valid-color: #18bc9c;--quarto-scss-export-form-feedback-icon-invalid-color: #e74c3c;--quarto-scss-export-form-valid-color: #18bc9c;--quarto-scss-export-form-valid-border-color: #18bc9c;--quarto-scss-export-form-invalid-color: #e74c3c;--quarto-scss-export-form-invalid-border-color: #e74c3c;--quarto-scss-export-nav-link-font-size: ;--quarto-scss-export-nav-link-font-weight: ;--quarto-scss-export-nav-link-color: #18bc9c;--quarto-scss-export-nav-link-hover-color: rgb(19.2, 150.4, 124.8);--quarto-scss-export-nav-tabs-link-hover-border-color: #ecf0f1 #ecf0f1 #ecf0f1;--quarto-scss-export-nav-tabs-link-active-color: #000;--quarto-scss-export-nav-tabs-link-active-bg: #fff;--quarto-scss-export-nav-pills-link-active-bg: #2c3e50;--quarto-scss-export-nav-pills-link-active-color: #fff;--quarto-scss-export-nav-underline-link-active-color: #000;--quarto-scss-export-navbar-padding-x: ;--quarto-scss-export-navbar-light-contrast: #fff;--quarto-scss-export-navbar-dark-contrast: #fff;--quarto-scss-export-navbar-light-icon-color: rgba(255, 255, 255, 0.75);--quarto-scss-export-navbar-dark-icon-color: rgba(255, 255, 255, 0.75);--quarto-scss-export-dropdown-color: #212529;--quarto-scss-export-dropdown-bg: #fff;--quarto-scss-export-dropdown-border-color: rgba(0, 0, 0, 0.175);--quarto-scss-export-dropdown-divider-bg: rgba(0, 0, 0, 0.175);--quarto-scss-export-dropdown-link-active-bg: #2c3e50;--quarto-scss-export-dropdown-link-active-color: #fff;--quarto-scss-export-dropdown-link-disabled-color: rgba(33, 37, 41, 0.5);--quarto-scss-export-dropdown-header-color: #6c757d;--quarto-scss-export-dropdown-dark-color: #dee2e6;--quarto-scss-export-dropdown-dark-bg: #343a40;--quarto-scss-export-dropdown-dark-border-color: rgba(0, 0, 0, 0.175);--quarto-scss-export-dropdown-dark-divider-bg: rgba(0, 0, 0, 0.175);--quarto-scss-export-dropdown-dark-box-shadow: ;--quarto-scss-export-dropdown-dark-link-color: #dee2e6;--quarto-scss-export-dropdown-dark-link-hover-color: #fff;--quarto-scss-export-dropdown-dark-link-hover-bg: rgba(255, 255, 255, 0.15);--quarto-scss-export-dropdown-dark-link-active-color: #fff;--quarto-scss-export-dropdown-dark-link-active-bg: #2c3e50;--quarto-scss-export-dropdown-dark-link-disabled-color: #adb5bd;--quarto-scss-export-dropdown-dark-header-color: #adb5bd;--quarto-scss-export-pagination-focus-color: rgb(19.2, 150.4, 124.8);--quarto-scss-export-pagination-focus-bg: #ecf0f1;--quarto-scss-export-pagination-active-color: #fff;--quarto-scss-export-card-title-color: ;--quarto-scss-export-card-subtitle-color: ;--quarto-scss-export-card-border-color: rgba(0, 0, 0, 0.175);--quarto-scss-export-card-box-shadow: ;--quarto-scss-export-card-cap-color: ;--quarto-scss-export-card-height: ;--quarto-scss-export-card-color: ;--quarto-scss-export-card-bg: #fff;--quarto-scss-export-accordion-color: #212529;--quarto-scss-export-accordion-bg: #fff;--quarto-scss-export-accordion-border-color: #dee2e6;--quarto-scss-export-accordion-button-color: #212529;--quarto-scss-export-accordion-button-bg: #fff;--quarto-scss-export-accordion-button-active-bg: rgb(212.8, 216.4, 220);--quarto-scss-export-accordion-button-active-color: rgb(17.6, 24.8, 32);--quarto-scss-export-accordion-button-focus-border-color: rgb(149.5, 158.5, 167.5);--quarto-scss-export-accordion-icon-color: #212529;--quarto-scss-export-accordion-icon-active-color: rgb(17.6, 24.8, 32);--quarto-scss-export-tooltip-color: #fff;--quarto-scss-export-tooltip-bg: #000;--quarto-scss-export-tooltip-margin: ;--quarto-scss-export-tooltip-arrow-color: ;--quarto-scss-export-form-feedback-tooltip-line-height: ;--quarto-scss-export-popover-border-color: rgba(0, 0, 0, 0.175);--quarto-scss-export-popover-header-bg: #ecf0f1;--quarto-scss-export-popover-body-color: #212529;--quarto-scss-export-popover-arrow-color: #fff;--quarto-scss-export-popover-arrow-outer-color: rgba(0, 0, 0, 0.175);--quarto-scss-export-toast-color: ;--quarto-scss-export-toast-background-color: rgba(255, 255, 255, 0.85);--quarto-scss-export-toast-border-color: rgba(0, 0, 0, 0.175);--quarto-scss-export-toast-header-color: rgba(33, 37, 41, 0.75);--quarto-scss-export-toast-header-background-color: rgba(255, 255, 255, 0.85);--quarto-scss-export-toast-header-border-color: rgba(0, 0, 0, 0.175);--quarto-scss-export-badge-color: #fff;--quarto-scss-export-modal-content-color: ;--quarto-scss-export-modal-content-bg: #fff;--quarto-scss-export-modal-content-border-color: rgba(0, 0, 0, 0.175);--quarto-scss-export-modal-backdrop-bg: #000;--quarto-scss-export-modal-header-border-color: #dee2e6;--quarto-scss-export-modal-footer-bg: ;--quarto-scss-export-modal-footer-border-color: #dee2e6;--quarto-scss-export-progress-bg: #ecf0f1;--quarto-scss-export-progress-bar-color: #fff;--quarto-scss-export-progress-bar-bg: #2c3e50;--quarto-scss-export-list-group-color: #212529;--quarto-scss-export-list-group-bg: #fff;--quarto-scss-export-list-group-border-color: #dee2e6;--quarto-scss-export-list-group-active-bg: #2c3e50;--quarto-scss-export-list-group-active-color: #fff;--quarto-scss-export-list-group-active-border-color: #2c3e50;--quarto-scss-export-list-group-disabled-color: rgba(33, 37, 41, 0.75);--quarto-scss-export-list-group-action-color: rgba(33, 37, 41, 0.75);--quarto-scss-export-list-group-action-hover-color: #000;--quarto-scss-export-list-group-action-active-color: #212529;--quarto-scss-export-list-group-action-active-bg: #ecf0f1;--quarto-scss-export-thumbnail-bg: #fff;--quarto-scss-export-thumbnail-border-color: #dee2e6;--quarto-scss-export-figure-caption-color: rgba(33, 37, 41, 0.75);--quarto-scss-export-breadcrumb-font-size: ;--quarto-scss-export-breadcrumb-bg: ;--quarto-scss-export-breadcrumb-divider-color: rgba(33, 37, 41, 0.75);--quarto-scss-export-breadcrumb-active-color: rgba(33, 37, 41, 0.75);--quarto-scss-export-carousel-control-color: #fff;--quarto-scss-export-carousel-indicator-active-bg: #fff;--quarto-scss-export-carousel-caption-color: #fff;--quarto-scss-export-carousel-dark-indicator-active-bg: #000;--quarto-scss-export-carousel-dark-caption-color: #000;--quarto-scss-export-offcanvas-border-color: rgba(0, 0, 0, 0.175);--quarto-scss-export-offcanvas-bg-color: #fff;--quarto-scss-export-offcanvas-color: #212529;--quarto-scss-export-offcanvas-backdrop-bg: #000;--quarto-scss-export-code-color-dark: white;--quarto-scss-export-kbd-color: #fff;--quarto-scss-export-kbd-bg: #212529;--quarto-scss-export-nested-kbd-font-weight: ;--quarto-scss-export-pre-bg: #f8f9fa;--quarto-scss-export-pre-color: #000;--quarto-scss-export-bslib-page-sidebar-title-bg: #2c3e50;--quarto-scss-export-bslib-page-sidebar-title-color: #fff;--quarto-scss-export-bslib-sidebar-bg: rgba(var(--bs-emphasis-color-rgb, 0, 0, 0), 0.05);--quarto-scss-export-bslib-sidebar-toggle-bg: rgba(var(--bs-emphasis-color-rgb, 0, 0, 0), 0.1);--quarto-scss-export-sidebar-color: rgb(89.25, 89.25, 89.25);--quarto-scss-export-sidebar-hover-color: rgba(12.72, 99.64, 82.68, 0.8);--quarto-scss-export-sidebar-disabled-color: rgba(89.25, 89.25, 89.25, 0.75);--quarto-scss-export-valuebox-bg-primary: rgba(39, 128, 227, 0.7);--quarto-scss-export-valuebox-bg-secondary: #6c757d;--quarto-scss-export-valuebox-bg-success: rgba(63, 182, 24, 0.7);--quarto-scss-export-valuebox-bg-info: rgba(153, 84, 187, 0.7);--quarto-scss-export-valuebox-bg-warning: rgba(255, 117, 24, 0.7);--quarto-scss-export-valuebox-bg-danger: rgba(255, 0, 57, 0.7);--quarto-scss-export-valuebox-bg-light: #ecf0f1;--quarto-scss-export-valuebox-bg-dark: #7b8a8b;--quarto-scss-export-mermaid-bg-color: #fff;--quarto-scss-export-mermaid-edge-color: #6c757d;--quarto-scss-export-mermaid-node-fg-color: #212529;--quarto-scss-export-mermaid-fg-color: #212529;--quarto-scss-export-mermaid-fg-color--lighter: rgb(55.7432432432, 62.5, 69.2567567568);--quarto-scss-export-mermaid-fg-color--lightest: rgb(78.4864864865, 88, 97.5135135135);--quarto-scss-export-mermaid-label-bg-color: #fff;--quarto-scss-export-mermaid-label-fg-color: #2c3e50;--quarto-scss-export-mermaid-node-bg-color: rgba(44, 62, 80, 0.1);--quarto-scss-export-code-block-border-left-color: #dee2e6;--quarto-scss-export-callout-color-note: #2c3e50;--quarto-scss-export-callout-color-tip: #18bc9c;--quarto-scss-export-callout-color-important: #e74c3c;--quarto-scss-export-callout-color-caution: #fd7e14;--quarto-scss-export-callout-color-warning: #f39c12;--quarto-scss-export-label-class-color: rgb(90.4, 25.2, 209.6);--quarto-scss-export-label-method-color: rgb(42.08, 109.68, 156.16);--quarto-scss-export-label-function-color: rgb(120.16, 42.16, 83.2);--quarto-scss-export-label-exception-color: rgb(156.64, 61.04, 54.4);--quarto-scss-export-label-property-color: rgb(29.28, 141.04, 112.64);--quarto-scss-export-label-constant-color: rgb(211.2, 113.2, 32);--quarto-scss-export-label-typealias-color: rgb(203.2, 137.2, 30.4);--quarto-scss-export-label-cli-color: rgb(24.16, 132.72, 115.84);--quarto-scss-export-label-cli-group-color: rgb(24.16, 132.72, 115.84);--quarto-scss-export-label-mcp-tool-color: #e6194B;--quarto-scss-export-label-mcp-resource-color: #3cb44b;--quarto-scss-export-label-mcp-resource-template-color: #f032e6;--quarto-scss-export-label-mcp-prompt-color: #4363d8;--quarto-scss-export-label-mcp-color: rgb(79.84, 54.64, 139.52);--quarto-scss-export-signature-background-color: rgb(241.6288, 242.3344, 243.04);--quarto-scss-export-label-mcp-completions-color: #911eb4;--quarto-scss-export-label-mcp-instructions-color: #f58231} \ No newline at end of file diff --git a/docs/site_libs/bootstrap/bootstrap-icons.css b/docs/site_libs/bootstrap/bootstrap-icons.css new file mode 100644 index 0000000..82b40f5 --- /dev/null +++ b/docs/site_libs/bootstrap/bootstrap-icons.css @@ -0,0 +1,2106 @@ +/*! + * Bootstrap Icons v1.13.1 (https://icons.getbootstrap.com/) + * Copyright 2019-2024 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/icons/blob/main/LICENSE) + */ + +@font-face { + font-display: block; + font-family: "bootstrap-icons"; + src: +url("./bootstrap-icons.woff?e34853135f9e39acf64315236852cd5a") format("woff"); +} + +.bi::before, +[class^="bi-"]::before, +[class*=" bi-"]::before { + display: inline-block; + font-family: bootstrap-icons !important; + font-style: normal; + font-weight: normal !important; + font-variant: normal; + text-transform: none; + line-height: 1; + vertical-align: -.125em; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.bi-123::before { content: "\f67f"; } +.bi-alarm-fill::before { content: "\f101"; } +.bi-alarm::before { content: "\f102"; } +.bi-align-bottom::before { content: "\f103"; } +.bi-align-center::before { content: "\f104"; } +.bi-align-end::before { content: "\f105"; } +.bi-align-middle::before { content: "\f106"; } +.bi-align-start::before { content: "\f107"; } +.bi-align-top::before { content: "\f108"; } +.bi-alt::before { content: "\f109"; } +.bi-app-indicator::before { content: "\f10a"; } +.bi-app::before { content: "\f10b"; } +.bi-archive-fill::before { content: "\f10c"; } +.bi-archive::before { content: "\f10d"; } +.bi-arrow-90deg-down::before { content: "\f10e"; } +.bi-arrow-90deg-left::before { content: "\f10f"; } +.bi-arrow-90deg-right::before { content: "\f110"; } +.bi-arrow-90deg-up::before { content: "\f111"; } +.bi-arrow-bar-down::before { content: "\f112"; } +.bi-arrow-bar-left::before { content: "\f113"; } +.bi-arrow-bar-right::before { content: "\f114"; } +.bi-arrow-bar-up::before { content: "\f115"; } +.bi-arrow-clockwise::before { content: "\f116"; } +.bi-arrow-counterclockwise::before { content: "\f117"; } +.bi-arrow-down-circle-fill::before { content: "\f118"; } +.bi-arrow-down-circle::before { content: "\f119"; } +.bi-arrow-down-left-circle-fill::before { content: "\f11a"; } +.bi-arrow-down-left-circle::before { content: "\f11b"; } +.bi-arrow-down-left-square-fill::before { content: "\f11c"; } +.bi-arrow-down-left-square::before { content: "\f11d"; } +.bi-arrow-down-left::before { content: "\f11e"; } +.bi-arrow-down-right-circle-fill::before { content: "\f11f"; } +.bi-arrow-down-right-circle::before { content: "\f120"; } +.bi-arrow-down-right-square-fill::before { content: "\f121"; } +.bi-arrow-down-right-square::before { content: "\f122"; } +.bi-arrow-down-right::before { content: "\f123"; } +.bi-arrow-down-short::before { content: "\f124"; } +.bi-arrow-down-square-fill::before { content: "\f125"; } +.bi-arrow-down-square::before { content: "\f126"; } +.bi-arrow-down-up::before { content: "\f127"; } +.bi-arrow-down::before { content: "\f128"; } +.bi-arrow-left-circle-fill::before { content: "\f129"; } +.bi-arrow-left-circle::before { content: "\f12a"; } +.bi-arrow-left-right::before { content: "\f12b"; } +.bi-arrow-left-short::before { content: "\f12c"; } +.bi-arrow-left-square-fill::before { content: "\f12d"; } +.bi-arrow-left-square::before { content: "\f12e"; } +.bi-arrow-left::before { content: "\f12f"; } +.bi-arrow-repeat::before { content: "\f130"; } +.bi-arrow-return-left::before { content: "\f131"; } +.bi-arrow-return-right::before { content: "\f132"; } +.bi-arrow-right-circle-fill::before { content: "\f133"; } +.bi-arrow-right-circle::before { content: "\f134"; } +.bi-arrow-right-short::before { content: "\f135"; } +.bi-arrow-right-square-fill::before { content: "\f136"; } +.bi-arrow-right-square::before { content: "\f137"; } +.bi-arrow-right::before { content: "\f138"; } +.bi-arrow-up-circle-fill::before { content: "\f139"; } +.bi-arrow-up-circle::before { content: "\f13a"; } +.bi-arrow-up-left-circle-fill::before { content: "\f13b"; } +.bi-arrow-up-left-circle::before { content: "\f13c"; } +.bi-arrow-up-left-square-fill::before { content: "\f13d"; } +.bi-arrow-up-left-square::before { content: "\f13e"; } +.bi-arrow-up-left::before { content: "\f13f"; } +.bi-arrow-up-right-circle-fill::before { content: "\f140"; } +.bi-arrow-up-right-circle::before { content: "\f141"; } +.bi-arrow-up-right-square-fill::before { content: "\f142"; } +.bi-arrow-up-right-square::before { content: "\f143"; } +.bi-arrow-up-right::before { content: "\f144"; } +.bi-arrow-up-short::before { content: "\f145"; } +.bi-arrow-up-square-fill::before { content: "\f146"; } +.bi-arrow-up-square::before { content: "\f147"; } +.bi-arrow-up::before { content: "\f148"; } +.bi-arrows-angle-contract::before { content: "\f149"; } +.bi-arrows-angle-expand::before { content: "\f14a"; } +.bi-arrows-collapse::before { content: "\f14b"; } +.bi-arrows-expand::before { content: "\f14c"; } +.bi-arrows-fullscreen::before { content: "\f14d"; } +.bi-arrows-move::before { content: "\f14e"; } +.bi-aspect-ratio-fill::before { content: "\f14f"; } +.bi-aspect-ratio::before { content: "\f150"; } +.bi-asterisk::before { content: "\f151"; } +.bi-at::before { content: "\f152"; } +.bi-award-fill::before { content: "\f153"; } +.bi-award::before { content: "\f154"; } +.bi-back::before { content: "\f155"; } +.bi-backspace-fill::before { content: "\f156"; } +.bi-backspace-reverse-fill::before { content: "\f157"; } +.bi-backspace-reverse::before { content: "\f158"; } +.bi-backspace::before { content: "\f159"; } +.bi-badge-3d-fill::before { content: "\f15a"; } +.bi-badge-3d::before { content: "\f15b"; } +.bi-badge-4k-fill::before { content: "\f15c"; } +.bi-badge-4k::before { content: "\f15d"; } +.bi-badge-8k-fill::before { content: "\f15e"; } +.bi-badge-8k::before { content: "\f15f"; } +.bi-badge-ad-fill::before { content: "\f160"; } +.bi-badge-ad::before { content: "\f161"; } +.bi-badge-ar-fill::before { content: "\f162"; } +.bi-badge-ar::before { content: "\f163"; } +.bi-badge-cc-fill::before { content: "\f164"; } +.bi-badge-cc::before { content: "\f165"; } +.bi-badge-hd-fill::before { content: "\f166"; } +.bi-badge-hd::before { content: "\f167"; } +.bi-badge-tm-fill::before { content: "\f168"; } +.bi-badge-tm::before { content: "\f169"; } +.bi-badge-vo-fill::before { content: "\f16a"; } +.bi-badge-vo::before { content: "\f16b"; } +.bi-badge-vr-fill::before { content: "\f16c"; } +.bi-badge-vr::before { content: "\f16d"; } +.bi-badge-wc-fill::before { content: "\f16e"; } +.bi-badge-wc::before { content: "\f16f"; } +.bi-bag-check-fill::before { content: "\f170"; } +.bi-bag-check::before { content: "\f171"; } +.bi-bag-dash-fill::before { content: "\f172"; } +.bi-bag-dash::before { content: "\f173"; } +.bi-bag-fill::before { content: "\f174"; } +.bi-bag-plus-fill::before { content: "\f175"; } +.bi-bag-plus::before { content: "\f176"; } +.bi-bag-x-fill::before { content: "\f177"; } +.bi-bag-x::before { content: "\f178"; } +.bi-bag::before { content: "\f179"; } +.bi-bar-chart-fill::before { content: "\f17a"; } +.bi-bar-chart-line-fill::before { content: "\f17b"; } +.bi-bar-chart-line::before { content: "\f17c"; } +.bi-bar-chart-steps::before { content: "\f17d"; } +.bi-bar-chart::before { content: "\f17e"; } +.bi-basket-fill::before { content: "\f17f"; } +.bi-basket::before { content: "\f180"; } +.bi-basket2-fill::before { content: "\f181"; } +.bi-basket2::before { content: "\f182"; } +.bi-basket3-fill::before { content: "\f183"; } +.bi-basket3::before { content: "\f184"; } +.bi-battery-charging::before { content: "\f185"; } +.bi-battery-full::before { content: "\f186"; } +.bi-battery-half::before { content: "\f187"; } +.bi-battery::before { content: "\f188"; } +.bi-bell-fill::before { content: "\f189"; } +.bi-bell::before { content: "\f18a"; } +.bi-bezier::before { content: "\f18b"; } +.bi-bezier2::before { content: "\f18c"; } +.bi-bicycle::before { content: "\f18d"; } +.bi-binoculars-fill::before { content: "\f18e"; } +.bi-binoculars::before { content: "\f18f"; } +.bi-blockquote-left::before { content: "\f190"; } +.bi-blockquote-right::before { content: "\f191"; } +.bi-book-fill::before { content: "\f192"; } +.bi-book-half::before { content: "\f193"; } +.bi-book::before { content: "\f194"; } +.bi-bookmark-check-fill::before { content: "\f195"; } +.bi-bookmark-check::before { content: "\f196"; } +.bi-bookmark-dash-fill::before { content: "\f197"; } +.bi-bookmark-dash::before { content: "\f198"; } +.bi-bookmark-fill::before { content: "\f199"; } +.bi-bookmark-heart-fill::before { content: "\f19a"; } +.bi-bookmark-heart::before { content: "\f19b"; } +.bi-bookmark-plus-fill::before { content: "\f19c"; } +.bi-bookmark-plus::before { content: "\f19d"; } +.bi-bookmark-star-fill::before { content: "\f19e"; } +.bi-bookmark-star::before { content: "\f19f"; } +.bi-bookmark-x-fill::before { content: "\f1a0"; } +.bi-bookmark-x::before { content: "\f1a1"; } +.bi-bookmark::before { content: "\f1a2"; } +.bi-bookmarks-fill::before { content: "\f1a3"; } +.bi-bookmarks::before { content: "\f1a4"; } +.bi-bookshelf::before { content: "\f1a5"; } +.bi-bootstrap-fill::before { content: "\f1a6"; } +.bi-bootstrap-reboot::before { content: "\f1a7"; } +.bi-bootstrap::before { content: "\f1a8"; } +.bi-border-all::before { content: "\f1a9"; } +.bi-border-bottom::before { content: "\f1aa"; } +.bi-border-center::before { content: "\f1ab"; } +.bi-border-inner::before { content: "\f1ac"; } +.bi-border-left::before { content: "\f1ad"; } +.bi-border-middle::before { content: "\f1ae"; } +.bi-border-outer::before { content: "\f1af"; } +.bi-border-right::before { content: "\f1b0"; } +.bi-border-style::before { content: "\f1b1"; } +.bi-border-top::before { content: "\f1b2"; } +.bi-border-width::before { content: "\f1b3"; } +.bi-border::before { content: "\f1b4"; } +.bi-bounding-box-circles::before { content: "\f1b5"; } +.bi-bounding-box::before { content: "\f1b6"; } +.bi-box-arrow-down-left::before { content: "\f1b7"; } +.bi-box-arrow-down-right::before { content: "\f1b8"; } +.bi-box-arrow-down::before { content: "\f1b9"; } +.bi-box-arrow-in-down-left::before { content: "\f1ba"; } +.bi-box-arrow-in-down-right::before { content: "\f1bb"; } +.bi-box-arrow-in-down::before { content: "\f1bc"; } +.bi-box-arrow-in-left::before { content: "\f1bd"; } +.bi-box-arrow-in-right::before { content: "\f1be"; } +.bi-box-arrow-in-up-left::before { content: "\f1bf"; } +.bi-box-arrow-in-up-right::before { content: "\f1c0"; } +.bi-box-arrow-in-up::before { content: "\f1c1"; } +.bi-box-arrow-left::before { content: "\f1c2"; } +.bi-box-arrow-right::before { content: "\f1c3"; } +.bi-box-arrow-up-left::before { content: "\f1c4"; } +.bi-box-arrow-up-right::before { content: "\f1c5"; } +.bi-box-arrow-up::before { content: "\f1c6"; } +.bi-box-seam::before { content: "\f1c7"; } +.bi-box::before { content: "\f1c8"; } +.bi-braces::before { content: "\f1c9"; } +.bi-bricks::before { content: "\f1ca"; } +.bi-briefcase-fill::before { content: "\f1cb"; } +.bi-briefcase::before { content: "\f1cc"; } +.bi-brightness-alt-high-fill::before { content: "\f1cd"; } +.bi-brightness-alt-high::before { content: "\f1ce"; } +.bi-brightness-alt-low-fill::before { content: "\f1cf"; } +.bi-brightness-alt-low::before { content: "\f1d0"; } +.bi-brightness-high-fill::before { content: "\f1d1"; } +.bi-brightness-high::before { content: "\f1d2"; } +.bi-brightness-low-fill::before { content: "\f1d3"; } +.bi-brightness-low::before { content: "\f1d4"; } +.bi-broadcast-pin::before { content: "\f1d5"; } +.bi-broadcast::before { content: "\f1d6"; } +.bi-brush-fill::before { content: "\f1d7"; } +.bi-brush::before { content: "\f1d8"; } +.bi-bucket-fill::before { content: "\f1d9"; } +.bi-bucket::before { content: "\f1da"; } +.bi-bug-fill::before { content: "\f1db"; } +.bi-bug::before { content: "\f1dc"; } +.bi-building::before { content: "\f1dd"; } +.bi-bullseye::before { content: "\f1de"; } +.bi-calculator-fill::before { content: "\f1df"; } +.bi-calculator::before { content: "\f1e0"; } +.bi-calendar-check-fill::before { content: "\f1e1"; } +.bi-calendar-check::before { content: "\f1e2"; } +.bi-calendar-date-fill::before { content: "\f1e3"; } +.bi-calendar-date::before { content: "\f1e4"; } +.bi-calendar-day-fill::before { content: "\f1e5"; } +.bi-calendar-day::before { content: "\f1e6"; } +.bi-calendar-event-fill::before { content: "\f1e7"; } +.bi-calendar-event::before { content: "\f1e8"; } +.bi-calendar-fill::before { content: "\f1e9"; } +.bi-calendar-minus-fill::before { content: "\f1ea"; } +.bi-calendar-minus::before { content: "\f1eb"; } +.bi-calendar-month-fill::before { content: "\f1ec"; } +.bi-calendar-month::before { content: "\f1ed"; } +.bi-calendar-plus-fill::before { content: "\f1ee"; } +.bi-calendar-plus::before { content: "\f1ef"; } +.bi-calendar-range-fill::before { content: "\f1f0"; } +.bi-calendar-range::before { content: "\f1f1"; } +.bi-calendar-week-fill::before { content: "\f1f2"; } +.bi-calendar-week::before { content: "\f1f3"; } +.bi-calendar-x-fill::before { content: "\f1f4"; } +.bi-calendar-x::before { content: "\f1f5"; } +.bi-calendar::before { content: "\f1f6"; } +.bi-calendar2-check-fill::before { content: "\f1f7"; } +.bi-calendar2-check::before { content: "\f1f8"; } +.bi-calendar2-date-fill::before { content: "\f1f9"; } +.bi-calendar2-date::before { content: "\f1fa"; } +.bi-calendar2-day-fill::before { content: "\f1fb"; } +.bi-calendar2-day::before { content: "\f1fc"; } +.bi-calendar2-event-fill::before { content: "\f1fd"; } +.bi-calendar2-event::before { content: "\f1fe"; } +.bi-calendar2-fill::before { content: "\f1ff"; } +.bi-calendar2-minus-fill::before { content: "\f200"; } +.bi-calendar2-minus::before { content: "\f201"; } +.bi-calendar2-month-fill::before { content: "\f202"; } +.bi-calendar2-month::before { content: "\f203"; } +.bi-calendar2-plus-fill::before { content: "\f204"; } +.bi-calendar2-plus::before { content: "\f205"; } +.bi-calendar2-range-fill::before { content: "\f206"; } +.bi-calendar2-range::before { content: "\f207"; } +.bi-calendar2-week-fill::before { content: "\f208"; } +.bi-calendar2-week::before { content: "\f209"; } +.bi-calendar2-x-fill::before { content: "\f20a"; } +.bi-calendar2-x::before { content: "\f20b"; } +.bi-calendar2::before { content: "\f20c"; } +.bi-calendar3-event-fill::before { content: "\f20d"; } +.bi-calendar3-event::before { content: "\f20e"; } +.bi-calendar3-fill::before { content: "\f20f"; } +.bi-calendar3-range-fill::before { content: "\f210"; } +.bi-calendar3-range::before { content: "\f211"; } +.bi-calendar3-week-fill::before { content: "\f212"; } +.bi-calendar3-week::before { content: "\f213"; } +.bi-calendar3::before { content: "\f214"; } +.bi-calendar4-event::before { content: "\f215"; } +.bi-calendar4-range::before { content: "\f216"; } +.bi-calendar4-week::before { content: "\f217"; } +.bi-calendar4::before { content: "\f218"; } +.bi-camera-fill::before { content: "\f219"; } +.bi-camera-reels-fill::before { content: "\f21a"; } +.bi-camera-reels::before { content: "\f21b"; } +.bi-camera-video-fill::before { content: "\f21c"; } +.bi-camera-video-off-fill::before { content: "\f21d"; } +.bi-camera-video-off::before { content: "\f21e"; } +.bi-camera-video::before { content: "\f21f"; } +.bi-camera::before { content: "\f220"; } +.bi-camera2::before { content: "\f221"; } +.bi-capslock-fill::before { content: "\f222"; } +.bi-capslock::before { content: "\f223"; } +.bi-card-checklist::before { content: "\f224"; } +.bi-card-heading::before { content: "\f225"; } +.bi-card-image::before { content: "\f226"; } +.bi-card-list::before { content: "\f227"; } +.bi-card-text::before { content: "\f228"; } +.bi-caret-down-fill::before { content: "\f229"; } +.bi-caret-down-square-fill::before { content: "\f22a"; } +.bi-caret-down-square::before { content: "\f22b"; } +.bi-caret-down::before { content: "\f22c"; } +.bi-caret-left-fill::before { content: "\f22d"; } +.bi-caret-left-square-fill::before { content: "\f22e"; } +.bi-caret-left-square::before { content: "\f22f"; } +.bi-caret-left::before { content: "\f230"; } +.bi-caret-right-fill::before { content: "\f231"; } +.bi-caret-right-square-fill::before { content: "\f232"; } +.bi-caret-right-square::before { content: "\f233"; } +.bi-caret-right::before { content: "\f234"; } +.bi-caret-up-fill::before { content: "\f235"; } +.bi-caret-up-square-fill::before { content: "\f236"; } +.bi-caret-up-square::before { content: "\f237"; } +.bi-caret-up::before { content: "\f238"; } +.bi-cart-check-fill::before { content: "\f239"; } +.bi-cart-check::before { content: "\f23a"; } +.bi-cart-dash-fill::before { content: "\f23b"; } +.bi-cart-dash::before { content: "\f23c"; } +.bi-cart-fill::before { content: "\f23d"; } +.bi-cart-plus-fill::before { content: "\f23e"; } +.bi-cart-plus::before { content: "\f23f"; } +.bi-cart-x-fill::before { content: "\f240"; } +.bi-cart-x::before { content: "\f241"; } +.bi-cart::before { content: "\f242"; } +.bi-cart2::before { content: "\f243"; } +.bi-cart3::before { content: "\f244"; } +.bi-cart4::before { content: "\f245"; } +.bi-cash-stack::before { content: "\f246"; } +.bi-cash::before { content: "\f247"; } +.bi-cast::before { content: "\f248"; } +.bi-chat-dots-fill::before { content: "\f249"; } +.bi-chat-dots::before { content: "\f24a"; } +.bi-chat-fill::before { content: "\f24b"; } +.bi-chat-left-dots-fill::before { content: "\f24c"; } +.bi-chat-left-dots::before { content: "\f24d"; } +.bi-chat-left-fill::before { content: "\f24e"; } +.bi-chat-left-quote-fill::before { content: "\f24f"; } +.bi-chat-left-quote::before { content: "\f250"; } +.bi-chat-left-text-fill::before { content: "\f251"; } +.bi-chat-left-text::before { content: "\f252"; } +.bi-chat-left::before { content: "\f253"; } +.bi-chat-quote-fill::before { content: "\f254"; } +.bi-chat-quote::before { content: "\f255"; } +.bi-chat-right-dots-fill::before { content: "\f256"; } +.bi-chat-right-dots::before { content: "\f257"; } +.bi-chat-right-fill::before { content: "\f258"; } +.bi-chat-right-quote-fill::before { content: "\f259"; } +.bi-chat-right-quote::before { content: "\f25a"; } +.bi-chat-right-text-fill::before { content: "\f25b"; } +.bi-chat-right-text::before { content: "\f25c"; } +.bi-chat-right::before { content: "\f25d"; } +.bi-chat-square-dots-fill::before { content: "\f25e"; } +.bi-chat-square-dots::before { content: "\f25f"; } +.bi-chat-square-fill::before { content: "\f260"; } +.bi-chat-square-quote-fill::before { content: "\f261"; } +.bi-chat-square-quote::before { content: "\f262"; } +.bi-chat-square-text-fill::before { content: "\f263"; } +.bi-chat-square-text::before { content: "\f264"; } +.bi-chat-square::before { content: "\f265"; } +.bi-chat-text-fill::before { content: "\f266"; } +.bi-chat-text::before { content: "\f267"; } +.bi-chat::before { content: "\f268"; } +.bi-check-all::before { content: "\f269"; } +.bi-check-circle-fill::before { content: "\f26a"; } +.bi-check-circle::before { content: "\f26b"; } +.bi-check-square-fill::before { content: "\f26c"; } +.bi-check-square::before { content: "\f26d"; } +.bi-check::before { content: "\f26e"; } +.bi-check2-all::before { content: "\f26f"; } +.bi-check2-circle::before { content: "\f270"; } +.bi-check2-square::before { content: "\f271"; } +.bi-check2::before { content: "\f272"; } +.bi-chevron-bar-contract::before { content: "\f273"; } +.bi-chevron-bar-down::before { content: "\f274"; } +.bi-chevron-bar-expand::before { content: "\f275"; } +.bi-chevron-bar-left::before { content: "\f276"; } +.bi-chevron-bar-right::before { content: "\f277"; } +.bi-chevron-bar-up::before { content: "\f278"; } +.bi-chevron-compact-down::before { content: "\f279"; } +.bi-chevron-compact-left::before { content: "\f27a"; } +.bi-chevron-compact-right::before { content: "\f27b"; } +.bi-chevron-compact-up::before { content: "\f27c"; } +.bi-chevron-contract::before { content: "\f27d"; } +.bi-chevron-double-down::before { content: "\f27e"; } +.bi-chevron-double-left::before { content: "\f27f"; } +.bi-chevron-double-right::before { content: "\f280"; } +.bi-chevron-double-up::before { content: "\f281"; } +.bi-chevron-down::before { content: "\f282"; } +.bi-chevron-expand::before { content: "\f283"; } +.bi-chevron-left::before { content: "\f284"; } +.bi-chevron-right::before { content: "\f285"; } +.bi-chevron-up::before { content: "\f286"; } +.bi-circle-fill::before { content: "\f287"; } +.bi-circle-half::before { content: "\f288"; } +.bi-circle-square::before { content: "\f289"; } +.bi-circle::before { content: "\f28a"; } +.bi-clipboard-check::before { content: "\f28b"; } +.bi-clipboard-data::before { content: "\f28c"; } +.bi-clipboard-minus::before { content: "\f28d"; } +.bi-clipboard-plus::before { content: "\f28e"; } +.bi-clipboard-x::before { content: "\f28f"; } +.bi-clipboard::before { content: "\f290"; } +.bi-clock-fill::before { content: "\f291"; } +.bi-clock-history::before { content: "\f292"; } +.bi-clock::before { content: "\f293"; } +.bi-cloud-arrow-down-fill::before { content: "\f294"; } +.bi-cloud-arrow-down::before { content: "\f295"; } +.bi-cloud-arrow-up-fill::before { content: "\f296"; } +.bi-cloud-arrow-up::before { content: "\f297"; } +.bi-cloud-check-fill::before { content: "\f298"; } +.bi-cloud-check::before { content: "\f299"; } +.bi-cloud-download-fill::before { content: "\f29a"; } +.bi-cloud-download::before { content: "\f29b"; } +.bi-cloud-drizzle-fill::before { content: "\f29c"; } +.bi-cloud-drizzle::before { content: "\f29d"; } +.bi-cloud-fill::before { content: "\f29e"; } +.bi-cloud-fog-fill::before { content: "\f29f"; } +.bi-cloud-fog::before { content: "\f2a0"; } +.bi-cloud-fog2-fill::before { content: "\f2a1"; } +.bi-cloud-fog2::before { content: "\f2a2"; } +.bi-cloud-hail-fill::before { content: "\f2a3"; } +.bi-cloud-hail::before { content: "\f2a4"; } +.bi-cloud-haze-fill::before { content: "\f2a6"; } +.bi-cloud-haze::before { content: "\f2a7"; } +.bi-cloud-haze2-fill::before { content: "\f2a8"; } +.bi-cloud-lightning-fill::before { content: "\f2a9"; } +.bi-cloud-lightning-rain-fill::before { content: "\f2aa"; } +.bi-cloud-lightning-rain::before { content: "\f2ab"; } +.bi-cloud-lightning::before { content: "\f2ac"; } +.bi-cloud-minus-fill::before { content: "\f2ad"; } +.bi-cloud-minus::before { content: "\f2ae"; } +.bi-cloud-moon-fill::before { content: "\f2af"; } +.bi-cloud-moon::before { content: "\f2b0"; } +.bi-cloud-plus-fill::before { content: "\f2b1"; } +.bi-cloud-plus::before { content: "\f2b2"; } +.bi-cloud-rain-fill::before { content: "\f2b3"; } +.bi-cloud-rain-heavy-fill::before { content: "\f2b4"; } +.bi-cloud-rain-heavy::before { content: "\f2b5"; } +.bi-cloud-rain::before { content: "\f2b6"; } +.bi-cloud-slash-fill::before { content: "\f2b7"; } +.bi-cloud-slash::before { content: "\f2b8"; } +.bi-cloud-sleet-fill::before { content: "\f2b9"; } +.bi-cloud-sleet::before { content: "\f2ba"; } +.bi-cloud-snow-fill::before { content: "\f2bb"; } +.bi-cloud-snow::before { content: "\f2bc"; } +.bi-cloud-sun-fill::before { content: "\f2bd"; } +.bi-cloud-sun::before { content: "\f2be"; } +.bi-cloud-upload-fill::before { content: "\f2bf"; } +.bi-cloud-upload::before { content: "\f2c0"; } +.bi-cloud::before { content: "\f2c1"; } +.bi-clouds-fill::before { content: "\f2c2"; } +.bi-clouds::before { content: "\f2c3"; } +.bi-cloudy-fill::before { content: "\f2c4"; } +.bi-cloudy::before { content: "\f2c5"; } +.bi-code-slash::before { content: "\f2c6"; } +.bi-code-square::before { content: "\f2c7"; } +.bi-code::before { content: "\f2c8"; } +.bi-collection-fill::before { content: "\f2c9"; } +.bi-collection-play-fill::before { content: "\f2ca"; } +.bi-collection-play::before { content: "\f2cb"; } +.bi-collection::before { content: "\f2cc"; } +.bi-columns-gap::before { content: "\f2cd"; } +.bi-columns::before { content: "\f2ce"; } +.bi-command::before { content: "\f2cf"; } +.bi-compass-fill::before { content: "\f2d0"; } +.bi-compass::before { content: "\f2d1"; } +.bi-cone-striped::before { content: "\f2d2"; } +.bi-cone::before { content: "\f2d3"; } +.bi-controller::before { content: "\f2d4"; } +.bi-cpu-fill::before { content: "\f2d5"; } +.bi-cpu::before { content: "\f2d6"; } +.bi-credit-card-2-back-fill::before { content: "\f2d7"; } +.bi-credit-card-2-back::before { content: "\f2d8"; } +.bi-credit-card-2-front-fill::before { content: "\f2d9"; } +.bi-credit-card-2-front::before { content: "\f2da"; } +.bi-credit-card-fill::before { content: "\f2db"; } +.bi-credit-card::before { content: "\f2dc"; } +.bi-crop::before { content: "\f2dd"; } +.bi-cup-fill::before { content: "\f2de"; } +.bi-cup-straw::before { content: "\f2df"; } +.bi-cup::before { content: "\f2e0"; } +.bi-cursor-fill::before { content: "\f2e1"; } +.bi-cursor-text::before { content: "\f2e2"; } +.bi-cursor::before { content: "\f2e3"; } +.bi-dash-circle-dotted::before { content: "\f2e4"; } +.bi-dash-circle-fill::before { content: "\f2e5"; } +.bi-dash-circle::before { content: "\f2e6"; } +.bi-dash-square-dotted::before { content: "\f2e7"; } +.bi-dash-square-fill::before { content: "\f2e8"; } +.bi-dash-square::before { content: "\f2e9"; } +.bi-dash::before { content: "\f2ea"; } +.bi-diagram-2-fill::before { content: "\f2eb"; } +.bi-diagram-2::before { content: "\f2ec"; } +.bi-diagram-3-fill::before { content: "\f2ed"; } +.bi-diagram-3::before { content: "\f2ee"; } +.bi-diamond-fill::before { content: "\f2ef"; } +.bi-diamond-half::before { content: "\f2f0"; } +.bi-diamond::before { content: "\f2f1"; } +.bi-dice-1-fill::before { content: "\f2f2"; } +.bi-dice-1::before { content: "\f2f3"; } +.bi-dice-2-fill::before { content: "\f2f4"; } +.bi-dice-2::before { content: "\f2f5"; } +.bi-dice-3-fill::before { content: "\f2f6"; } +.bi-dice-3::before { content: "\f2f7"; } +.bi-dice-4-fill::before { content: "\f2f8"; } +.bi-dice-4::before { content: "\f2f9"; } +.bi-dice-5-fill::before { content: "\f2fa"; } +.bi-dice-5::before { content: "\f2fb"; } +.bi-dice-6-fill::before { content: "\f2fc"; } +.bi-dice-6::before { content: "\f2fd"; } +.bi-disc-fill::before { content: "\f2fe"; } +.bi-disc::before { content: "\f2ff"; } +.bi-discord::before { content: "\f300"; } +.bi-display-fill::before { content: "\f301"; } +.bi-display::before { content: "\f302"; } +.bi-distribute-horizontal::before { content: "\f303"; } +.bi-distribute-vertical::before { content: "\f304"; } +.bi-door-closed-fill::before { content: "\f305"; } +.bi-door-closed::before { content: "\f306"; } +.bi-door-open-fill::before { content: "\f307"; } +.bi-door-open::before { content: "\f308"; } +.bi-dot::before { content: "\f309"; } +.bi-download::before { content: "\f30a"; } +.bi-droplet-fill::before { content: "\f30b"; } +.bi-droplet-half::before { content: "\f30c"; } +.bi-droplet::before { content: "\f30d"; } +.bi-earbuds::before { content: "\f30e"; } +.bi-easel-fill::before { content: "\f30f"; } +.bi-easel::before { content: "\f310"; } +.bi-egg-fill::before { content: "\f311"; } +.bi-egg-fried::before { content: "\f312"; } +.bi-egg::before { content: "\f313"; } +.bi-eject-fill::before { content: "\f314"; } +.bi-eject::before { content: "\f315"; } +.bi-emoji-angry-fill::before { content: "\f316"; } +.bi-emoji-angry::before { content: "\f317"; } +.bi-emoji-dizzy-fill::before { content: "\f318"; } +.bi-emoji-dizzy::before { content: "\f319"; } +.bi-emoji-expressionless-fill::before { content: "\f31a"; } +.bi-emoji-expressionless::before { content: "\f31b"; } +.bi-emoji-frown-fill::before { content: "\f31c"; } +.bi-emoji-frown::before { content: "\f31d"; } +.bi-emoji-heart-eyes-fill::before { content: "\f31e"; } +.bi-emoji-heart-eyes::before { content: "\f31f"; } +.bi-emoji-laughing-fill::before { content: "\f320"; } +.bi-emoji-laughing::before { content: "\f321"; } +.bi-emoji-neutral-fill::before { content: "\f322"; } +.bi-emoji-neutral::before { content: "\f323"; } +.bi-emoji-smile-fill::before { content: "\f324"; } +.bi-emoji-smile-upside-down-fill::before { content: "\f325"; } +.bi-emoji-smile-upside-down::before { content: "\f326"; } +.bi-emoji-smile::before { content: "\f327"; } +.bi-emoji-sunglasses-fill::before { content: "\f328"; } +.bi-emoji-sunglasses::before { content: "\f329"; } +.bi-emoji-wink-fill::before { content: "\f32a"; } +.bi-emoji-wink::before { content: "\f32b"; } +.bi-envelope-fill::before { content: "\f32c"; } +.bi-envelope-open-fill::before { content: "\f32d"; } +.bi-envelope-open::before { content: "\f32e"; } +.bi-envelope::before { content: "\f32f"; } +.bi-eraser-fill::before { content: "\f330"; } +.bi-eraser::before { content: "\f331"; } +.bi-exclamation-circle-fill::before { content: "\f332"; } +.bi-exclamation-circle::before { content: "\f333"; } +.bi-exclamation-diamond-fill::before { content: "\f334"; } +.bi-exclamation-diamond::before { content: "\f335"; } +.bi-exclamation-octagon-fill::before { content: "\f336"; } +.bi-exclamation-octagon::before { content: "\f337"; } +.bi-exclamation-square-fill::before { content: "\f338"; } +.bi-exclamation-square::before { content: "\f339"; } +.bi-exclamation-triangle-fill::before { content: "\f33a"; } +.bi-exclamation-triangle::before { content: "\f33b"; } +.bi-exclamation::before { content: "\f33c"; } +.bi-exclude::before { content: "\f33d"; } +.bi-eye-fill::before { content: "\f33e"; } +.bi-eye-slash-fill::before { content: "\f33f"; } +.bi-eye-slash::before { content: "\f340"; } +.bi-eye::before { content: "\f341"; } +.bi-eyedropper::before { content: "\f342"; } +.bi-eyeglasses::before { content: "\f343"; } +.bi-facebook::before { content: "\f344"; } +.bi-file-arrow-down-fill::before { content: "\f345"; } +.bi-file-arrow-down::before { content: "\f346"; } +.bi-file-arrow-up-fill::before { content: "\f347"; } +.bi-file-arrow-up::before { content: "\f348"; } +.bi-file-bar-graph-fill::before { content: "\f349"; } +.bi-file-bar-graph::before { content: "\f34a"; } +.bi-file-binary-fill::before { content: "\f34b"; } +.bi-file-binary::before { content: "\f34c"; } +.bi-file-break-fill::before { content: "\f34d"; } +.bi-file-break::before { content: "\f34e"; } +.bi-file-check-fill::before { content: "\f34f"; } +.bi-file-check::before { content: "\f350"; } +.bi-file-code-fill::before { content: "\f351"; } +.bi-file-code::before { content: "\f352"; } +.bi-file-diff-fill::before { content: "\f353"; } +.bi-file-diff::before { content: "\f354"; } +.bi-file-earmark-arrow-down-fill::before { content: "\f355"; } +.bi-file-earmark-arrow-down::before { content: "\f356"; } +.bi-file-earmark-arrow-up-fill::before { content: "\f357"; } +.bi-file-earmark-arrow-up::before { content: "\f358"; } +.bi-file-earmark-bar-graph-fill::before { content: "\f359"; } +.bi-file-earmark-bar-graph::before { content: "\f35a"; } +.bi-file-earmark-binary-fill::before { content: "\f35b"; } +.bi-file-earmark-binary::before { content: "\f35c"; } +.bi-file-earmark-break-fill::before { content: "\f35d"; } +.bi-file-earmark-break::before { content: "\f35e"; } +.bi-file-earmark-check-fill::before { content: "\f35f"; } +.bi-file-earmark-check::before { content: "\f360"; } +.bi-file-earmark-code-fill::before { content: "\f361"; } +.bi-file-earmark-code::before { content: "\f362"; } +.bi-file-earmark-diff-fill::before { content: "\f363"; } +.bi-file-earmark-diff::before { content: "\f364"; } +.bi-file-earmark-easel-fill::before { content: "\f365"; } +.bi-file-earmark-easel::before { content: "\f366"; } +.bi-file-earmark-excel-fill::before { content: "\f367"; } +.bi-file-earmark-excel::before { content: "\f368"; } +.bi-file-earmark-fill::before { content: "\f369"; } +.bi-file-earmark-font-fill::before { content: "\f36a"; } +.bi-file-earmark-font::before { content: "\f36b"; } +.bi-file-earmark-image-fill::before { content: "\f36c"; } +.bi-file-earmark-image::before { content: "\f36d"; } +.bi-file-earmark-lock-fill::before { content: "\f36e"; } +.bi-file-earmark-lock::before { content: "\f36f"; } +.bi-file-earmark-lock2-fill::before { content: "\f370"; } +.bi-file-earmark-lock2::before { content: "\f371"; } +.bi-file-earmark-medical-fill::before { content: "\f372"; } +.bi-file-earmark-medical::before { content: "\f373"; } +.bi-file-earmark-minus-fill::before { content: "\f374"; } +.bi-file-earmark-minus::before { content: "\f375"; } +.bi-file-earmark-music-fill::before { content: "\f376"; } +.bi-file-earmark-music::before { content: "\f377"; } +.bi-file-earmark-person-fill::before { content: "\f378"; } +.bi-file-earmark-person::before { content: "\f379"; } +.bi-file-earmark-play-fill::before { content: "\f37a"; } +.bi-file-earmark-play::before { content: "\f37b"; } +.bi-file-earmark-plus-fill::before { content: "\f37c"; } +.bi-file-earmark-plus::before { content: "\f37d"; } +.bi-file-earmark-post-fill::before { content: "\f37e"; } +.bi-file-earmark-post::before { content: "\f37f"; } +.bi-file-earmark-ppt-fill::before { content: "\f380"; } +.bi-file-earmark-ppt::before { content: "\f381"; } +.bi-file-earmark-richtext-fill::before { content: "\f382"; } +.bi-file-earmark-richtext::before { content: "\f383"; } +.bi-file-earmark-ruled-fill::before { content: "\f384"; } +.bi-file-earmark-ruled::before { content: "\f385"; } +.bi-file-earmark-slides-fill::before { content: "\f386"; } +.bi-file-earmark-slides::before { content: "\f387"; } +.bi-file-earmark-spreadsheet-fill::before { content: "\f388"; } +.bi-file-earmark-spreadsheet::before { content: "\f389"; } +.bi-file-earmark-text-fill::before { content: "\f38a"; } +.bi-file-earmark-text::before { content: "\f38b"; } +.bi-file-earmark-word-fill::before { content: "\f38c"; } +.bi-file-earmark-word::before { content: "\f38d"; } +.bi-file-earmark-x-fill::before { content: "\f38e"; } +.bi-file-earmark-x::before { content: "\f38f"; } +.bi-file-earmark-zip-fill::before { content: "\f390"; } +.bi-file-earmark-zip::before { content: "\f391"; } +.bi-file-earmark::before { content: "\f392"; } +.bi-file-easel-fill::before { content: "\f393"; } +.bi-file-easel::before { content: "\f394"; } +.bi-file-excel-fill::before { content: "\f395"; } +.bi-file-excel::before { content: "\f396"; } +.bi-file-fill::before { content: "\f397"; } +.bi-file-font-fill::before { content: "\f398"; } +.bi-file-font::before { content: "\f399"; } +.bi-file-image-fill::before { content: "\f39a"; } +.bi-file-image::before { content: "\f39b"; } +.bi-file-lock-fill::before { content: "\f39c"; } +.bi-file-lock::before { content: "\f39d"; } +.bi-file-lock2-fill::before { content: "\f39e"; } +.bi-file-lock2::before { content: "\f39f"; } +.bi-file-medical-fill::before { content: "\f3a0"; } +.bi-file-medical::before { content: "\f3a1"; } +.bi-file-minus-fill::before { content: "\f3a2"; } +.bi-file-minus::before { content: "\f3a3"; } +.bi-file-music-fill::before { content: "\f3a4"; } +.bi-file-music::before { content: "\f3a5"; } +.bi-file-person-fill::before { content: "\f3a6"; } +.bi-file-person::before { content: "\f3a7"; } +.bi-file-play-fill::before { content: "\f3a8"; } +.bi-file-play::before { content: "\f3a9"; } +.bi-file-plus-fill::before { content: "\f3aa"; } +.bi-file-plus::before { content: "\f3ab"; } +.bi-file-post-fill::before { content: "\f3ac"; } +.bi-file-post::before { content: "\f3ad"; } +.bi-file-ppt-fill::before { content: "\f3ae"; } +.bi-file-ppt::before { content: "\f3af"; } +.bi-file-richtext-fill::before { content: "\f3b0"; } +.bi-file-richtext::before { content: "\f3b1"; } +.bi-file-ruled-fill::before { content: "\f3b2"; } +.bi-file-ruled::before { content: "\f3b3"; } +.bi-file-slides-fill::before { content: "\f3b4"; } +.bi-file-slides::before { content: "\f3b5"; } +.bi-file-spreadsheet-fill::before { content: "\f3b6"; } +.bi-file-spreadsheet::before { content: "\f3b7"; } +.bi-file-text-fill::before { content: "\f3b8"; } +.bi-file-text::before { content: "\f3b9"; } +.bi-file-word-fill::before { content: "\f3ba"; } +.bi-file-word::before { content: "\f3bb"; } +.bi-file-x-fill::before { content: "\f3bc"; } +.bi-file-x::before { content: "\f3bd"; } +.bi-file-zip-fill::before { content: "\f3be"; } +.bi-file-zip::before { content: "\f3bf"; } +.bi-file::before { content: "\f3c0"; } +.bi-files-alt::before { content: "\f3c1"; } +.bi-files::before { content: "\f3c2"; } +.bi-film::before { content: "\f3c3"; } +.bi-filter-circle-fill::before { content: "\f3c4"; } +.bi-filter-circle::before { content: "\f3c5"; } +.bi-filter-left::before { content: "\f3c6"; } +.bi-filter-right::before { content: "\f3c7"; } +.bi-filter-square-fill::before { content: "\f3c8"; } +.bi-filter-square::before { content: "\f3c9"; } +.bi-filter::before { content: "\f3ca"; } +.bi-flag-fill::before { content: "\f3cb"; } +.bi-flag::before { content: "\f3cc"; } +.bi-flower1::before { content: "\f3cd"; } +.bi-flower2::before { content: "\f3ce"; } +.bi-flower3::before { content: "\f3cf"; } +.bi-folder-check::before { content: "\f3d0"; } +.bi-folder-fill::before { content: "\f3d1"; } +.bi-folder-minus::before { content: "\f3d2"; } +.bi-folder-plus::before { content: "\f3d3"; } +.bi-folder-symlink-fill::before { content: "\f3d4"; } +.bi-folder-symlink::before { content: "\f3d5"; } +.bi-folder-x::before { content: "\f3d6"; } +.bi-folder::before { content: "\f3d7"; } +.bi-folder2-open::before { content: "\f3d8"; } +.bi-folder2::before { content: "\f3d9"; } +.bi-fonts::before { content: "\f3da"; } +.bi-forward-fill::before { content: "\f3db"; } +.bi-forward::before { content: "\f3dc"; } +.bi-front::before { content: "\f3dd"; } +.bi-fullscreen-exit::before { content: "\f3de"; } +.bi-fullscreen::before { content: "\f3df"; } +.bi-funnel-fill::before { content: "\f3e0"; } +.bi-funnel::before { content: "\f3e1"; } +.bi-gear-fill::before { content: "\f3e2"; } +.bi-gear-wide-connected::before { content: "\f3e3"; } +.bi-gear-wide::before { content: "\f3e4"; } +.bi-gear::before { content: "\f3e5"; } +.bi-gem::before { content: "\f3e6"; } +.bi-geo-alt-fill::before { content: "\f3e7"; } +.bi-geo-alt::before { content: "\f3e8"; } +.bi-geo-fill::before { content: "\f3e9"; } +.bi-geo::before { content: "\f3ea"; } +.bi-gift-fill::before { content: "\f3eb"; } +.bi-gift::before { content: "\f3ec"; } +.bi-github::before { content: "\f3ed"; } +.bi-globe::before { content: "\f3ee"; } +.bi-globe2::before { content: "\f3ef"; } +.bi-google::before { content: "\f3f0"; } +.bi-graph-down::before { content: "\f3f1"; } +.bi-graph-up::before { content: "\f3f2"; } +.bi-grid-1x2-fill::before { content: "\f3f3"; } +.bi-grid-1x2::before { content: "\f3f4"; } +.bi-grid-3x2-gap-fill::before { content: "\f3f5"; } +.bi-grid-3x2-gap::before { content: "\f3f6"; } +.bi-grid-3x2::before { content: "\f3f7"; } +.bi-grid-3x3-gap-fill::before { content: "\f3f8"; } +.bi-grid-3x3-gap::before { content: "\f3f9"; } +.bi-grid-3x3::before { content: "\f3fa"; } +.bi-grid-fill::before { content: "\f3fb"; } +.bi-grid::before { content: "\f3fc"; } +.bi-grip-horizontal::before { content: "\f3fd"; } +.bi-grip-vertical::before { content: "\f3fe"; } +.bi-hammer::before { content: "\f3ff"; } +.bi-hand-index-fill::before { content: "\f400"; } +.bi-hand-index-thumb-fill::before { content: "\f401"; } +.bi-hand-index-thumb::before { content: "\f402"; } +.bi-hand-index::before { content: "\f403"; } +.bi-hand-thumbs-down-fill::before { content: "\f404"; } +.bi-hand-thumbs-down::before { content: "\f405"; } +.bi-hand-thumbs-up-fill::before { content: "\f406"; } +.bi-hand-thumbs-up::before { content: "\f407"; } +.bi-handbag-fill::before { content: "\f408"; } +.bi-handbag::before { content: "\f409"; } +.bi-hash::before { content: "\f40a"; } +.bi-hdd-fill::before { content: "\f40b"; } +.bi-hdd-network-fill::before { content: "\f40c"; } +.bi-hdd-network::before { content: "\f40d"; } +.bi-hdd-rack-fill::before { content: "\f40e"; } +.bi-hdd-rack::before { content: "\f40f"; } +.bi-hdd-stack-fill::before { content: "\f410"; } +.bi-hdd-stack::before { content: "\f411"; } +.bi-hdd::before { content: "\f412"; } +.bi-headphones::before { content: "\f413"; } +.bi-headset::before { content: "\f414"; } +.bi-heart-fill::before { content: "\f415"; } +.bi-heart-half::before { content: "\f416"; } +.bi-heart::before { content: "\f417"; } +.bi-heptagon-fill::before { content: "\f418"; } +.bi-heptagon-half::before { content: "\f419"; } +.bi-heptagon::before { content: "\f41a"; } +.bi-hexagon-fill::before { content: "\f41b"; } +.bi-hexagon-half::before { content: "\f41c"; } +.bi-hexagon::before { content: "\f41d"; } +.bi-hourglass-bottom::before { content: "\f41e"; } +.bi-hourglass-split::before { content: "\f41f"; } +.bi-hourglass-top::before { content: "\f420"; } +.bi-hourglass::before { content: "\f421"; } +.bi-house-door-fill::before { content: "\f422"; } +.bi-house-door::before { content: "\f423"; } +.bi-house-fill::before { content: "\f424"; } +.bi-house::before { content: "\f425"; } +.bi-hr::before { content: "\f426"; } +.bi-hurricane::before { content: "\f427"; } +.bi-image-alt::before { content: "\f428"; } +.bi-image-fill::before { content: "\f429"; } +.bi-image::before { content: "\f42a"; } +.bi-images::before { content: "\f42b"; } +.bi-inbox-fill::before { content: "\f42c"; } +.bi-inbox::before { content: "\f42d"; } +.bi-inboxes-fill::before { content: "\f42e"; } +.bi-inboxes::before { content: "\f42f"; } +.bi-info-circle-fill::before { content: "\f430"; } +.bi-info-circle::before { content: "\f431"; } +.bi-info-square-fill::before { content: "\f432"; } +.bi-info-square::before { content: "\f433"; } +.bi-info::before { content: "\f434"; } +.bi-input-cursor-text::before { content: "\f435"; } +.bi-input-cursor::before { content: "\f436"; } +.bi-instagram::before { content: "\f437"; } +.bi-intersect::before { content: "\f438"; } +.bi-journal-album::before { content: "\f439"; } +.bi-journal-arrow-down::before { content: "\f43a"; } +.bi-journal-arrow-up::before { content: "\f43b"; } +.bi-journal-bookmark-fill::before { content: "\f43c"; } +.bi-journal-bookmark::before { content: "\f43d"; } +.bi-journal-check::before { content: "\f43e"; } +.bi-journal-code::before { content: "\f43f"; } +.bi-journal-medical::before { content: "\f440"; } +.bi-journal-minus::before { content: "\f441"; } +.bi-journal-plus::before { content: "\f442"; } +.bi-journal-richtext::before { content: "\f443"; } +.bi-journal-text::before { content: "\f444"; } +.bi-journal-x::before { content: "\f445"; } +.bi-journal::before { content: "\f446"; } +.bi-journals::before { content: "\f447"; } +.bi-joystick::before { content: "\f448"; } +.bi-justify-left::before { content: "\f449"; } +.bi-justify-right::before { content: "\f44a"; } +.bi-justify::before { content: "\f44b"; } +.bi-kanban-fill::before { content: "\f44c"; } +.bi-kanban::before { content: "\f44d"; } +.bi-key-fill::before { content: "\f44e"; } +.bi-key::before { content: "\f44f"; } +.bi-keyboard-fill::before { content: "\f450"; } +.bi-keyboard::before { content: "\f451"; } +.bi-ladder::before { content: "\f452"; } +.bi-lamp-fill::before { content: "\f453"; } +.bi-lamp::before { content: "\f454"; } +.bi-laptop-fill::before { content: "\f455"; } +.bi-laptop::before { content: "\f456"; } +.bi-layer-backward::before { content: "\f457"; } +.bi-layer-forward::before { content: "\f458"; } +.bi-layers-fill::before { content: "\f459"; } +.bi-layers-half::before { content: "\f45a"; } +.bi-layers::before { content: "\f45b"; } +.bi-layout-sidebar-inset-reverse::before { content: "\f45c"; } +.bi-layout-sidebar-inset::before { content: "\f45d"; } +.bi-layout-sidebar-reverse::before { content: "\f45e"; } +.bi-layout-sidebar::before { content: "\f45f"; } +.bi-layout-split::before { content: "\f460"; } +.bi-layout-text-sidebar-reverse::before { content: "\f461"; } +.bi-layout-text-sidebar::before { content: "\f462"; } +.bi-layout-text-window-reverse::before { content: "\f463"; } +.bi-layout-text-window::before { content: "\f464"; } +.bi-layout-three-columns::before { content: "\f465"; } +.bi-layout-wtf::before { content: "\f466"; } +.bi-life-preserver::before { content: "\f467"; } +.bi-lightbulb-fill::before { content: "\f468"; } +.bi-lightbulb-off-fill::before { content: "\f469"; } +.bi-lightbulb-off::before { content: "\f46a"; } +.bi-lightbulb::before { content: "\f46b"; } +.bi-lightning-charge-fill::before { content: "\f46c"; } +.bi-lightning-charge::before { content: "\f46d"; } +.bi-lightning-fill::before { content: "\f46e"; } +.bi-lightning::before { content: "\f46f"; } +.bi-link-45deg::before { content: "\f470"; } +.bi-link::before { content: "\f471"; } +.bi-linkedin::before { content: "\f472"; } +.bi-list-check::before { content: "\f473"; } +.bi-list-nested::before { content: "\f474"; } +.bi-list-ol::before { content: "\f475"; } +.bi-list-stars::before { content: "\f476"; } +.bi-list-task::before { content: "\f477"; } +.bi-list-ul::before { content: "\f478"; } +.bi-list::before { content: "\f479"; } +.bi-lock-fill::before { content: "\f47a"; } +.bi-lock::before { content: "\f47b"; } +.bi-mailbox::before { content: "\f47c"; } +.bi-mailbox2::before { content: "\f47d"; } +.bi-map-fill::before { content: "\f47e"; } +.bi-map::before { content: "\f47f"; } +.bi-markdown-fill::before { content: "\f480"; } +.bi-markdown::before { content: "\f481"; } +.bi-mask::before { content: "\f482"; } +.bi-megaphone-fill::before { content: "\f483"; } +.bi-megaphone::before { content: "\f484"; } +.bi-menu-app-fill::before { content: "\f485"; } +.bi-menu-app::before { content: "\f486"; } +.bi-menu-button-fill::before { content: "\f487"; } +.bi-menu-button-wide-fill::before { content: "\f488"; } +.bi-menu-button-wide::before { content: "\f489"; } +.bi-menu-button::before { content: "\f48a"; } +.bi-menu-down::before { content: "\f48b"; } +.bi-menu-up::before { content: "\f48c"; } +.bi-mic-fill::before { content: "\f48d"; } +.bi-mic-mute-fill::before { content: "\f48e"; } +.bi-mic-mute::before { content: "\f48f"; } +.bi-mic::before { content: "\f490"; } +.bi-minecart-loaded::before { content: "\f491"; } +.bi-minecart::before { content: "\f492"; } +.bi-moisture::before { content: "\f493"; } +.bi-moon-fill::before { content: "\f494"; } +.bi-moon-stars-fill::before { content: "\f495"; } +.bi-moon-stars::before { content: "\f496"; } +.bi-moon::before { content: "\f497"; } +.bi-mouse-fill::before { content: "\f498"; } +.bi-mouse::before { content: "\f499"; } +.bi-mouse2-fill::before { content: "\f49a"; } +.bi-mouse2::before { content: "\f49b"; } +.bi-mouse3-fill::before { content: "\f49c"; } +.bi-mouse3::before { content: "\f49d"; } +.bi-music-note-beamed::before { content: "\f49e"; } +.bi-music-note-list::before { content: "\f49f"; } +.bi-music-note::before { content: "\f4a0"; } +.bi-music-player-fill::before { content: "\f4a1"; } +.bi-music-player::before { content: "\f4a2"; } +.bi-newspaper::before { content: "\f4a3"; } +.bi-node-minus-fill::before { content: "\f4a4"; } +.bi-node-minus::before { content: "\f4a5"; } +.bi-node-plus-fill::before { content: "\f4a6"; } +.bi-node-plus::before { content: "\f4a7"; } +.bi-nut-fill::before { content: "\f4a8"; } +.bi-nut::before { content: "\f4a9"; } +.bi-octagon-fill::before { content: "\f4aa"; } +.bi-octagon-half::before { content: "\f4ab"; } +.bi-octagon::before { content: "\f4ac"; } +.bi-option::before { content: "\f4ad"; } +.bi-outlet::before { content: "\f4ae"; } +.bi-paint-bucket::before { content: "\f4af"; } +.bi-palette-fill::before { content: "\f4b0"; } +.bi-palette::before { content: "\f4b1"; } +.bi-palette2::before { content: "\f4b2"; } +.bi-paperclip::before { content: "\f4b3"; } +.bi-paragraph::before { content: "\f4b4"; } +.bi-patch-check-fill::before { content: "\f4b5"; } +.bi-patch-check::before { content: "\f4b6"; } +.bi-patch-exclamation-fill::before { content: "\f4b7"; } +.bi-patch-exclamation::before { content: "\f4b8"; } +.bi-patch-minus-fill::before { content: "\f4b9"; } +.bi-patch-minus::before { content: "\f4ba"; } +.bi-patch-plus-fill::before { content: "\f4bb"; } +.bi-patch-plus::before { content: "\f4bc"; } +.bi-patch-question-fill::before { content: "\f4bd"; } +.bi-patch-question::before { content: "\f4be"; } +.bi-pause-btn-fill::before { content: "\f4bf"; } +.bi-pause-btn::before { content: "\f4c0"; } +.bi-pause-circle-fill::before { content: "\f4c1"; } +.bi-pause-circle::before { content: "\f4c2"; } +.bi-pause-fill::before { content: "\f4c3"; } +.bi-pause::before { content: "\f4c4"; } +.bi-peace-fill::before { content: "\f4c5"; } +.bi-peace::before { content: "\f4c6"; } +.bi-pen-fill::before { content: "\f4c7"; } +.bi-pen::before { content: "\f4c8"; } +.bi-pencil-fill::before { content: "\f4c9"; } +.bi-pencil-square::before { content: "\f4ca"; } +.bi-pencil::before { content: "\f4cb"; } +.bi-pentagon-fill::before { content: "\f4cc"; } +.bi-pentagon-half::before { content: "\f4cd"; } +.bi-pentagon::before { content: "\f4ce"; } +.bi-people-fill::before { content: "\f4cf"; } +.bi-people::before { content: "\f4d0"; } +.bi-percent::before { content: "\f4d1"; } +.bi-person-badge-fill::before { content: "\f4d2"; } +.bi-person-badge::before { content: "\f4d3"; } +.bi-person-bounding-box::before { content: "\f4d4"; } +.bi-person-check-fill::before { content: "\f4d5"; } +.bi-person-check::before { content: "\f4d6"; } +.bi-person-circle::before { content: "\f4d7"; } +.bi-person-dash-fill::before { content: "\f4d8"; } +.bi-person-dash::before { content: "\f4d9"; } +.bi-person-fill::before { content: "\f4da"; } +.bi-person-lines-fill::before { content: "\f4db"; } +.bi-person-plus-fill::before { content: "\f4dc"; } +.bi-person-plus::before { content: "\f4dd"; } +.bi-person-square::before { content: "\f4de"; } +.bi-person-x-fill::before { content: "\f4df"; } +.bi-person-x::before { content: "\f4e0"; } +.bi-person::before { content: "\f4e1"; } +.bi-phone-fill::before { content: "\f4e2"; } +.bi-phone-landscape-fill::before { content: "\f4e3"; } +.bi-phone-landscape::before { content: "\f4e4"; } +.bi-phone-vibrate-fill::before { content: "\f4e5"; } +.bi-phone-vibrate::before { content: "\f4e6"; } +.bi-phone::before { content: "\f4e7"; } +.bi-pie-chart-fill::before { content: "\f4e8"; } +.bi-pie-chart::before { content: "\f4e9"; } +.bi-pin-angle-fill::before { content: "\f4ea"; } +.bi-pin-angle::before { content: "\f4eb"; } +.bi-pin-fill::before { content: "\f4ec"; } +.bi-pin::before { content: "\f4ed"; } +.bi-pip-fill::before { content: "\f4ee"; } +.bi-pip::before { content: "\f4ef"; } +.bi-play-btn-fill::before { content: "\f4f0"; } +.bi-play-btn::before { content: "\f4f1"; } +.bi-play-circle-fill::before { content: "\f4f2"; } +.bi-play-circle::before { content: "\f4f3"; } +.bi-play-fill::before { content: "\f4f4"; } +.bi-play::before { content: "\f4f5"; } +.bi-plug-fill::before { content: "\f4f6"; } +.bi-plug::before { content: "\f4f7"; } +.bi-plus-circle-dotted::before { content: "\f4f8"; } +.bi-plus-circle-fill::before { content: "\f4f9"; } +.bi-plus-circle::before { content: "\f4fa"; } +.bi-plus-square-dotted::before { content: "\f4fb"; } +.bi-plus-square-fill::before { content: "\f4fc"; } +.bi-plus-square::before { content: "\f4fd"; } +.bi-plus::before { content: "\f4fe"; } +.bi-power::before { content: "\f4ff"; } +.bi-printer-fill::before { content: "\f500"; } +.bi-printer::before { content: "\f501"; } +.bi-puzzle-fill::before { content: "\f502"; } +.bi-puzzle::before { content: "\f503"; } +.bi-question-circle-fill::before { content: "\f504"; } +.bi-question-circle::before { content: "\f505"; } +.bi-question-diamond-fill::before { content: "\f506"; } +.bi-question-diamond::before { content: "\f507"; } +.bi-question-octagon-fill::before { content: "\f508"; } +.bi-question-octagon::before { content: "\f509"; } +.bi-question-square-fill::before { content: "\f50a"; } +.bi-question-square::before { content: "\f50b"; } +.bi-question::before { content: "\f50c"; } +.bi-rainbow::before { content: "\f50d"; } +.bi-receipt-cutoff::before { content: "\f50e"; } +.bi-receipt::before { content: "\f50f"; } +.bi-reception-0::before { content: "\f510"; } +.bi-reception-1::before { content: "\f511"; } +.bi-reception-2::before { content: "\f512"; } +.bi-reception-3::before { content: "\f513"; } +.bi-reception-4::before { content: "\f514"; } +.bi-record-btn-fill::before { content: "\f515"; } +.bi-record-btn::before { content: "\f516"; } +.bi-record-circle-fill::before { content: "\f517"; } +.bi-record-circle::before { content: "\f518"; } +.bi-record-fill::before { content: "\f519"; } +.bi-record::before { content: "\f51a"; } +.bi-record2-fill::before { content: "\f51b"; } +.bi-record2::before { content: "\f51c"; } +.bi-reply-all-fill::before { content: "\f51d"; } +.bi-reply-all::before { content: "\f51e"; } +.bi-reply-fill::before { content: "\f51f"; } +.bi-reply::before { content: "\f520"; } +.bi-rss-fill::before { content: "\f521"; } +.bi-rss::before { content: "\f522"; } +.bi-rulers::before { content: "\f523"; } +.bi-save-fill::before { content: "\f524"; } +.bi-save::before { content: "\f525"; } +.bi-save2-fill::before { content: "\f526"; } +.bi-save2::before { content: "\f527"; } +.bi-scissors::before { content: "\f528"; } +.bi-screwdriver::before { content: "\f529"; } +.bi-search::before { content: "\f52a"; } +.bi-segmented-nav::before { content: "\f52b"; } +.bi-server::before { content: "\f52c"; } +.bi-share-fill::before { content: "\f52d"; } +.bi-share::before { content: "\f52e"; } +.bi-shield-check::before { content: "\f52f"; } +.bi-shield-exclamation::before { content: "\f530"; } +.bi-shield-fill-check::before { content: "\f531"; } +.bi-shield-fill-exclamation::before { content: "\f532"; } +.bi-shield-fill-minus::before { content: "\f533"; } +.bi-shield-fill-plus::before { content: "\f534"; } +.bi-shield-fill-x::before { content: "\f535"; } +.bi-shield-fill::before { content: "\f536"; } +.bi-shield-lock-fill::before { content: "\f537"; } +.bi-shield-lock::before { content: "\f538"; } +.bi-shield-minus::before { content: "\f539"; } +.bi-shield-plus::before { content: "\f53a"; } +.bi-shield-shaded::before { content: "\f53b"; } +.bi-shield-slash-fill::before { content: "\f53c"; } +.bi-shield-slash::before { content: "\f53d"; } +.bi-shield-x::before { content: "\f53e"; } +.bi-shield::before { content: "\f53f"; } +.bi-shift-fill::before { content: "\f540"; } +.bi-shift::before { content: "\f541"; } +.bi-shop-window::before { content: "\f542"; } +.bi-shop::before { content: "\f543"; } +.bi-shuffle::before { content: "\f544"; } +.bi-signpost-2-fill::before { content: "\f545"; } +.bi-signpost-2::before { content: "\f546"; } +.bi-signpost-fill::before { content: "\f547"; } +.bi-signpost-split-fill::before { content: "\f548"; } +.bi-signpost-split::before { content: "\f549"; } +.bi-signpost::before { content: "\f54a"; } +.bi-sim-fill::before { content: "\f54b"; } +.bi-sim::before { content: "\f54c"; } +.bi-skip-backward-btn-fill::before { content: "\f54d"; } +.bi-skip-backward-btn::before { content: "\f54e"; } +.bi-skip-backward-circle-fill::before { content: "\f54f"; } +.bi-skip-backward-circle::before { content: "\f550"; } +.bi-skip-backward-fill::before { content: "\f551"; } +.bi-skip-backward::before { content: "\f552"; } +.bi-skip-end-btn-fill::before { content: "\f553"; } +.bi-skip-end-btn::before { content: "\f554"; } +.bi-skip-end-circle-fill::before { content: "\f555"; } +.bi-skip-end-circle::before { content: "\f556"; } +.bi-skip-end-fill::before { content: "\f557"; } +.bi-skip-end::before { content: "\f558"; } +.bi-skip-forward-btn-fill::before { content: "\f559"; } +.bi-skip-forward-btn::before { content: "\f55a"; } +.bi-skip-forward-circle-fill::before { content: "\f55b"; } +.bi-skip-forward-circle::before { content: "\f55c"; } +.bi-skip-forward-fill::before { content: "\f55d"; } +.bi-skip-forward::before { content: "\f55e"; } +.bi-skip-start-btn-fill::before { content: "\f55f"; } +.bi-skip-start-btn::before { content: "\f560"; } +.bi-skip-start-circle-fill::before { content: "\f561"; } +.bi-skip-start-circle::before { content: "\f562"; } +.bi-skip-start-fill::before { content: "\f563"; } +.bi-skip-start::before { content: "\f564"; } +.bi-slack::before { content: "\f565"; } +.bi-slash-circle-fill::before { content: "\f566"; } +.bi-slash-circle::before { content: "\f567"; } +.bi-slash-square-fill::before { content: "\f568"; } +.bi-slash-square::before { content: "\f569"; } +.bi-slash::before { content: "\f56a"; } +.bi-sliders::before { content: "\f56b"; } +.bi-smartwatch::before { content: "\f56c"; } +.bi-snow::before { content: "\f56d"; } +.bi-snow2::before { content: "\f56e"; } +.bi-snow3::before { content: "\f56f"; } +.bi-sort-alpha-down-alt::before { content: "\f570"; } +.bi-sort-alpha-down::before { content: "\f571"; } +.bi-sort-alpha-up-alt::before { content: "\f572"; } +.bi-sort-alpha-up::before { content: "\f573"; } +.bi-sort-down-alt::before { content: "\f574"; } +.bi-sort-down::before { content: "\f575"; } +.bi-sort-numeric-down-alt::before { content: "\f576"; } +.bi-sort-numeric-down::before { content: "\f577"; } +.bi-sort-numeric-up-alt::before { content: "\f578"; } +.bi-sort-numeric-up::before { content: "\f579"; } +.bi-sort-up-alt::before { content: "\f57a"; } +.bi-sort-up::before { content: "\f57b"; } +.bi-soundwave::before { content: "\f57c"; } +.bi-speaker-fill::before { content: "\f57d"; } +.bi-speaker::before { content: "\f57e"; } +.bi-speedometer::before { content: "\f57f"; } +.bi-speedometer2::before { content: "\f580"; } +.bi-spellcheck::before { content: "\f581"; } +.bi-square-fill::before { content: "\f582"; } +.bi-square-half::before { content: "\f583"; } +.bi-square::before { content: "\f584"; } +.bi-stack::before { content: "\f585"; } +.bi-star-fill::before { content: "\f586"; } +.bi-star-half::before { content: "\f587"; } +.bi-star::before { content: "\f588"; } +.bi-stars::before { content: "\f589"; } +.bi-stickies-fill::before { content: "\f58a"; } +.bi-stickies::before { content: "\f58b"; } +.bi-sticky-fill::before { content: "\f58c"; } +.bi-sticky::before { content: "\f58d"; } +.bi-stop-btn-fill::before { content: "\f58e"; } +.bi-stop-btn::before { content: "\f58f"; } +.bi-stop-circle-fill::before { content: "\f590"; } +.bi-stop-circle::before { content: "\f591"; } +.bi-stop-fill::before { content: "\f592"; } +.bi-stop::before { content: "\f593"; } +.bi-stoplights-fill::before { content: "\f594"; } +.bi-stoplights::before { content: "\f595"; } +.bi-stopwatch-fill::before { content: "\f596"; } +.bi-stopwatch::before { content: "\f597"; } +.bi-subtract::before { content: "\f598"; } +.bi-suit-club-fill::before { content: "\f599"; } +.bi-suit-club::before { content: "\f59a"; } +.bi-suit-diamond-fill::before { content: "\f59b"; } +.bi-suit-diamond::before { content: "\f59c"; } +.bi-suit-heart-fill::before { content: "\f59d"; } +.bi-suit-heart::before { content: "\f59e"; } +.bi-suit-spade-fill::before { content: "\f59f"; } +.bi-suit-spade::before { content: "\f5a0"; } +.bi-sun-fill::before { content: "\f5a1"; } +.bi-sun::before { content: "\f5a2"; } +.bi-sunglasses::before { content: "\f5a3"; } +.bi-sunrise-fill::before { content: "\f5a4"; } +.bi-sunrise::before { content: "\f5a5"; } +.bi-sunset-fill::before { content: "\f5a6"; } +.bi-sunset::before { content: "\f5a7"; } +.bi-symmetry-horizontal::before { content: "\f5a8"; } +.bi-symmetry-vertical::before { content: "\f5a9"; } +.bi-table::before { content: "\f5aa"; } +.bi-tablet-fill::before { content: "\f5ab"; } +.bi-tablet-landscape-fill::before { content: "\f5ac"; } +.bi-tablet-landscape::before { content: "\f5ad"; } +.bi-tablet::before { content: "\f5ae"; } +.bi-tag-fill::before { content: "\f5af"; } +.bi-tag::before { content: "\f5b0"; } +.bi-tags-fill::before { content: "\f5b1"; } +.bi-tags::before { content: "\f5b2"; } +.bi-telegram::before { content: "\f5b3"; } +.bi-telephone-fill::before { content: "\f5b4"; } +.bi-telephone-forward-fill::before { content: "\f5b5"; } +.bi-telephone-forward::before { content: "\f5b6"; } +.bi-telephone-inbound-fill::before { content: "\f5b7"; } +.bi-telephone-inbound::before { content: "\f5b8"; } +.bi-telephone-minus-fill::before { content: "\f5b9"; } +.bi-telephone-minus::before { content: "\f5ba"; } +.bi-telephone-outbound-fill::before { content: "\f5bb"; } +.bi-telephone-outbound::before { content: "\f5bc"; } +.bi-telephone-plus-fill::before { content: "\f5bd"; } +.bi-telephone-plus::before { content: "\f5be"; } +.bi-telephone-x-fill::before { content: "\f5bf"; } +.bi-telephone-x::before { content: "\f5c0"; } +.bi-telephone::before { content: "\f5c1"; } +.bi-terminal-fill::before { content: "\f5c2"; } +.bi-terminal::before { content: "\f5c3"; } +.bi-text-center::before { content: "\f5c4"; } +.bi-text-indent-left::before { content: "\f5c5"; } +.bi-text-indent-right::before { content: "\f5c6"; } +.bi-text-left::before { content: "\f5c7"; } +.bi-text-paragraph::before { content: "\f5c8"; } +.bi-text-right::before { content: "\f5c9"; } +.bi-textarea-resize::before { content: "\f5ca"; } +.bi-textarea-t::before { content: "\f5cb"; } +.bi-textarea::before { content: "\f5cc"; } +.bi-thermometer-half::before { content: "\f5cd"; } +.bi-thermometer-high::before { content: "\f5ce"; } +.bi-thermometer-low::before { content: "\f5cf"; } +.bi-thermometer-snow::before { content: "\f5d0"; } +.bi-thermometer-sun::before { content: "\f5d1"; } +.bi-thermometer::before { content: "\f5d2"; } +.bi-three-dots-vertical::before { content: "\f5d3"; } +.bi-three-dots::before { content: "\f5d4"; } +.bi-toggle-off::before { content: "\f5d5"; } +.bi-toggle-on::before { content: "\f5d6"; } +.bi-toggle2-off::before { content: "\f5d7"; } +.bi-toggle2-on::before { content: "\f5d8"; } +.bi-toggles::before { content: "\f5d9"; } +.bi-toggles2::before { content: "\f5da"; } +.bi-tools::before { content: "\f5db"; } +.bi-tornado::before { content: "\f5dc"; } +.bi-trash-fill::before { content: "\f5dd"; } +.bi-trash::before { content: "\f5de"; } +.bi-trash2-fill::before { content: "\f5df"; } +.bi-trash2::before { content: "\f5e0"; } +.bi-tree-fill::before { content: "\f5e1"; } +.bi-tree::before { content: "\f5e2"; } +.bi-triangle-fill::before { content: "\f5e3"; } +.bi-triangle-half::before { content: "\f5e4"; } +.bi-triangle::before { content: "\f5e5"; } +.bi-trophy-fill::before { content: "\f5e6"; } +.bi-trophy::before { content: "\f5e7"; } +.bi-tropical-storm::before { content: "\f5e8"; } +.bi-truck-flatbed::before { content: "\f5e9"; } +.bi-truck::before { content: "\f5ea"; } +.bi-tsunami::before { content: "\f5eb"; } +.bi-tv-fill::before { content: "\f5ec"; } +.bi-tv::before { content: "\f5ed"; } +.bi-twitch::before { content: "\f5ee"; } +.bi-twitter::before { content: "\f5ef"; } +.bi-type-bold::before { content: "\f5f0"; } +.bi-type-h1::before { content: "\f5f1"; } +.bi-type-h2::before { content: "\f5f2"; } +.bi-type-h3::before { content: "\f5f3"; } +.bi-type-italic::before { content: "\f5f4"; } +.bi-type-strikethrough::before { content: "\f5f5"; } +.bi-type-underline::before { content: "\f5f6"; } +.bi-type::before { content: "\f5f7"; } +.bi-ui-checks-grid::before { content: "\f5f8"; } +.bi-ui-checks::before { content: "\f5f9"; } +.bi-ui-radios-grid::before { content: "\f5fa"; } +.bi-ui-radios::before { content: "\f5fb"; } +.bi-umbrella-fill::before { content: "\f5fc"; } +.bi-umbrella::before { content: "\f5fd"; } +.bi-union::before { content: "\f5fe"; } +.bi-unlock-fill::before { content: "\f5ff"; } +.bi-unlock::before { content: "\f600"; } +.bi-upc-scan::before { content: "\f601"; } +.bi-upc::before { content: "\f602"; } +.bi-upload::before { content: "\f603"; } +.bi-vector-pen::before { content: "\f604"; } +.bi-view-list::before { content: "\f605"; } +.bi-view-stacked::before { content: "\f606"; } +.bi-vinyl-fill::before { content: "\f607"; } +.bi-vinyl::before { content: "\f608"; } +.bi-voicemail::before { content: "\f609"; } +.bi-volume-down-fill::before { content: "\f60a"; } +.bi-volume-down::before { content: "\f60b"; } +.bi-volume-mute-fill::before { content: "\f60c"; } +.bi-volume-mute::before { content: "\f60d"; } +.bi-volume-off-fill::before { content: "\f60e"; } +.bi-volume-off::before { content: "\f60f"; } +.bi-volume-up-fill::before { content: "\f610"; } +.bi-volume-up::before { content: "\f611"; } +.bi-vr::before { content: "\f612"; } +.bi-wallet-fill::before { content: "\f613"; } +.bi-wallet::before { content: "\f614"; } +.bi-wallet2::before { content: "\f615"; } +.bi-watch::before { content: "\f616"; } +.bi-water::before { content: "\f617"; } +.bi-whatsapp::before { content: "\f618"; } +.bi-wifi-1::before { content: "\f619"; } +.bi-wifi-2::before { content: "\f61a"; } +.bi-wifi-off::before { content: "\f61b"; } +.bi-wifi::before { content: "\f61c"; } +.bi-wind::before { content: "\f61d"; } +.bi-window-dock::before { content: "\f61e"; } +.bi-window-sidebar::before { content: "\f61f"; } +.bi-window::before { content: "\f620"; } +.bi-wrench::before { content: "\f621"; } +.bi-x-circle-fill::before { content: "\f622"; } +.bi-x-circle::before { content: "\f623"; } +.bi-x-diamond-fill::before { content: "\f624"; } +.bi-x-diamond::before { content: "\f625"; } +.bi-x-octagon-fill::before { content: "\f626"; } +.bi-x-octagon::before { content: "\f627"; } +.bi-x-square-fill::before { content: "\f628"; } +.bi-x-square::before { content: "\f629"; } +.bi-x::before { content: "\f62a"; } +.bi-youtube::before { content: "\f62b"; } +.bi-zoom-in::before { content: "\f62c"; } +.bi-zoom-out::before { content: "\f62d"; } +.bi-bank::before { content: "\f62e"; } +.bi-bank2::before { content: "\f62f"; } +.bi-bell-slash-fill::before { content: "\f630"; } +.bi-bell-slash::before { content: "\f631"; } +.bi-cash-coin::before { content: "\f632"; } +.bi-check-lg::before { content: "\f633"; } +.bi-coin::before { content: "\f634"; } +.bi-currency-bitcoin::before { content: "\f635"; } +.bi-currency-dollar::before { content: "\f636"; } +.bi-currency-euro::before { content: "\f637"; } +.bi-currency-exchange::before { content: "\f638"; } +.bi-currency-pound::before { content: "\f639"; } +.bi-currency-yen::before { content: "\f63a"; } +.bi-dash-lg::before { content: "\f63b"; } +.bi-exclamation-lg::before { content: "\f63c"; } +.bi-file-earmark-pdf-fill::before { content: "\f63d"; } +.bi-file-earmark-pdf::before { content: "\f63e"; } +.bi-file-pdf-fill::before { content: "\f63f"; } +.bi-file-pdf::before { content: "\f640"; } +.bi-gender-ambiguous::before { content: "\f641"; } +.bi-gender-female::before { content: "\f642"; } +.bi-gender-male::before { content: "\f643"; } +.bi-gender-trans::before { content: "\f644"; } +.bi-headset-vr::before { content: "\f645"; } +.bi-info-lg::before { content: "\f646"; } +.bi-mastodon::before { content: "\f647"; } +.bi-messenger::before { content: "\f648"; } +.bi-piggy-bank-fill::before { content: "\f649"; } +.bi-piggy-bank::before { content: "\f64a"; } +.bi-pin-map-fill::before { content: "\f64b"; } +.bi-pin-map::before { content: "\f64c"; } +.bi-plus-lg::before { content: "\f64d"; } +.bi-question-lg::before { content: "\f64e"; } +.bi-recycle::before { content: "\f64f"; } +.bi-reddit::before { content: "\f650"; } +.bi-safe-fill::before { content: "\f651"; } +.bi-safe2-fill::before { content: "\f652"; } +.bi-safe2::before { content: "\f653"; } +.bi-sd-card-fill::before { content: "\f654"; } +.bi-sd-card::before { content: "\f655"; } +.bi-skype::before { content: "\f656"; } +.bi-slash-lg::before { content: "\f657"; } +.bi-translate::before { content: "\f658"; } +.bi-x-lg::before { content: "\f659"; } +.bi-safe::before { content: "\f65a"; } +.bi-apple::before { content: "\f65b"; } +.bi-microsoft::before { content: "\f65d"; } +.bi-windows::before { content: "\f65e"; } +.bi-behance::before { content: "\f65c"; } +.bi-dribbble::before { content: "\f65f"; } +.bi-line::before { content: "\f660"; } +.bi-medium::before { content: "\f661"; } +.bi-paypal::before { content: "\f662"; } +.bi-pinterest::before { content: "\f663"; } +.bi-signal::before { content: "\f664"; } +.bi-snapchat::before { content: "\f665"; } +.bi-spotify::before { content: "\f666"; } +.bi-stack-overflow::before { content: "\f667"; } +.bi-strava::before { content: "\f668"; } +.bi-wordpress::before { content: "\f669"; } +.bi-vimeo::before { content: "\f66a"; } +.bi-activity::before { content: "\f66b"; } +.bi-easel2-fill::before { content: "\f66c"; } +.bi-easel2::before { content: "\f66d"; } +.bi-easel3-fill::before { content: "\f66e"; } +.bi-easel3::before { content: "\f66f"; } +.bi-fan::before { content: "\f670"; } +.bi-fingerprint::before { content: "\f671"; } +.bi-graph-down-arrow::before { content: "\f672"; } +.bi-graph-up-arrow::before { content: "\f673"; } +.bi-hypnotize::before { content: "\f674"; } +.bi-magic::before { content: "\f675"; } +.bi-person-rolodex::before { content: "\f676"; } +.bi-person-video::before { content: "\f677"; } +.bi-person-video2::before { content: "\f678"; } +.bi-person-video3::before { content: "\f679"; } +.bi-person-workspace::before { content: "\f67a"; } +.bi-radioactive::before { content: "\f67b"; } +.bi-webcam-fill::before { content: "\f67c"; } +.bi-webcam::before { content: "\f67d"; } +.bi-yin-yang::before { content: "\f67e"; } +.bi-bandaid-fill::before { content: "\f680"; } +.bi-bandaid::before { content: "\f681"; } +.bi-bluetooth::before { content: "\f682"; } +.bi-body-text::before { content: "\f683"; } +.bi-boombox::before { content: "\f684"; } +.bi-boxes::before { content: "\f685"; } +.bi-dpad-fill::before { content: "\f686"; } +.bi-dpad::before { content: "\f687"; } +.bi-ear-fill::before { content: "\f688"; } +.bi-ear::before { content: "\f689"; } +.bi-envelope-check-fill::before { content: "\f68b"; } +.bi-envelope-check::before { content: "\f68c"; } +.bi-envelope-dash-fill::before { content: "\f68e"; } +.bi-envelope-dash::before { content: "\f68f"; } +.bi-envelope-exclamation-fill::before { content: "\f691"; } +.bi-envelope-exclamation::before { content: "\f692"; } +.bi-envelope-plus-fill::before { content: "\f693"; } +.bi-envelope-plus::before { content: "\f694"; } +.bi-envelope-slash-fill::before { content: "\f696"; } +.bi-envelope-slash::before { content: "\f697"; } +.bi-envelope-x-fill::before { content: "\f699"; } +.bi-envelope-x::before { content: "\f69a"; } +.bi-explicit-fill::before { content: "\f69b"; } +.bi-explicit::before { content: "\f69c"; } +.bi-git::before { content: "\f69d"; } +.bi-infinity::before { content: "\f69e"; } +.bi-list-columns-reverse::before { content: "\f69f"; } +.bi-list-columns::before { content: "\f6a0"; } +.bi-meta::before { content: "\f6a1"; } +.bi-nintendo-switch::before { content: "\f6a4"; } +.bi-pc-display-horizontal::before { content: "\f6a5"; } +.bi-pc-display::before { content: "\f6a6"; } +.bi-pc-horizontal::before { content: "\f6a7"; } +.bi-pc::before { content: "\f6a8"; } +.bi-playstation::before { content: "\f6a9"; } +.bi-plus-slash-minus::before { content: "\f6aa"; } +.bi-projector-fill::before { content: "\f6ab"; } +.bi-projector::before { content: "\f6ac"; } +.bi-qr-code-scan::before { content: "\f6ad"; } +.bi-qr-code::before { content: "\f6ae"; } +.bi-quora::before { content: "\f6af"; } +.bi-quote::before { content: "\f6b0"; } +.bi-robot::before { content: "\f6b1"; } +.bi-send-check-fill::before { content: "\f6b2"; } +.bi-send-check::before { content: "\f6b3"; } +.bi-send-dash-fill::before { content: "\f6b4"; } +.bi-send-dash::before { content: "\f6b5"; } +.bi-send-exclamation-fill::before { content: "\f6b7"; } +.bi-send-exclamation::before { content: "\f6b8"; } +.bi-send-fill::before { content: "\f6b9"; } +.bi-send-plus-fill::before { content: "\f6ba"; } +.bi-send-plus::before { content: "\f6bb"; } +.bi-send-slash-fill::before { content: "\f6bc"; } +.bi-send-slash::before { content: "\f6bd"; } +.bi-send-x-fill::before { content: "\f6be"; } +.bi-send-x::before { content: "\f6bf"; } +.bi-send::before { content: "\f6c0"; } +.bi-steam::before { content: "\f6c1"; } +.bi-terminal-dash::before { content: "\f6c3"; } +.bi-terminal-plus::before { content: "\f6c4"; } +.bi-terminal-split::before { content: "\f6c5"; } +.bi-ticket-detailed-fill::before { content: "\f6c6"; } +.bi-ticket-detailed::before { content: "\f6c7"; } +.bi-ticket-fill::before { content: "\f6c8"; } +.bi-ticket-perforated-fill::before { content: "\f6c9"; } +.bi-ticket-perforated::before { content: "\f6ca"; } +.bi-ticket::before { content: "\f6cb"; } +.bi-tiktok::before { content: "\f6cc"; } +.bi-window-dash::before { content: "\f6cd"; } +.bi-window-desktop::before { content: "\f6ce"; } +.bi-window-fullscreen::before { content: "\f6cf"; } +.bi-window-plus::before { content: "\f6d0"; } +.bi-window-split::before { content: "\f6d1"; } +.bi-window-stack::before { content: "\f6d2"; } +.bi-window-x::before { content: "\f6d3"; } +.bi-xbox::before { content: "\f6d4"; } +.bi-ethernet::before { content: "\f6d5"; } +.bi-hdmi-fill::before { content: "\f6d6"; } +.bi-hdmi::before { content: "\f6d7"; } +.bi-usb-c-fill::before { content: "\f6d8"; } +.bi-usb-c::before { content: "\f6d9"; } +.bi-usb-fill::before { content: "\f6da"; } +.bi-usb-plug-fill::before { content: "\f6db"; } +.bi-usb-plug::before { content: "\f6dc"; } +.bi-usb-symbol::before { content: "\f6dd"; } +.bi-usb::before { content: "\f6de"; } +.bi-boombox-fill::before { content: "\f6df"; } +.bi-displayport::before { content: "\f6e1"; } +.bi-gpu-card::before { content: "\f6e2"; } +.bi-memory::before { content: "\f6e3"; } +.bi-modem-fill::before { content: "\f6e4"; } +.bi-modem::before { content: "\f6e5"; } +.bi-motherboard-fill::before { content: "\f6e6"; } +.bi-motherboard::before { content: "\f6e7"; } +.bi-optical-audio-fill::before { content: "\f6e8"; } +.bi-optical-audio::before { content: "\f6e9"; } +.bi-pci-card::before { content: "\f6ea"; } +.bi-router-fill::before { content: "\f6eb"; } +.bi-router::before { content: "\f6ec"; } +.bi-thunderbolt-fill::before { content: "\f6ef"; } +.bi-thunderbolt::before { content: "\f6f0"; } +.bi-usb-drive-fill::before { content: "\f6f1"; } +.bi-usb-drive::before { content: "\f6f2"; } +.bi-usb-micro-fill::before { content: "\f6f3"; } +.bi-usb-micro::before { content: "\f6f4"; } +.bi-usb-mini-fill::before { content: "\f6f5"; } +.bi-usb-mini::before { content: "\f6f6"; } +.bi-cloud-haze2::before { content: "\f6f7"; } +.bi-device-hdd-fill::before { content: "\f6f8"; } +.bi-device-hdd::before { content: "\f6f9"; } +.bi-device-ssd-fill::before { content: "\f6fa"; } +.bi-device-ssd::before { content: "\f6fb"; } +.bi-displayport-fill::before { content: "\f6fc"; } +.bi-mortarboard-fill::before { content: "\f6fd"; } +.bi-mortarboard::before { content: "\f6fe"; } +.bi-terminal-x::before { content: "\f6ff"; } +.bi-arrow-through-heart-fill::before { content: "\f700"; } +.bi-arrow-through-heart::before { content: "\f701"; } +.bi-badge-sd-fill::before { content: "\f702"; } +.bi-badge-sd::before { content: "\f703"; } +.bi-bag-heart-fill::before { content: "\f704"; } +.bi-bag-heart::before { content: "\f705"; } +.bi-balloon-fill::before { content: "\f706"; } +.bi-balloon-heart-fill::before { content: "\f707"; } +.bi-balloon-heart::before { content: "\f708"; } +.bi-balloon::before { content: "\f709"; } +.bi-box2-fill::before { content: "\f70a"; } +.bi-box2-heart-fill::before { content: "\f70b"; } +.bi-box2-heart::before { content: "\f70c"; } +.bi-box2::before { content: "\f70d"; } +.bi-braces-asterisk::before { content: "\f70e"; } +.bi-calendar-heart-fill::before { content: "\f70f"; } +.bi-calendar-heart::before { content: "\f710"; } +.bi-calendar2-heart-fill::before { content: "\f711"; } +.bi-calendar2-heart::before { content: "\f712"; } +.bi-chat-heart-fill::before { content: "\f713"; } +.bi-chat-heart::before { content: "\f714"; } +.bi-chat-left-heart-fill::before { content: "\f715"; } +.bi-chat-left-heart::before { content: "\f716"; } +.bi-chat-right-heart-fill::before { content: "\f717"; } +.bi-chat-right-heart::before { content: "\f718"; } +.bi-chat-square-heart-fill::before { content: "\f719"; } +.bi-chat-square-heart::before { content: "\f71a"; } +.bi-clipboard-check-fill::before { content: "\f71b"; } +.bi-clipboard-data-fill::before { content: "\f71c"; } +.bi-clipboard-fill::before { content: "\f71d"; } +.bi-clipboard-heart-fill::before { content: "\f71e"; } +.bi-clipboard-heart::before { content: "\f71f"; } +.bi-clipboard-minus-fill::before { content: "\f720"; } +.bi-clipboard-plus-fill::before { content: "\f721"; } +.bi-clipboard-pulse::before { content: "\f722"; } +.bi-clipboard-x-fill::before { content: "\f723"; } +.bi-clipboard2-check-fill::before { content: "\f724"; } +.bi-clipboard2-check::before { content: "\f725"; } +.bi-clipboard2-data-fill::before { content: "\f726"; } +.bi-clipboard2-data::before { content: "\f727"; } +.bi-clipboard2-fill::before { content: "\f728"; } +.bi-clipboard2-heart-fill::before { content: "\f729"; } +.bi-clipboard2-heart::before { content: "\f72a"; } +.bi-clipboard2-minus-fill::before { content: "\f72b"; } +.bi-clipboard2-minus::before { content: "\f72c"; } +.bi-clipboard2-plus-fill::before { content: "\f72d"; } +.bi-clipboard2-plus::before { content: "\f72e"; } +.bi-clipboard2-pulse-fill::before { content: "\f72f"; } +.bi-clipboard2-pulse::before { content: "\f730"; } +.bi-clipboard2-x-fill::before { content: "\f731"; } +.bi-clipboard2-x::before { content: "\f732"; } +.bi-clipboard2::before { content: "\f733"; } +.bi-emoji-kiss-fill::before { content: "\f734"; } +.bi-emoji-kiss::before { content: "\f735"; } +.bi-envelope-heart-fill::before { content: "\f736"; } +.bi-envelope-heart::before { content: "\f737"; } +.bi-envelope-open-heart-fill::before { content: "\f738"; } +.bi-envelope-open-heart::before { content: "\f739"; } +.bi-envelope-paper-fill::before { content: "\f73a"; } +.bi-envelope-paper-heart-fill::before { content: "\f73b"; } +.bi-envelope-paper-heart::before { content: "\f73c"; } +.bi-envelope-paper::before { content: "\f73d"; } +.bi-filetype-aac::before { content: "\f73e"; } +.bi-filetype-ai::before { content: "\f73f"; } +.bi-filetype-bmp::before { content: "\f740"; } +.bi-filetype-cs::before { content: "\f741"; } +.bi-filetype-css::before { content: "\f742"; } +.bi-filetype-csv::before { content: "\f743"; } +.bi-filetype-doc::before { content: "\f744"; } +.bi-filetype-docx::before { content: "\f745"; } +.bi-filetype-exe::before { content: "\f746"; } +.bi-filetype-gif::before { content: "\f747"; } +.bi-filetype-heic::before { content: "\f748"; } +.bi-filetype-html::before { content: "\f749"; } +.bi-filetype-java::before { content: "\f74a"; } +.bi-filetype-jpg::before { content: "\f74b"; } +.bi-filetype-js::before { content: "\f74c"; } +.bi-filetype-jsx::before { content: "\f74d"; } +.bi-filetype-key::before { content: "\f74e"; } +.bi-filetype-m4p::before { content: "\f74f"; } +.bi-filetype-md::before { content: "\f750"; } +.bi-filetype-mdx::before { content: "\f751"; } +.bi-filetype-mov::before { content: "\f752"; } +.bi-filetype-mp3::before { content: "\f753"; } +.bi-filetype-mp4::before { content: "\f754"; } +.bi-filetype-otf::before { content: "\f755"; } +.bi-filetype-pdf::before { content: "\f756"; } +.bi-filetype-php::before { content: "\f757"; } +.bi-filetype-png::before { content: "\f758"; } +.bi-filetype-ppt::before { content: "\f75a"; } +.bi-filetype-psd::before { content: "\f75b"; } +.bi-filetype-py::before { content: "\f75c"; } +.bi-filetype-raw::before { content: "\f75d"; } +.bi-filetype-rb::before { content: "\f75e"; } +.bi-filetype-sass::before { content: "\f75f"; } +.bi-filetype-scss::before { content: "\f760"; } +.bi-filetype-sh::before { content: "\f761"; } +.bi-filetype-svg::before { content: "\f762"; } +.bi-filetype-tiff::before { content: "\f763"; } +.bi-filetype-tsx::before { content: "\f764"; } +.bi-filetype-ttf::before { content: "\f765"; } +.bi-filetype-txt::before { content: "\f766"; } +.bi-filetype-wav::before { content: "\f767"; } +.bi-filetype-woff::before { content: "\f768"; } +.bi-filetype-xls::before { content: "\f76a"; } +.bi-filetype-xml::before { content: "\f76b"; } +.bi-filetype-yml::before { content: "\f76c"; } +.bi-heart-arrow::before { content: "\f76d"; } +.bi-heart-pulse-fill::before { content: "\f76e"; } +.bi-heart-pulse::before { content: "\f76f"; } +.bi-heartbreak-fill::before { content: "\f770"; } +.bi-heartbreak::before { content: "\f771"; } +.bi-hearts::before { content: "\f772"; } +.bi-hospital-fill::before { content: "\f773"; } +.bi-hospital::before { content: "\f774"; } +.bi-house-heart-fill::before { content: "\f775"; } +.bi-house-heart::before { content: "\f776"; } +.bi-incognito::before { content: "\f777"; } +.bi-magnet-fill::before { content: "\f778"; } +.bi-magnet::before { content: "\f779"; } +.bi-person-heart::before { content: "\f77a"; } +.bi-person-hearts::before { content: "\f77b"; } +.bi-phone-flip::before { content: "\f77c"; } +.bi-plugin::before { content: "\f77d"; } +.bi-postage-fill::before { content: "\f77e"; } +.bi-postage-heart-fill::before { content: "\f77f"; } +.bi-postage-heart::before { content: "\f780"; } +.bi-postage::before { content: "\f781"; } +.bi-postcard-fill::before { content: "\f782"; } +.bi-postcard-heart-fill::before { content: "\f783"; } +.bi-postcard-heart::before { content: "\f784"; } +.bi-postcard::before { content: "\f785"; } +.bi-search-heart-fill::before { content: "\f786"; } +.bi-search-heart::before { content: "\f787"; } +.bi-sliders2-vertical::before { content: "\f788"; } +.bi-sliders2::before { content: "\f789"; } +.bi-trash3-fill::before { content: "\f78a"; } +.bi-trash3::before { content: "\f78b"; } +.bi-valentine::before { content: "\f78c"; } +.bi-valentine2::before { content: "\f78d"; } +.bi-wrench-adjustable-circle-fill::before { content: "\f78e"; } +.bi-wrench-adjustable-circle::before { content: "\f78f"; } +.bi-wrench-adjustable::before { content: "\f790"; } +.bi-filetype-json::before { content: "\f791"; } +.bi-filetype-pptx::before { content: "\f792"; } +.bi-filetype-xlsx::before { content: "\f793"; } +.bi-1-circle-fill::before { content: "\f796"; } +.bi-1-circle::before { content: "\f797"; } +.bi-1-square-fill::before { content: "\f798"; } +.bi-1-square::before { content: "\f799"; } +.bi-2-circle-fill::before { content: "\f79c"; } +.bi-2-circle::before { content: "\f79d"; } +.bi-2-square-fill::before { content: "\f79e"; } +.bi-2-square::before { content: "\f79f"; } +.bi-3-circle-fill::before { content: "\f7a2"; } +.bi-3-circle::before { content: "\f7a3"; } +.bi-3-square-fill::before { content: "\f7a4"; } +.bi-3-square::before { content: "\f7a5"; } +.bi-4-circle-fill::before { content: "\f7a8"; } +.bi-4-circle::before { content: "\f7a9"; } +.bi-4-square-fill::before { content: "\f7aa"; } +.bi-4-square::before { content: "\f7ab"; } +.bi-5-circle-fill::before { content: "\f7ae"; } +.bi-5-circle::before { content: "\f7af"; } +.bi-5-square-fill::before { content: "\f7b0"; } +.bi-5-square::before { content: "\f7b1"; } +.bi-6-circle-fill::before { content: "\f7b4"; } +.bi-6-circle::before { content: "\f7b5"; } +.bi-6-square-fill::before { content: "\f7b6"; } +.bi-6-square::before { content: "\f7b7"; } +.bi-7-circle-fill::before { content: "\f7ba"; } +.bi-7-circle::before { content: "\f7bb"; } +.bi-7-square-fill::before { content: "\f7bc"; } +.bi-7-square::before { content: "\f7bd"; } +.bi-8-circle-fill::before { content: "\f7c0"; } +.bi-8-circle::before { content: "\f7c1"; } +.bi-8-square-fill::before { content: "\f7c2"; } +.bi-8-square::before { content: "\f7c3"; } +.bi-9-circle-fill::before { content: "\f7c6"; } +.bi-9-circle::before { content: "\f7c7"; } +.bi-9-square-fill::before { content: "\f7c8"; } +.bi-9-square::before { content: "\f7c9"; } +.bi-airplane-engines-fill::before { content: "\f7ca"; } +.bi-airplane-engines::before { content: "\f7cb"; } +.bi-airplane-fill::before { content: "\f7cc"; } +.bi-airplane::before { content: "\f7cd"; } +.bi-alexa::before { content: "\f7ce"; } +.bi-alipay::before { content: "\f7cf"; } +.bi-android::before { content: "\f7d0"; } +.bi-android2::before { content: "\f7d1"; } +.bi-box-fill::before { content: "\f7d2"; } +.bi-box-seam-fill::before { content: "\f7d3"; } +.bi-browser-chrome::before { content: "\f7d4"; } +.bi-browser-edge::before { content: "\f7d5"; } +.bi-browser-firefox::before { content: "\f7d6"; } +.bi-browser-safari::before { content: "\f7d7"; } +.bi-c-circle-fill::before { content: "\f7da"; } +.bi-c-circle::before { content: "\f7db"; } +.bi-c-square-fill::before { content: "\f7dc"; } +.bi-c-square::before { content: "\f7dd"; } +.bi-capsule-pill::before { content: "\f7de"; } +.bi-capsule::before { content: "\f7df"; } +.bi-car-front-fill::before { content: "\f7e0"; } +.bi-car-front::before { content: "\f7e1"; } +.bi-cassette-fill::before { content: "\f7e2"; } +.bi-cassette::before { content: "\f7e3"; } +.bi-cc-circle-fill::before { content: "\f7e6"; } +.bi-cc-circle::before { content: "\f7e7"; } +.bi-cc-square-fill::before { content: "\f7e8"; } +.bi-cc-square::before { content: "\f7e9"; } +.bi-cup-hot-fill::before { content: "\f7ea"; } +.bi-cup-hot::before { content: "\f7eb"; } +.bi-currency-rupee::before { content: "\f7ec"; } +.bi-dropbox::before { content: "\f7ed"; } +.bi-escape::before { content: "\f7ee"; } +.bi-fast-forward-btn-fill::before { content: "\f7ef"; } +.bi-fast-forward-btn::before { content: "\f7f0"; } +.bi-fast-forward-circle-fill::before { content: "\f7f1"; } +.bi-fast-forward-circle::before { content: "\f7f2"; } +.bi-fast-forward-fill::before { content: "\f7f3"; } +.bi-fast-forward::before { content: "\f7f4"; } +.bi-filetype-sql::before { content: "\f7f5"; } +.bi-fire::before { content: "\f7f6"; } +.bi-google-play::before { content: "\f7f7"; } +.bi-h-circle-fill::before { content: "\f7fa"; } +.bi-h-circle::before { content: "\f7fb"; } +.bi-h-square-fill::before { content: "\f7fc"; } +.bi-h-square::before { content: "\f7fd"; } +.bi-indent::before { content: "\f7fe"; } +.bi-lungs-fill::before { content: "\f7ff"; } +.bi-lungs::before { content: "\f800"; } +.bi-microsoft-teams::before { content: "\f801"; } +.bi-p-circle-fill::before { content: "\f804"; } +.bi-p-circle::before { content: "\f805"; } +.bi-p-square-fill::before { content: "\f806"; } +.bi-p-square::before { content: "\f807"; } +.bi-pass-fill::before { content: "\f808"; } +.bi-pass::before { content: "\f809"; } +.bi-prescription::before { content: "\f80a"; } +.bi-prescription2::before { content: "\f80b"; } +.bi-r-circle-fill::before { content: "\f80e"; } +.bi-r-circle::before { content: "\f80f"; } +.bi-r-square-fill::before { content: "\f810"; } +.bi-r-square::before { content: "\f811"; } +.bi-repeat-1::before { content: "\f812"; } +.bi-repeat::before { content: "\f813"; } +.bi-rewind-btn-fill::before { content: "\f814"; } +.bi-rewind-btn::before { content: "\f815"; } +.bi-rewind-circle-fill::before { content: "\f816"; } +.bi-rewind-circle::before { content: "\f817"; } +.bi-rewind-fill::before { content: "\f818"; } +.bi-rewind::before { content: "\f819"; } +.bi-train-freight-front-fill::before { content: "\f81a"; } +.bi-train-freight-front::before { content: "\f81b"; } +.bi-train-front-fill::before { content: "\f81c"; } +.bi-train-front::before { content: "\f81d"; } +.bi-train-lightrail-front-fill::before { content: "\f81e"; } +.bi-train-lightrail-front::before { content: "\f81f"; } +.bi-truck-front-fill::before { content: "\f820"; } +.bi-truck-front::before { content: "\f821"; } +.bi-ubuntu::before { content: "\f822"; } +.bi-unindent::before { content: "\f823"; } +.bi-unity::before { content: "\f824"; } +.bi-universal-access-circle::before { content: "\f825"; } +.bi-universal-access::before { content: "\f826"; } +.bi-virus::before { content: "\f827"; } +.bi-virus2::before { content: "\f828"; } +.bi-wechat::before { content: "\f829"; } +.bi-yelp::before { content: "\f82a"; } +.bi-sign-stop-fill::before { content: "\f82b"; } +.bi-sign-stop-lights-fill::before { content: "\f82c"; } +.bi-sign-stop-lights::before { content: "\f82d"; } +.bi-sign-stop::before { content: "\f82e"; } +.bi-sign-turn-left-fill::before { content: "\f82f"; } +.bi-sign-turn-left::before { content: "\f830"; } +.bi-sign-turn-right-fill::before { content: "\f831"; } +.bi-sign-turn-right::before { content: "\f832"; } +.bi-sign-turn-slight-left-fill::before { content: "\f833"; } +.bi-sign-turn-slight-left::before { content: "\f834"; } +.bi-sign-turn-slight-right-fill::before { content: "\f835"; } +.bi-sign-turn-slight-right::before { content: "\f836"; } +.bi-sign-yield-fill::before { content: "\f837"; } +.bi-sign-yield::before { content: "\f838"; } +.bi-ev-station-fill::before { content: "\f839"; } +.bi-ev-station::before { content: "\f83a"; } +.bi-fuel-pump-diesel-fill::before { content: "\f83b"; } +.bi-fuel-pump-diesel::before { content: "\f83c"; } +.bi-fuel-pump-fill::before { content: "\f83d"; } +.bi-fuel-pump::before { content: "\f83e"; } +.bi-0-circle-fill::before { content: "\f83f"; } +.bi-0-circle::before { content: "\f840"; } +.bi-0-square-fill::before { content: "\f841"; } +.bi-0-square::before { content: "\f842"; } +.bi-rocket-fill::before { content: "\f843"; } +.bi-rocket-takeoff-fill::before { content: "\f844"; } +.bi-rocket-takeoff::before { content: "\f845"; } +.bi-rocket::before { content: "\f846"; } +.bi-stripe::before { content: "\f847"; } +.bi-subscript::before { content: "\f848"; } +.bi-superscript::before { content: "\f849"; } +.bi-trello::before { content: "\f84a"; } +.bi-envelope-at-fill::before { content: "\f84b"; } +.bi-envelope-at::before { content: "\f84c"; } +.bi-regex::before { content: "\f84d"; } +.bi-text-wrap::before { content: "\f84e"; } +.bi-sign-dead-end-fill::before { content: "\f84f"; } +.bi-sign-dead-end::before { content: "\f850"; } +.bi-sign-do-not-enter-fill::before { content: "\f851"; } +.bi-sign-do-not-enter::before { content: "\f852"; } +.bi-sign-intersection-fill::before { content: "\f853"; } +.bi-sign-intersection-side-fill::before { content: "\f854"; } +.bi-sign-intersection-side::before { content: "\f855"; } +.bi-sign-intersection-t-fill::before { content: "\f856"; } +.bi-sign-intersection-t::before { content: "\f857"; } +.bi-sign-intersection-y-fill::before { content: "\f858"; } +.bi-sign-intersection-y::before { content: "\f859"; } +.bi-sign-intersection::before { content: "\f85a"; } +.bi-sign-merge-left-fill::before { content: "\f85b"; } +.bi-sign-merge-left::before { content: "\f85c"; } +.bi-sign-merge-right-fill::before { content: "\f85d"; } +.bi-sign-merge-right::before { content: "\f85e"; } +.bi-sign-no-left-turn-fill::before { content: "\f85f"; } +.bi-sign-no-left-turn::before { content: "\f860"; } +.bi-sign-no-parking-fill::before { content: "\f861"; } +.bi-sign-no-parking::before { content: "\f862"; } +.bi-sign-no-right-turn-fill::before { content: "\f863"; } +.bi-sign-no-right-turn::before { content: "\f864"; } +.bi-sign-railroad-fill::before { content: "\f865"; } +.bi-sign-railroad::before { content: "\f866"; } +.bi-building-add::before { content: "\f867"; } +.bi-building-check::before { content: "\f868"; } +.bi-building-dash::before { content: "\f869"; } +.bi-building-down::before { content: "\f86a"; } +.bi-building-exclamation::before { content: "\f86b"; } +.bi-building-fill-add::before { content: "\f86c"; } +.bi-building-fill-check::before { content: "\f86d"; } +.bi-building-fill-dash::before { content: "\f86e"; } +.bi-building-fill-down::before { content: "\f86f"; } +.bi-building-fill-exclamation::before { content: "\f870"; } +.bi-building-fill-gear::before { content: "\f871"; } +.bi-building-fill-lock::before { content: "\f872"; } +.bi-building-fill-slash::before { content: "\f873"; } +.bi-building-fill-up::before { content: "\f874"; } +.bi-building-fill-x::before { content: "\f875"; } +.bi-building-fill::before { content: "\f876"; } +.bi-building-gear::before { content: "\f877"; } +.bi-building-lock::before { content: "\f878"; } +.bi-building-slash::before { content: "\f879"; } +.bi-building-up::before { content: "\f87a"; } +.bi-building-x::before { content: "\f87b"; } +.bi-buildings-fill::before { content: "\f87c"; } +.bi-buildings::before { content: "\f87d"; } +.bi-bus-front-fill::before { content: "\f87e"; } +.bi-bus-front::before { content: "\f87f"; } +.bi-ev-front-fill::before { content: "\f880"; } +.bi-ev-front::before { content: "\f881"; } +.bi-globe-americas::before { content: "\f882"; } +.bi-globe-asia-australia::before { content: "\f883"; } +.bi-globe-central-south-asia::before { content: "\f884"; } +.bi-globe-europe-africa::before { content: "\f885"; } +.bi-house-add-fill::before { content: "\f886"; } +.bi-house-add::before { content: "\f887"; } +.bi-house-check-fill::before { content: "\f888"; } +.bi-house-check::before { content: "\f889"; } +.bi-house-dash-fill::before { content: "\f88a"; } +.bi-house-dash::before { content: "\f88b"; } +.bi-house-down-fill::before { content: "\f88c"; } +.bi-house-down::before { content: "\f88d"; } +.bi-house-exclamation-fill::before { content: "\f88e"; } +.bi-house-exclamation::before { content: "\f88f"; } +.bi-house-gear-fill::before { content: "\f890"; } +.bi-house-gear::before { content: "\f891"; } +.bi-house-lock-fill::before { content: "\f892"; } +.bi-house-lock::before { content: "\f893"; } +.bi-house-slash-fill::before { content: "\f894"; } +.bi-house-slash::before { content: "\f895"; } +.bi-house-up-fill::before { content: "\f896"; } +.bi-house-up::before { content: "\f897"; } +.bi-house-x-fill::before { content: "\f898"; } +.bi-house-x::before { content: "\f899"; } +.bi-person-add::before { content: "\f89a"; } +.bi-person-down::before { content: "\f89b"; } +.bi-person-exclamation::before { content: "\f89c"; } +.bi-person-fill-add::before { content: "\f89d"; } +.bi-person-fill-check::before { content: "\f89e"; } +.bi-person-fill-dash::before { content: "\f89f"; } +.bi-person-fill-down::before { content: "\f8a0"; } +.bi-person-fill-exclamation::before { content: "\f8a1"; } +.bi-person-fill-gear::before { content: "\f8a2"; } +.bi-person-fill-lock::before { content: "\f8a3"; } +.bi-person-fill-slash::before { content: "\f8a4"; } +.bi-person-fill-up::before { content: "\f8a5"; } +.bi-person-fill-x::before { content: "\f8a6"; } +.bi-person-gear::before { content: "\f8a7"; } +.bi-person-lock::before { content: "\f8a8"; } +.bi-person-slash::before { content: "\f8a9"; } +.bi-person-up::before { content: "\f8aa"; } +.bi-scooter::before { content: "\f8ab"; } +.bi-taxi-front-fill::before { content: "\f8ac"; } +.bi-taxi-front::before { content: "\f8ad"; } +.bi-amd::before { content: "\f8ae"; } +.bi-database-add::before { content: "\f8af"; } +.bi-database-check::before { content: "\f8b0"; } +.bi-database-dash::before { content: "\f8b1"; } +.bi-database-down::before { content: "\f8b2"; } +.bi-database-exclamation::before { content: "\f8b3"; } +.bi-database-fill-add::before { content: "\f8b4"; } +.bi-database-fill-check::before { content: "\f8b5"; } +.bi-database-fill-dash::before { content: "\f8b6"; } +.bi-database-fill-down::before { content: "\f8b7"; } +.bi-database-fill-exclamation::before { content: "\f8b8"; } +.bi-database-fill-gear::before { content: "\f8b9"; } +.bi-database-fill-lock::before { content: "\f8ba"; } +.bi-database-fill-slash::before { content: "\f8bb"; } +.bi-database-fill-up::before { content: "\f8bc"; } +.bi-database-fill-x::before { content: "\f8bd"; } +.bi-database-fill::before { content: "\f8be"; } +.bi-database-gear::before { content: "\f8bf"; } +.bi-database-lock::before { content: "\f8c0"; } +.bi-database-slash::before { content: "\f8c1"; } +.bi-database-up::before { content: "\f8c2"; } +.bi-database-x::before { content: "\f8c3"; } +.bi-database::before { content: "\f8c4"; } +.bi-houses-fill::before { content: "\f8c5"; } +.bi-houses::before { content: "\f8c6"; } +.bi-nvidia::before { content: "\f8c7"; } +.bi-person-vcard-fill::before { content: "\f8c8"; } +.bi-person-vcard::before { content: "\f8c9"; } +.bi-sina-weibo::before { content: "\f8ca"; } +.bi-tencent-qq::before { content: "\f8cb"; } +.bi-wikipedia::before { content: "\f8cc"; } +.bi-alphabet-uppercase::before { content: "\f2a5"; } +.bi-alphabet::before { content: "\f68a"; } +.bi-amazon::before { content: "\f68d"; } +.bi-arrows-collapse-vertical::before { content: "\f690"; } +.bi-arrows-expand-vertical::before { content: "\f695"; } +.bi-arrows-vertical::before { content: "\f698"; } +.bi-arrows::before { content: "\f6a2"; } +.bi-ban-fill::before { content: "\f6a3"; } +.bi-ban::before { content: "\f6b6"; } +.bi-bing::before { content: "\f6c2"; } +.bi-cake::before { content: "\f6e0"; } +.bi-cake2::before { content: "\f6ed"; } +.bi-cookie::before { content: "\f6ee"; } +.bi-copy::before { content: "\f759"; } +.bi-crosshair::before { content: "\f769"; } +.bi-crosshair2::before { content: "\f794"; } +.bi-emoji-astonished-fill::before { content: "\f795"; } +.bi-emoji-astonished::before { content: "\f79a"; } +.bi-emoji-grimace-fill::before { content: "\f79b"; } +.bi-emoji-grimace::before { content: "\f7a0"; } +.bi-emoji-grin-fill::before { content: "\f7a1"; } +.bi-emoji-grin::before { content: "\f7a6"; } +.bi-emoji-surprise-fill::before { content: "\f7a7"; } +.bi-emoji-surprise::before { content: "\f7ac"; } +.bi-emoji-tear-fill::before { content: "\f7ad"; } +.bi-emoji-tear::before { content: "\f7b2"; } +.bi-envelope-arrow-down-fill::before { content: "\f7b3"; } +.bi-envelope-arrow-down::before { content: "\f7b8"; } +.bi-envelope-arrow-up-fill::before { content: "\f7b9"; } +.bi-envelope-arrow-up::before { content: "\f7be"; } +.bi-feather::before { content: "\f7bf"; } +.bi-feather2::before { content: "\f7c4"; } +.bi-floppy-fill::before { content: "\f7c5"; } +.bi-floppy::before { content: "\f7d8"; } +.bi-floppy2-fill::before { content: "\f7d9"; } +.bi-floppy2::before { content: "\f7e4"; } +.bi-gitlab::before { content: "\f7e5"; } +.bi-highlighter::before { content: "\f7f8"; } +.bi-marker-tip::before { content: "\f802"; } +.bi-nvme-fill::before { content: "\f803"; } +.bi-nvme::before { content: "\f80c"; } +.bi-opencollective::before { content: "\f80d"; } +.bi-pci-card-network::before { content: "\f8cd"; } +.bi-pci-card-sound::before { content: "\f8ce"; } +.bi-radar::before { content: "\f8cf"; } +.bi-send-arrow-down-fill::before { content: "\f8d0"; } +.bi-send-arrow-down::before { content: "\f8d1"; } +.bi-send-arrow-up-fill::before { content: "\f8d2"; } +.bi-send-arrow-up::before { content: "\f8d3"; } +.bi-sim-slash-fill::before { content: "\f8d4"; } +.bi-sim-slash::before { content: "\f8d5"; } +.bi-sourceforge::before { content: "\f8d6"; } +.bi-substack::before { content: "\f8d7"; } +.bi-threads-fill::before { content: "\f8d8"; } +.bi-threads::before { content: "\f8d9"; } +.bi-transparency::before { content: "\f8da"; } +.bi-twitter-x::before { content: "\f8db"; } +.bi-type-h4::before { content: "\f8dc"; } +.bi-type-h5::before { content: "\f8dd"; } +.bi-type-h6::before { content: "\f8de"; } +.bi-backpack-fill::before { content: "\f8df"; } +.bi-backpack::before { content: "\f8e0"; } +.bi-backpack2-fill::before { content: "\f8e1"; } +.bi-backpack2::before { content: "\f8e2"; } +.bi-backpack3-fill::before { content: "\f8e3"; } +.bi-backpack3::before { content: "\f8e4"; } +.bi-backpack4-fill::before { content: "\f8e5"; } +.bi-backpack4::before { content: "\f8e6"; } +.bi-brilliance::before { content: "\f8e7"; } +.bi-cake-fill::before { content: "\f8e8"; } +.bi-cake2-fill::before { content: "\f8e9"; } +.bi-duffle-fill::before { content: "\f8ea"; } +.bi-duffle::before { content: "\f8eb"; } +.bi-exposure::before { content: "\f8ec"; } +.bi-gender-neuter::before { content: "\f8ed"; } +.bi-highlights::before { content: "\f8ee"; } +.bi-luggage-fill::before { content: "\f8ef"; } +.bi-luggage::before { content: "\f8f0"; } +.bi-mailbox-flag::before { content: "\f8f1"; } +.bi-mailbox2-flag::before { content: "\f8f2"; } +.bi-noise-reduction::before { content: "\f8f3"; } +.bi-passport-fill::before { content: "\f8f4"; } +.bi-passport::before { content: "\f8f5"; } +.bi-person-arms-up::before { content: "\f8f6"; } +.bi-person-raised-hand::before { content: "\f8f7"; } +.bi-person-standing-dress::before { content: "\f8f8"; } +.bi-person-standing::before { content: "\f8f9"; } +.bi-person-walking::before { content: "\f8fa"; } +.bi-person-wheelchair::before { content: "\f8fb"; } +.bi-shadows::before { content: "\f8fc"; } +.bi-suitcase-fill::before { content: "\f8fd"; } +.bi-suitcase-lg-fill::before { content: "\f8fe"; } +.bi-suitcase-lg::before { content: "\f8ff"; } +.bi-suitcase::before { content: "\f900"; } +.bi-suitcase2-fill::before { content: "\f901"; } +.bi-suitcase2::before { content: "\f902"; } +.bi-vignette::before { content: "\f903"; } +.bi-bluesky::before { content: "\f7f9"; } +.bi-tux::before { content: "\f904"; } +.bi-beaker-fill::before { content: "\f905"; } +.bi-beaker::before { content: "\f906"; } +.bi-flask-fill::before { content: "\f907"; } +.bi-flask-florence-fill::before { content: "\f908"; } +.bi-flask-florence::before { content: "\f909"; } +.bi-flask::before { content: "\f90a"; } +.bi-leaf-fill::before { content: "\f90b"; } +.bi-leaf::before { content: "\f90c"; } +.bi-measuring-cup-fill::before { content: "\f90d"; } +.bi-measuring-cup::before { content: "\f90e"; } +.bi-unlock2-fill::before { content: "\f90f"; } +.bi-unlock2::before { content: "\f910"; } +.bi-battery-low::before { content: "\f911"; } +.bi-anthropic::before { content: "\f912"; } +.bi-apple-music::before { content: "\f913"; } +.bi-claude::before { content: "\f914"; } +.bi-openai::before { content: "\f915"; } +.bi-perplexity::before { content: "\f916"; } +.bi-css::before { content: "\f917"; } +.bi-javascript::before { content: "\f918"; } +.bi-typescript::before { content: "\f919"; } +.bi-fork-knife::before { content: "\f91a"; } +.bi-globe-americas-fill::before { content: "\f91b"; } +.bi-globe-asia-australia-fill::before { content: "\f91c"; } +.bi-globe-central-south-asia-fill::before { content: "\f91d"; } +.bi-globe-europe-africa-fill::before { content: "\f91e"; } diff --git a/docs/site_libs/bootstrap/bootstrap-icons.woff b/docs/site_libs/bootstrap/bootstrap-icons.woff new file mode 100644 index 0000000..a4fa4f0 Binary files /dev/null and b/docs/site_libs/bootstrap/bootstrap-icons.woff differ diff --git a/docs/site_libs/bootstrap/bootstrap.min.js b/docs/site_libs/bootstrap/bootstrap.min.js new file mode 100644 index 0000000..e8f21f7 --- /dev/null +++ b/docs/site_libs/bootstrap/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v5.3.1 (https://getbootstrap.com/) + * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=I(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return P(s,{delegateTarget:r}),n.oneOff&&N.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return P(n,{delegateTarget:t}),i.oneOff&&N.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function $(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function I(t){return t=t.replace(y,""),T[t]||t}const N={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))$(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(w,"");a&&!e.includes(s)||D(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;D(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==I(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=P(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function P(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function M(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function j(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const F={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${j(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${j(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=M(t.dataset[n])}return e},getDataAttribute:(t,e)=>M(t.getAttribute(`data-bs-${j(e)}`))};class H{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?F.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?F.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],r=o(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class W extends H{constructor(t,i){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(i),e.set(this._element,this.constructor.DATA_KEY,this))}dispose(){e.remove(this._element,this.constructor.DATA_KEY),N.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return e.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.1"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return n(e)},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;N.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},q=".bs.alert",V=`close${q}`,K=`closed${q}`;class Q extends W{static get NAME(){return"alert"}close(){if(N.trigger(this._element,V).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),N.trigger(this._element,K),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(Q,"close"),m(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}N.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),m(Y);const U=".bs.swipe",G=`touchstart${U}`,J=`touchmove${U}`,Z=`touchend${U}`,tt=`pointerdown${U}`,et=`pointerup${U}`,it={endCallback:null,leftCallback:null,rightCallback:null},nt={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class st extends H{constructor(t,e){super(),this._element=t,t&&st.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return it}static get DefaultType(){return nt}static get NAME(){return"swipe"}dispose(){N.off(this._element,U)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),g(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&g(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(N.on(this._element,tt,(t=>this._start(t))),N.on(this._element,et,(t=>this._end(t))),this._element.classList.add("pointer-event")):(N.on(this._element,G,(t=>this._start(t))),N.on(this._element,J,(t=>this._move(t))),N.on(this._element,Z,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const ot=".bs.carousel",rt=".data-api",at="next",lt="prev",ct="left",ht="right",dt=`slide${ot}`,ut=`slid${ot}`,ft=`keydown${ot}`,pt=`mouseenter${ot}`,mt=`mouseleave${ot}`,gt=`dragstart${ot}`,_t=`load${ot}${rt}`,bt=`click${ot}${rt}`,vt="carousel",yt="active",wt=".active",At=".carousel-item",Et=wt+At,Tt={ArrowLeft:ht,ArrowRight:ct},Ct={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},Ot={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class xt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===vt&&this.cycle()}static get Default(){return Ct}static get DefaultType(){return Ot}static get NAME(){return"carousel"}next(){this._slide(at)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(lt)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?N.one(this._element,ut,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void N.one(this._element,ut,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?at:lt;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&N.on(this._element,ft,(t=>this._keydown(t))),"hover"===this._config.pause&&(N.on(this._element,pt,(()=>this.pause())),N.on(this._element,mt,(()=>this._maybeEnableCycle()))),this._config.touch&&st.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))N.on(t,gt,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(ct)),rightCallback:()=>this._slide(this._directionToOrder(ht)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new st(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=Tt[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(wt,this._indicatorsElement);e.classList.remove(yt),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(yt),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===at,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>N.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(dt).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(yt),i.classList.remove(yt,c,l),this._isSliding=!1,r(ut)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(Et,this._element)}_getItems(){return z.find(At,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===ct?lt:at:t===ct?at:lt}_orderToDirection(t){return p()?t===lt?ct:ht:t===lt?ht:ct}static jQueryInterface(t){return this.each((function(){const e=xt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}N.on(document,bt,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(vt))return;t.preventDefault();const i=xt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===F.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),N.on(window,_t,(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)xt.getOrCreateInstance(e)})),m(xt);const kt=".bs.collapse",Lt=`show${kt}`,St=`shown${kt}`,Dt=`hide${kt}`,$t=`hidden${kt}`,It=`click${kt}.data-api`,Nt="show",Pt="collapse",Mt="collapsing",jt=`:scope .${Pt} .${Pt}`,Ft='[data-bs-toggle="collapse"]',Ht={parent:null,toggle:!0},Wt={parent:"(null|element)",toggle:"boolean"};class Bt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(Ft);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Ht}static get DefaultType(){return Wt}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>Bt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(N.trigger(this._element,Lt).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(Pt),this._element.classList.add(Mt),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt,Nt),this._element.style[e]="",N.trigger(this._element,St)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(N.trigger(this._element,Dt).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(Mt),this._element.classList.remove(Pt,Nt);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt),N.trigger(this._element,$t)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(Nt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(Ft);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(jt,this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=Bt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}N.on(document,It,Ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))Bt.getOrCreateInstance(t,{toggle:!1}).toggle()})),m(Bt);var zt="top",Rt="bottom",qt="right",Vt="left",Kt="auto",Qt=[zt,Rt,qt,Vt],Xt="start",Yt="end",Ut="clippingParents",Gt="viewport",Jt="popper",Zt="reference",te=Qt.reduce((function(t,e){return t.concat([e+"-"+Xt,e+"-"+Yt])}),[]),ee=[].concat(Qt,[Kt]).reduce((function(t,e){return t.concat([e,e+"-"+Xt,e+"-"+Yt])}),[]),ie="beforeRead",ne="read",se="afterRead",oe="beforeMain",re="main",ae="afterMain",le="beforeWrite",ce="write",he="afterWrite",de=[ie,ne,se,oe,re,ae,le,ce,he];function ue(t){return t?(t.nodeName||"").toLowerCase():null}function fe(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function pe(t){return t instanceof fe(t).Element||t instanceof Element}function me(t){return t instanceof fe(t).HTMLElement||t instanceof HTMLElement}function ge(t){return"undefined"!=typeof ShadowRoot&&(t instanceof fe(t).ShadowRoot||t instanceof ShadowRoot)}const _e={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];me(s)&&ue(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});me(n)&&ue(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function be(t){return t.split("-")[0]}var ve=Math.max,ye=Math.min,we=Math.round;function Ae(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Ee(){return!/^((?!chrome|android).)*safari/i.test(Ae())}function Te(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&me(t)&&(s=t.offsetWidth>0&&we(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&we(n.height)/t.offsetHeight||1);var r=(pe(t)?fe(t):window).visualViewport,a=!Ee()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function Ce(t){var e=Te(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Oe(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&ge(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function xe(t){return fe(t).getComputedStyle(t)}function ke(t){return["table","td","th"].indexOf(ue(t))>=0}function Le(t){return((pe(t)?t.ownerDocument:t.document)||window.document).documentElement}function Se(t){return"html"===ue(t)?t:t.assignedSlot||t.parentNode||(ge(t)?t.host:null)||Le(t)}function De(t){return me(t)&&"fixed"!==xe(t).position?t.offsetParent:null}function $e(t){for(var e=fe(t),i=De(t);i&&ke(i)&&"static"===xe(i).position;)i=De(i);return i&&("html"===ue(i)||"body"===ue(i)&&"static"===xe(i).position)?e:i||function(t){var e=/firefox/i.test(Ae());if(/Trident/i.test(Ae())&&me(t)&&"fixed"===xe(t).position)return null;var i=Se(t);for(ge(i)&&(i=i.host);me(i)&&["html","body"].indexOf(ue(i))<0;){var n=xe(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Ie(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function Ne(t,e,i){return ve(t,ye(e,i))}function Pe(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Me(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const je={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=be(i.placement),l=Ie(a),c=[Vt,qt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return Pe("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Me(t,Qt))}(s.padding,i),d=Ce(o),u="y"===l?zt:Vt,f="y"===l?Rt:qt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=$e(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=Ne(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Oe(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Fe(t){return t.split("-")[1]}var He={top:"auto",right:"auto",bottom:"auto",left:"auto"};function We(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=Vt,y=zt,w=window;if(c){var A=$e(i),E="clientHeight",T="clientWidth";A===fe(i)&&"static"!==xe(A=Le(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===zt||(s===Vt||s===qt)&&o===Yt)&&(y=Rt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==Vt&&(s!==zt&&s!==Rt||o!==Yt)||(v=qt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&He),x=!0===h?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:we(i*s)/s||0,y:we(n*s)/s||0}}({x:f,y:m},fe(i)):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const Be={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:be(e.placement),variation:Fe(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,We(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,We(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var ze={passive:!0};const Re={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=fe(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,ze)})),a&&l.addEventListener("resize",i.update,ze),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,ze)})),a&&l.removeEventListener("resize",i.update,ze)}},data:{}};var qe={left:"right",right:"left",bottom:"top",top:"bottom"};function Ve(t){return t.replace(/left|right|bottom|top/g,(function(t){return qe[t]}))}var Ke={start:"end",end:"start"};function Qe(t){return t.replace(/start|end/g,(function(t){return Ke[t]}))}function Xe(t){var e=fe(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ye(t){return Te(Le(t)).left+Xe(t).scrollLeft}function Ue(t){var e=xe(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ge(t){return["html","body","#document"].indexOf(ue(t))>=0?t.ownerDocument.body:me(t)&&Ue(t)?t:Ge(Se(t))}function Je(t,e){var i;void 0===e&&(e=[]);var n=Ge(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=fe(n),r=s?[o].concat(o.visualViewport||[],Ue(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Je(Se(r)))}function Ze(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function ti(t,e,i){return e===Gt?Ze(function(t,e){var i=fe(t),n=Le(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Ee();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+Ye(t),y:l}}(t,i)):pe(e)?function(t,e){var i=Te(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):Ze(function(t){var e,i=Le(t),n=Xe(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ve(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ve(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Ye(t),l=-n.scrollTop;return"rtl"===xe(s||i).direction&&(a+=ve(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Le(t)))}function ei(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?be(s):null,r=s?Fe(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case zt:e={x:a,y:i.y-n.height};break;case Rt:e={x:a,y:i.y+i.height};break;case qt:e={x:i.x+i.width,y:l};break;case Vt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Ie(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case Xt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Yt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ii(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?Ut:a,c=i.rootBoundary,h=void 0===c?Gt:c,d=i.elementContext,u=void 0===d?Jt:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=Pe("number"!=typeof g?g:Me(g,Qt)),b=u===Jt?Zt:Jt,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=Je(Se(t)),i=["absolute","fixed"].indexOf(xe(t).position)>=0&&me(t)?$e(t):t;return pe(i)?e.filter((function(t){return pe(t)&&Oe(t,i)&&"body"!==ue(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=ti(t,i,n);return e.top=ve(s.top,e.top),e.right=ye(s.right,e.right),e.bottom=ye(s.bottom,e.bottom),e.left=ve(s.left,e.left),e}),ti(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(pe(y)?y:y.contextElement||Le(t.elements.popper),l,h,r),A=Te(t.elements.reference),E=ei({reference:A,element:v,strategy:"absolute",placement:s}),T=Ze(Object.assign({},v,E)),C=u===Jt?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===Jt&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[qt,Rt].indexOf(t)>=0?1:-1,i=[zt,Rt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function ni(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ee:l,h=Fe(n),d=h?a?te:te.filter((function(t){return Fe(t)===h})):Qt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ii(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[be(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const si={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=be(g),b=l||(_!==g&&p?function(t){if(be(t)===Kt)return[];var e=Ve(t);return[Qe(t),e,Qe(e)]}(g):[Ve(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(be(i)===Kt?ni(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=ii(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),$=L?k?qt:Vt:k?Rt:zt;y[S]>w[S]&&($=Ve($));var I=Ve($),N=[];if(o&&N.push(D[x]<=0),a&&N.push(D[$]<=0,D[I]<=0),N.every((function(t){return t}))){T=O,E=!1;break}A.set(O,N)}if(E)for(var P=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==P(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function oi(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function ri(t){return[zt,qt,Rt,Vt].some((function(e){return t[e]>=0}))}const ai={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ii(e,{elementContext:"reference"}),a=ii(e,{altBoundary:!0}),l=oi(r,n),c=oi(a,s,o),h=ri(l),d=ri(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},li={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ee.reduce((function(t,i){return t[i]=function(t,e,i){var n=be(t),s=[Vt,zt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[Vt,qt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},ci={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=ei({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},hi={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ii(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=be(e.placement),b=Fe(e.placement),v=!b,y=Ie(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?zt:Vt,D="y"===y?Rt:qt,$="y"===y?"height":"width",I=A[y],N=I+g[S],P=I-g[D],M=f?-T[$]/2:0,j=b===Xt?E[$]:T[$],F=b===Xt?-T[$]:-E[$],H=e.elements.arrow,W=f&&H?Ce(H):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=Ne(0,E[$],W[$]),V=v?E[$]/2-M-q-z-O.mainAxis:j-q-z-O.mainAxis,K=v?-E[$]/2+M+q+R+O.mainAxis:F+q+R+O.mainAxis,Q=e.elements.arrow&&$e(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=I+K-Y,G=Ne(f?ye(N,I+V-Y-X):N,I,f?ve(P,U):P);A[y]=G,k[y]=G-I}if(a){var J,Z="x"===y?zt:Vt,tt="x"===y?Rt:qt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[zt,Vt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=Ne(t,e,i);return n>i?i:n}(at,et,lt):Ne(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function di(t,e,i){void 0===i&&(i=!1);var n,s,o=me(e),r=me(e)&&function(t){var e=t.getBoundingClientRect(),i=we(e.width)/t.offsetWidth||1,n=we(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=Le(e),l=Te(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==ue(e)||Ue(a))&&(c=(n=e)!==fe(n)&&me(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Xe(n)),me(e)?((h=Te(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Ye(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function ui(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var fi={placement:"bottom",modifiers:[],strategy:"absolute"};function pi(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(F.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...g(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Ti,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=qi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(Ni);for(const i of e){const e=qi.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ei,Ti].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Ii)?this:z.prev(this,Ii)[0]||z.next(this,Ii)[0]||z.findOne(Ii,t.delegateTarget.parentNode),o=qi.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}N.on(document,Si,Ii,qi.dataApiKeydownHandler),N.on(document,Si,Pi,qi.dataApiKeydownHandler),N.on(document,Li,qi.clearMenus),N.on(document,Di,qi.clearMenus),N.on(document,Li,Ii,(function(t){t.preventDefault(),qi.getOrCreateInstance(this).toggle()})),m(qi);const Vi="backdrop",Ki="show",Qi=`mousedown.bs.${Vi}`,Xi={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Yi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Ui extends H{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Xi}static get DefaultType(){return Yi}static get NAME(){return Vi}show(t){if(!this._config.isVisible)return void g(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(Ki),this._emulateAnimation((()=>{g(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Ki),this._emulateAnimation((()=>{this.dispose(),g(t)}))):g(t)}dispose(){this._isAppended&&(N.off(this._element,Qi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),N.on(t,Qi,(()=>{g(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const Gi=".bs.focustrap",Ji=`focusin${Gi}`,Zi=`keydown.tab${Gi}`,tn="backward",en={autofocus:!0,trapElement:null},nn={autofocus:"boolean",trapElement:"element"};class sn extends H{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return en}static get DefaultType(){return nn}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),N.off(document,Gi),N.on(document,Ji,(t=>this._handleFocusin(t))),N.on(document,Zi,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,N.off(document,Gi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===tn?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?tn:"forward")}}const on=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",rn=".sticky-top",an="padding-right",ln="margin-right";class cn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,an,(e=>e+t)),this._setElementAttributes(on,an,(e=>e+t)),this._setElementAttributes(rn,ln,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,an),this._resetElementAttributes(on,an),this._resetElementAttributes(rn,ln)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&F.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=F.getDataAttribute(t,e);null!==i?(F.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const hn=".bs.modal",dn=`hide${hn}`,un=`hidePrevented${hn}`,fn=`hidden${hn}`,pn=`show${hn}`,mn=`shown${hn}`,gn=`resize${hn}`,_n=`click.dismiss${hn}`,bn=`mousedown.dismiss${hn}`,vn=`keydown.dismiss${hn}`,yn=`click${hn}.data-api`,wn="modal-open",An="show",En="modal-static",Tn={backdrop:!0,focus:!0,keyboard:!0},Cn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class On extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new cn,this._addEventListeners()}static get Default(){return Tn}static get DefaultType(){return Cn}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||N.trigger(this._element,pn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(wn),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(N.trigger(this._element,dn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(An),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){N.off(window,hn),N.off(this._dialog,hn),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Ui({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(An),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,N.trigger(this._element,mn,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){N.on(this._element,vn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),N.on(window,gn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),N.on(this._element,bn,(t=>{N.one(this._element,_n,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(wn),this._resetAdjustments(),this._scrollBar.reset(),N.trigger(this._element,fn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(N.trigger(this._element,un).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(En)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(En),this._queueCallback((()=>{this._element.classList.remove(En),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=On.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}N.on(document,yn,'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),N.one(e,pn,(t=>{t.defaultPrevented||N.one(e,fn,(()=>{a(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&On.getInstance(i).hide(),On.getOrCreateInstance(e).toggle(this)})),R(On),m(On);const xn=".bs.offcanvas",kn=".data-api",Ln=`load${xn}${kn}`,Sn="show",Dn="showing",$n="hiding",In=".offcanvas.show",Nn=`show${xn}`,Pn=`shown${xn}`,Mn=`hide${xn}`,jn=`hidePrevented${xn}`,Fn=`hidden${xn}`,Hn=`resize${xn}`,Wn=`click${xn}${kn}`,Bn=`keydown.dismiss${xn}`,zn={backdrop:!0,keyboard:!0,scroll:!1},Rn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class qn extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return zn}static get DefaultType(){return Rn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||N.trigger(this._element,Nn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new cn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Dn),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Sn),this._element.classList.remove(Dn),N.trigger(this._element,Pn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(N.trigger(this._element,Mn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add($n),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Sn,$n),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new cn).reset(),N.trigger(this._element,Fn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Ui({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():N.trigger(this._element,jn)}:null})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_addEventListeners(){N.on(this._element,Bn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():N.trigger(this._element,jn))}))}static jQueryInterface(t){return this.each((function(){const e=qn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}N.on(document,Wn,'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;N.one(e,Fn,(()=>{a(this)&&this.focus()}));const i=z.findOne(In);i&&i!==e&&qn.getInstance(i).hide(),qn.getOrCreateInstance(e).toggle(this)})),N.on(window,Ln,(()=>{for(const t of z.find(In))qn.getOrCreateInstance(t).show()})),N.on(window,Hn,(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&qn.getOrCreateInstance(t).hide()})),R(qn),m(qn);const Vn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Kn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Qn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Xn=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Kn.has(i)||Boolean(Qn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Yn={allowList:Vn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
    "},Un={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Gn={entry:"(string|element|function|null)",selector:"(string|element)"};class Jn extends H{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Yn}static get DefaultType(){return Un}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Gn)}_setContent(t,e,i){const n=z.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Xn(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return g(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Zn=new Set(["sanitize","allowList","sanitizeFn"]),ts="fade",es="show",is=".modal",ns="hide.bs.modal",ss="hover",os="focus",rs={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},as={allowList:Vn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},ls={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class cs extends W{constructor(t,e){if(void 0===vi)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return as}static get DefaultType(){return ls}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),N.off(this._element.closest(is),ns,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=N.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),N.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._queueCallback((()=>{N.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!N.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger[os]=!1,this._activeTrigger[ss]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),N.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(ts,es),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(ts),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Jn({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(ts)}_isShown(){return this.tip&&this.tip.classList.contains(es)}_createPopper(t){const e=g(this._config.placement,[this,t,this._element]),i=rs[e.toUpperCase()];return bi(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return g(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...g(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)N.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===ss?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===ss?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");N.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?os:ss]=!0,e._enter()})),N.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?os:ss]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},N.on(this._element.closest(is),ns,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=F.getDataAttributes(this._element);for(const t of Object.keys(e))Zn.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=cs.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(cs);const hs={...cs.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},ds={...cs.DefaultType,content:"(null|string|element|function)"};class us extends cs{static get Default(){return hs}static get DefaultType(){return ds}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(us);const fs=".bs.scrollspy",ps=`activate${fs}`,ms=`click${fs}`,gs=`load${fs}.data-api`,_s="active",bs="[href]",vs=".nav-link",ys=`${vs}, .nav-item > ${vs}, .list-group-item`,ws={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},As={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class Es extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return ws}static get DefaultType(){return As}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(N.off(this._config.target,ms),N.on(this._config.target,ms,bs,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(bs,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=z.findOne(decodeURI(e.hash),this._element);a(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(_s),this._activateParents(t),N.trigger(this._element,ps,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(_s);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,ys))t.classList.add(_s)}_clearActiveClass(t){t.classList.remove(_s);const e=z.find(`${bs}.${_s}`,t);for(const t of e)t.classList.remove(_s)}static jQueryInterface(t){return this.each((function(){const e=Es.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(window,gs,(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))Es.getOrCreateInstance(t)})),m(Es);const Ts=".bs.tab",Cs=`hide${Ts}`,Os=`hidden${Ts}`,xs=`show${Ts}`,ks=`shown${Ts}`,Ls=`click${Ts}`,Ss=`keydown${Ts}`,Ds=`load${Ts}`,$s="ArrowLeft",Is="ArrowRight",Ns="ArrowUp",Ps="ArrowDown",Ms="Home",js="End",Fs="active",Hs="fade",Ws="show",Bs=":not(.dropdown-toggle)",zs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Rs=`.nav-link${Bs}, .list-group-item${Bs}, [role="tab"]${Bs}, ${zs}`,qs=`.${Fs}[data-bs-toggle="tab"], .${Fs}[data-bs-toggle="pill"], .${Fs}[data-bs-toggle="list"]`;class Vs extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),N.on(this._element,Ss,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?N.trigger(e,Cs,{relatedTarget:t}):null;N.trigger(t,xs,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Fs),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),N.trigger(t,ks,{relatedTarget:e})):t.classList.add(Ws)}),t,t.classList.contains(Hs)))}_deactivate(t,e){t&&(t.classList.remove(Fs),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),N.trigger(t,Os,{relatedTarget:e})):t.classList.remove(Ws)}),t,t.classList.contains(Hs)))}_keydown(t){if(![$s,Is,Ns,Ps,Ms,js].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!l(t)));let i;if([Ms,js].includes(t.key))i=e[t.key===Ms?0:e.length-1];else{const n=[Is,Ps].includes(t.key);i=b(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Vs.getOrCreateInstance(i).show())}_getChildren(){return z.find(Rs,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(".dropdown-toggle",Fs),n(".dropdown-menu",Ws),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Fs)}_getInnerElement(t){return t.matches(Rs)?t:z.findOne(Rs,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Vs.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(document,Ls,zs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||Vs.getOrCreateInstance(this).show()})),N.on(window,Ds,(()=>{for(const t of z.find(qs))Vs.getOrCreateInstance(t)})),m(Vs);const Ks=".bs.toast",Qs=`mouseover${Ks}`,Xs=`mouseout${Ks}`,Ys=`focusin${Ks}`,Us=`focusout${Ks}`,Gs=`hide${Ks}`,Js=`hidden${Ks}`,Zs=`show${Ks}`,to=`shown${Ks}`,eo="hide",io="show",no="showing",so={animation:"boolean",autohide:"boolean",delay:"number"},oo={animation:!0,autohide:!0,delay:5e3};class ro extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return oo}static get DefaultType(){return so}static get NAME(){return"toast"}show(){N.trigger(this._element,Zs).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(eo),d(this._element),this._element.classList.add(io,no),this._queueCallback((()=>{this._element.classList.remove(no),N.trigger(this._element,to),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(N.trigger(this._element,Gs).defaultPrevented||(this._element.classList.add(no),this._queueCallback((()=>{this._element.classList.add(eo),this._element.classList.remove(no,io),N.trigger(this._element,Js)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(io),super.dispose()}isShown(){return this._element.classList.contains(io)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){N.on(this._element,Qs,(t=>this._onInteraction(t,!0))),N.on(this._element,Xs,(t=>this._onInteraction(t,!1))),N.on(this._element,Ys,(t=>this._onInteraction(t,!0))),N.on(this._element,Us,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=ro.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(ro),m(ro),{Alert:Q,Button:Y,Carousel:xt,Collapse:Bt,Dropdown:qi,Modal:On,Offcanvas:qn,Popover:us,ScrollSpy:Es,Tab:Vs,Toast:ro,Tooltip:cs}})); +//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/docs/site_libs/clipboard/clipboard.min.js b/docs/site_libs/clipboard/clipboard.min.js new file mode 100644 index 0000000..1103f81 --- /dev/null +++ b/docs/site_libs/clipboard/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1.anchorjs-link,.anchorjs-link:focus{opacity:1}",A.sheet.cssRules.length),A.sheet.insertRule("[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}",A.sheet.cssRules.length),A.sheet.insertRule('@font-face{font-family:anchorjs-icons;src:url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype")}',A.sheet.cssRules.length)),h=document.querySelectorAll("[id]"),t=[].map.call(h,function(A){return A.id}),i=0;i\]./()*\\\n\t\b\v\u00A0]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),A=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||A||!1}}}); +// @license-end \ No newline at end of file diff --git a/docs/site_libs/quarto-html/popper.min.js b/docs/site_libs/quarto-html/popper.min.js new file mode 100644 index 0000000..e3726d7 --- /dev/null +++ b/docs/site_libs/quarto-html/popper.min.js @@ -0,0 +1,6 @@ +/** + * @popperjs/core v2.11.7 - MIT License + */ + +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Popper={})}(this,(function(e){"use strict";function t(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function n(e){return e instanceof t(e).Element||e instanceof Element}function r(e){return e instanceof t(e).HTMLElement||e instanceof HTMLElement}function o(e){return"undefined"!=typeof ShadowRoot&&(e instanceof t(e).ShadowRoot||e instanceof ShadowRoot)}var i=Math.max,a=Math.min,s=Math.round;function f(){var e=navigator.userAgentData;return null!=e&&e.brands&&Array.isArray(e.brands)?e.brands.map((function(e){return e.brand+"/"+e.version})).join(" "):navigator.userAgent}function c(){return!/^((?!chrome|android).)*safari/i.test(f())}function p(e,o,i){void 0===o&&(o=!1),void 0===i&&(i=!1);var a=e.getBoundingClientRect(),f=1,p=1;o&&r(e)&&(f=e.offsetWidth>0&&s(a.width)/e.offsetWidth||1,p=e.offsetHeight>0&&s(a.height)/e.offsetHeight||1);var u=(n(e)?t(e):window).visualViewport,l=!c()&&i,d=(a.left+(l&&u?u.offsetLeft:0))/f,h=(a.top+(l&&u?u.offsetTop:0))/p,m=a.width/f,v=a.height/p;return{width:m,height:v,top:h,right:d+m,bottom:h+v,left:d,x:d,y:h}}function u(e){var n=t(e);return{scrollLeft:n.pageXOffset,scrollTop:n.pageYOffset}}function l(e){return e?(e.nodeName||"").toLowerCase():null}function d(e){return((n(e)?e.ownerDocument:e.document)||window.document).documentElement}function h(e){return p(d(e)).left+u(e).scrollLeft}function m(e){return t(e).getComputedStyle(e)}function v(e){var t=m(e),n=t.overflow,r=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+r)}function y(e,n,o){void 0===o&&(o=!1);var i,a,f=r(n),c=r(n)&&function(e){var t=e.getBoundingClientRect(),n=s(t.width)/e.offsetWidth||1,r=s(t.height)/e.offsetHeight||1;return 1!==n||1!==r}(n),m=d(n),y=p(e,c,o),g={scrollLeft:0,scrollTop:0},b={x:0,y:0};return(f||!f&&!o)&&(("body"!==l(n)||v(m))&&(g=(i=n)!==t(i)&&r(i)?{scrollLeft:(a=i).scrollLeft,scrollTop:a.scrollTop}:u(i)),r(n)?((b=p(n,!0)).x+=n.clientLeft,b.y+=n.clientTop):m&&(b.x=h(m))),{x:y.left+g.scrollLeft-b.x,y:y.top+g.scrollTop-b.y,width:y.width,height:y.height}}function g(e){var t=p(e),n=e.offsetWidth,r=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-r)<=1&&(r=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:r}}function b(e){return"html"===l(e)?e:e.assignedSlot||e.parentNode||(o(e)?e.host:null)||d(e)}function x(e){return["html","body","#document"].indexOf(l(e))>=0?e.ownerDocument.body:r(e)&&v(e)?e:x(b(e))}function w(e,n){var r;void 0===n&&(n=[]);var o=x(e),i=o===(null==(r=e.ownerDocument)?void 0:r.body),a=t(o),s=i?[a].concat(a.visualViewport||[],v(o)?o:[]):o,f=n.concat(s);return i?f:f.concat(w(b(s)))}function O(e){return["table","td","th"].indexOf(l(e))>=0}function j(e){return r(e)&&"fixed"!==m(e).position?e.offsetParent:null}function E(e){for(var n=t(e),i=j(e);i&&O(i)&&"static"===m(i).position;)i=j(i);return i&&("html"===l(i)||"body"===l(i)&&"static"===m(i).position)?n:i||function(e){var t=/firefox/i.test(f());if(/Trident/i.test(f())&&r(e)&&"fixed"===m(e).position)return null;var n=b(e);for(o(n)&&(n=n.host);r(n)&&["html","body"].indexOf(l(n))<0;){var i=m(n);if("none"!==i.transform||"none"!==i.perspective||"paint"===i.contain||-1!==["transform","perspective"].indexOf(i.willChange)||t&&"filter"===i.willChange||t&&i.filter&&"none"!==i.filter)return n;n=n.parentNode}return null}(e)||n}var D="top",A="bottom",L="right",P="left",M="auto",k=[D,A,L,P],W="start",B="end",H="viewport",T="popper",R=k.reduce((function(e,t){return e.concat([t+"-"+W,t+"-"+B])}),[]),S=[].concat(k,[M]).reduce((function(e,t){return e.concat([t,t+"-"+W,t+"-"+B])}),[]),V=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function q(e){var t=new Map,n=new Set,r=[];function o(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var r=t.get(e);r&&o(r)}})),r.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||o(e)})),r}function C(e){return e.split("-")[0]}function N(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&o(n)){var r=t;do{if(r&&e.isSameNode(r))return!0;r=r.parentNode||r.host}while(r)}return!1}function I(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function _(e,r,o){return r===H?I(function(e,n){var r=t(e),o=d(e),i=r.visualViewport,a=o.clientWidth,s=o.clientHeight,f=0,p=0;if(i){a=i.width,s=i.height;var u=c();(u||!u&&"fixed"===n)&&(f=i.offsetLeft,p=i.offsetTop)}return{width:a,height:s,x:f+h(e),y:p}}(e,o)):n(r)?function(e,t){var n=p(e,!1,"fixed"===t);return n.top=n.top+e.clientTop,n.left=n.left+e.clientLeft,n.bottom=n.top+e.clientHeight,n.right=n.left+e.clientWidth,n.width=e.clientWidth,n.height=e.clientHeight,n.x=n.left,n.y=n.top,n}(r,o):I(function(e){var t,n=d(e),r=u(e),o=null==(t=e.ownerDocument)?void 0:t.body,a=i(n.scrollWidth,n.clientWidth,o?o.scrollWidth:0,o?o.clientWidth:0),s=i(n.scrollHeight,n.clientHeight,o?o.scrollHeight:0,o?o.clientHeight:0),f=-r.scrollLeft+h(e),c=-r.scrollTop;return"rtl"===m(o||n).direction&&(f+=i(n.clientWidth,o?o.clientWidth:0)-a),{width:a,height:s,x:f,y:c}}(d(e)))}function F(e,t,o,s){var f="clippingParents"===t?function(e){var t=w(b(e)),o=["absolute","fixed"].indexOf(m(e).position)>=0&&r(e)?E(e):e;return n(o)?t.filter((function(e){return n(e)&&N(e,o)&&"body"!==l(e)})):[]}(e):[].concat(t),c=[].concat(f,[o]),p=c[0],u=c.reduce((function(t,n){var r=_(e,n,s);return t.top=i(r.top,t.top),t.right=a(r.right,t.right),t.bottom=a(r.bottom,t.bottom),t.left=i(r.left,t.left),t}),_(e,p,s));return u.width=u.right-u.left,u.height=u.bottom-u.top,u.x=u.left,u.y=u.top,u}function U(e){return e.split("-")[1]}function z(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function X(e){var t,n=e.reference,r=e.element,o=e.placement,i=o?C(o):null,a=o?U(o):null,s=n.x+n.width/2-r.width/2,f=n.y+n.height/2-r.height/2;switch(i){case D:t={x:s,y:n.y-r.height};break;case A:t={x:s,y:n.y+n.height};break;case L:t={x:n.x+n.width,y:f};break;case P:t={x:n.x-r.width,y:f};break;default:t={x:n.x,y:n.y}}var c=i?z(i):null;if(null!=c){var p="y"===c?"height":"width";switch(a){case W:t[c]=t[c]-(n[p]/2-r[p]/2);break;case B:t[c]=t[c]+(n[p]/2-r[p]/2)}}return t}function Y(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function G(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function J(e,t){void 0===t&&(t={});var r=t,o=r.placement,i=void 0===o?e.placement:o,a=r.strategy,s=void 0===a?e.strategy:a,f=r.boundary,c=void 0===f?"clippingParents":f,u=r.rootBoundary,l=void 0===u?H:u,h=r.elementContext,m=void 0===h?T:h,v=r.altBoundary,y=void 0!==v&&v,g=r.padding,b=void 0===g?0:g,x=Y("number"!=typeof b?b:G(b,k)),w=m===T?"reference":T,O=e.rects.popper,j=e.elements[y?w:m],E=F(n(j)?j:j.contextElement||d(e.elements.popper),c,l,s),P=p(e.elements.reference),M=X({reference:P,element:O,strategy:"absolute",placement:i}),W=I(Object.assign({},O,M)),B=m===T?W:P,R={top:E.top-B.top+x.top,bottom:B.bottom-E.bottom+x.bottom,left:E.left-B.left+x.left,right:B.right-E.right+x.right},S=e.modifiersData.offset;if(m===T&&S){var V=S[i];Object.keys(R).forEach((function(e){var t=[L,A].indexOf(e)>=0?1:-1,n=[D,A].indexOf(e)>=0?"y":"x";R[e]+=V[n]*t}))}return R}var K={placement:"bottom",modifiers:[],strategy:"absolute"};function Q(){for(var e=arguments.length,t=new Array(e),n=0;n=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*o,[P,L].indexOf(r)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],f=s.x,c=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=f,t.modifiersData.popperOffsets.y+=c),t.modifiersData[r]=a}},se={left:"right",right:"left",bottom:"top",top:"bottom"};function fe(e){return e.replace(/left|right|bottom|top/g,(function(e){return se[e]}))}var ce={start:"end",end:"start"};function pe(e){return e.replace(/start|end/g,(function(e){return ce[e]}))}function ue(e,t){void 0===t&&(t={});var n=t,r=n.placement,o=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,f=n.allowedAutoPlacements,c=void 0===f?S:f,p=U(r),u=p?s?R:R.filter((function(e){return U(e)===p})):k,l=u.filter((function(e){return c.indexOf(e)>=0}));0===l.length&&(l=u);var d=l.reduce((function(t,n){return t[n]=J(e,{placement:n,boundary:o,rootBoundary:i,padding:a})[C(n)],t}),{});return Object.keys(d).sort((function(e,t){return d[e]-d[t]}))}var le={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name;if(!t.modifiersData[r]._skip){for(var o=n.mainAxis,i=void 0===o||o,a=n.altAxis,s=void 0===a||a,f=n.fallbackPlacements,c=n.padding,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.flipVariations,h=void 0===d||d,m=n.allowedAutoPlacements,v=t.options.placement,y=C(v),g=f||(y===v||!h?[fe(v)]:function(e){if(C(e)===M)return[];var t=fe(e);return[pe(e),t,pe(t)]}(v)),b=[v].concat(g).reduce((function(e,n){return e.concat(C(n)===M?ue(t,{placement:n,boundary:p,rootBoundary:u,padding:c,flipVariations:h,allowedAutoPlacements:m}):n)}),[]),x=t.rects.reference,w=t.rects.popper,O=new Map,j=!0,E=b[0],k=0;k=0,S=R?"width":"height",V=J(t,{placement:B,boundary:p,rootBoundary:u,altBoundary:l,padding:c}),q=R?T?L:P:T?A:D;x[S]>w[S]&&(q=fe(q));var N=fe(q),I=[];if(i&&I.push(V[H]<=0),s&&I.push(V[q]<=0,V[N]<=0),I.every((function(e){return e}))){E=B,j=!1;break}O.set(B,I)}if(j)for(var _=function(e){var t=b.find((function(t){var n=O.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return E=t,"break"},F=h?3:1;F>0;F--){if("break"===_(F))break}t.placement!==E&&(t.modifiersData[r]._skip=!0,t.placement=E,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function de(e,t,n){return i(e,a(t,n))}var he={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.mainAxis,s=void 0===o||o,f=n.altAxis,c=void 0!==f&&f,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.padding,h=n.tether,m=void 0===h||h,v=n.tetherOffset,y=void 0===v?0:v,b=J(t,{boundary:p,rootBoundary:u,padding:d,altBoundary:l}),x=C(t.placement),w=U(t.placement),O=!w,j=z(x),M="x"===j?"y":"x",k=t.modifiersData.popperOffsets,B=t.rects.reference,H=t.rects.popper,T="function"==typeof y?y(Object.assign({},t.rects,{placement:t.placement})):y,R="number"==typeof T?{mainAxis:T,altAxis:T}:Object.assign({mainAxis:0,altAxis:0},T),S=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,V={x:0,y:0};if(k){if(s){var q,N="y"===j?D:P,I="y"===j?A:L,_="y"===j?"height":"width",F=k[j],X=F+b[N],Y=F-b[I],G=m?-H[_]/2:0,K=w===W?B[_]:H[_],Q=w===W?-H[_]:-B[_],Z=t.elements.arrow,$=m&&Z?g(Z):{width:0,height:0},ee=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},te=ee[N],ne=ee[I],re=de(0,B[_],$[_]),oe=O?B[_]/2-G-re-te-R.mainAxis:K-re-te-R.mainAxis,ie=O?-B[_]/2+G+re+ne+R.mainAxis:Q+re+ne+R.mainAxis,ae=t.elements.arrow&&E(t.elements.arrow),se=ae?"y"===j?ae.clientTop||0:ae.clientLeft||0:0,fe=null!=(q=null==S?void 0:S[j])?q:0,ce=F+ie-fe,pe=de(m?a(X,F+oe-fe-se):X,F,m?i(Y,ce):Y);k[j]=pe,V[j]=pe-F}if(c){var ue,le="x"===j?D:P,he="x"===j?A:L,me=k[M],ve="y"===M?"height":"width",ye=me+b[le],ge=me-b[he],be=-1!==[D,P].indexOf(x),xe=null!=(ue=null==S?void 0:S[M])?ue:0,we=be?ye:me-B[ve]-H[ve]-xe+R.altAxis,Oe=be?me+B[ve]+H[ve]-xe-R.altAxis:ge,je=m&&be?function(e,t,n){var r=de(e,t,n);return r>n?n:r}(we,me,Oe):de(m?we:ye,me,m?Oe:ge);k[M]=je,V[M]=je-me}t.modifiersData[r]=V}},requiresIfExists:["offset"]};var me={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,r=e.name,o=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=C(n.placement),f=z(s),c=[P,L].indexOf(s)>=0?"height":"width";if(i&&a){var p=function(e,t){return Y("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:G(e,k))}(o.padding,n),u=g(i),l="y"===f?D:P,d="y"===f?A:L,h=n.rects.reference[c]+n.rects.reference[f]-a[f]-n.rects.popper[c],m=a[f]-n.rects.reference[f],v=E(i),y=v?"y"===f?v.clientHeight||0:v.clientWidth||0:0,b=h/2-m/2,x=p[l],w=y-u[c]-p[d],O=y/2-u[c]/2+b,j=de(x,O,w),M=f;n.modifiersData[r]=((t={})[M]=j,t.centerOffset=j-O,t)}},effect:function(e){var t=e.state,n=e.options.element,r=void 0===n?"[data-popper-arrow]":n;null!=r&&("string"!=typeof r||(r=t.elements.popper.querySelector(r)))&&N(t.elements.popper,r)&&(t.elements.arrow=r)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ve(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function ye(e){return[D,L,A,P].some((function(t){return e[t]>=0}))}var ge={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,r=t.rects.reference,o=t.rects.popper,i=t.modifiersData.preventOverflow,a=J(t,{elementContext:"reference"}),s=J(t,{altBoundary:!0}),f=ve(a,r),c=ve(s,o,i),p=ye(f),u=ye(c);t.modifiersData[n]={referenceClippingOffsets:f,popperEscapeOffsets:c,isReferenceHidden:p,hasPopperEscaped:u},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":p,"data-popper-escaped":u})}},be=Z({defaultModifiers:[ee,te,oe,ie]}),xe=[ee,te,oe,ie,ae,le,he,me,ge],we=Z({defaultModifiers:xe});e.applyStyles=ie,e.arrow=me,e.computeStyles=oe,e.createPopper=we,e.createPopperLite=be,e.defaultModifiers=xe,e.detectOverflow=J,e.eventListeners=ee,e.flip=le,e.hide=ge,e.offset=ae,e.popperGenerator=Z,e.popperOffsets=te,e.preventOverflow=he,Object.defineProperty(e,"__esModule",{value:!0})})); + diff --git a/docs/site_libs/quarto-html/quarto-syntax-highlighting-15634bcf2e68342d4ad2dfa704d543f6.css b/docs/site_libs/quarto-html/quarto-syntax-highlighting-15634bcf2e68342d4ad2dfa704d543f6.css new file mode 100644 index 0000000..180f8c7 --- /dev/null +++ b/docs/site_libs/quarto-html/quarto-syntax-highlighting-15634bcf2e68342d4ad2dfa704d543f6.css @@ -0,0 +1,236 @@ +/* quarto syntax highlight colors */ +:root { + --quarto-hl-ot-color: #003B4F; + --quarto-hl-at-color: #657422; + --quarto-hl-ss-color: #20794D; + --quarto-hl-an-color: #5E5E5E; + --quarto-hl-fu-color: #4758AB; + --quarto-hl-st-color: #20794D; + --quarto-hl-cf-color: #003B4F; + --quarto-hl-op-color: #5E5E5E; + --quarto-hl-er-color: #AD0000; + --quarto-hl-bn-color: #AD0000; + --quarto-hl-al-color: #AD0000; + --quarto-hl-va-color: #111111; + --quarto-hl-bu-color: inherit; + --quarto-hl-ex-color: inherit; + --quarto-hl-pp-color: #AD0000; + --quarto-hl-in-color: #5E5E5E; + --quarto-hl-vs-color: #20794D; + --quarto-hl-wa-color: #5E5E5E; + --quarto-hl-do-color: #5E5E5E; + --quarto-hl-im-color: #00769E; + --quarto-hl-ch-color: #20794D; + --quarto-hl-dt-color: #AD0000; + --quarto-hl-fl-color: #AD0000; + --quarto-hl-co-color: #5E5E5E; + --quarto-hl-cv-color: #5E5E5E; + --quarto-hl-cn-color: #8f5902; + --quarto-hl-sc-color: #5E5E5E; + --quarto-hl-dv-color: #AD0000; + --quarto-hl-kw-color: #003B4F; +} + +/* other quarto variables */ +:root { + --quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +/* syntax highlight based on Pandoc's rules */ +pre > code.sourceCode > span { + color: #003B4F; +} + +code.sourceCode > span { + color: #003B4F; +} + +div.sourceCode, +div.sourceCode pre.sourceCode { + color: #003B4F; +} + +/* Normal */ +code span { + color: #003B4F; +} + +/* Alert */ +code span.al { + color: #AD0000; + font-style: inherit; +} + +/* Annotation */ +code span.an { + color: #5E5E5E; + font-style: inherit; +} + +/* Attribute */ +code span.at { + color: #657422; + font-style: inherit; +} + +/* BaseN */ +code span.bn { + color: #AD0000; + font-style: inherit; +} + +/* BuiltIn */ +code span.bu { + font-style: inherit; +} + +/* ControlFlow */ +code span.cf { + color: #003B4F; + font-weight: bold; + font-style: inherit; +} + +/* Char */ +code span.ch { + color: #20794D; + font-style: inherit; +} + +/* Constant */ +code span.cn { + color: #8f5902; + font-style: inherit; +} + +/* Comment */ +code span.co { + color: #5E5E5E; + font-style: inherit; +} + +/* CommentVar */ +code span.cv { + color: #5E5E5E; + font-style: italic; +} + +/* Documentation */ +code span.do { + color: #5E5E5E; + font-style: italic; +} + +/* DataType */ +code span.dt { + color: #AD0000; + font-style: inherit; +} + +/* DecVal */ +code span.dv { + color: #AD0000; + font-style: inherit; +} + +/* Error */ +code span.er { + color: #AD0000; + font-style: inherit; +} + +/* Extension */ +code span.ex { + font-style: inherit; +} + +/* Float */ +code span.fl { + color: #AD0000; + font-style: inherit; +} + +/* Function */ +code span.fu { + color: #4758AB; + font-style: inherit; +} + +/* Import */ +code span.im { + color: #00769E; + font-style: inherit; +} + +/* Information */ +code span.in { + color: #5E5E5E; + font-style: inherit; +} + +/* Keyword */ +code span.kw { + color: #003B4F; + font-weight: bold; + font-style: inherit; +} + +/* Operator */ +code span.op { + color: #5E5E5E; + font-style: inherit; +} + +/* Other */ +code span.ot { + color: #003B4F; + font-style: inherit; +} + +/* Preprocessor */ +code span.pp { + color: #AD0000; + font-style: inherit; +} + +/* SpecialChar */ +code span.sc { + color: #5E5E5E; + font-style: inherit; +} + +/* SpecialString */ +code span.ss { + color: #20794D; + font-style: inherit; +} + +/* String */ +code span.st { + color: #20794D; + font-style: inherit; +} + +/* Variable */ +code span.va { + color: #111111; + font-style: inherit; +} + +/* VerbatimString */ +code span.vs { + color: #20794D; + font-style: inherit; +} + +/* Warning */ +code span.wa { + color: #5E5E5E; + font-style: italic; +} + +.prevent-inlining { + content: " { + // Find any conflicting margin elements and add margins to the + // top to prevent overlap + const marginChildren = window.document.querySelectorAll( + ".column-margin.column-container > *, .margin-caption, .aside" + ); + + let lastBottom = 0; + for (const marginChild of marginChildren) { + if (marginChild.offsetParent !== null) { + // clear the top margin so we recompute it + marginChild.style.marginTop = null; + const top = marginChild.getBoundingClientRect().top + window.scrollY; + if (top < lastBottom) { + const marginChildStyle = window.getComputedStyle(marginChild); + const marginBottom = parseFloat(marginChildStyle["marginBottom"]); + const margin = lastBottom - top + marginBottom; + marginChild.style.marginTop = `${margin}px`; + } + const styles = window.getComputedStyle(marginChild); + const marginTop = parseFloat(styles["marginTop"]); + lastBottom = top + marginChild.getBoundingClientRect().height + marginTop; + } + } +}; + +window.document.addEventListener("DOMContentLoaded", function (_event) { + // Recompute the position of margin elements anytime the body size changes + if (window.ResizeObserver) { + const resizeObserver = new window.ResizeObserver( + throttle(() => { + layoutMarginEls(); + if ( + window.document.body.getBoundingClientRect().width < 990 && + isReaderMode() + ) { + quartoToggleReader(); + } + }, 50) + ); + resizeObserver.observe(window.document.body); + } + + const tocEl = window.document.querySelector('nav.toc-active[role="doc-toc"]'); + const sidebarEl = window.document.getElementById("quarto-sidebar"); + const leftTocEl = window.document.getElementById("quarto-sidebar-toc-left"); + const marginSidebarEl = window.document.getElementById( + "quarto-margin-sidebar" + ); + // function to determine whether the element has a previous sibling that is active + const prevSiblingIsActiveLink = (el) => { + const sibling = el.previousElementSibling; + if (sibling && sibling.tagName === "A") { + return sibling.classList.contains("active"); + } else { + return false; + } + }; + + // dispatch for htmlwidgets + // they use slideenter event to trigger resize + function fireSlideEnter() { + const event = window.document.createEvent("Event"); + event.initEvent("slideenter", true, true); + window.document.dispatchEvent(event); + } + + const tabs = window.document.querySelectorAll('a[data-bs-toggle="tab"]'); + tabs.forEach((tab) => { + tab.addEventListener("shown.bs.tab", fireSlideEnter); + }); + + // dispatch for shiny + // they use BS shown and hidden events to trigger rendering + function distpatchShinyEvents(previous, current) { + if (window.jQuery) { + if (previous) { + window.jQuery(previous).trigger("hidden"); + } + if (current) { + window.jQuery(current).trigger("shown"); + } + } + } + + // tabby.js listener: Trigger event for htmlwidget and shiny + document.addEventListener( + "tabby", + function (event) { + fireSlideEnter(); + distpatchShinyEvents(event.detail.previousTab, event.detail.tab); + }, + false + ); + + // Track scrolling and mark TOC links as active + // get table of contents and sidebar (bail if we don't have at least one) + const tocLinks = tocEl + ? [...tocEl.querySelectorAll("a[data-scroll-target]")] + : []; + const makeActive = (link) => tocLinks[link].classList.add("active"); + const removeActive = (link) => tocLinks[link].classList.remove("active"); + const removeAllActive = () => + [...Array(tocLinks.length).keys()].forEach((link) => removeActive(link)); + + // activate the anchor for a section associated with this TOC entry + tocLinks.forEach((link) => { + link.addEventListener("click", () => { + if (link.href.indexOf("#") !== -1) { + const anchor = link.href.split("#")[1]; + const heading = window.document.querySelector( + `[data-anchor-id="${anchor}"]` + ); + if (heading) { + // Add the class + heading.classList.add("reveal-anchorjs-link"); + + // function to show the anchor + const handleMouseout = () => { + heading.classList.remove("reveal-anchorjs-link"); + heading.removeEventListener("mouseout", handleMouseout); + }; + + // add a function to clear the anchor when the user mouses out of it + heading.addEventListener("mouseout", handleMouseout); + } + } + }); + }); + + const sections = tocLinks.map((link) => { + const target = link.getAttribute("data-scroll-target"); + if (target.startsWith("#")) { + return window.document.getElementById(decodeURI(`${target.slice(1)}`)); + } else { + return window.document.querySelector(decodeURI(`${target}`)); + } + }); + + const sectionMargin = 200; + let currentActive = 0; + // track whether we've initialized state the first time + let init = false; + + const updateActiveLink = () => { + // The index from bottom to top (e.g. reversed list) + let sectionIndex = -1; + if ( + window.innerHeight + window.pageYOffset >= + window.document.body.offsetHeight + ) { + // This is the no-scroll case where last section should be the active one + sectionIndex = 0; + } else { + // This finds the last section visible on screen that should be made active + sectionIndex = [...sections].reverse().findIndex((section) => { + if (section) { + return window.pageYOffset >= section.offsetTop - sectionMargin; + } else { + return false; + } + }); + } + if (sectionIndex > -1) { + const current = sections.length - sectionIndex - 1; + if (current !== currentActive) { + removeAllActive(); + currentActive = current; + makeActive(current); + if (init) { + window.dispatchEvent(sectionChanged); + } + init = true; + } + } + }; + + const inHiddenRegion = (top, bottom, hiddenRegions) => { + for (const region of hiddenRegions) { + if (top <= region.bottom && bottom >= region.top) { + return true; + } + } + return false; + }; + + const categorySelector = "header.quarto-title-block .quarto-category"; + const activateCategories = (href) => { + // Find any categories + // Surround them with a link pointing back to: + // #category=Authoring + try { + const categoryEls = window.document.querySelectorAll(categorySelector); + for (const categoryEl of categoryEls) { + const categoryText = categoryEl.textContent; + if (categoryText) { + const link = `${href}#category=${encodeURIComponent(categoryText)}`; + const linkEl = window.document.createElement("a"); + linkEl.setAttribute("href", link); + for (const child of categoryEl.childNodes) { + linkEl.append(child); + } + categoryEl.appendChild(linkEl); + } + } + } catch { + // Ignore errors + } + }; + function hasTitleCategories() { + return window.document.querySelector(categorySelector) !== null; + } + + function offsetRelativeUrl(url) { + const offset = getMeta("quarto:offset"); + return offset ? offset + url : url; + } + + function offsetAbsoluteUrl(url) { + const offset = getMeta("quarto:offset"); + const baseUrl = new URL(offset, window.location); + + const projRelativeUrl = url.replace(baseUrl, ""); + if (projRelativeUrl.startsWith("/")) { + return projRelativeUrl; + } else { + return "/" + projRelativeUrl; + } + } + + // read a meta tag value + function getMeta(metaName) { + const metas = window.document.getElementsByTagName("meta"); + for (let i = 0; i < metas.length; i++) { + if (metas[i].getAttribute("name") === metaName) { + return metas[i].getAttribute("content"); + } + } + return ""; + } + + async function findAndActivateCategories() { + // Categories search with listing only use path without query + const currentPagePath = offsetAbsoluteUrl( + window.location.origin + window.location.pathname + ); + const response = await fetch(offsetRelativeUrl("listings.json")); + if (response.status == 200) { + return response.json().then(function (listingPaths) { + const listingHrefs = []; + for (const listingPath of listingPaths) { + const pathWithoutLeadingSlash = listingPath.listing.substring(1); + for (const item of listingPath.items) { + const encodedItem = encodeURI(item); + if ( + encodedItem === currentPagePath || + encodedItem === currentPagePath + "index.html" + ) { + // Resolve this path against the offset to be sure + // we already are using the correct path to the listing + // (this adjusts the listing urls to be rooted against + // whatever root the page is actually running against) + const relative = offsetRelativeUrl(pathWithoutLeadingSlash); + const baseUrl = window.location; + const resolvedPath = new URL(relative, baseUrl); + listingHrefs.push(resolvedPath.pathname); + break; + } + } + } + + // Look up the tree for a nearby linting and use that if we find one + const nearestListing = findNearestParentListing( + offsetAbsoluteUrl(window.location.pathname), + listingHrefs + ); + if (nearestListing) { + activateCategories(nearestListing); + } else { + // See if the referrer is a listing page for this item + const referredRelativePath = offsetAbsoluteUrl(document.referrer); + const referrerListing = listingHrefs.find((listingHref) => { + const isListingReferrer = + listingHref === referredRelativePath || + listingHref === referredRelativePath + "index.html"; + return isListingReferrer; + }); + + if (referrerListing) { + // Try to use the referrer if possible + activateCategories(referrerListing); + } else if (listingHrefs.length > 0) { + // Otherwise, just fall back to the first listing + activateCategories(listingHrefs[0]); + } + } + }); + } + } + if (hasTitleCategories()) { + findAndActivateCategories(); + } + + const findNearestParentListing = (href, listingHrefs) => { + if (!href || !listingHrefs) { + return undefined; + } + // Look up the tree for a nearby linting and use that if we find one + const relativeParts = href.substring(1).split("/"); + while (relativeParts.length > 0) { + const path = relativeParts.join("/"); + for (const listingHref of listingHrefs) { + if (listingHref.startsWith(path)) { + return listingHref; + } + } + relativeParts.pop(); + } + + return undefined; + }; + + const manageSidebarVisiblity = (el, placeholderDescriptor) => { + let isVisible = true; + let elRect; + + return (hiddenRegions) => { + if (el === null) { + return; + } + + // Find the last element of the TOC + const lastChildEl = el.lastElementChild; + + if (lastChildEl) { + // Converts the sidebar to a menu + const convertToMenu = () => { + for (const child of el.children) { + child.style.opacity = 0; + child.style.overflow = "hidden"; + child.style.pointerEvents = "none"; + } + + nexttick(() => { + const toggleContainer = window.document.createElement("div"); + toggleContainer.style.width = "100%"; + toggleContainer.classList.add("zindex-over-content"); + toggleContainer.classList.add("quarto-sidebar-toggle"); + toggleContainer.classList.add("headroom-target"); // Marks this to be managed by headeroom + toggleContainer.id = placeholderDescriptor.id; + toggleContainer.style.position = "fixed"; + + const toggleIcon = window.document.createElement("i"); + toggleIcon.classList.add("quarto-sidebar-toggle-icon"); + toggleIcon.classList.add("bi"); + toggleIcon.classList.add("bi-caret-down-fill"); + + const toggleTitle = window.document.createElement("div"); + const titleEl = window.document.body.querySelector( + placeholderDescriptor.titleSelector + ); + if (titleEl) { + toggleTitle.append( + titleEl.textContent || titleEl.innerText, + toggleIcon + ); + } + toggleTitle.classList.add("zindex-over-content"); + toggleTitle.classList.add("quarto-sidebar-toggle-title"); + toggleContainer.append(toggleTitle); + + const toggleContents = window.document.createElement("div"); + toggleContents.classList = el.classList; + toggleContents.classList.add("zindex-over-content"); + toggleContents.classList.add("quarto-sidebar-toggle-contents"); + for (const child of el.children) { + if (child.id === "toc-title") { + continue; + } + + const clone = child.cloneNode(true); + clone.style.opacity = 1; + clone.style.pointerEvents = null; + clone.style.display = null; + toggleContents.append(clone); + } + toggleContents.style.height = "0px"; + const positionToggle = () => { + // position the element (top left of parent, same width as parent) + if (!elRect) { + elRect = el.getBoundingClientRect(); + } + toggleContainer.style.left = `${elRect.left}px`; + toggleContainer.style.top = `${elRect.top}px`; + toggleContainer.style.width = `${elRect.width}px`; + }; + positionToggle(); + + toggleContainer.append(toggleContents); + el.parentElement.prepend(toggleContainer); + + // Process clicks + let tocShowing = false; + // Allow the caller to control whether this is dismissed + // when it is clicked (e.g. sidebar navigation supports + // opening and closing the nav tree, so don't dismiss on click) + const clickEl = placeholderDescriptor.dismissOnClick + ? toggleContainer + : toggleTitle; + + const closeToggle = () => { + if (tocShowing) { + toggleContainer.classList.remove("expanded"); + toggleContents.style.height = "0px"; + tocShowing = false; + } + }; + + // Get rid of any expanded toggle if the user scrolls + window.document.addEventListener( + "scroll", + throttle(() => { + closeToggle(); + }, 50) + ); + + // Handle positioning of the toggle + window.addEventListener( + "resize", + throttle(() => { + elRect = undefined; + positionToggle(); + }, 50) + ); + + window.addEventListener("quarto-hrChanged", () => { + elRect = undefined; + }); + + // Process the click + clickEl.onclick = () => { + if (!tocShowing) { + toggleContainer.classList.add("expanded"); + toggleContents.style.height = null; + tocShowing = true; + } else { + closeToggle(); + } + }; + }); + }; + + // Converts a sidebar from a menu back to a sidebar + const convertToSidebar = () => { + for (const child of el.children) { + child.style.opacity = 1; + child.style.overflow = null; + child.style.pointerEvents = null; + } + + const placeholderEl = window.document.getElementById( + placeholderDescriptor.id + ); + if (placeholderEl) { + placeholderEl.remove(); + } + + el.classList.remove("rollup"); + }; + + if (isReaderMode()) { + convertToMenu(); + isVisible = false; + } else { + // Find the top and bottom o the element that is being managed + const elTop = el.offsetTop; + const elBottom = + elTop + lastChildEl.offsetTop + lastChildEl.offsetHeight; + + if (!isVisible) { + // If the element is current not visible reveal if there are + // no conflicts with overlay regions + if (!inHiddenRegion(elTop, elBottom, hiddenRegions)) { + convertToSidebar(); + isVisible = true; + } + } else { + // If the element is visible, hide it if it conflicts with overlay regions + // and insert a placeholder toggle (or if we're in reader mode) + if (inHiddenRegion(elTop, elBottom, hiddenRegions)) { + convertToMenu(); + isVisible = false; + } + } + } + } + }; + }; + + const tabEls = document.querySelectorAll('a[data-bs-toggle="tab"]'); + for (const tabEl of tabEls) { + const id = tabEl.getAttribute("data-bs-target"); + if (id) { + const columnEl = document.querySelector( + `${id} .column-margin, .tabset-margin-content` + ); + if (columnEl) + tabEl.addEventListener("shown.bs.tab", function (event) { + const el = event.srcElement; + if (el) { + const visibleCls = `${el.id}-margin-content`; + // walk up until we find a parent tabset + let panelTabsetEl = el.parentElement; + while (panelTabsetEl) { + if (panelTabsetEl.classList.contains("panel-tabset")) { + break; + } + panelTabsetEl = panelTabsetEl.parentElement; + } + + if (panelTabsetEl) { + const prevSib = panelTabsetEl.previousElementSibling; + if ( + prevSib && + prevSib.classList.contains("tabset-margin-container") + ) { + const childNodes = prevSib.querySelectorAll( + ".tabset-margin-content" + ); + for (const childEl of childNodes) { + if (childEl.classList.contains(visibleCls)) { + childEl.classList.remove("collapse"); + } else { + childEl.classList.add("collapse"); + } + } + } + } + } + + layoutMarginEls(); + }); + } + } + + // Manage the visibility of the toc and the sidebar + const marginScrollVisibility = manageSidebarVisiblity(marginSidebarEl, { + id: "quarto-toc-toggle", + titleSelector: "#toc-title", + dismissOnClick: true, + }); + const sidebarScrollVisiblity = manageSidebarVisiblity(sidebarEl, { + id: "quarto-sidebarnav-toggle", + titleSelector: ".title", + dismissOnClick: false, + }); + let tocLeftScrollVisibility; + if (leftTocEl) { + tocLeftScrollVisibility = manageSidebarVisiblity(leftTocEl, { + id: "quarto-lefttoc-toggle", + titleSelector: "#toc-title", + dismissOnClick: true, + }); + } + + // Find the first element that uses formatting in special columns + const conflictingEls = window.document.body.querySelectorAll( + '[class^="column-"], [class*=" column-"], aside, [class*="margin-caption"], [class*=" margin-caption"], [class*="margin-ref"], [class*=" margin-ref"]' + ); + + // Filter all the possibly conflicting elements into ones + // the do conflict on the left or ride side + const arrConflictingEls = Array.from(conflictingEls); + const leftSideConflictEls = arrConflictingEls.filter((el) => { + if (el.tagName === "ASIDE") { + return false; + } + return Array.from(el.classList).find((className) => { + return ( + className !== "column-body" && + className.startsWith("column-") && + !className.endsWith("right") && + !className.endsWith("container") && + className !== "column-margin" + ); + }); + }); + const rightSideConflictEls = arrConflictingEls.filter((el) => { + if (el.tagName === "ASIDE") { + return true; + } + + const hasMarginCaption = Array.from(el.classList).find((className) => { + return className == "margin-caption"; + }); + if (hasMarginCaption) { + return true; + } + + return Array.from(el.classList).find((className) => { + return ( + className !== "column-body" && + !className.endsWith("container") && + className.startsWith("column-") && + !className.endsWith("left") + ); + }); + }); + + const kOverlapPaddingSize = 10; + function toRegions(els) { + return els.map((el) => { + const boundRect = el.getBoundingClientRect(); + const top = + boundRect.top + + document.documentElement.scrollTop - + kOverlapPaddingSize; + return { + top, + bottom: top + el.scrollHeight + 2 * kOverlapPaddingSize, + }; + }); + } + + let hasObserved = false; + const visibleItemObserver = (els) => { + let visibleElements = [...els]; + const intersectionObserver = new IntersectionObserver( + (entries, _observer) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + if (visibleElements.indexOf(entry.target) === -1) { + visibleElements.push(entry.target); + } + } else { + visibleElements = visibleElements.filter((visibleEntry) => { + return visibleEntry !== entry; + }); + } + }); + + if (!hasObserved) { + hideOverlappedSidebars(); + } + hasObserved = true; + }, + {} + ); + els.forEach((el) => { + intersectionObserver.observe(el); + }); + + return { + getVisibleEntries: () => { + return visibleElements; + }, + }; + }; + + const rightElementObserver = visibleItemObserver(rightSideConflictEls); + const leftElementObserver = visibleItemObserver(leftSideConflictEls); + + const hideOverlappedSidebars = () => { + marginScrollVisibility(toRegions(rightElementObserver.getVisibleEntries())); + sidebarScrollVisiblity(toRegions(leftElementObserver.getVisibleEntries())); + if (tocLeftScrollVisibility) { + tocLeftScrollVisibility( + toRegions(leftElementObserver.getVisibleEntries()) + ); + } + }; + + window.quartoToggleReader = () => { + // Applies a slow class (or removes it) + // to update the transition speed + const slowTransition = (slow) => { + const manageTransition = (id, slow) => { + const el = document.getElementById(id); + if (el) { + if (slow) { + el.classList.add("slow"); + } else { + el.classList.remove("slow"); + } + } + }; + + manageTransition("TOC", slow); + manageTransition("quarto-sidebar", slow); + }; + const readerMode = !isReaderMode(); + setReaderModeValue(readerMode); + + // If we're entering reader mode, slow the transition + if (readerMode) { + slowTransition(readerMode); + } + highlightReaderToggle(readerMode); + hideOverlappedSidebars(); + + // If we're exiting reader mode, restore the non-slow transition + if (!readerMode) { + slowTransition(!readerMode); + } + }; + + const highlightReaderToggle = (readerMode) => { + const els = document.querySelectorAll(".quarto-reader-toggle"); + if (els) { + els.forEach((el) => { + if (readerMode) { + el.classList.add("reader"); + } else { + el.classList.remove("reader"); + } + }); + } + }; + + const setReaderModeValue = (val) => { + if (window.location.protocol !== "file:") { + window.localStorage.setItem("quarto-reader-mode", val); + } else { + localReaderMode = val; + } + }; + + const isReaderMode = () => { + if (window.location.protocol !== "file:") { + return window.localStorage.getItem("quarto-reader-mode") === "true"; + } else { + return localReaderMode; + } + }; + let localReaderMode = null; + + const tocOpenDepthStr = tocEl?.getAttribute("data-toc-expanded"); + const tocOpenDepth = tocOpenDepthStr ? Number(tocOpenDepthStr) : 1; + + // Walk the TOC and collapse/expand nodes + // Nodes are expanded if: + // - they are top level + // - they have children that are 'active' links + // - they are directly below an link that is 'active' + const walk = (el, depth) => { + // Tick depth when we enter a UL + if (el.tagName === "UL") { + depth = depth + 1; + } + + // It this is active link + let isActiveNode = false; + if (el.tagName === "A" && el.classList.contains("active")) { + isActiveNode = true; + } + + // See if there is an active child to this element + let hasActiveChild = false; + for (const child of el.children) { + hasActiveChild = walk(child, depth) || hasActiveChild; + } + + // Process the collapse state if this is an UL + if (el.tagName === "UL") { + if (tocOpenDepth === -1 && depth > 1) { + // toc-expand: false + el.classList.add("collapse"); + } else if ( + depth <= tocOpenDepth || + hasActiveChild || + prevSiblingIsActiveLink(el) + ) { + el.classList.remove("collapse"); + } else { + el.classList.add("collapse"); + } + + // untick depth when we leave a UL + depth = depth - 1; + } + return hasActiveChild || isActiveNode; + }; + + // walk the TOC and expand / collapse any items that should be shown + if (tocEl) { + updateActiveLink(); + walk(tocEl, 0); + } + + // Throttle the scroll event and walk peridiocally + window.document.addEventListener( + "scroll", + throttle(() => { + if (tocEl) { + updateActiveLink(); + walk(tocEl, 0); + } + if (!isReaderMode()) { + hideOverlappedSidebars(); + } + }, 5) + ); + window.addEventListener( + "resize", + throttle(() => { + if (tocEl) { + updateActiveLink(); + walk(tocEl, 0); + } + if (!isReaderMode()) { + hideOverlappedSidebars(); + } + }, 10) + ); + hideOverlappedSidebars(); + highlightReaderToggle(isReaderMode()); +}); + +tabsets.init(); + +function throttle(func, wait) { + let waiting = false; + return function () { + if (!waiting) { + func.apply(this, arguments); + waiting = true; + setTimeout(function () { + waiting = false; + }, wait); + } + }; +} + +function nexttick(func) { + return setTimeout(func, 0); +} diff --git a/docs/site_libs/quarto-html/tabsets/tabsets.js b/docs/site_libs/quarto-html/tabsets/tabsets.js new file mode 100644 index 0000000..51345d0 --- /dev/null +++ b/docs/site_libs/quarto-html/tabsets/tabsets.js @@ -0,0 +1,95 @@ +// grouped tabsets + +export function init() { + window.addEventListener("pageshow", (_event) => { + function getTabSettings() { + const data = localStorage.getItem("quarto-persistent-tabsets-data"); + if (!data) { + localStorage.setItem("quarto-persistent-tabsets-data", "{}"); + return {}; + } + if (data) { + return JSON.parse(data); + } + } + + function setTabSettings(data) { + localStorage.setItem( + "quarto-persistent-tabsets-data", + JSON.stringify(data) + ); + } + + function setTabState(groupName, groupValue) { + const data = getTabSettings(); + data[groupName] = groupValue; + setTabSettings(data); + } + + function toggleTab(tab, active) { + const tabPanelId = tab.getAttribute("aria-controls"); + const tabPanel = document.getElementById(tabPanelId); + if (active) { + tab.classList.add("active"); + tabPanel.classList.add("active"); + } else { + tab.classList.remove("active"); + tabPanel.classList.remove("active"); + } + } + + function toggleAll(selectedGroup, selectorsToSync) { + for (const [thisGroup, tabs] of Object.entries(selectorsToSync)) { + const active = selectedGroup === thisGroup; + for (const tab of tabs) { + toggleTab(tab, active); + } + } + } + + function findSelectorsToSyncByLanguage() { + const result = {}; + const tabs = Array.from( + document.querySelectorAll(`div[data-group] a[id^='tabset-']`) + ); + for (const item of tabs) { + const div = item.parentElement.parentElement.parentElement; + const group = div.getAttribute("data-group"); + if (!result[group]) { + result[group] = {}; + } + const selectorsToSync = result[group]; + const value = item.innerHTML; + if (!selectorsToSync[value]) { + selectorsToSync[value] = []; + } + selectorsToSync[value].push(item); + } + return result; + } + + function setupSelectorSync() { + const selectorsToSync = findSelectorsToSyncByLanguage(); + Object.entries(selectorsToSync).forEach(([group, tabSetsByValue]) => { + Object.entries(tabSetsByValue).forEach(([value, items]) => { + items.forEach((item) => { + item.addEventListener("click", (_event) => { + setTabState(group, value); + toggleAll(value, selectorsToSync[group]); + }); + }); + }); + }); + return selectorsToSync; + } + + const selectorsToSync = setupSelectorSync(); + for (const [group, selectedName] of Object.entries(getTabSettings())) { + const selectors = selectorsToSync[group]; + // it's possible that stale state gives us empty selections, so we explicitly check here. + if (selectors) { + toggleAll(selectedName, selectors); + } + } + }); +} diff --git a/docs/site_libs/quarto-html/tippy.css b/docs/site_libs/quarto-html/tippy.css new file mode 100644 index 0000000..e6ae635 --- /dev/null +++ b/docs/site_libs/quarto-html/tippy.css @@ -0,0 +1 @@ +.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1} \ No newline at end of file diff --git a/docs/site_libs/quarto-html/tippy.umd.min.js b/docs/site_libs/quarto-html/tippy.umd.min.js new file mode 100644 index 0000000..ca292be --- /dev/null +++ b/docs/site_libs/quarto-html/tippy.umd.min.js @@ -0,0 +1,2 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],t):(e=e||self).tippy=t(e.Popper)}(this,(function(e){"use strict";var t={passive:!0,capture:!0},n=function(){return document.body};function r(e,t,n){if(Array.isArray(e)){var r=e[t];return null==r?Array.isArray(n)?n[t]:n:r}return e}function o(e,t){var n={}.toString.call(e);return 0===n.indexOf("[object")&&n.indexOf(t+"]")>-1}function i(e,t){return"function"==typeof e?e.apply(void 0,t):e}function a(e,t){return 0===t?e:function(r){clearTimeout(n),n=setTimeout((function(){e(r)}),t)};var n}function s(e,t){var n=Object.assign({},e);return t.forEach((function(e){delete n[e]})),n}function u(e){return[].concat(e)}function c(e,t){-1===e.indexOf(t)&&e.push(t)}function p(e){return e.split("-")[0]}function f(e){return[].slice.call(e)}function l(e){return Object.keys(e).reduce((function(t,n){return void 0!==e[n]&&(t[n]=e[n]),t}),{})}function d(){return document.createElement("div")}function v(e){return["Element","Fragment"].some((function(t){return o(e,t)}))}function m(e){return o(e,"MouseEvent")}function g(e){return!(!e||!e._tippy||e._tippy.reference!==e)}function h(e){return v(e)?[e]:function(e){return o(e,"NodeList")}(e)?f(e):Array.isArray(e)?e:f(document.querySelectorAll(e))}function b(e,t){e.forEach((function(e){e&&(e.style.transitionDuration=t+"ms")}))}function y(e,t){e.forEach((function(e){e&&e.setAttribute("data-state",t)}))}function w(e){var t,n=u(e)[0];return null!=n&&null!=(t=n.ownerDocument)&&t.body?n.ownerDocument:document}function E(e,t,n){var r=t+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(t){e[r](t,n)}))}function O(e,t){for(var n=t;n;){var r;if(e.contains(n))return!0;n=null==n.getRootNode||null==(r=n.getRootNode())?void 0:r.host}return!1}var x={isTouch:!1},C=0;function T(){x.isTouch||(x.isTouch=!0,window.performance&&document.addEventListener("mousemove",A))}function A(){var e=performance.now();e-C<20&&(x.isTouch=!1,document.removeEventListener("mousemove",A)),C=e}function L(){var e=document.activeElement;if(g(e)){var t=e._tippy;e.blur&&!t.state.isVisible&&e.blur()}}var D=!!("undefined"!=typeof window&&"undefined"!=typeof document)&&!!window.msCrypto,R=Object.assign({appendTo:n,aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},{animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),k=Object.keys(R);function P(e){var t=(e.plugins||[]).reduce((function(t,n){var r,o=n.name,i=n.defaultValue;o&&(t[o]=void 0!==e[o]?e[o]:null!=(r=R[o])?r:i);return t}),{});return Object.assign({},e,t)}function j(e,t){var n=Object.assign({},t,{content:i(t.content,[e])},t.ignoreAttributes?{}:function(e,t){return(t?Object.keys(P(Object.assign({},R,{plugins:t}))):k).reduce((function(t,n){var r=(e.getAttribute("data-tippy-"+n)||"").trim();if(!r)return t;if("content"===n)t[n]=r;else try{t[n]=JSON.parse(r)}catch(e){t[n]=r}return t}),{})}(e,t.plugins));return n.aria=Object.assign({},R.aria,n.aria),n.aria={expanded:"auto"===n.aria.expanded?t.interactive:n.aria.expanded,content:"auto"===n.aria.content?t.interactive?null:"describedby":n.aria.content},n}function M(e,t){e.innerHTML=t}function V(e){var t=d();return!0===e?t.className="tippy-arrow":(t.className="tippy-svg-arrow",v(e)?t.appendChild(e):M(t,e)),t}function I(e,t){v(t.content)?(M(e,""),e.appendChild(t.content)):"function"!=typeof t.content&&(t.allowHTML?M(e,t.content):e.textContent=t.content)}function S(e){var t=e.firstElementChild,n=f(t.children);return{box:t,content:n.find((function(e){return e.classList.contains("tippy-content")})),arrow:n.find((function(e){return e.classList.contains("tippy-arrow")||e.classList.contains("tippy-svg-arrow")})),backdrop:n.find((function(e){return e.classList.contains("tippy-backdrop")}))}}function N(e){var t=d(),n=d();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var r=d();function o(n,r){var o=S(t),i=o.box,a=o.content,s=o.arrow;r.theme?i.setAttribute("data-theme",r.theme):i.removeAttribute("data-theme"),"string"==typeof r.animation?i.setAttribute("data-animation",r.animation):i.removeAttribute("data-animation"),r.inertia?i.setAttribute("data-inertia",""):i.removeAttribute("data-inertia"),i.style.maxWidth="number"==typeof r.maxWidth?r.maxWidth+"px":r.maxWidth,r.role?i.setAttribute("role",r.role):i.removeAttribute("role"),n.content===r.content&&n.allowHTML===r.allowHTML||I(a,e.props),r.arrow?s?n.arrow!==r.arrow&&(i.removeChild(s),i.appendChild(V(r.arrow))):i.appendChild(V(r.arrow)):s&&i.removeChild(s)}return r.className="tippy-content",r.setAttribute("data-state","hidden"),I(r,e.props),t.appendChild(n),n.appendChild(r),o(e.props,e.props),{popper:t,onUpdate:o}}N.$$tippy=!0;var B=1,H=[],U=[];function _(o,s){var v,g,h,C,T,A,L,k,M=j(o,Object.assign({},R,P(l(s)))),V=!1,I=!1,N=!1,_=!1,F=[],W=a(we,M.interactiveDebounce),X=B++,Y=(k=M.plugins).filter((function(e,t){return k.indexOf(e)===t})),$={id:X,reference:o,popper:d(),popperInstance:null,props:M,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:Y,clearDelayTimeouts:function(){clearTimeout(v),clearTimeout(g),cancelAnimationFrame(h)},setProps:function(e){if($.state.isDestroyed)return;ae("onBeforeUpdate",[$,e]),be();var t=$.props,n=j(o,Object.assign({},t,l(e),{ignoreAttributes:!0}));$.props=n,he(),t.interactiveDebounce!==n.interactiveDebounce&&(ce(),W=a(we,n.interactiveDebounce));t.triggerTarget&&!n.triggerTarget?u(t.triggerTarget).forEach((function(e){e.removeAttribute("aria-expanded")})):n.triggerTarget&&o.removeAttribute("aria-expanded");ue(),ie(),J&&J(t,n);$.popperInstance&&(Ce(),Ae().forEach((function(e){requestAnimationFrame(e._tippy.popperInstance.forceUpdate)})));ae("onAfterUpdate",[$,e])},setContent:function(e){$.setProps({content:e})},show:function(){var e=$.state.isVisible,t=$.state.isDestroyed,o=!$.state.isEnabled,a=x.isTouch&&!$.props.touch,s=r($.props.duration,0,R.duration);if(e||t||o||a)return;if(te().hasAttribute("disabled"))return;if(ae("onShow",[$],!1),!1===$.props.onShow($))return;$.state.isVisible=!0,ee()&&(z.style.visibility="visible");ie(),de(),$.state.isMounted||(z.style.transition="none");if(ee()){var u=re(),p=u.box,f=u.content;b([p,f],0)}A=function(){var e;if($.state.isVisible&&!_){if(_=!0,z.offsetHeight,z.style.transition=$.props.moveTransition,ee()&&$.props.animation){var t=re(),n=t.box,r=t.content;b([n,r],s),y([n,r],"visible")}se(),ue(),c(U,$),null==(e=$.popperInstance)||e.forceUpdate(),ae("onMount",[$]),$.props.animation&&ee()&&function(e,t){me(e,t)}(s,(function(){$.state.isShown=!0,ae("onShown",[$])}))}},function(){var e,t=$.props.appendTo,r=te();e=$.props.interactive&&t===n||"parent"===t?r.parentNode:i(t,[r]);e.contains(z)||e.appendChild(z);$.state.isMounted=!0,Ce()}()},hide:function(){var e=!$.state.isVisible,t=$.state.isDestroyed,n=!$.state.isEnabled,o=r($.props.duration,1,R.duration);if(e||t||n)return;if(ae("onHide",[$],!1),!1===$.props.onHide($))return;$.state.isVisible=!1,$.state.isShown=!1,_=!1,V=!1,ee()&&(z.style.visibility="hidden");if(ce(),ve(),ie(!0),ee()){var i=re(),a=i.box,s=i.content;$.props.animation&&(b([a,s],o),y([a,s],"hidden"))}se(),ue(),$.props.animation?ee()&&function(e,t){me(e,(function(){!$.state.isVisible&&z.parentNode&&z.parentNode.contains(z)&&t()}))}(o,$.unmount):$.unmount()},hideWithInteractivity:function(e){ne().addEventListener("mousemove",W),c(H,W),W(e)},enable:function(){$.state.isEnabled=!0},disable:function(){$.hide(),$.state.isEnabled=!1},unmount:function(){$.state.isVisible&&$.hide();if(!$.state.isMounted)return;Te(),Ae().forEach((function(e){e._tippy.unmount()})),z.parentNode&&z.parentNode.removeChild(z);U=U.filter((function(e){return e!==$})),$.state.isMounted=!1,ae("onHidden",[$])},destroy:function(){if($.state.isDestroyed)return;$.clearDelayTimeouts(),$.unmount(),be(),delete o._tippy,$.state.isDestroyed=!0,ae("onDestroy",[$])}};if(!M.render)return $;var q=M.render($),z=q.popper,J=q.onUpdate;z.setAttribute("data-tippy-root",""),z.id="tippy-"+$.id,$.popper=z,o._tippy=$,z._tippy=$;var G=Y.map((function(e){return e.fn($)})),K=o.hasAttribute("aria-expanded");return he(),ue(),ie(),ae("onCreate",[$]),M.showOnCreate&&Le(),z.addEventListener("mouseenter",(function(){$.props.interactive&&$.state.isVisible&&$.clearDelayTimeouts()})),z.addEventListener("mouseleave",(function(){$.props.interactive&&$.props.trigger.indexOf("mouseenter")>=0&&ne().addEventListener("mousemove",W)})),$;function Q(){var e=$.props.touch;return Array.isArray(e)?e:[e,0]}function Z(){return"hold"===Q()[0]}function ee(){var e;return!(null==(e=$.props.render)||!e.$$tippy)}function te(){return L||o}function ne(){var e=te().parentNode;return e?w(e):document}function re(){return S(z)}function oe(e){return $.state.isMounted&&!$.state.isVisible||x.isTouch||C&&"focus"===C.type?0:r($.props.delay,e?0:1,R.delay)}function ie(e){void 0===e&&(e=!1),z.style.pointerEvents=$.props.interactive&&!e?"":"none",z.style.zIndex=""+$.props.zIndex}function ae(e,t,n){var r;(void 0===n&&(n=!0),G.forEach((function(n){n[e]&&n[e].apply(n,t)})),n)&&(r=$.props)[e].apply(r,t)}function se(){var e=$.props.aria;if(e.content){var t="aria-"+e.content,n=z.id;u($.props.triggerTarget||o).forEach((function(e){var r=e.getAttribute(t);if($.state.isVisible)e.setAttribute(t,r?r+" "+n:n);else{var o=r&&r.replace(n,"").trim();o?e.setAttribute(t,o):e.removeAttribute(t)}}))}}function ue(){!K&&$.props.aria.expanded&&u($.props.triggerTarget||o).forEach((function(e){$.props.interactive?e.setAttribute("aria-expanded",$.state.isVisible&&e===te()?"true":"false"):e.removeAttribute("aria-expanded")}))}function ce(){ne().removeEventListener("mousemove",W),H=H.filter((function(e){return e!==W}))}function pe(e){if(!x.isTouch||!N&&"mousedown"!==e.type){var t=e.composedPath&&e.composedPath()[0]||e.target;if(!$.props.interactive||!O(z,t)){if(u($.props.triggerTarget||o).some((function(e){return O(e,t)}))){if(x.isTouch)return;if($.state.isVisible&&$.props.trigger.indexOf("click")>=0)return}else ae("onClickOutside",[$,e]);!0===$.props.hideOnClick&&($.clearDelayTimeouts(),$.hide(),I=!0,setTimeout((function(){I=!1})),$.state.isMounted||ve())}}}function fe(){N=!0}function le(){N=!1}function de(){var e=ne();e.addEventListener("mousedown",pe,!0),e.addEventListener("touchend",pe,t),e.addEventListener("touchstart",le,t),e.addEventListener("touchmove",fe,t)}function ve(){var e=ne();e.removeEventListener("mousedown",pe,!0),e.removeEventListener("touchend",pe,t),e.removeEventListener("touchstart",le,t),e.removeEventListener("touchmove",fe,t)}function me(e,t){var n=re().box;function r(e){e.target===n&&(E(n,"remove",r),t())}if(0===e)return t();E(n,"remove",T),E(n,"add",r),T=r}function ge(e,t,n){void 0===n&&(n=!1),u($.props.triggerTarget||o).forEach((function(r){r.addEventListener(e,t,n),F.push({node:r,eventType:e,handler:t,options:n})}))}function he(){var e;Z()&&(ge("touchstart",ye,{passive:!0}),ge("touchend",Ee,{passive:!0})),(e=$.props.trigger,e.split(/\s+/).filter(Boolean)).forEach((function(e){if("manual"!==e)switch(ge(e,ye),e){case"mouseenter":ge("mouseleave",Ee);break;case"focus":ge(D?"focusout":"blur",Oe);break;case"focusin":ge("focusout",Oe)}}))}function be(){F.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),F=[]}function ye(e){var t,n=!1;if($.state.isEnabled&&!xe(e)&&!I){var r="focus"===(null==(t=C)?void 0:t.type);C=e,L=e.currentTarget,ue(),!$.state.isVisible&&m(e)&&H.forEach((function(t){return t(e)})),"click"===e.type&&($.props.trigger.indexOf("mouseenter")<0||V)&&!1!==$.props.hideOnClick&&$.state.isVisible?n=!0:Le(e),"click"===e.type&&(V=!n),n&&!r&&De(e)}}function we(e){var t=e.target,n=te().contains(t)||z.contains(t);"mousemove"===e.type&&n||function(e,t){var n=t.clientX,r=t.clientY;return e.every((function(e){var t=e.popperRect,o=e.popperState,i=e.props.interactiveBorder,a=p(o.placement),s=o.modifiersData.offset;if(!s)return!0;var u="bottom"===a?s.top.y:0,c="top"===a?s.bottom.y:0,f="right"===a?s.left.x:0,l="left"===a?s.right.x:0,d=t.top-r+u>i,v=r-t.bottom-c>i,m=t.left-n+f>i,g=n-t.right-l>i;return d||v||m||g}))}(Ae().concat(z).map((function(e){var t,n=null==(t=e._tippy.popperInstance)?void 0:t.state;return n?{popperRect:e.getBoundingClientRect(),popperState:n,props:M}:null})).filter(Boolean),e)&&(ce(),De(e))}function Ee(e){xe(e)||$.props.trigger.indexOf("click")>=0&&V||($.props.interactive?$.hideWithInteractivity(e):De(e))}function Oe(e){$.props.trigger.indexOf("focusin")<0&&e.target!==te()||$.props.interactive&&e.relatedTarget&&z.contains(e.relatedTarget)||De(e)}function xe(e){return!!x.isTouch&&Z()!==e.type.indexOf("touch")>=0}function Ce(){Te();var t=$.props,n=t.popperOptions,r=t.placement,i=t.offset,a=t.getReferenceClientRect,s=t.moveTransition,u=ee()?S(z).arrow:null,c=a?{getBoundingClientRect:a,contextElement:a.contextElement||te()}:o,p=[{name:"offset",options:{offset:i}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!s}},{name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(e){var t=e.state;if(ee()){var n=re().box;["placement","reference-hidden","escaped"].forEach((function(e){"placement"===e?n.setAttribute("data-placement",t.placement):t.attributes.popper["data-popper-"+e]?n.setAttribute("data-"+e,""):n.removeAttribute("data-"+e)})),t.attributes.popper={}}}}];ee()&&u&&p.push({name:"arrow",options:{element:u,padding:3}}),p.push.apply(p,(null==n?void 0:n.modifiers)||[]),$.popperInstance=e.createPopper(c,z,Object.assign({},n,{placement:r,onFirstUpdate:A,modifiers:p}))}function Te(){$.popperInstance&&($.popperInstance.destroy(),$.popperInstance=null)}function Ae(){return f(z.querySelectorAll("[data-tippy-root]"))}function Le(e){$.clearDelayTimeouts(),e&&ae("onTrigger",[$,e]),de();var t=oe(!0),n=Q(),r=n[0],o=n[1];x.isTouch&&"hold"===r&&o&&(t=o),t?v=setTimeout((function(){$.show()}),t):$.show()}function De(e){if($.clearDelayTimeouts(),ae("onUntrigger",[$,e]),$.state.isVisible){if(!($.props.trigger.indexOf("mouseenter")>=0&&$.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(e.type)>=0&&V)){var t=oe(!1);t?g=setTimeout((function(){$.state.isVisible&&$.hide()}),t):h=requestAnimationFrame((function(){$.hide()}))}}else ve()}}function F(e,n){void 0===n&&(n={});var r=R.plugins.concat(n.plugins||[]);document.addEventListener("touchstart",T,t),window.addEventListener("blur",L);var o=Object.assign({},n,{plugins:r}),i=h(e).reduce((function(e,t){var n=t&&_(t,o);return n&&e.push(n),e}),[]);return v(e)?i[0]:i}F.defaultProps=R,F.setDefaultProps=function(e){Object.keys(e).forEach((function(t){R[t]=e[t]}))},F.currentInput=x;var W=Object.assign({},e.applyStyles,{effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow)}}),X={mouseover:"mouseenter",focusin:"focus",click:"click"};var Y={name:"animateFill",defaultValue:!1,fn:function(e){var t;if(null==(t=e.props.render)||!t.$$tippy)return{};var n=S(e.popper),r=n.box,o=n.content,i=e.props.animateFill?function(){var e=d();return e.className="tippy-backdrop",y([e],"hidden"),e}():null;return{onCreate:function(){i&&(r.insertBefore(i,r.firstElementChild),r.setAttribute("data-animatefill",""),r.style.overflow="hidden",e.setProps({arrow:!1,animation:"shift-away"}))},onMount:function(){if(i){var e=r.style.transitionDuration,t=Number(e.replace("ms",""));o.style.transitionDelay=Math.round(t/10)+"ms",i.style.transitionDuration=e,y([i],"visible")}},onShow:function(){i&&(i.style.transitionDuration="0ms")},onHide:function(){i&&y([i],"hidden")}}}};var $={clientX:0,clientY:0},q=[];function z(e){var t=e.clientX,n=e.clientY;$={clientX:t,clientY:n}}var J={name:"followCursor",defaultValue:!1,fn:function(e){var t=e.reference,n=w(e.props.triggerTarget||t),r=!1,o=!1,i=!0,a=e.props;function s(){return"initial"===e.props.followCursor&&e.state.isVisible}function u(){n.addEventListener("mousemove",f)}function c(){n.removeEventListener("mousemove",f)}function p(){r=!0,e.setProps({getReferenceClientRect:null}),r=!1}function f(n){var r=!n.target||t.contains(n.target),o=e.props.followCursor,i=n.clientX,a=n.clientY,s=t.getBoundingClientRect(),u=i-s.left,c=a-s.top;!r&&e.props.interactive||e.setProps({getReferenceClientRect:function(){var e=t.getBoundingClientRect(),n=i,r=a;"initial"===o&&(n=e.left+u,r=e.top+c);var s="horizontal"===o?e.top:r,p="vertical"===o?e.right:n,f="horizontal"===o?e.bottom:r,l="vertical"===o?e.left:n;return{width:p-l,height:f-s,top:s,right:p,bottom:f,left:l}}})}function l(){e.props.followCursor&&(q.push({instance:e,doc:n}),function(e){e.addEventListener("mousemove",z)}(n))}function d(){0===(q=q.filter((function(t){return t.instance!==e}))).filter((function(e){return e.doc===n})).length&&function(e){e.removeEventListener("mousemove",z)}(n)}return{onCreate:l,onDestroy:d,onBeforeUpdate:function(){a=e.props},onAfterUpdate:function(t,n){var i=n.followCursor;r||void 0!==i&&a.followCursor!==i&&(d(),i?(l(),!e.state.isMounted||o||s()||u()):(c(),p()))},onMount:function(){e.props.followCursor&&!o&&(i&&(f($),i=!1),s()||u())},onTrigger:function(e,t){m(t)&&($={clientX:t.clientX,clientY:t.clientY}),o="focus"===t.type},onHidden:function(){e.props.followCursor&&(p(),c(),i=!0)}}}};var G={name:"inlinePositioning",defaultValue:!1,fn:function(e){var t,n=e.reference;var r=-1,o=!1,i=[],a={name:"tippyInlinePositioning",enabled:!0,phase:"afterWrite",fn:function(o){var a=o.state;e.props.inlinePositioning&&(-1!==i.indexOf(a.placement)&&(i=[]),t!==a.placement&&-1===i.indexOf(a.placement)&&(i.push(a.placement),e.setProps({getReferenceClientRect:function(){return function(e){return function(e,t,n,r){if(n.length<2||null===e)return t;if(2===n.length&&r>=0&&n[0].left>n[1].right)return n[r]||t;switch(e){case"top":case"bottom":var o=n[0],i=n[n.length-1],a="top"===e,s=o.top,u=i.bottom,c=a?o.left:i.left,p=a?o.right:i.right;return{top:s,bottom:u,left:c,right:p,width:p-c,height:u-s};case"left":case"right":var f=Math.min.apply(Math,n.map((function(e){return e.left}))),l=Math.max.apply(Math,n.map((function(e){return e.right}))),d=n.filter((function(t){return"left"===e?t.left===f:t.right===l})),v=d[0].top,m=d[d.length-1].bottom;return{top:v,bottom:m,left:f,right:l,width:l-f,height:m-v};default:return t}}(p(e),n.getBoundingClientRect(),f(n.getClientRects()),r)}(a.placement)}})),t=a.placement)}};function s(){var t;o||(t=function(e,t){var n;return{popperOptions:Object.assign({},e.popperOptions,{modifiers:[].concat(((null==(n=e.popperOptions)?void 0:n.modifiers)||[]).filter((function(e){return e.name!==t.name})),[t])})}}(e.props,a),o=!0,e.setProps(t),o=!1)}return{onCreate:s,onAfterUpdate:s,onTrigger:function(t,n){if(m(n)){var o=f(e.reference.getClientRects()),i=o.find((function(e){return e.left-2<=n.clientX&&e.right+2>=n.clientX&&e.top-2<=n.clientY&&e.bottom+2>=n.clientY})),a=o.indexOf(i);r=a>-1?a:r}},onHidden:function(){r=-1}}}};var K={name:"sticky",defaultValue:!1,fn:function(e){var t=e.reference,n=e.popper;function r(t){return!0===e.props.sticky||e.props.sticky===t}var o=null,i=null;function a(){var s=r("reference")?(e.popperInstance?e.popperInstance.state.elements.reference:t).getBoundingClientRect():null,u=r("popper")?n.getBoundingClientRect():null;(s&&Q(o,s)||u&&Q(i,u))&&e.popperInstance&&e.popperInstance.update(),o=s,i=u,e.state.isMounted&&requestAnimationFrame(a)}return{onMount:function(){e.props.sticky&&a()}}}};function Q(e,t){return!e||!t||(e.top!==t.top||e.right!==t.right||e.bottom!==t.bottom||e.left!==t.left)}return F.setDefaultProps({plugins:[Y,J,G,K],render:N}),F.createSingleton=function(e,t){var n;void 0===t&&(t={});var r,o=e,i=[],a=[],c=t.overrides,p=[],f=!1;function l(){a=o.map((function(e){return u(e.props.triggerTarget||e.reference)})).reduce((function(e,t){return e.concat(t)}),[])}function v(){i=o.map((function(e){return e.reference}))}function m(e){o.forEach((function(t){e?t.enable():t.disable()}))}function g(e){return o.map((function(t){var n=t.setProps;return t.setProps=function(o){n(o),t.reference===r&&e.setProps(o)},function(){t.setProps=n}}))}function h(e,t){var n=a.indexOf(t);if(t!==r){r=t;var s=(c||[]).concat("content").reduce((function(e,t){return e[t]=o[n].props[t],e}),{});e.setProps(Object.assign({},s,{getReferenceClientRect:"function"==typeof s.getReferenceClientRect?s.getReferenceClientRect:function(){var e;return null==(e=i[n])?void 0:e.getBoundingClientRect()}}))}}m(!1),v(),l();var b={fn:function(){return{onDestroy:function(){m(!0)},onHidden:function(){r=null},onClickOutside:function(e){e.props.showOnCreate&&!f&&(f=!0,r=null)},onShow:function(e){e.props.showOnCreate&&!f&&(f=!0,h(e,i[0]))},onTrigger:function(e,t){h(e,t.currentTarget)}}}},y=F(d(),Object.assign({},s(t,["overrides"]),{plugins:[b].concat(t.plugins||[]),triggerTarget:a,popperOptions:Object.assign({},t.popperOptions,{modifiers:[].concat((null==(n=t.popperOptions)?void 0:n.modifiers)||[],[W])})})),w=y.show;y.show=function(e){if(w(),!r&&null==e)return h(y,i[0]);if(!r||null!=e){if("number"==typeof e)return i[e]&&h(y,i[e]);if(o.indexOf(e)>=0){var t=e.reference;return h(y,t)}return i.indexOf(e)>=0?h(y,e):void 0}},y.showNext=function(){var e=i[0];if(!r)return y.show(0);var t=i.indexOf(r);y.show(i[t+1]||e)},y.showPrevious=function(){var e=i[i.length-1];if(!r)return y.show(e);var t=i.indexOf(r),n=i[t-1]||e;y.show(n)};var E=y.setProps;return y.setProps=function(e){c=e.overrides||c,E(e)},y.setInstances=function(e){m(!0),p.forEach((function(e){return e()})),o=e,m(!1),v(),l(),p=g(y),y.setProps({triggerTarget:a})},p=g(y),y},F.delegate=function(e,n){var r=[],o=[],i=!1,a=n.target,c=s(n,["target"]),p=Object.assign({},c,{trigger:"manual",touch:!1}),f=Object.assign({touch:R.touch},c,{showOnCreate:!0}),l=F(e,p);function d(e){if(e.target&&!i){var t=e.target.closest(a);if(t){var r=t.getAttribute("data-tippy-trigger")||n.trigger||R.trigger;if(!t._tippy&&!("touchstart"===e.type&&"boolean"==typeof f.touch||"touchstart"!==e.type&&r.indexOf(X[e.type])<0)){var s=F(t,f);s&&(o=o.concat(s))}}}}function v(e,t,n,o){void 0===o&&(o=!1),e.addEventListener(t,n,o),r.push({node:e,eventType:t,handler:n,options:o})}return u(l).forEach((function(e){var n=e.destroy,a=e.enable,s=e.disable;e.destroy=function(e){void 0===e&&(e=!0),e&&o.forEach((function(e){e.destroy()})),o=[],r.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),r=[],n()},e.enable=function(){a(),o.forEach((function(e){return e.enable()})),i=!1},e.disable=function(){s(),o.forEach((function(e){return e.disable()})),i=!0},function(e){var n=e.reference;v(n,"touchstart",d,t),v(n,"mouseover",d),v(n,"focusin",d),v(n,"click",d)}(e)})),l},F.hideAll=function(e){var t=void 0===e?{}:e,n=t.exclude,r=t.duration;U.forEach((function(e){var t=!1;if(n&&(t=g(n)?e.reference===n:e.popper===n.popper),!t){var o=e.props.duration;e.setProps({duration:r}),e.hide(),e.state.isDestroyed||e.setProps({duration:o})}}))},F.roundArrow='',F})); + diff --git a/docs/site_libs/quarto-nav/headroom.min.js b/docs/site_libs/quarto-nav/headroom.min.js new file mode 100644 index 0000000..b08f1df --- /dev/null +++ b/docs/site_libs/quarto-nav/headroom.min.js @@ -0,0 +1,7 @@ +/*! + * headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it + * Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js + * License: MIT + */ + +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=ls.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t){return t===Object(t)?t:{down:t,up:t}}function s(t,n){n=n||{},Object.assign(this,s.options,n),this.classes=Object.assign({},s.options.classes,n.classes),this.elem=t,this.tolerance=o(this.tolerance),this.offset=o(this.offset),this.initialised=!1,this.frozen=!1}return s.prototype={constructor:s,init:function(){return s.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},s.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},s.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),s}); diff --git a/docs/site_libs/quarto-nav/quarto-nav.js b/docs/site_libs/quarto-nav/quarto-nav.js new file mode 100644 index 0000000..38cc430 --- /dev/null +++ b/docs/site_libs/quarto-nav/quarto-nav.js @@ -0,0 +1,325 @@ +const headroomChanged = new CustomEvent("quarto-hrChanged", { + detail: {}, + bubbles: true, + cancelable: false, + composed: false, +}); + +const announceDismiss = () => { + const annEl = window.document.getElementById("quarto-announcement"); + if (annEl) { + annEl.remove(); + + const annId = annEl.getAttribute("data-announcement-id"); + window.localStorage.setItem(`quarto-announce-${annId}`, "true"); + } +}; + +const announceRegister = () => { + const annEl = window.document.getElementById("quarto-announcement"); + if (annEl) { + const annId = annEl.getAttribute("data-announcement-id"); + const isDismissed = + window.localStorage.getItem(`quarto-announce-${annId}`) || false; + if (isDismissed) { + announceDismiss(); + return; + } else { + annEl.classList.remove("hidden"); + } + + const actionEl = annEl.querySelector(".quarto-announcement-action"); + if (actionEl) { + actionEl.addEventListener("click", function (e) { + e.preventDefault(); + // Hide the bar immediately + announceDismiss(); + }); + } + } +}; + +window.document.addEventListener("DOMContentLoaded", function () { + let init = false; + + announceRegister(); + + // Manage the back to top button, if one is present. + let lastScrollTop = window.pageYOffset || document.documentElement.scrollTop; + const scrollDownBuffer = 5; + const scrollUpBuffer = 35; + const btn = document.getElementById("quarto-back-to-top"); + const hideBackToTop = () => { + btn.style.display = "none"; + }; + const showBackToTop = () => { + btn.style.display = "inline-block"; + }; + if (btn) { + window.document.addEventListener( + "scroll", + function () { + const currentScrollTop = + window.pageYOffset || document.documentElement.scrollTop; + + // Shows and hides the button 'intelligently' as the user scrolls + if (currentScrollTop - scrollDownBuffer > lastScrollTop) { + hideBackToTop(); + lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop; + } else if (currentScrollTop < lastScrollTop - scrollUpBuffer) { + showBackToTop(); + lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop; + } + + // Show the button at the bottom, hides it at the top + if (currentScrollTop <= 0) { + hideBackToTop(); + } else if ( + window.innerHeight + currentScrollTop >= + document.body.offsetHeight + ) { + showBackToTop(); + } + }, + false + ); + } + + function throttle(func, wait) { + var timeout; + return function () { + const context = this; + const args = arguments; + const later = function () { + clearTimeout(timeout); + timeout = null; + func.apply(context, args); + }; + + if (!timeout) { + timeout = setTimeout(later, wait); + } + }; + } + + function headerOffset() { + // Set an offset if there is are fixed top navbar + const headerEl = window.document.querySelector("header.fixed-top"); + if (headerEl) { + return headerEl.clientHeight; + } else { + return 0; + } + } + + function footerOffset() { + const footerEl = window.document.querySelector("footer.footer"); + if (footerEl) { + return footerEl.clientHeight; + } else { + return 0; + } + } + + function dashboardOffset() { + const dashboardNavEl = window.document.getElementById( + "quarto-dashboard-header" + ); + if (dashboardNavEl !== null) { + return dashboardNavEl.clientHeight; + } else { + return 0; + } + } + + function updateDocumentOffsetWithoutAnimation() { + updateDocumentOffset(false); + } + + function updateDocumentOffset(animated) { + // set body offset + const topOffset = headerOffset(); + const bodyOffset = topOffset + footerOffset() + dashboardOffset(); + const bodyEl = window.document.body; + bodyEl.setAttribute("data-bs-offset", topOffset); + bodyEl.style.paddingTop = topOffset + "px"; + + // deal with sidebar offsets + const sidebars = window.document.querySelectorAll( + ".sidebar, .headroom-target" + ); + sidebars.forEach((sidebar) => { + if (!animated) { + sidebar.classList.add("notransition"); + // Remove the no transition class after the animation has time to complete + setTimeout(function () { + sidebar.classList.remove("notransition"); + }, 201); + } + + if (window.Headroom && sidebar.classList.contains("sidebar-unpinned")) { + sidebar.style.top = "0"; + sidebar.style.maxHeight = "100vh"; + } else { + sidebar.style.top = topOffset + "px"; + sidebar.style.maxHeight = "calc(100vh - " + topOffset + "px)"; + } + }); + + // allow space for footer + const mainContainer = window.document.querySelector(".quarto-container"); + if (mainContainer) { + mainContainer.style.minHeight = "calc(100vh - " + bodyOffset + "px)"; + } + + // link offset + let linkStyle = window.document.querySelector("#quarto-target-style"); + if (!linkStyle) { + linkStyle = window.document.createElement("style"); + linkStyle.setAttribute("id", "quarto-target-style"); + window.document.head.appendChild(linkStyle); + } + while (linkStyle.firstChild) { + linkStyle.removeChild(linkStyle.firstChild); + } + if (topOffset > 0) { + linkStyle.appendChild( + window.document.createTextNode(` + section:target::before { + content: ""; + display: block; + height: ${topOffset}px; + margin: -${topOffset}px 0 0; + }`) + ); + } + if (init) { + window.dispatchEvent(headroomChanged); + } + init = true; + } + + // initialize headroom + var header = window.document.querySelector("#quarto-header"); + if (header && window.Headroom) { + const headroom = new window.Headroom(header, { + tolerance: 5, + onPin: function () { + const sidebars = window.document.querySelectorAll( + ".sidebar, .headroom-target" + ); + sidebars.forEach((sidebar) => { + sidebar.classList.remove("sidebar-unpinned"); + }); + updateDocumentOffset(); + }, + onUnpin: function () { + const sidebars = window.document.querySelectorAll( + ".sidebar, .headroom-target" + ); + sidebars.forEach((sidebar) => { + sidebar.classList.add("sidebar-unpinned"); + }); + updateDocumentOffset(); + }, + }); + headroom.init(); + + let frozen = false; + window.quartoToggleHeadroom = function () { + if (frozen) { + headroom.unfreeze(); + frozen = false; + } else { + headroom.freeze(); + frozen = true; + } + }; + } + + window.addEventListener( + "hashchange", + function (e) { + if ( + getComputedStyle(document.documentElement).scrollBehavior !== "smooth" + ) { + window.scrollTo(0, window.pageYOffset - headerOffset()); + } + }, + false + ); + + // Observe size changed for the header + const headerEl = window.document.querySelector("header.fixed-top"); + if (headerEl && window.ResizeObserver) { + const observer = new window.ResizeObserver(() => { + setTimeout(updateDocumentOffsetWithoutAnimation, 0); + }); + observer.observe(headerEl, { + attributes: true, + childList: true, + characterData: true, + }); + } else { + window.addEventListener( + "resize", + throttle(updateDocumentOffsetWithoutAnimation, 50) + ); + } + setTimeout(updateDocumentOffsetWithoutAnimation, 250); + + // fixup index.html links if we aren't on the filesystem + if (window.location.protocol !== "file:") { + const links = window.document.querySelectorAll("a"); + for (let i = 0; i < links.length; i++) { + if (links[i].href) { + links[i].dataset.originalHref = links[i].href; + links[i].href = links[i].href.replace(/\/index\.html/, "/"); + } + } + + // Fixup any sharing links that require urls + // Append url to any sharing urls + const sharingLinks = window.document.querySelectorAll( + "a.sidebar-tools-main-item, a.quarto-navigation-tool, a.quarto-navbar-tools, a.quarto-navbar-tools-item" + ); + for (let i = 0; i < sharingLinks.length; i++) { + const sharingLink = sharingLinks[i]; + const href = sharingLink.getAttribute("href"); + if (href) { + sharingLink.setAttribute( + "href", + href.replace("|url|", window.location.href) + ); + } + } + + // Scroll the active navigation item into view, if necessary + const navSidebar = window.document.querySelector("nav#quarto-sidebar"); + if (navSidebar) { + // Find the active item + const activeItem = navSidebar.querySelector("li.sidebar-item a.active"); + if (activeItem) { + // Wait for the scroll height and height to resolve by observing size changes on the + // nav element that is scrollable + const resizeObserver = new ResizeObserver((_entries) => { + // The bottom of the element + const elBottom = activeItem.offsetTop; + const viewBottom = navSidebar.scrollTop + navSidebar.clientHeight; + + // The element height and scroll height are the same, then we are still loading + if (viewBottom !== navSidebar.scrollHeight) { + // Determine if the item isn't visible and scroll to it + if (elBottom >= viewBottom) { + navSidebar.scrollTop = elBottom; + } + + // stop observing now since we've completed the scroll + resizeObserver.unobserve(navSidebar); + } + }); + resizeObserver.observe(navSidebar); + } + } + } +}); diff --git a/docs/site_libs/quarto-search/autocomplete.umd.js b/docs/site_libs/quarto-search/autocomplete.umd.js new file mode 100644 index 0000000..6090a55 --- /dev/null +++ b/docs/site_libs/quarto-search/autocomplete.umd.js @@ -0,0 +1,3 @@ +/*! @algolia/autocomplete-js 1.19.1 | MIT License | © Algolia, Inc. and contributors | https://github.com/algolia/autocomplete */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["@algolia/autocomplete-js"]={})}(this,(function(e){"use strict";function t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function n(e){for(var n=1;n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function a(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,i,u,a=[],l=!0,c=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;l=!1}else for(;!(l=(r=i.call(n)).done)&&(a.push(r.value),a.length!==t);l=!0);}catch(e){c=!0,o=e}finally{try{if(!l&&null!=n.return&&(u=n.return(),Object(u)!==u))return}finally{if(c)throw o}}return a}}(e,t)||c(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(e){return function(e){if(Array.isArray(e))return s(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||c(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function c(e,t){if(e){if("string"==typeof e)return s(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(e,t):void 0}}function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);ne.length)&&(t=e.length);for(var n=0,r=new Array(t);ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function x(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function N(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:20,n=[],r=0;r=3||2===n&&r>=4||1===n&&r>=10);function i(t,n,r){if(o&&void 0!==r){var i=r[0].__autocomplete_algoliaCredentials,u={"X-Algolia-Application-Id":i.appId,"X-Algolia-API-Key":i.apiKey};e.apply(void 0,[t].concat(D(n),[{headers:u}]))}else e.apply(void 0,[t].concat(D(n)))}return{init:function(t,n){e("init",{appId:t,apiKey:n})},setAuthenticatedUserToken:function(t){e("setAuthenticatedUserToken",t)},setUserToken:function(t){e("setUserToken",t)},clickedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&i("clickedObjectIDsAfterSearch",B(t),t[0].items)},clickedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&i("clickedObjectIDs",B(t),t[0].items)},clickedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r0&&e.apply(void 0,["clickedFilters"].concat(n))},convertedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&i("convertedObjectIDsAfterSearch",B(t),t[0].items)},convertedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&i("convertedObjectIDs",B(t),t[0].items)},convertedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r0&&e.apply(void 0,["convertedFilters"].concat(n))},viewedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&t.reduce((function(e,t){var n=t.items,r=k(t,A);return[].concat(D(e),D(q(N(N({},r),{},{objectIDs:(null==n?void 0:n.map((function(e){return e.objectID})))||r.objectIDs})).map((function(e){return{items:n,payload:e}}))))}),[]).forEach((function(e){var t=e.items;return i("viewedObjectIDs",[e.payload],t)}))},viewedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r0&&e.apply(void 0,["viewedFilters"].concat(n))}}}function L(e){var t=e.items.reduce((function(e,t){var n;return e[t.__autocomplete_indexName]=(null!==(n=e[t.__autocomplete_indexName])&&void 0!==n?n:[]).concat(t),e}),{});return Object.keys(t).map((function(e){return{index:e,items:t[e],algoliaSource:["autocomplete"]}}))}function F(e){return e.objectID&&e.__autocomplete_indexName&&e.__autocomplete_queryID}function U(e){return U="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},U(e)}function M(e){return function(e){if(Array.isArray(e))return H(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return H(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return H(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function H(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&z({onItemsChange:o,items:n,insights:c,state:t}))}}),0);return{name:"aa.algoliaInsightsPlugin",subscribe:function(e){var t=e.setContext,n=e.onSelect,r=e.onActive;function o(e){t({algoliaInsightsPlugin:{__algoliaSearchParameters:W(W({},a?{clickAnalytics:!0}:{}),e?{userToken:X(e)}:{}),insights:c}})}l("addAlgoliaAgent","insights-plugin"),o(),l("onUserTokenChange",(function(e){o(e)})),l("getUserToken",null,(function(e,t){o(t)})),n((function(e){var t=e.item,n=e.state,r=e.event,o=e.source;F(t)&&i({state:n,event:r,insights:c,item:t,insightsEvents:[W({eventName:"Item Selected"},j({item:t,items:o.getItems().filter(F)}))]})})),r((function(e){var t=e.item,n=e.source,r=e.state,o=e.event;F(t)&&u({state:r,event:o,insights:c,item:t,insightsEvents:[W({eventName:"Item Active"},j({item:t,items:n.getItems().filter(F)}))]})}))},onStateChange:function(e){var t=e.state;m({state:t})},__autocomplete_pluginOptions:e}}function J(){var e,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],n=arguments.length>1?arguments[1]:void 0;return[].concat(M(t),["autocomplete-internal"],M(null!==(e=n.algoliaInsightsPlugin)&&void 0!==e&&e.__automaticInsights?["autocomplete-automatic"]:[]))}function X(e){return"number"==typeof e?e.toString():e}function Y(e,t){var n=t;return{then:function(t,r){return Y(e.then(ee(t,n,e),ee(r,n,e)),n)},catch:function(t){return Y(e.catch(ee(t,n,e)),n)},finally:function(t){return t&&n.onCancelList.push(t),Y(e.finally(ee(t&&function(){return n.onCancelList=[],t()},n,e)),n)},cancel:function(){n.isCanceled=!0;var e=n.onCancelList;n.onCancelList=[],e.forEach((function(e){e()}))},isCanceled:function(){return!0===n.isCanceled}}}function Z(e){return Y(e,{isCanceled:!1,onCancelList:[]})}function ee(e,t,n){return e?function(n){return t.isCanceled?n:e(n)}:n}var te,ne=!0;function re(e,t,n,r){if(!n)return null;if(e<0&&(null===t||null!==r&&0===t))return n+e;var o=(null===t?-1:t)+e;return o<=-1||o>=n?null===r?null:0:o}function oe(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function ie(e){for(var t=1;t=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,u=!0,a=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return u=e.done,e},e:function(e){a=!0,i=e},f:function(){try{u||null==n.return||n.return()}finally{if(a)throw i}}}}function ce(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0?t.wait(Math.max.apply(Math,o)):void 0};function fe(e){var t=function(e){var t=e.collections.map((function(e){return e.items.length})).reduce((function(e,t,n){var r=(e[n-1]||0)+t;return e.push(r),e}),[]).reduce((function(t,n){return n<=e.activeItemId?t+1:t}),0);return e.collections[t]}(e);if(!t)return null;var n=t.items[function(e){for(var t=e.state,n=e.collection,r=!1,o=0,i=0;!1===r;){var u=t.collections[o];if(u===n){r=!0;break}i+=u.items.length,o++}return t.activeItemId-i}({state:e,collection:t})],r=t.source;return{item:n,itemInputValue:r.getItemInputValue({item:n,state:e}),itemUrl:r.getItemUrl({item:n,state:e}),source:r}}function pe(e,t,n){return[e,null==n?void 0:n.sourceId,t].filter(Boolean).join("-").replace(/\s/g,"")}var me=/((gt|sm)-|galaxy nexus)|samsung[- ]|samsungbrowser/i;function ve(e){return e.nativeEvent||e}function de(e){return de="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},de(e)}function ye(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function be(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==de(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==de(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===de(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function ge(e,t,n){var r,o=t.initialState;return{getState:function(){return o},dispatch:function(r,i){var u=function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n0},reshape:function(e){return e.sources}},e),{},{id:null!==(n=e.id)&&void 0!==n?n:d(),plugins:o,initialState:Ae({activeItemId:null,query:"",completion:null,collections:[],isOpen:!1,status:"idle",context:{}},e.initialState),onStateChange:function(t){var n;null===(n=e.onStateChange)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onStateChange)||void 0===n?void 0:n.call(e,t)}))},onSubmit:function(t){var n;null===(n=e.onSubmit)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onSubmit)||void 0===n?void 0:n.call(e,t)}))},onReset:function(t){var n;null===(n=e.onReset)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onReset)||void 0===n?void 0:n.call(e,t)}))},getSources:function(n){return Promise.all([].concat(Pe(o.map((function(e){return e.getSources}))),[e.getSources]).filter(Boolean).map((function(e){return function(e,t){var n=[];return Promise.resolve(e(t)).then((function(e){return Promise.all(e.filter((function(e){return Boolean(e)})).map((function(e){if(e.sourceId,n.includes(e.sourceId))throw new Error("[Autocomplete] The `sourceId` ".concat(JSON.stringify(e.sourceId)," is not unique."));n.push(e.sourceId);var t={getItemInputValue:function(e){return e.state.query},getItemUrl:function(){},onSelect:function(e){(0,e.setIsOpen)(!1)},onActive:_,onResolve:_};Object.keys(t).forEach((function(e){t[e].__default=!0}));var r=ie(ie({},t),e);return Promise.resolve(r)})))}))}(e,n)}))).then((function(e){return m(e)})).then((function(e){return e.map((function(e){return Ae(Ae({},e),{},{onSelect:function(n){e.onSelect(n),t.forEach((function(e){var t;return null===(t=e.onSelect)||void 0===t?void 0:t.call(e,n)}))},onActive:function(n){e.onActive(n),t.forEach((function(e){var t;return null===(t=e.onActive)||void 0===t?void 0:t.call(e,n)}))},onResolve:function(n){e.onResolve(n),t.forEach((function(e){var t;return null===(t=e.onResolve)||void 0===t?void 0:t.call(e,n)}))}})}))}))},navigator:Ae({navigate:function(e){var t=e.itemUrl;r.location.assign(t)},navigateNewTab:function(e){var t=e.itemUrl,n=r.open(t,"_blank","noopener");null==n||n.focus()},navigateNewWindow:function(e){var t=e.itemUrl;r.open(t,"_blank","noopener")}},e.navigator)})}function Ce(e){return Ce="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ce(e)}function ke(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function xe(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var Je,Xe,Ye,Ze=null,et=(Je=-1,Xe=-1,Ye=void 0,function(e){var t=++Je;return Promise.resolve(e).then((function(e){return Ye&&t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function lt(e){return lt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},lt(e)}var ct=["props","refresh","store"],st=["inputElement","formElement","panelElement"],ft=["inputElement"],pt=["inputElement","maxLength"],mt=["source"],vt=["item","source"];function dt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function yt(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function ht(e){var t=e.props,n=e.refresh,r=e.store,o=gt(e,ct);return{getEnvironmentProps:function(e){var n=e.inputElement,o=e.formElement,i=e.panelElement;function u(e){!r.getState().isOpen&&r.pendingRequests.isEmpty()||e.target===n||!1===[o,i].some((function(t){return n=t,r=e.target,n===r||n.contains(r);var n,r}))&&(r.dispatch("blur",null),t.debug||r.pendingRequests.cancelAll())}return yt({onTouchStart:u,onMouseDown:u,onTouchMove:function(e){!1!==r.getState().isOpen&&n===t.environment.document.activeElement&&e.target!==n&&n.blur()}},gt(e,st))},getRootProps:function(e){return yt({role:"combobox","aria-expanded":r.getState().isOpen,"aria-haspopup":"listbox","aria-controls":r.getState().isOpen?r.getState().collections.map((function(e){var n=e.source;return pe(t.id,"list",n)})).join(" "):void 0,"aria-labelledby":pe(t.id,"label")},e)},getFormProps:function(e){e.inputElement;var i=gt(e,ft),u=function(i){var u;t.onSubmit(yt({event:i,refresh:n,state:r.getState()},o)),r.dispatch("submit",null),null===(u=e.inputElement)||void 0===u||u.blur()};return yt({action:"",noValidate:!0,role:"search",onSubmit:function(e){e.preventDefault();var n=se(t.plugins,r.pendingRequests);void 0!==n?n.then((function(){return u(e)})):u(e)},onReset:function(i){var u;i.preventDefault(),t.onReset(yt({event:i,refresh:n,state:r.getState()},o)),r.dispatch("reset",null),null===(u=e.inputElement)||void 0===u||u.focus()}},i)},getLabelProps:function(e){return yt({htmlFor:pe(t.id,"input"),id:pe(t.id,"label")},e)},getInputProps:function(e){var i;function u(e){(t.openOnFocus||Boolean(r.getState().query))&&tt(yt({event:e,props:t,query:r.getState().completion||r.getState().query,refresh:n,store:r},o)),r.dispatch("focus",null)}var a=e||{};a.inputElement;var l=a.maxLength,c=void 0===l?512:l,s=gt(a,pt),f=fe(r.getState()),p=function(e){return Boolean(e&&e.match(me))}((null===(i=t.environment.navigator)||void 0===i?void 0:i.userAgent)||""),m=t.enterKeyHint||(null!=f&&f.itemUrl&&!p?"go":"search");return yt({"aria-autocomplete":"both","aria-activedescendant":r.getState().isOpen&&null!==r.getState().activeItemId?pe(t.id,"item-".concat(r.getState().activeItemId),null==f?void 0:f.source):void 0,"aria-controls":r.getState().isOpen?r.getState().collections.filter((function(e){return e.items.length>0})).map((function(e){var n=e.source;return pe(t.id,"list",n)})).join(" "):void 0,"aria-labelledby":pe(t.id,"label"),value:r.getState().completion||r.getState().query,id:pe(t.id,"input"),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",enterKeyHint:m,spellCheck:"false",autoFocus:t.autoFocus,placeholder:t.placeholder,maxLength:c,type:"search",onChange:function(e){var i=e.currentTarget.value;t.ignoreCompositionEvents&&ve(e).isComposing?o.setQuery(i):tt(yt({event:e,props:t,query:i.slice(0,c),refresh:n,store:r},o))},onCompositionEnd:function(e){tt(yt({event:e,props:t,query:e.currentTarget.value.slice(0,c),refresh:n,store:r},o))},onKeyDown:function(e){ve(e).isComposing||function(e){var t=e.event,n=e.props,r=e.refresh,o=e.store,i=at(e,rt);if("ArrowUp"===t.key||"ArrowDown"===t.key){var u=function(){var e=fe(o.getState()),t=n.environment.document.getElementById(pe(n.id,"item-".concat(o.getState().activeItemId),null==e?void 0:e.source));t&&(t.scrollIntoViewIfNeeded?t.scrollIntoViewIfNeeded(!1):t.scrollIntoView(!1))},a=function(){var e=fe(o.getState());if(null!==o.getState().activeItemId&&e){var n=e.item,u=e.itemInputValue,a=e.itemUrl,l=e.source;l.onActive(it({event:t,item:n,itemInputValue:u,itemUrl:a,refresh:r,source:l,state:o.getState()},i))}};t.preventDefault(),!1===o.getState().isOpen&&(n.openOnFocus||Boolean(o.getState().query))?tt(it({event:t,props:n,query:o.getState().query,refresh:r,store:o},i)).then((function(){o.dispatch(t.key,{nextActiveItemId:n.defaultActiveItemId}),a(),setTimeout(u,0)})):(o.dispatch(t.key,{}),a(),u())}else if("Escape"===t.key)t.preventDefault(),o.dispatch(t.key,null),o.pendingRequests.cancelAll();else if("Tab"===t.key)o.dispatch("blur",null),o.pendingRequests.cancelAll();else if("Enter"===t.key){if(null===o.getState().activeItemId||o.getState().collections.every((function(e){return 0===e.items.length}))){var l=se(n.plugins,o.pendingRequests);return void(void 0!==l?l.then(o.pendingRequests.cancelAll):n.debug||o.pendingRequests.cancelAll())}t.preventDefault();var c=fe(o.getState()),s=c.item,f=c.itemInputValue,p=c.itemUrl,m=c.source;if(t.metaKey||t.ctrlKey)void 0!==p&&(m.onSelect(it({event:t,item:s,itemInputValue:f,itemUrl:p,refresh:r,source:m,state:o.getState()},i)),n.navigator.navigateNewTab({itemUrl:p,item:s,state:o.getState()}));else if(t.shiftKey)void 0!==p&&(m.onSelect(it({event:t,item:s,itemInputValue:f,itemUrl:p,refresh:r,source:m,state:o.getState()},i)),n.navigator.navigateNewWindow({itemUrl:p,item:s,state:o.getState()}));else if(t.altKey);else{if(void 0!==p)return m.onSelect(it({event:t,item:s,itemInputValue:f,itemUrl:p,refresh:r,source:m,state:o.getState()},i)),void n.navigator.navigate({itemUrl:p,item:s,state:o.getState()});tt(it({event:t,nextState:{isOpen:!1},props:n,query:f,refresh:r,store:o},i)).then((function(){m.onSelect(it({event:t,item:s,itemInputValue:f,itemUrl:p,refresh:r,source:m,state:o.getState()},i))}))}}}(yt({event:e,props:t,refresh:n,store:r},o))},onFocus:u,onBlur:_,onClick:function(n){e.inputElement!==t.environment.document.activeElement||r.getState().isOpen||u(n)}},s)},getPanelProps:function(e){return yt({onMouseDown:function(e){e.preventDefault()},onMouseLeave:function(){r.dispatch("mouseleave",null)}},e)},getListProps:function(e){var n=e||{},r=n.source,o=gt(n,mt);return yt({role:"listbox","aria-labelledby":pe(t.id,"label"),id:pe(t.id,"list",r)},o)},getItemProps:function(e){var i=e.item,u=e.source,a=gt(e,vt);return yt({id:pe(t.id,"item-".concat(i.__autocomplete_id),u),role:"option","aria-selected":r.getState().activeItemId===i.__autocomplete_id,onMouseMove:function(e){if(i.__autocomplete_id!==r.getState().activeItemId){r.dispatch("mousemove",i.__autocomplete_id);var t=fe(r.getState());if(null!==r.getState().activeItemId&&t){var u=t.item,a=t.itemInputValue,l=t.itemUrl,c=t.source;c.onActive(yt({event:e,item:u,itemInputValue:a,itemUrl:l,refresh:n,source:c,state:r.getState()},o))}}},onMouseDown:function(e){e.preventDefault()},onClick:function(e){var a=u.getItemInputValue({item:i,state:r.getState()}),l=u.getItemUrl({item:i,state:r.getState()});(l?Promise.resolve():tt(yt({event:e,nextState:{isOpen:!1},props:t,query:a,refresh:n,store:r},o))).then((function(){u.onSelect(yt({event:e,item:i,itemInputValue:a,itemUrl:l,refresh:n,source:u,state:r.getState()},o))}))}},a)}}}function _t(e){return _t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},_t(e)}function Ot(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function St(e){for(var t=1;t=5&&((o||!e&&5===r)&&(u.push(r,0,o,n),r=6),e&&(u.push(r,e,0,n),r=6)),o=""},l=0;l"===t?(r=1,o=""):o=t+o[0]:i?t===i?i="":o+=t:'"'===t||"'"===t?i=t:">"===t?(a(),r=1):r&&("="===t?(r=5,n=o,o=""):"/"===t&&(r<5||">"===e[l][c+1])?(a(),3===r&&(u=u[0]),r=u,(u=u[0]).push(2,0,r),r=0):" "===t||"\t"===t||"\n"===t||"\r"===t?(a(),r=2):o+=t),3===r&&"!--"===o&&(r=4,u=u[0])}return a(),u}(e)),t),arguments,[])).length>1?t:t[0]}var Ft=function(e){var t=e.environment,n=t.document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("class","aa-ClearIcon"),n.setAttribute("viewBox","0 0 24 24"),n.setAttribute("width","18"),n.setAttribute("height","18"),n.setAttribute("fill","currentColor");var r=t.document.createElementNS("http://www.w3.org/2000/svg","path");return r.setAttribute("d","M5.293 6.707l5.293 5.293-5.293 5.293c-0.391 0.391-0.391 1.024 0 1.414s1.024 0.391 1.414 0l5.293-5.293 5.293 5.293c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-5.293-5.293 5.293-5.293c0.391-0.391 0.391-1.024 0-1.414s-1.024-0.391-1.414 0l-5.293 5.293-5.293-5.293c-0.391-0.391-1.024-0.391-1.414 0s-0.391 1.024 0 1.414z"),n.appendChild(r),n};function Ut(e,t){if("string"==typeof t){var n=e.document.querySelector(t);return"The element ".concat(JSON.stringify(t)," is not in the document."),n}return t}function Mt(){for(var e=arguments.length,t=new Array(e),n=0;n2&&(u.children=arguments.length>3?on.call(arguments,2):n),"function"==typeof e&&null!=e.defaultProps)for(i in e.defaultProps)void 0===u[i]&&(u[i]=e.defaultProps[i]);return gn(e,u,r,o,null)}function gn(e,t,n,r,o){var i={type:e,props:t,key:n,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++an:o};return null==o&&null!=un.vnode&&un.vnode(i),i}function hn(e){return e.children}function _n(e,t){this.props=e,this.context=t}function On(e,t){if(null==t)return e.__?On(e.__,e.__.__k.indexOf(e)+1):null;for(var n;tt&&ln.sort(fn));Pn.__r=0}function wn(e,t,n,r,o,i,u,a,l,c){var s,f,p,m,v,d,y,b=r&&r.__k||mn,g=b.length;for(n.__k=[],s=0;s0?gn(m.type,m.props,m.key,m.ref?m.ref:null,m.__v):m)){if(m.__=n,m.__b=n.__b+1,null===(p=b[s])||p&&m.key==p.key&&m.type===p.type)b[s]=void 0;else for(f=0;f=0;t--)if((n=e.__k[t])&&(r=En(n)))return r;return null}function Dn(e,t,n){"-"===t[0]?e.setProperty(t,null==n?"":n):e[t]=null==n?"":"number"!=typeof n||vn.test(t)?n:n+"px"}function Cn(e,t,n,r,o){var i;e:if("style"===t)if("string"==typeof n)e.style.cssText=n;else{if("string"==typeof r&&(e.style.cssText=r=""),r)for(t in r)n&&t in n||Dn(e.style,t,"");if(n)for(t in n)r&&n[t]===r[t]||Dn(e.style,t,n[t])}else if("o"===t[0]&&"n"===t[1])i=t!==(t=t.replace(/Capture$/,"")),t=t.toLowerCase()in e?t.toLowerCase().slice(2):t.slice(2),e.l||(e.l={}),e.l[t+i]=n,n?r||e.addEventListener(t,i?xn:kn,i):e.removeEventListener(t,i?xn:kn,i);else if("dangerouslySetInnerHTML"!==t){if(o)t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!==t&&"height"!==t&&"href"!==t&&"list"!==t&&"form"!==t&&"tabIndex"!==t&&"download"!==t&&t in e)try{e[t]=null==n?"":n;break e}catch(e){}"function"==typeof n||(null==n||!1===n&&"-"!==t[4]?e.removeAttribute(t):e.setAttribute(t,n))}}function kn(e){return this.l[e.type+!1](un.event?un.event(e):e)}function xn(e){return this.l[e.type+!0](un.event?un.event(e):e)}function Nn(e,t,n,r,o,i,u,a,l){var c,s,f,p,m,v,d,y,b,g,h,_,O,S,j,P=t.type;if(void 0!==t.constructor)return null;null!=n.__h&&(l=n.__h,a=t.__e=n.__e,t.__h=null,i=[a]),(c=un.__b)&&c(t);try{e:if("function"==typeof P){if(y=t.props,b=(c=P.contextType)&&r[c.__c],g=c?b?b.props.value:c.__:r,n.__c?d=(s=t.__c=n.__c).__=s.__E:("prototype"in P&&P.prototype.render?t.__c=s=new P(y,g):(t.__c=s=new _n(y,g),s.constructor=P,s.render=Ln),b&&b.sub(s),s.props=y,s.state||(s.state={}),s.context=g,s.__n=r,f=s.__d=!0,s.__h=[],s._sb=[]),null==s.__s&&(s.__s=s.state),null!=P.getDerivedStateFromProps&&(s.__s==s.state&&(s.__s=dn({},s.__s)),dn(s.__s,P.getDerivedStateFromProps(y,s.__s))),p=s.props,m=s.state,s.__v=t,f)null==P.getDerivedStateFromProps&&null!=s.componentWillMount&&s.componentWillMount(),null!=s.componentDidMount&&s.__h.push(s.componentDidMount);else{if(null==P.getDerivedStateFromProps&&y!==p&&null!=s.componentWillReceiveProps&&s.componentWillReceiveProps(y,g),!s.__e&&null!=s.shouldComponentUpdate&&!1===s.shouldComponentUpdate(y,s.__s,g)||t.__v===n.__v){for(t.__v!==n.__v&&(s.props=y,s.state=s.__s,s.__d=!1),s.__e=!1,t.__e=n.__e,t.__k=n.__k,t.__k.forEach((function(e){e&&(e.__=t)})),h=0;h0&&void 0!==arguments[0]?arguments[0]:[];return{get:function(){return e},add:function(t){var n=e[e.length-1];(null==n?void 0:n.isHighlighted)===t.isHighlighted?e[e.length-1]={value:n.value+t.value,isHighlighted:n.isHighlighted}:e.push(t)}}}(n?[{value:n,isHighlighted:!1}]:[]);return t.forEach((function(e){var t=e.split(Un);r.add({value:t[0],isHighlighted:!0}),""!==t[1]&&r.add({value:t[1],isHighlighted:!1})})),r.get()}function Hn(e){return function(e){if(Array.isArray(e))return Vn(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return Vn(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Vn(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Vn(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n",""":'"',"'":"'"},Kn=new RegExp(/\w/i),$n=/&(amp|quot|lt|gt|#39);/g,zn=RegExp($n.source);function Gn(e,t){var n,r,o,i=e[t],u=(null===(n=e[t+1])||void 0===n?void 0:n.isHighlighted)||!0,a=(null===(r=e[t-1])||void 0===r?void 0:r.isHighlighted)||!0;return Kn.test((o=i.value)&&zn.test(o)?o.replace($n,(function(e){return Qn[e]})):o)||a!==u?i.isHighlighted:a}function Jn(e){return Jn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Jn(e)}function Xn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Yn(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function vr(e){return function(e){if(Array.isArray(e))return dr(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return dr(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return dr(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function dr(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0;if(!_.value.core.openOnFocus&&!t.query)return n;var r=Boolean(y.current||_.value.renderer.renderNoResults);return!n&&r||n},__autocomplete_metadata:{userAgents:wr,options:e}}))})),j=f(n({collections:[],completion:null,context:{},isOpen:!1,query:"",activeItemId:null,status:"idle"},_.value.core.initialState)),P={getEnvironmentProps:_.value.renderer.getEnvironmentProps,getFormProps:_.value.renderer.getFormProps,getInputProps:_.value.renderer.getInputProps,getItemProps:_.value.renderer.getItemProps,getLabelProps:_.value.renderer.getLabelProps,getListProps:_.value.renderer.getListProps,getPanelProps:_.value.renderer.getPanelProps,getRootProps:_.value.renderer.getRootProps},w={setActiveItemId:S.value.setActiveItemId,setQuery:S.value.setQuery,setCollections:S.value.setCollections,setIsOpen:S.value.setIsOpen,setStatus:S.value.setStatus,setContext:S.value.setContext,refresh:S.value.refresh,navigator:S.value.navigator},I=m((function(){return Lt.bind(_.value.renderer.renderer.createElement)})),A=m((function(){return rn({autocomplete:S.value,autocompleteScopeApi:w,classNames:_.value.renderer.classNames,environment:_.value.core.environment,isDetached:O.value,placeholder:_.value.core.placeholder,propGetters:P,setIsModalOpen:k,state:j.current,translations:_.value.renderer.translations})}));function E(){Jt(A.value.panel,{style:O.value?{}:Pr({panelPlacement:_.value.renderer.panelPlacement,container:A.value.root,form:A.value.form,environment:_.value.core.environment})})}function D(e){j.current=e;var t={autocomplete:S.value,autocompleteScopeApi:w,classNames:_.value.renderer.classNames,components:_.value.renderer.components,container:_.value.renderer.container,html:I.value,dom:A.value,panelContainer:O.value?A.value.detachedContainer:_.value.renderer.panelContainer,propGetters:P,state:j.current,renderer:_.value.renderer.renderer},r=!b(e)&&!y.current&&_.value.renderer.renderNoResults||_.value.renderer.render;!function(e){var t=e.autocomplete,r=e.autocompleteScopeApi,o=e.dom,i=e.propGetters,u=e.state;Xt(o.root,i.getRootProps(n({state:u,props:t.getRootProps({})},r))),Xt(o.input,i.getInputProps(n({state:u,props:t.getInputProps({inputElement:o.input}),inputElement:o.input},r))),Jt(o.label,{hidden:"stalled"===u.status}),Jt(o.loadingIndicator,{hidden:"stalled"!==u.status}),Jt(o.clearButton,{hidden:!u.query}),Jt(o.detachedSearchButtonQuery,{textContent:u.query}),Jt(o.detachedSearchButtonPlaceholder,{hidden:Boolean(u.query)})}(t),function(e,t){var r=t.autocomplete,o=t.autocompleteScopeApi,u=t.classNames,a=t.html,l=t.dom,c=t.panelContainer,s=t.propGetters,f=t.state,p=t.components,m=t.renderer;if(f.isOpen){c.contains(l.panel)||"loading"===f.status||c.appendChild(l.panel),l.panel.classList.toggle("aa-Panel--stalled","stalled"===f.status);var v=f.collections.filter((function(e){var t=e.source,n=e.items;return t.templates.noResults||n.length>0})).map((function(e,t){var l=e.source,c=e.items;return m.createElement("section",{key:t,className:u.source,"data-autocomplete-source-id":l.sourceId},l.templates.header&&m.createElement("div",{className:u.sourceHeader},l.templates.header({components:p,createElement:m.createElement,Fragment:m.Fragment,items:c,source:l,state:f,html:a})),l.templates.noResults&&0===c.length?m.createElement("div",{className:u.sourceNoResults},l.templates.noResults({components:p,createElement:m.createElement,Fragment:m.Fragment,source:l,state:f,html:a})):m.createElement("ul",i({className:u.list},s.getListProps(n({state:f,props:r.getListProps({source:l})},o))),c.map((function(e){var t=r.getItemProps({item:e,source:l});return m.createElement("li",i({key:t.id,className:u.item},s.getItemProps(n({state:f,props:t},o))),l.templates.item({components:p,createElement:m.createElement,Fragment:m.Fragment,item:e,state:f,html:a}))}))),l.templates.footer&&m.createElement("div",{className:u.sourceFooter},l.templates.footer({components:p,createElement:m.createElement,Fragment:m.Fragment,items:c,source:l,state:f,html:a})))})),d=m.createElement(m.Fragment,null,m.createElement("div",{className:u.panelLayout},v),m.createElement("div",{className:"aa-GradientBottom"})),y=v.reduce((function(e,t){return e[t.props["data-autocomplete-source-id"]]=t,e}),{});e(n(n({children:d,state:f,sections:v,elements:y},m),{},{components:p,html:a},o),l.panel)}else c.contains(l.panel)&&c.removeChild(l.panel)}(r,t)}function C(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};l();var t=_.value.renderer,n=t.components,r=u(t,Ir);g.current=Vt(r,_.value.core,{components:Wt(n,(function(e){return!e.value.hasOwnProperty("__autocomplete_componentName")})),initialState:j.current},e),v(),c(),S.value.refresh().then((function(){D(j.current)}))}function k(e){e!==_.value.core.environment.document.body.contains(A.value.detachedOverlay)&&(e?(_.value.core.environment.document.body.appendChild(A.value.detachedOverlay),_.value.core.environment.document.body.classList.add("aa-Detached"),A.value.input.focus()):(_.value.core.environment.document.body.removeChild(A.value.detachedOverlay),_.value.core.environment.document.body.classList.remove("aa-Detached")))}return a((function(){var e=S.value.getEnvironmentProps({formElement:A.value.form,panelElement:A.value.panel,inputElement:A.value.input});return Jt(_.value.core.environment,e),function(){Jt(_.value.core.environment,Object.keys(e).reduce((function(e,t){return n(n({},e),{},o({},t,void 0))}),{}))}})),a((function(){var e=O.value?_.value.core.environment.document.body:_.value.renderer.panelContainer,t=O.value?A.value.detachedOverlay:A.value.panel;return O.value&&j.current.isOpen&&k(!0),D(j.current),function(){e.contains(t)&&(e.removeChild(t),e.classList.remove("aa-Detached"))}})),a((function(){var e=_.value.renderer.container;return e.appendChild(A.value.root),function(){e.removeChild(A.value.root)}})),a((function(){var e=p((function(e){D(e.state)}),0);return h.current=function(t){var n=t.state,r=t.prevState;(O.value&&r.isOpen!==n.isOpen&&k(n.isOpen),O.value||!n.isOpen||r.isOpen||E(),n.query!==r.query)&&_.value.core.environment.document.querySelectorAll(".aa-Panel--scrollable").forEach((function(e){0!==e.scrollTop&&(e.scrollTop=0)}));e({state:n})},function(){h.current=void 0}})),a((function(){var e=p((function(){var e=O.value;O.value=_.value.core.environment.matchMedia(_.value.renderer.detachedMediaQuery).matches,e!==O.value?C({}):requestAnimationFrame(E)}),20);return _.value.core.environment.addEventListener("resize",e),function(){_.value.core.environment.removeEventListener("resize",e)}})),a((function(){if(!O.value)return function(){};function e(e){A.value.detachedContainer.classList.toggle("aa-DetachedContainer--modal",e)}function t(t){e(t.matches)}var n=_.value.core.environment.matchMedia(getComputedStyle(_.value.core.environment.document.documentElement).getPropertyValue("--aa-detached-modal-media-query"));e(n.matches);var r=Boolean(n.addEventListener);return r?n.addEventListener("change",t):n.addListener(t),function(){r?n.removeEventListener("change",t):n.removeListener(t)}})),a((function(){return requestAnimationFrame(E),function(){}})),n(n({},w),{},{update:C,destroy:function(){l()}})},e.getAlgoliaFacets=function(e){var t=Ar({transformResponse:function(e){return e.facetHits}}),r=e.queries.map((function(e){return n(n({},e),{},{type:"facet"})}));return t(n(n({},e),{},{queries:r}))},e.getAlgoliaResults=Er,Object.defineProperty(e,"__esModule",{value:!0})})); + diff --git a/docs/site_libs/quarto-search/fuse.min.js b/docs/site_libs/quarto-search/fuse.min.js new file mode 100644 index 0000000..adc2835 --- /dev/null +++ b/docs/site_libs/quarto-search/fuse.min.js @@ -0,0 +1,9 @@ +/** + * Fuse.js v6.6.2 - Lightweight fuzzy-search (http://fusejs.io) + * + * Copyright (c) 2022 Kiro Risk (http://kiro.me) + * All Rights Reserved. Apache Software License 2.0 + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ +var e,t;e=this,t=function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var n=1;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,n=new Map,r=Math.pow(10,t);return{get:function(t){var i=t.match(C).length;if(n.has(i))return n.get(i);var o=1/Math.pow(i,.5*e),c=parseFloat(Math.round(o*r)/r);return n.set(i,c),c},clear:function(){n.clear()}}}var $=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.getFn,i=void 0===n?I.getFn:n,o=t.fieldNormWeight,c=void 0===o?I.fieldNormWeight:o;r(this,e),this.norm=E(c,3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return o(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,g(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();g(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?I.getFn:r,o=n.fieldNormWeight,c=void 0===o?I.fieldNormWeight:o,a=new $({getFn:i,fieldNormWeight:c});return a.setKeys(e.map(_)),a.setSources(t),a.create(),a}function R(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,o=void 0===i?0:i,c=t.expectedLocation,a=void 0===c?0:c,s=t.distance,u=void 0===s?I.distance:s,h=t.ignoreLocation,l=void 0===h?I.ignoreLocation:h,f=r/e.length;if(l)return f;var d=Math.abs(a-o);return u?f+d/u:d?1:f}function N(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:I.minMatchCharLength,n=[],r=-1,i=-1,o=0,c=e.length;o=t&&n.push([r,i]),r=-1)}return e[o-1]&&o-r>=t&&n.push([r,o-1]),n}var P=32;function W(e){for(var t={},n=0,r=e.length;n1&&void 0!==arguments[1]?arguments[1]:{},o=i.location,c=void 0===o?I.location:o,a=i.threshold,s=void 0===a?I.threshold:a,u=i.distance,h=void 0===u?I.distance:u,l=i.includeMatches,f=void 0===l?I.includeMatches:l,d=i.findAllMatches,v=void 0===d?I.findAllMatches:d,g=i.minMatchCharLength,y=void 0===g?I.minMatchCharLength:g,p=i.isCaseSensitive,m=void 0===p?I.isCaseSensitive:p,k=i.ignoreLocation,M=void 0===k?I.ignoreLocation:k;if(r(this,e),this.options={location:c,threshold:s,distance:h,includeMatches:f,findAllMatches:v,minMatchCharLength:y,isCaseSensitive:m,ignoreLocation:M},this.pattern=m?t:t.toLowerCase(),this.chunks=[],this.pattern.length){var b=function(e,t){n.chunks.push({pattern:e,alphabet:W(e),startIndex:t})},x=this.pattern.length;if(x>P){for(var w=0,L=x%P,S=x-L;w3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,o=void 0===i?I.location:i,c=r.distance,a=void 0===c?I.distance:c,s=r.threshold,u=void 0===s?I.threshold:s,h=r.findAllMatches,l=void 0===h?I.findAllMatches:h,f=r.minMatchCharLength,d=void 0===f?I.minMatchCharLength:f,v=r.includeMatches,g=void 0===v?I.includeMatches:v,y=r.ignoreLocation,p=void 0===y?I.ignoreLocation:y;if(t.length>P)throw new Error(w(P));for(var m,k=t.length,M=e.length,b=Math.max(0,Math.min(o,M)),x=u,L=b,S=d>1||g,_=S?Array(M):[];(m=e.indexOf(t,L))>-1;){var O=R(t,{currentLocation:m,expectedLocation:b,distance:a,ignoreLocation:p});if(x=Math.min(O,x),L=m+k,S)for(var j=0;j=z;q-=1){var B=q-1,J=n[e.charAt(B)];if(S&&(_[B]=+!!J),K[q]=(K[q+1]<<1|1)&J,F&&(K[q]|=(A[q+1]|A[q])<<1|1|A[q+1]),K[q]&$&&(C=R(t,{errors:F,currentLocation:B,expectedLocation:b,distance:a,ignoreLocation:p}))<=x){if(x=C,(L=B)<=b)break;z=Math.max(1,2*b-L)}}if(R(t,{errors:F+1,currentLocation:b,expectedLocation:b,distance:a,ignoreLocation:p})>x)break;A=K}var U={isMatch:L>=0,score:Math.max(.001,C)};if(S){var V=N(_,d);V.length?g&&(U.indices=V):U.isMatch=!1}return U}(e,n,i,{location:c+o,distance:a,threshold:s,findAllMatches:u,minMatchCharLength:h,includeMatches:r,ignoreLocation:l}),p=y.isMatch,m=y.score,k=y.indices;p&&(g=!0),v+=m,p&&k&&(d=[].concat(f(d),f(k)))}));var y={isMatch:g,score:g?v/this.chunks.length:1};return g&&r&&(y.indices=d),y}}]),e}(),z=function(){function e(t){r(this,e),this.pattern=t}return o(e,[{key:"search",value:function(){}}],[{key:"isMultiMatch",value:function(e){return D(e,this.multiRegex)}},{key:"isSingleMatch",value:function(e){return D(e,this.singleRegex)}}]),e}();function D(e,t){var n=e.match(t);return n?n[1]:null}var K=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=e===this.pattern;return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}}],[{key:"type",get:function(){return"exact"}},{key:"multiRegex",get:function(){return/^="(.*)"$/}},{key:"singleRegex",get:function(){return/^=(.*)$/}}]),n}(z),q=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=-1===e.indexOf(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-exact"}},{key:"multiRegex",get:function(){return/^!"(.*)"$/}},{key:"singleRegex",get:function(){return/^!(.*)$/}}]),n}(z),B=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}}],[{key:"type",get:function(){return"prefix-exact"}},{key:"multiRegex",get:function(){return/^\^"(.*)"$/}},{key:"singleRegex",get:function(){return/^\^(.*)$/}}]),n}(z),J=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=!e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-prefix-exact"}},{key:"multiRegex",get:function(){return/^!\^"(.*)"$/}},{key:"singleRegex",get:function(){return/^!\^(.*)$/}}]),n}(z),U=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[e.length-this.pattern.length,e.length-1]}}}],[{key:"type",get:function(){return"suffix-exact"}},{key:"multiRegex",get:function(){return/^"(.*)"\$$/}},{key:"singleRegex",get:function(){return/^(.*)\$$/}}]),n}(z),V=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=!e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-suffix-exact"}},{key:"multiRegex",get:function(){return/^!"(.*)"\$$/}},{key:"singleRegex",get:function(){return/^!(.*)\$$/}}]),n}(z),G=function(e){a(n,e);var t=l(n);function n(e){var i,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=o.location,a=void 0===c?I.location:c,s=o.threshold,u=void 0===s?I.threshold:s,h=o.distance,l=void 0===h?I.distance:h,f=o.includeMatches,d=void 0===f?I.includeMatches:f,v=o.findAllMatches,g=void 0===v?I.findAllMatches:v,y=o.minMatchCharLength,p=void 0===y?I.minMatchCharLength:y,m=o.isCaseSensitive,k=void 0===m?I.isCaseSensitive:m,M=o.ignoreLocation,b=void 0===M?I.ignoreLocation:M;return r(this,n),(i=t.call(this,e))._bitapSearch=new T(e,{location:a,threshold:u,distance:l,includeMatches:d,findAllMatches:g,minMatchCharLength:p,isCaseSensitive:k,ignoreLocation:b}),i}return o(n,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),n}(z),H=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){for(var t,n=0,r=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,r.push([t,n-1]);var o=!!r.length;return{isMatch:o,score:o?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),n}(z),Q=[K,H,B,J,V,U,q,G],X=Q.length,Y=/ +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/;function Z(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map((function(e){for(var n=e.trim().split(Y).filter((function(e){return e&&!!e.trim()})),r=[],i=0,o=n.length;i1&&void 0!==arguments[1]?arguments[1]:{},i=n.isCaseSensitive,o=void 0===i?I.isCaseSensitive:i,c=n.includeMatches,a=void 0===c?I.includeMatches:c,s=n.minMatchCharLength,u=void 0===s?I.minMatchCharLength:s,h=n.ignoreLocation,l=void 0===h?I.ignoreLocation:h,f=n.findAllMatches,d=void 0===f?I.findAllMatches:f,v=n.location,g=void 0===v?I.location:v,y=n.threshold,p=void 0===y?I.threshold:y,m=n.distance,k=void 0===m?I.distance:m;r(this,e),this.query=null,this.options={isCaseSensitive:o,includeMatches:a,minMatchCharLength:u,findAllMatches:d,ignoreLocation:l,location:g,threshold:p,distance:k},this.pattern=o?t:t.toLowerCase(),this.query=Z(this.pattern,this.options)}return o(e,[{key:"searchIn",value:function(e){var t=this.query;if(!t)return{isMatch:!1,score:1};var n=this.options,r=n.includeMatches;e=n.isCaseSensitive?e:e.toLowerCase();for(var i=0,o=[],c=0,a=0,s=t.length;a-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function ve(e,t){t.score=e.score}function ge(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?I.includeMatches:r,o=n.includeScore,c=void 0===o?I.includeScore:o,a=[];return i&&a.push(de),c&&a.push(ve),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return a.length&&a.forEach((function(t){t(e,r)})),r}))}var ye=function(){function e(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;r(this,e),this.options=t(t({},I),i),this.options.useExtendedSearch,this._keyStore=new S(this.options.keys),this.setCollection(n,o)}return o(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof $))throw new Error("Incorrect 'index' type");this._myIndex=t||F(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(e){k(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n1&&void 0!==arguments[1]?arguments[1]:{},n=t.limit,r=void 0===n?-1:n,i=this.options,o=i.includeMatches,c=i.includeScore,a=i.shouldSort,s=i.sortFn,u=i.ignoreFieldNorm,h=g(e)?g(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return fe(h,{ignoreFieldNorm:u}),a&&h.sort(s),y(r)&&r>-1&&(h=h.slice(0,r)),ge(h,this._docs,{includeMatches:o,includeScore:c})}},{key:"_searchStringList",value:function(e){var t=re(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,o=e.n;if(k(n)){var c=t.searchIn(n),a=c.isMatch,s=c.score,u=c.indices;a&&r.push({item:n,idx:i,matches:[{score:s,value:n,norm:o,indices:u}]})}})),r}},{key:"_searchLogical",value:function(e){var t=this,n=function(e,t){var n=(arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).auto,r=void 0===n||n,i=function e(n){var i=Object.keys(n),o=ue(n);if(!o&&i.length>1&&!se(n))return e(le(n));if(he(n)){var c=o?n[ce]:i[0],a=o?n[ae]:n[c];if(!g(a))throw new Error(x(c));var s={keyId:j(c),pattern:a};return r&&(s.searcher=re(a,t)),s}var u={children:[],operator:i[0]};return i.forEach((function(t){var r=n[t];v(r)&&r.forEach((function(t){u.children.push(e(t))}))})),u};return se(e)||(e=le(e)),i(e)}(e,this.options),r=function e(n,r,i){if(!n.children){var o=n.keyId,c=n.searcher,a=t._findMatches({key:t._keyStore.get(o),value:t._myIndex.getValueForItemAtKeyId(r,o),searcher:c});return a&&a.length?[{idx:i,item:r,matches:a}]:[]}for(var s=[],u=0,h=n.children.length;u1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?I.getFn:n,i=t.fieldNormWeight,o=void 0===i?I.fieldNormWeight:i,c=e.keys,a=e.records,s=new $({getFn:r,fieldNormWeight:o});return s.setKeys(c),s.setIndexRecords(a),s},ye.config=I,function(){ne.push.apply(ne,arguments)}(te),ye},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Fuse=t(); \ No newline at end of file diff --git a/docs/site_libs/quarto-search/quarto-search.js b/docs/site_libs/quarto-search/quarto-search.js new file mode 100644 index 0000000..437e38f --- /dev/null +++ b/docs/site_libs/quarto-search/quarto-search.js @@ -0,0 +1,1457 @@ +const kQueryArg = "q"; +const kResultsArg = "show-results"; + +// If items don't provide a URL, then both the navigator and the onSelect +// function aren't called (and therefore, the default implementation is used) +// +// We're using this sentinel URL to signal to those handlers that this +// item is a more item (along with the type) and can be handled appropriately +const kItemTypeMoreHref = "0767FDFD-0422-4E5A-BC8A-3BE11E5BBA05"; + +// Capture search params and clean ?q= from URL at module load time, before +// any DOMContentLoaded handlers run. quarto-nav.js resolves all hrefs +// against window.location during DOMContentLoaded — if ?q= is still present, +// every link on the page gets the query param baked into its href. +const currentUrl = new URL(window.location); +const kQuery = currentUrl.searchParams.get(kQueryArg); +if (kQuery) { + const replacementUrl = new URL(window.location); + replacementUrl.searchParams.delete(kQueryArg); + window.history.replaceState({}, "", replacementUrl); +} + +window.document.addEventListener("DOMContentLoaded", function (_event) { + // Ensure that search is available on this page. If it isn't, + // should return early and not do anything + var searchEl = window.document.getElementById("quarto-search"); + if (!searchEl) return; + + const { autocomplete } = window["@algolia/autocomplete-js"]; + + let quartoSearchOptions = {}; + let language = {}; + const searchOptionEl = window.document.getElementById( + "quarto-search-options" + ); + if (searchOptionEl) { + const jsonStr = searchOptionEl.textContent; + quartoSearchOptions = JSON.parse(jsonStr); + language = quartoSearchOptions.language; + } + + // note the search mode + if (quartoSearchOptions.type === "overlay") { + searchEl.classList.add("type-overlay"); + } else { + searchEl.classList.add("type-textbox"); + } + + // Used to determine highlighting behavior for this page + // A `q` query param is expected when the user follows a search + // to this page + const query = kQuery; + const showSearchResults = currentUrl.searchParams.get(kResultsArg); + const mainEl = window.document.querySelector("main"); + + // highlight matches on the page + if (query && mainEl) { + highlight(query, mainEl); + + // Activate tabs on pageshow — after tabsets.js restores localStorage state. + // tabsets.js registers its pageshow handler during module execution (before + // DOMContentLoaded). By registering ours during DOMContentLoaded, listener + // ordering guarantees we run after tabsets.js — so search activation wins. + window.addEventListener("pageshow", function (event) { + if (!event.persisted) { + for (const mark of mainEl.querySelectorAll("mark")) { + openAllTabsetsContainingEl(mark); + } + // Only scroll to first match when there's no hash fragment. + // With a hash, the browser already scrolled to the target section. + if (!currentUrl.hash) { + requestAnimationFrame(() => scrollToFirstVisibleMatch(mainEl)); + } + } + }, { once: true }); + } + + // function to clear highlighting on the page when the search query changes + // (e.g. if the user edits the query or clears it) + let highlighting = true; + const resetHighlighting = (searchTerm) => { + if (mainEl && highlighting && query && searchTerm !== query) { + clearHighlight(query, mainEl); + highlighting = false; + } + }; + + // Responsively switch to overlay mode if the search is present on the navbar + // Note that switching the sidebar to overlay mode requires more coordinate (not just + // the media query since we generate different HTML for sidebar overlays than we do + // for sidebar input UI) + const detachedMediaQuery = + quartoSearchOptions.type === "overlay" ? "all" : "(max-width: 991px)"; + + // If configured, include the analytics client to send insights + const plugins = configurePlugins(quartoSearchOptions); + + let lastState = null; + const { setIsOpen, setQuery, setCollections } = autocomplete({ + container: searchEl, + detachedMediaQuery: detachedMediaQuery, + defaultActiveItemId: 0, + panelContainer: "#quarto-search-results", + panelPlacement: quartoSearchOptions["panel-placement"], + debug: false, + openOnFocus: true, + plugins, + classNames: { + form: "d-flex", + }, + placeholder: language["search-text-placeholder"], + translations: { + clearButtonTitle: language["search-clear-button-title"], + detachedCancelButtonText: language["search-detached-cancel-button-title"], + submitButtonTitle: language["search-submit-button-title"], + }, + initialState: { + query, + }, + getItemUrl({ item }) { + return item.href; + }, + onStateChange({ state }) { + // If this is a file URL, note that + + // Perhaps reset highlighting + resetHighlighting(state.query); + + // If the panel just opened, ensure the panel is positioned properly + if (state.isOpen) { + if (lastState && !lastState.isOpen) { + setTimeout(() => { + positionPanel(quartoSearchOptions["panel-placement"]); + }, 150); + } + } + + // Perhaps show the copy link + showCopyLink(state.query, quartoSearchOptions); + + lastState = state; + }, + reshape({ sources, state }) { + return sources.map((source) => { + try { + const items = source.getItems(); + + // Validate the items + validateItems(items); + + // group the items by document + const groupedItems = new Map(); + items.forEach((item) => { + const hrefParts = item.href.split("#"); + const baseHref = hrefParts[0]; + const isDocumentItem = hrefParts.length === 1; + + const items = groupedItems.get(baseHref); + if (!items) { + groupedItems.set(baseHref, [item]); + } else { + // If the href for this item matches the document + // exactly, place this item first as it is the item that represents + // the document itself + if (isDocumentItem) { + items.unshift(item); + } else { + items.push(item); + } + groupedItems.set(baseHref, items); + } + }); + + const reshapedItems = []; + let count = 1; + for (const [_key, value] of groupedItems) { + const firstItem = value[0]; + reshapedItems.push({ + ...firstItem, + type: kItemTypeDoc, + }); + + const collapseMatches = quartoSearchOptions["collapse-after"]; + const collapseCount = + typeof collapseMatches === "number" ? collapseMatches : 1; + + if (value.length > 1) { + const target = `search-more-${count}`; + const isExpanded = + state.context.expanded && + state.context.expanded.includes(target); + + const remainingCount = value.length - collapseCount; + + for (let i = 1; i < value.length; i++) { + if (collapseMatches && i === collapseCount) { + reshapedItems.push({ + target, + title: isExpanded + ? language["search-hide-matches-text"] + : remainingCount === 1 + ? `${remainingCount} ${language["search-more-match-text"]}` + : `${remainingCount} ${language["search-more-matches-text"]}`, + type: kItemTypeMore, + href: kItemTypeMoreHref, + }); + } + + if (isExpanded || !collapseMatches || i < collapseCount) { + reshapedItems.push({ + ...value[i], + type: kItemTypeItem, + target, + }); + } + } + } + count += 1; + } + + return { + ...source, + getItems() { + return reshapedItems; + }, + }; + } catch (error) { + // Some form of error occurred + return { + ...source, + getItems() { + return [ + { + title: error.name || "An Error Occurred While Searching", + text: + error.message || + "An unknown error occurred while attempting to perform the requested search.", + type: kItemTypeError, + }, + ]; + }, + }; + } + }); + }, + navigator: { + navigate({ itemUrl }) { + if (itemUrl !== offsetURL(kItemTypeMoreHref)) { + window.location.assign(itemUrl); + } + }, + navigateNewTab({ itemUrl }) { + if (itemUrl !== offsetURL(kItemTypeMoreHref)) { + const windowReference = window.open(itemUrl, "_blank", "noopener"); + if (windowReference) { + windowReference.focus(); + } + } + }, + navigateNewWindow({ itemUrl }) { + if (itemUrl !== offsetURL(kItemTypeMoreHref)) { + window.open(itemUrl, "_blank", "noopener"); + } + }, + }, + getSources({ state, setContext, setActiveItemId, refresh }) { + return [ + { + sourceId: "documents", + getItemUrl({ item }) { + if (item.href) { + return offsetURL(item.href); + } else { + return undefined; + } + }, + onSelect({ + item, + state, + setContext, + setIsOpen, + setActiveItemId, + refresh, + }) { + if (item.type === kItemTypeMore) { + toggleExpanded(item, state, setContext, setActiveItemId, refresh); + + // Toggle more + setIsOpen(true); + } + }, + getItems({ query }) { + if (query === null || query === "") { + return []; + } + + const limit = quartoSearchOptions.limit; + if (quartoSearchOptions.algolia) { + return algoliaSearch(query, limit, quartoSearchOptions.algolia); + } else { + // Fuse search options + const fuseSearchOptions = { + isCaseSensitive: false, + shouldSort: true, + minMatchCharLength: 2, + limit: limit, + }; + + return readSearchData().then(function (fuse) { + return fuseSearch(query, fuse, fuseSearchOptions); + }); + } + }, + templates: { + noResults({ createElement }) { + const hasQuery = lastState.query; + + return createElement( + "div", + { + class: `quarto-search-no-results${hasQuery ? "" : " no-query" + }`, + }, + language["search-no-results-text"] + ); + }, + header({ items, createElement }) { + // count the documents + const count = items.filter((item) => { + return item.type === kItemTypeDoc; + }).length; + + if (count > 0) { + return createElement( + "div", + { class: "search-result-header" }, + `${count} ${language["search-matching-documents-text"]}` + ); + } else { + return createElement( + "div", + { class: "search-result-header-no-results" }, + `` + ); + } + }, + footer({ _items, createElement }) { + if ( + quartoSearchOptions.algolia && + quartoSearchOptions.algolia["show-logo"] + ) { + const libDir = quartoSearchOptions.algolia["libDir"]; + const logo = createElement("img", { + src: offsetURL( + `${libDir}/quarto-search/search-by-algolia.svg` + ), + class: "algolia-search-logo", + }); + return createElement( + "a", + { href: "http://www.algolia.com/" }, + logo + ); + } + }, + + item({ item, createElement }) { + if (item.text && item.href && !item.href.includes('?q=')) { + const [main, hash] = item.href.split('#') + const hashAppend = hash ? '#' + hash : '' + item.href = main + '?q=' + encodeURIComponent(state.query) + hashAppend + } + + return renderItem( + item, + createElement, + state, + setActiveItemId, + setContext, + refresh, + quartoSearchOptions + ); + }, + }, + }, + ]; + }, + }); + + window.quartoOpenSearch = () => { + setIsOpen(false); + setIsOpen(true); + focusSearchInput(); + }; + + document.addEventListener("keyup", (event) => { + const { key } = event; + const kbds = quartoSearchOptions["keyboard-shortcut"]; + const focusedEl = document.activeElement; + + const isFormElFocused = [ + "input", + "select", + "textarea", + "button", + "option", + ].find((tag) => { + return focusedEl.tagName.toLowerCase() === tag; + }); + + if ( + kbds && + kbds.includes(key) && + !isFormElFocused && + !document.activeElement.isContentEditable + ) { + event.preventDefault(); + window.quartoOpenSearch(); + } + }); + + // Remove the labeleledby attribute since it is pointing + // to a non-existent label + if (quartoSearchOptions.type === "overlay") { + const inputEl = window.document.querySelector( + "#quarto-search .aa-Autocomplete" + ); + if (inputEl) { + inputEl.removeAttribute("aria-labelledby"); + } + } + + function throttle(func, wait) { + let waiting = false; + return function () { + if (!waiting) { + func.apply(this, arguments); + waiting = true; + setTimeout(function () { + waiting = false; + }, wait); + } + }; + } + + // If the main document scrolls dismiss the search results + // (otherwise, since they're floating in the document they can scroll with the document) + window.document.body.onscroll = throttle(() => { + // Only do this if we're not detached + // Bug #7117 + // This will happen when the keyboard is shown on ios (resulting in a scroll) + // which then closed the search UI + if (!window.matchMedia(detachedMediaQuery).matches) { + setIsOpen(false); + } + }, 50); + + if (showSearchResults) { + setIsOpen(true); + focusSearchInput(); + } +}); + +function configurePlugins(quartoSearchOptions) { + const autocompletePlugins = []; + const algoliaOptions = quartoSearchOptions.algolia; + if ( + algoliaOptions && + algoliaOptions["analytics-events"] && + algoliaOptions["search-only-api-key"] && + algoliaOptions["application-id"] + ) { + const apiKey = algoliaOptions["search-only-api-key"]; + const appId = algoliaOptions["application-id"]; + + // Aloglia insights may not be loaded because they require cookie consent + // Use deferred loading so events will start being recorded when/if consent + // is granted. + const algoliaInsightsDeferredPlugin = deferredLoadPlugin(() => { + if ( + window.aa && + window["@algolia/autocomplete-plugin-algolia-insights"] + ) { + // Check if cookie consent is enabled from search options + const cookieConsentEnabled = algoliaOptions["cookie-consent-enabled"] || false; + + // Generate random session token only when cookies are disabled + const userToken = cookieConsentEnabled ? undefined : Array.from(Array(20), () => + Math.floor(Math.random() * 36).toString(36) + ).join(""); + + window.aa("init", { + appId, + apiKey, + useCookie: cookieConsentEnabled, + userToken: userToken, + }); + + const { createAlgoliaInsightsPlugin } = + window["@algolia/autocomplete-plugin-algolia-insights"]; + // Register the insights client + const algoliaInsightsPlugin = createAlgoliaInsightsPlugin({ + insightsClient: window.aa, + onItemsChange({ insights, insightsEvents }) { + const events = insightsEvents.flatMap((event) => { + // This API limits the number of items per event to 20 + const chunkSize = 20; + const itemChunks = []; + const eventItems = event.items; + for (let i = 0; i < eventItems.length; i += chunkSize) { + itemChunks.push(eventItems.slice(i, i + chunkSize)); + } + // Split the items into multiple events that can be sent + const events = itemChunks.map((items) => { + return { + ...event, + items, + }; + }); + return events; + }); + + for (const event of events) { + insights.viewedObjectIDs(event); + } + }, + }); + return algoliaInsightsPlugin; + } + }); + + // Add the plugin + autocompletePlugins.push(algoliaInsightsDeferredPlugin); + return autocompletePlugins; + } +} + +// For plugins that may not load immediately, create a wrapper +// plugin and forward events and plugin data once the plugin +// is initialized. This is useful for cases like cookie consent +// which may prevent the analytics insights event plugin from initializing +// immediately. +function deferredLoadPlugin(createPlugin) { + let plugin = undefined; + let subscribeObj = undefined; + const wrappedPlugin = () => { + if (!plugin && subscribeObj) { + plugin = createPlugin(); + if (plugin && plugin.subscribe) { + plugin.subscribe(subscribeObj); + } + } + return plugin; + }; + + return { + subscribe: (obj) => { + subscribeObj = obj; + }, + onStateChange: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.onStateChange) { + plugin.onStateChange(obj); + } + }, + onSubmit: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.onSubmit) { + plugin.onSubmit(obj); + } + }, + onReset: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.onReset) { + plugin.onReset(obj); + } + }, + getSources: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.getSources) { + return plugin.getSources(obj); + } else { + return Promise.resolve([]); + } + }, + data: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.data) { + plugin.data(obj); + } + }, + }; +} + +function validateItems(items) { + // Validate the first item + if (items.length > 0) { + const item = items[0]; + const missingFields = []; + if (item.href == undefined) { + missingFields.push("href"); + } + if (!item.title == undefined) { + missingFields.push("title"); + } + if (!item.text == undefined) { + missingFields.push("text"); + } + + if (missingFields.length === 1) { + throw { + name: `Error: Search index is missing the ${missingFields[0]} field.`, + message: `The items being returned for this search do not include all the required fields. Please ensure that your index items include the ${missingFields[0]} field or use index-fields in your _quarto.yml file to specify the field names.`, + }; + } else if (missingFields.length > 1) { + const missingFieldList = missingFields + .map((field) => { + return `${field}`; + }) + .join(", "); + + throw { + name: `Error: Search index is missing the following fields: ${missingFieldList}.`, + message: `The items being returned for this search do not include all the required fields. Please ensure that your index items includes the following fields: ${missingFieldList}, or use index-fields in your _quarto.yml file to specify the field names.`, + }; + } + } +} + +let lastQuery = null; +function showCopyLink(query, options) { + const language = options.language; + lastQuery = query; + // Insert share icon + const inputSuffixEl = window.document.body.querySelector( + ".aa-Form .aa-InputWrapperSuffix" + ); + + if (inputSuffixEl) { + let copyButtonEl = window.document.body.querySelector( + ".aa-Form .aa-InputWrapperSuffix .aa-CopyButton" + ); + + if (copyButtonEl === null) { + copyButtonEl = window.document.createElement("button"); + copyButtonEl.setAttribute("class", "aa-CopyButton"); + copyButtonEl.setAttribute("type", "button"); + copyButtonEl.setAttribute("title", language["search-copy-link-title"]); + copyButtonEl.onmousedown = (e) => { + e.preventDefault(); + e.stopPropagation(); + }; + + const linkIcon = "bi-clipboard"; + const checkIcon = "bi-check2"; + + const shareIconEl = window.document.createElement("i"); + shareIconEl.setAttribute("class", `bi ${linkIcon}`); + copyButtonEl.appendChild(shareIconEl); + inputSuffixEl.prepend(copyButtonEl); + + const clipboard = new window.ClipboardJS(".aa-CopyButton", { + text: function (_trigger) { + const copyUrl = new URL(window.location); + copyUrl.searchParams.set(kQueryArg, lastQuery); + copyUrl.searchParams.set(kResultsArg, "1"); + return copyUrl.toString(); + }, + }); + clipboard.on("success", function (e) { + // Focus the input + + // button target + const button = e.trigger; + const icon = button.querySelector("i.bi"); + + // flash "checked" + icon.classList.add(checkIcon); + icon.classList.remove(linkIcon); + setTimeout(function () { + icon.classList.remove(checkIcon); + icon.classList.add(linkIcon); + }, 1000); + }); + } + + // If there is a query, show the link icon + if (copyButtonEl) { + if (lastQuery && options["copy-button"]) { + copyButtonEl.style.display = "flex"; + } else { + copyButtonEl.style.display = "none"; + } + } + } +} + +/* Search Index Handling */ +// create the index +var fuseIndex = undefined; +var shownWarning = false; + +// fuse index options +const kFuseIndexOptions = { + keys: [ + { name: "title", weight: 20 }, + { name: "section", weight: 20 }, + { name: "text", weight: 10 }, + ], + ignoreLocation: true, + threshold: 0.1, +}; + +async function readSearchData() { + // Initialize the search index on demand + if (fuseIndex === undefined) { + if (window.location.protocol === "file:" && !shownWarning) { + window.alert( + "Search requires JavaScript features disabled when running in file://... URLs. In order to use search, please run this document in a web server." + ); + shownWarning = true; + return; + } + const fuse = new window.Fuse([], kFuseIndexOptions); + + // fetch the main search.json + const response = await fetch(offsetURL("search.json")); + if (response.status == 200) { + return response.json().then(function (searchDocs) { + searchDocs.forEach(function (searchDoc) { + fuse.add(searchDoc); + }); + fuseIndex = fuse; + return fuseIndex; + }); + } else { + return Promise.reject( + new Error( + "Unexpected status from search index request: " + response.status + ) + ); + } + } + + return fuseIndex; +} + +function inputElement() { + return window.document.body.querySelector(".aa-Form .aa-Input"); +} + +function focusSearchInput() { + setTimeout(() => { + const inputEl = inputElement(); + if (inputEl) { + inputEl.focus(); + } + }, 50); +} + +/* Panels */ +const kItemTypeDoc = "document"; +const kItemTypeMore = "document-more"; +const kItemTypeItem = "document-item"; +const kItemTypeError = "error"; + +function renderItem( + item, + createElement, + state, + setActiveItemId, + setContext, + refresh, + quartoSearchOptions +) { + switch (item.type) { + case kItemTypeDoc: + return createDocumentCard( + createElement, + "file-richtext", + item.title, + item.section, + item.text, + item.href, + item.crumbs, + quartoSearchOptions + ); + case kItemTypeMore: + return createMoreCard( + createElement, + item, + state, + setActiveItemId, + setContext, + refresh + ); + case kItemTypeItem: + return createSectionCard( + createElement, + item.section, + item.text, + item.href + ); + case kItemTypeError: + return createErrorCard(createElement, item.title, item.text); + default: + return undefined; + } +} + +function createDocumentCard( + createElement, + icon, + title, + section, + text, + href, + crumbs, + quartoSearchOptions +) { + const iconEl = createElement("i", { + class: `bi bi-${icon} search-result-icon`, + }); + const titleEl = createElement("p", { class: "search-result-title" }, title); + const titleContents = [iconEl, titleEl]; + const showParent = quartoSearchOptions["show-item-context"]; + if (crumbs && showParent) { + let crumbsOut = undefined; + const crumbClz = ["search-result-crumbs"]; + if (showParent === "root") { + crumbsOut = crumbs.length > 1 ? crumbs[0] : undefined; + } else if (showParent === "parent") { + crumbsOut = crumbs.length > 1 ? crumbs[crumbs.length - 2] : undefined; + } else { + crumbsOut = crumbs.length > 1 ? crumbs.join(" > ") : undefined; + crumbClz.push("search-result-crumbs-wrap"); + } + + const crumbEl = createElement( + "p", + { class: crumbClz.join(" ") }, + crumbsOut + ); + titleContents.push(crumbEl); + } + + const titleContainerEl = createElement( + "div", + { class: "search-result-title-container" }, + titleContents + ); + + const textEls = []; + if (section) { + const sectionEl = createElement( + "p", + { class: "search-result-section" }, + section + ); + textEls.push(sectionEl); + } + const descEl = createElement("p", { + class: "search-result-text", + dangerouslySetInnerHTML: { + __html: text, + }, + }); + textEls.push(descEl); + + const textContainerEl = createElement( + "div", + { class: "search-result-text-container" }, + textEls + ); + + const containerEl = createElement( + "div", + { + class: "search-result-container", + }, + [titleContainerEl, textContainerEl] + ); + + const linkEl = createElement( + "a", + { + href: offsetURL(href), + class: "search-result-link", + }, + containerEl + ); + + const classes = ["search-result-doc", "search-item"]; + if (!section) { + classes.push("document-selectable"); + } + + return createElement( + "div", + { + class: classes.join(" "), + }, + linkEl + ); +} + +function createMoreCard( + createElement, + item, + state, + setActiveItemId, + setContext, + refresh +) { + const moreCardEl = createElement( + "div", + { + class: "search-result-more search-item", + onClick: (e) => { + // Handle expanding the sections by adding the expanded + // section to the list of expanded sections + toggleExpanded(item, state, setContext, setActiveItemId, refresh); + e.stopPropagation(); + }, + }, + item.title + ); + + return moreCardEl; +} + +function toggleExpanded(item, state, setContext, setActiveItemId, refresh) { + const expanded = state.context.expanded || []; + if (expanded.includes(item.target)) { + setContext({ + expanded: expanded.filter((target) => target !== item.target), + }); + } else { + setContext({ expanded: [...expanded, item.target] }); + } + + refresh(); + setActiveItemId(item.__autocomplete_id); +} + +function createSectionCard(createElement, section, text, href) { + const sectionEl = createSection(createElement, section, text, href); + return createElement( + "div", + { + class: "search-result-doc-section search-item", + }, + sectionEl + ); +} + +function createSection(createElement, title, text, href) { + const descEl = createElement("p", { + class: "search-result-text", + dangerouslySetInnerHTML: { + __html: text, + }, + }); + + const titleEl = createElement("p", { class: "search-result-section" }, title); + const linkEl = createElement( + "a", + { + href: offsetURL(href), + class: "search-result-link", + }, + [titleEl, descEl] + ); + return linkEl; +} + +function createErrorCard(createElement, title, text) { + const descEl = createElement("p", { + class: "search-error-text", + dangerouslySetInnerHTML: { + __html: text, + }, + }); + + const titleEl = createElement("p", { + class: "search-error-title", + dangerouslySetInnerHTML: { + __html: ` ${title}`, + }, + }); + const errorEl = createElement("div", { class: "search-error" }, [ + titleEl, + descEl, + ]); + return errorEl; +} + +function positionPanel(pos) { + const panelEl = window.document.querySelector( + "#quarto-search-results .aa-Panel" + ); + const inputEl = window.document.querySelector( + "#quarto-search .aa-Autocomplete" + ); + + if (panelEl && inputEl) { + panelEl.style.top = `${Math.round(panelEl.offsetTop)}px`; + if (pos === "start") { + panelEl.style.left = `${Math.round(inputEl.left)}px`; + } else { + panelEl.style.right = `${Math.round(inputEl.offsetRight)}px`; + } + } +} + +/* Highlighting */ +// highlighting functions +function highlightMatch(query, text) { + if (text) { + const start = text.toLowerCase().indexOf(query.toLowerCase()); + if (start !== -1) { + const startMark = ""; + const endMark = ""; + + const end = start + query.length; + text = + text.slice(0, start) + + startMark + + text.slice(start, end) + + endMark + + text.slice(end); + const startInfo = clipStart(text, start); + const endInfo = clipEnd( + text, + startInfo.position + startMark.length + endMark.length + ); + text = + startInfo.prefix + + text.slice(startInfo.position, endInfo.position) + + endInfo.suffix; + + return text; + } else { + return text; + } + } else { + return text; + } +} + +function clipStart(text, pos) { + const clipStart = pos - 50; + if (clipStart < 0) { + // This will just return the start of the string + return { + position: 0, + prefix: "", + }; + } else { + // We're clipping before the start of the string, walk backwards to the first space. + const spacePos = findSpace(text, pos, -1); + return { + position: spacePos.position, + prefix: "", + }; + } +} + +function clipEnd(text, pos) { + const clipEnd = pos + 200; + if (clipEnd > text.length) { + return { + position: text.length, + suffix: "", + }; + } else { + const spacePos = findSpace(text, clipEnd, 1); + return { + position: spacePos.position, + suffix: spacePos.clipped ? "…" : "", + }; + } +} + +function findSpace(text, start, step) { + let stepPos = start; + while (stepPos > -1 && stepPos < text.length) { + const char = text[stepPos]; + if (char === " " || char === "," || char === ":") { + return { + position: step === 1 ? stepPos : stepPos - step, + clipped: stepPos > 1 && stepPos < text.length, + }; + } + stepPos = stepPos + step; + } + + return { + position: stepPos - step, + clipped: false, + }; +} + +// removes highlighting as implemented by the mark tag +function clearHighlight(searchterm, el) { + const childNodes = el.childNodes; + for (let i = childNodes.length - 1; i >= 0; i--) { + const node = childNodes[i]; + if (node.nodeType === Node.ELEMENT_NODE) { + if ( + node.tagName === "MARK" && + node.innerText.toLowerCase() === searchterm.toLowerCase() + ) { + el.replaceChild(document.createTextNode(node.innerText), node); + } else { + clearHighlight(searchterm, node); + } + } + } +} + +/** Get all html nodes under the given `root` that don't have children. */ +function getLeafNodes(root) { + let leaves = []; + + function traverse(node) { + if (node.childNodes.length === 0) { + leaves.push(node); + } else { + node.childNodes.forEach(traverse); + } + } + + traverse(root); + return leaves; +} +/** create and return `${txt}` */ +const markEl = txt => { + const el = document.createElement("mark"); + el.appendChild(document.createTextNode(txt)); + return el +} +/** get all ancestors of an element matching the given css selector */ +const matchAncestors = (el, selector) => { + let ancestors = []; + while (el) { + if (el.matches?.(selector)) ancestors.push(el); + el = el.parentNode; + } + return ancestors; +}; + +const isWhitespace = s => s.trim().length === 0 +// ================= +// MATCHING CODE +// ================= +const initMatch = () => ({ + i: 0, + lohisByNode: new Map() +}) +/** + * keeps track of the start (lo) and end (hi) index of the match per node (leaf) + * note: mutates the contents of `matchContext` + */ +const advanceMatch = (leaf, leafi, matchContext) => { + matchContext.i++ + + const curLoHi = matchContext.lohisByNode.get(leaf) + + matchContext.lohisByNode.set(leaf, { lo: curLoHi?.lo ?? leafi, hi: leafi }) +} +/** + * Finds all non-overlapping matches for a search string in the document. + * The search string may be split between multiple consecutive leaf nodes. + * + * Whitespace in the search string must be present in the document to match, but + * there may be addititional whitespace in the document that is ignored. + * + * e.g. searching for `dogs rock` would match `dogs \n rock`, + * and would contribute the match + * `{ i:9, els: new Map([[textNode, {lo:0, hi:8}],[spanNode,{lo:0,hi:5}]]) }` + * + * @returns {Map[]} + */ +function searchMatches(inSearch, el) { + // searchText has all sequences of whitespace replaced by a single space + const searchText = inSearch.toLowerCase().replace(/\s+/g, ' ') + const leafNodes = getLeafNodes(el) + + /** @type {Map[]} */ + const matches = [] + /** @type {{i:number; els:Map}[]} */ + let curMatchContext = initMatch() + + for (const leaf of leafNodes) { + const leafStr = leaf.textContent.toLowerCase() + // for each character in this leaf's text: + for (let leafi = 0; leafi < leafStr.length; leafi++) { + + if (isWhitespace(leafStr[leafi])) { + // if there is at least one whitespace in the document + // we advance over a search text whitespace. + if (isWhitespace(searchText[curMatchContext.i])) advanceMatch(leaf, leafi, curMatchContext) + // all sequences of whitespace are otherwise ignored. + } else { + if (searchText[curMatchContext.i] === leafStr[leafi]) { + advanceMatch(leaf, leafi, curMatchContext) + } else { + curMatchContext = initMatch() + // if current character in the document did not match at i in the search text, + // reset the search and see if that character matches at 0 in the search text. + if (searchText[curMatchContext.i] === leafStr[leafi]) advanceMatch(leaf, leafi, curMatchContext) + } + } + + const isMatchComplete = curMatchContext.i === searchText.length + if (isMatchComplete) { + matches.push(curMatchContext.lohisByNode) + curMatchContext = initMatch() + } + } + } + + return matches +} + +/** + * e.g. `markMatches(myTextNode, [[0,5],[12,15]])` would wrap the + * character sequences in myTextNode from 0-5 and 12-15 in marks. + * Its important to mark all sequences in a text node at once + * because this function replaces the entire text node; so any + * other references to that text node will no longer be in the DOM. + */ +function markMatches(node, lohis) { + const text = node.nodeValue + + const markFragment = document.createDocumentFragment(); + + let prevHi = 0 + for (const [lo, hi] of lohis) { + markFragment.append( + document.createTextNode(text.slice(prevHi, lo)), + markEl(text.slice(lo, hi + 1)) + ) + prevHi = hi + 1 + } + markFragment.append( + document.createTextNode(text.slice(prevHi, text.length)) + ) + + const parent = node.parentElement + parent?.replaceChild(markFragment, node) + return parent +} + +// Activate ancestor tabs so a search match inside an inactive pane becomes visible. +// When multiple panes in the same tabset contain matches, avoid switching away from +// the currently active pane — the user already sees a match there. +function openAllTabsetsContainingEl(el) { + for (const pane of matchAncestors(el, '.tab-pane')) { + const tabContent = pane.closest('.tab-content'); + if (!tabContent) continue; + const activePane = tabContent.querySelector(':scope > .tab-pane.active'); + if (activePane?.querySelector('mark')) continue; + const tabButton = document.querySelector(`[data-bs-target="#${pane.id}"]`); + if (tabButton) new bootstrap.Tab(tabButton).show(); + } +} + +function scrollToFirstVisibleMatch(mainEl) { + for (const mark of mainEl.querySelectorAll("mark")) { + const isMarkVisible = matchAncestors(mark, '.tab-pane').every(markTabPane => + markTabPane.classList.contains("active") + ) + if (isMarkVisible) { + mark.scrollIntoView({ behavior: "smooth", block: "center" }); + return; + } + } +} + +/** + * e.g. + * ```js + * const m = new Map() + * + * arrayMapPush(m, 'dog', 'Max') + * console.log(m) // Map { dog->['Max'] } + * + * arrayMapPush(m, 'dog', 'Samba') + * arrayMapPush(m, 'cat', 'Scruffle') + * console.log(m) // Map { dog->['Max', 'Samba'], cat->['Scruffle'] } + * ``` + */ +const arrayMapPush = (map, key, item) => { + if (!map.has(key)) map.set(key, []) + map.set(key, [...map.get(key), item]) +} + +// copy&paste any string from a quarto page and +// this should find that string in the page and highlight it. +// exception: text that starts outside/inside a tabset and ends +// inside/outside that tabset. +function highlight(searchStr, el) { + const matches = searchMatches(searchStr, el); + + const matchesGroupedByNode = new Map() + for (const match of matches) { + for (const [mel, { lo, hi }] of match) { + arrayMapPush(matchesGroupedByNode, mel, [lo, hi]) + } + } + + for (const [node, lohis] of matchesGroupedByNode) { + markMatches(node, lohis) + } +} + +/* Link Handling */ +// get the offset from this page for a given site root relative url +function offsetURL(url) { + var offset = getMeta("quarto:offset"); + return offset ? offset + url : url; +} + +// read a meta tag value +function getMeta(metaName) { + var metas = window.document.getElementsByTagName("meta"); + for (let i = 0; i < metas.length; i++) { + if (metas[i].getAttribute("name") === metaName) { + return metas[i].getAttribute("content"); + } + } + return ""; +} + +function algoliaSearch(query, limit, algoliaOptions) { + const { getAlgoliaResults } = window["@algolia/autocomplete-preset-algolia"]; + + const applicationId = algoliaOptions["application-id"]; + const searchOnlyApiKey = algoliaOptions["search-only-api-key"]; + const indexName = algoliaOptions["index-name"]; + const indexFields = algoliaOptions["index-fields"]; + const searchClient = window.algoliasearch(applicationId, searchOnlyApiKey); + const searchParams = algoliaOptions["params"]; + const searchAnalytics = !!algoliaOptions["analytics-events"]; + + return getAlgoliaResults({ + searchClient, + queries: [ + { + indexName: indexName, + query, + params: { + hitsPerPage: limit, + clickAnalytics: searchAnalytics, + ...searchParams, + }, + }, + ], + transformResponse: (response) => { + if (!indexFields) { + return response.hits.map((hit) => { + return hit.map((item) => { + return { + ...item, + text: highlightMatch(query, item.text), + }; + }); + }); + } else { + const remappedHits = response.hits.map((hit) => { + return hit.map((item) => { + const newItem = { ...item }; + ["href", "section", "title", "text", "crumbs"].forEach( + (keyName) => { + const mappedName = indexFields[keyName]; + if ( + mappedName && + item[mappedName] !== undefined && + mappedName !== keyName + ) { + newItem[keyName] = item[mappedName]; + delete newItem[mappedName]; + } + } + ); + newItem.text = highlightMatch(query, newItem.text); + return newItem; + }); + }); + return remappedHits; + } + }, + }); +} + +let subSearchTerm = undefined; +let subSearchFuse = undefined; +const kFuseMaxWait = 125; + +async function fuseSearch(query, fuse, fuseOptions) { + let index = fuse; + // Fuse.js using the Bitap algorithm for text matching which runs in + // O(nm) time (no matter the structure of the text). In our case this + // means that long search terms mixed with large index gets very slow + // + // This injects a subIndex that will be used once the terms get long enough + // Usually making this subindex is cheap since there will typically be + // a subset of results matching the existing query + if (subSearchFuse !== undefined && query.startsWith(subSearchTerm)) { + // Use the existing subSearchFuse + index = subSearchFuse; + } else if (subSearchFuse !== undefined) { + // The term changed, discard the existing fuse + subSearchFuse = undefined; + subSearchTerm = undefined; + } + + // Search using the active fuse + const then = performance.now(); + const resultsRaw = await index.search(query, fuseOptions); + const now = performance.now(); + + const results = resultsRaw.map((result) => { + const addParam = (url, name, value) => { + const anchorParts = url.split("#"); + const baseUrl = anchorParts[0]; + const sep = baseUrl.search("\\?") > 0 ? "&" : "?"; + anchorParts[0] = baseUrl + sep + name + "=" + value; + return anchorParts.join("#"); + }; + + return { + title: result.item.title, + section: result.item.section, + href: addParam(result.item.href, kQueryArg, query), + text: highlightMatch(query, result.item.text), + crumbs: result.item.crumbs, + }; + }); + + // If we don't have a subfuse and the query is long enough, go ahead + // and create a subfuse to use for subsequent queries + if ( + now - then > kFuseMaxWait && + subSearchFuse === undefined && + resultsRaw.length < fuseOptions.limit + ) { + subSearchTerm = query; + subSearchFuse = new window.Fuse([], kFuseIndexOptions); + resultsRaw.forEach((rr) => { + subSearchFuse.add(rr.item); + }); + } + return results; +} diff --git a/docs/sitemap.xml b/docs/sitemap.xml new file mode 100644 index 0000000..6953daf --- /dev/null +++ b/docs/sitemap.xml @@ -0,0 +1,51 @@ + + + + https://mkennedy.codes/docs/python-switch/ + 2026-07-21 + weekly + 1.0 + + + https://mkennedy.codes/docs/python-switch/reference/ + 2026-07-21 + monthly + 0.8 + + + https://mkennedy.codes/docs/python-switch/reference/closed_range.html + 2026-07-21 + monthly + 0.8 + + + https://mkennedy.codes/docs/python-switch/reference/switch.html + 2026-07-21 + monthly + 0.8 + + + https://mkennedy.codes/docs/python-switch/changelog/ + 2026-07-21 + monthly + 0.5 + + + https://mkennedy.codes/docs/python-switch/license.html + 2026-07-21 + monthly + 0.5 + + + https://mkennedy.codes/docs/python-switch/package-info.html + 2026-07-21 + monthly + 0.5 + + + https://mkennedy.codes/docs/python-switch/skills.html + 2026-07-21 + monthly + 0.5 + + \ No newline at end of file diff --git a/docs/skill.md b/docs/skill.md new file mode 100644 index 0000000..107bf8b --- /dev/null +++ b/docs/skill.md @@ -0,0 +1,126 @@ +--- +name: switchlang +description: > + Adds switch blocks to the Python language. Use when writing Python code that uses the switchlang package. +license: MIT +compatibility: Requires Python >=3.9. +--- + +# switchlang + +Adds switch blocks to the Python language. + +## Installation + +```bash +pip install switchlang +``` + +## When to use what + +| Need | Use | +|------|-----| +| Map several discrete values to one action | `s.case(['c', 'a'], func) — list keys expand to one case per item` | +| Match an inclusive numeric span | `s.case(closed_range(1, 5), func)` | +| Run the next case too (fall-through) | `s.case(key, func, fallthrough=True)` | +| Get the matched case's return value | `s.result, after the with block exits` | +| Handle 'nothing matched' | `s.default(func), registered last` | +| Match a key but do nothing | `s.case(key, lambda: None)` | + +## API overview + +### The switch block + +The context manager that gives Python an explicit switch statement. Use it in a `with` block, register cases, then read `result`. + + +- `switch`: An explicit switch statement for Python, implemented as a context manager + +### Range helpers + +Helpers for mapping ranges of values to a single case. + + +- `closed_range`: Create a closed range for a case: both `start` and `stop` are included + +## Gotchas + +1. Cases execute on block exit, not at registration: case()/default() only register; the matched function runs in __exit__, and s.result is only readable after the with block (reading it inside raises). +2. Case functions take no parameters — bind arguments with a lambda: s.case('b', lambda: process(val)). Passing process(val) calls it immediately and registers its return value. +3. default() ordering is not enforced: a default registered before a matching case runs as well. Always register default() last. +4. Adjacent closed_range cases overlap (closed_range(1, 5) and closed_range(5, 9) both contain 5) and raise a duplicate-case ValueError — follow closed_range(1, 5) with closed_range(6, 9). +5. Keys are matched with == and stored in a set: they must be hashable, and equal-comparing keys (1 and True, 1 and 1.0) are duplicates. +6. If no case matches and no default() is registered, the block raises Exception on exit. +7. An exception raised inside the with block aborts the switch — it is re-raised and no case actions run. +8. fallthrough=None is reserved for internal use — pass only True or False. + +## Best practices + +- Register default() as the last statement in every switch block. +- Read s.result only after the with block exits; capture per-case data via lambdas or closures. +- Use closed_range(start, stop) for inclusive numeric spans and plain range() for half-open ones. +- Import from the package — from switchlang import switch, closed_range — never from the private __switchlang_impl module. + +## End-to-end wiring + +A complete, minimal switch — registration inside the `with` block, execution at block exit, result read after: + +```python +from switchlang import switch, closed_range + +action = get_action() + +with switch(action) as s: + s.case(['c', 'a'], create_account) # several keys -> one action + s.case('l', log_into_account) + s.case('', lambda: None) # explicit "do nothing" case + s.case(closed_range(1, 5), lambda: set_level(action)) # inclusive 1..5 + s.default(unknown_command) # ALWAYS register last + +print(s.result) # return value of whichever case ran — only valid here, after the block +``` + +## The execution model (this is what code generators get wrong) + +`case()` and `default()` only **register** cases — nothing executes at those lines. The matched function (and any fall-through functions) run inside `__exit__` as the `with` block closes. Three consequences: + +- Case functions take **zero parameters**. Bind data with a lambda or closure: `s.case('b', lambda: process(val, num))` — never `s.case('b', process(val, num))`, which would call the function immediately and register its return value. +- `s.result` is only readable **after** the block; reading it inside raises even when the case has already been registered and matched. +- Registration errors (duplicate key, non-callable action, empty list/range) raise at the `s.case(...)` line, but the "no case matched and no default" error raises at the block's closing line. + +## Fall-through, from the usage side + +Fall-through is opt-in per case. The next registered case then runs **whether or not its key matches**, continuing until a case without `fallthrough=True`. The last function executed supplies `result`: + +```python +value = 2 +with switch(value) as s: + s.case(1, lambda: 'one') + s.case(2, lambda: 'two', fallthrough=True) + s.case(3, lambda: 'three') # runs too (its key is never compared), then the chain stops + s.default(lambda: 'other') + +s.result # 'three' +``` + +Pass only `True` or `False` — `fallthrough=None` is reserved for the library's internal list/range expansion. + +## Keys: equality, hashability, ranges + +Matching is plain `key == value`, and keys are stored in a `set`, so every key must be hashable and keys that compare equal are duplicates (`1` and `True`, `1` and `1.0` collide). A `list` or `range` key is expanded so each item becomes its own case for the same function. `closed_range(start, stop)` is inclusive on **both** ends — and because of that, adjacent closed ranges share their endpoint and raise the duplicate-case error: use `closed_range(1, 5)` with `closed_range(6, 9)`, not `closed_range(5, 9)`. + +## When to reach for this vs `match` + +`match` (3.10+) destructures by *shape*; `switchlang` dispatches on *values*. Prefer `switchlang` when you need opt-in fall-through, case lists built at runtime (`s.case(some_list, action)`), a captured return value (`s.result`), or Python 3.9 support. Prefer `match` for structural pattern matching on tuples/dataclasses/nested data. Remember: `import switchlang`, `pip install switchlang` — the repo name `python-switch` is not the import name. + +## Fetching the docs as Markdown + +Every page on the documentation site has a plain-Markdown twin: swap the `.html` extension for `.md` to get token-efficient source without the site chrome. For example https://mkennedy.codes/docs/python-switch/reference/switch.html is also available at https://mkennedy.codes/docs/python-switch/reference/switch.md. Prefer the `.md` form when reading these docs programmatically. + + +## Resources + +- [Full documentation](https://mkennedy.codes/docs/python-switch/) +- [llms.txt](llms.txt) — Indexed API reference for LLMs +- [llms-full.txt](llms-full.txt) — Comprehensive documentation for LLMs +- [Source code](https://github.com/mikeckennedy/python-switch) diff --git a/docs/skills.html b/docs/skills.html new file mode 100644 index 0000000..e668cda --- /dev/null +++ b/docs/skills.html @@ -0,0 +1,729 @@ + + + + + + + + + +Skills – switchlang | switchlang + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/termshow.css b/docs/termshow.css new file mode 100644 index 0000000..fa68925 --- /dev/null +++ b/docs/termshow.css @@ -0,0 +1,649 @@ +/* Great Docs Termshow Player Styles */ + +/* Embedded JetBrains Mono subset (OFL license) — includes box-drawing chars */ +@font-face { + font-family: "JetBrains Mono"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(JetBrainsMono-Regular.subset.woff2) format("woff2"); + unicode-range: U+0020-007E, U+00A0-00FF, U+2010-2027, U+2190-219F, + U+2500-257F, U+2580-259F, U+25A0-25C0, U+2298, U+2605-2606, + U+2705, U+2714, U+2716, U+2718, U+26A0; +} + +@font-face { + font-family: "JetBrains Mono"; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(JetBrainsMono-Bold.subset.woff2) format("woff2"); + unicode-range: U+0020-007E, U+00A0-00FF, U+2010-2027, U+2190-219F, + U+2500-257F, U+2580-259F, U+25A0-25C0, U+2298, U+2605-2606, + U+2705, U+2714, U+2716, U+2718, U+26A0; +} + +.gd-termshow { + --gd-tp-bg: #1e1e2e; + --gd-tp-fg: #cdd6f4; + --gd-tp-border: #313244; + --gd-tp-accent: #89b4fa; + --gd-tp-controls-bg: #181825; + --gd-tp-progress-bg: #45475a; + --gd-tp-chapter-color: #f9e2af; + --gd-tp-ann-bg: rgba(30, 30, 46, 0.88); + --gd-tp-ann-border: rgba(137, 180, 250, 0.4); + --gd-tp-radius: 8px; + + position: relative; + border-radius: var(--gd-tp-radius); + overflow: hidden; + border: 1px solid var(--gd-tp-border); + max-width: 100%; + margin: 1.5em 0; + background: var(--gd-tp-bg); + container-type: inline-size; + overflow-anchor: none; +} + +/* Prevent any player internals from being used as scroll anchors */ +.gd-termshow * { + overflow-anchor: none; +} + +/* Viewport */ +.gd-tp-viewport { + position: relative; + width: 100%; + overflow: hidden; + outline: none; + container-type: inline-size; + user-select: none; + -webkit-user-select: none; +} + +.gd-tp-viewport:focus-visible { + box-shadow: inset 0 0 0 2px var(--gd-tp-accent); +} + +.gd-tp-svg { + width: 100%; + display: flex; + align-items: center; + justify-content: center; +} + +.gd-tp-svg svg { + width: 100%; + height: auto; + display: block; + margin-top: -2px; +} + +/* Poster image (before JS loads) */ +.gd-termshow-poster { + width: 100%; + height: auto; + display: block; +} + +/* Annotations */ +.gd-tp-annotations { + position: absolute; + inset: 0; + pointer-events: none; + padding: 12px; + contain: layout style; +} + +/* Highlights overlay — top: -2px matches the SVG's margin-top: -2px */ +.gd-tp-highlights { + position: absolute; + top: -2px; + left: 0; + right: 0; + bottom: 0; + pointer-events: none; + contain: layout style; + z-index: 1; +} + +.gd-tp-highlight { + --hl-color: #f1fa8c; + transition: opacity 0.15s ease; + box-sizing: border-box; + border-radius: max(1px, 0.426cqi); +} + +/* Styles */ +.gd-tp-hl-outline { + box-shadow: 0 0 0 max(1px, 0.284cqi) var(--hl-color); +} + +.gd-tp-hl-underline { + border-bottom: max(1px, 0.284cqi) solid var(--hl-color); + border-radius: 0; +} + +.gd-tp-hl-underline-wavy { + border-radius: 0; +} +.gd-tp-hl-underline-wavy::after { + content: ''; + position: absolute; + left: 0; + right: 0; + bottom: 0; + height: max(2px, 0.568cqi); + background-color: var(--hl-color); + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='4' viewBox='0 0 8 4'%3E%3Cpath d='M0 2Q2 0 4 2Q6 4 8 2' fill='none' stroke='black' stroke-width='1.5'/%3E%3C/svg%3E"); + -webkit-mask-repeat: repeat-x; + -webkit-mask-size: max(4px, 1.136cqi) max(2px, 0.568cqi); + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='4' viewBox='0 0 8 4'%3E%3Cpath d='M0 2Q2 0 4 2Q6 4 8 2' fill='none' stroke='black' stroke-width='1.5'/%3E%3C/svg%3E"); + mask-repeat: repeat-x; + mask-size: max(4px, 1.136cqi) max(2px, 0.568cqi); +} + +.gd-tp-hl-background { + background: color-mix(in srgb, var(--hl-color) 20%, transparent); +} + +.gd-tp-hl-spotlight { + background: color-mix(in srgb, var(--hl-color) 10%, transparent); + box-shadow: 0 0 max(8px, 2.84cqi) color-mix(in srgb, var(--hl-color) 40%, transparent); +} + +.gd-tp-hl-glow { + box-shadow: 0 0 max(4px, 1.136cqi) max(1px, 0.284cqi) var(--hl-color), inset 0 0 max(2px, 0.568cqi) max(1px, 0.142cqi) color-mix(in srgb, var(--hl-color) 30%, transparent); +} + +.gd-tp-hl-box { + border: max(1px, 0.284cqi) solid var(--hl-color); + background: color-mix(in srgb, var(--hl-color) 10%, transparent); +} + +.gd-tp-hl-bracket { + border-left: max(2px, 0.426cqi) solid var(--hl-color); + border-radius: 0; +} + +.gd-tp-hl-badge-before, +.gd-tp-hl-badge-after { + border: max(1px, 0.213cqi) solid var(--hl-color); +} + +.gd-tp-hl-badge { + position: absolute; + background: var(--hl-color); + color: #1e1e2e; + font-size: max(7px, 1.42cqi); + font-weight: 600; + padding: max(1px, 0.142cqi) max(3px, 0.71cqi); + border-radius: max(1px, 0.426cqi); + white-space: nowrap; + line-height: 1.3; +} + +.gd-tp-hl-badge-before .gd-tp-hl-badge { + top: max(-14px, -1.989cqi); + left: 0; +} + +.gd-tp-hl-badge-after .gd-tp-hl-badge { + bottom: max(-14px, -1.989cqi); + left: 0; +} + +/* Pulse animation */ +@keyframes gd-tp-hl-pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } +} + +.gd-tp-hl-pulse { + animation: gd-tp-hl-pulse 1.5s ease-in-out infinite; +} + +.gd-tp-annotation { + position: absolute; + padding: clamp(4px, 1.2cqi, 10px) clamp(6px, 1.8cqi, 14px); + border-radius: 6px; + font-size: clamp(10px, 2cqi, 14px); + line-height: 1.4; + color: var(--gd-tp-fg); + transition: opacity 0.3s ease; +} + +.gd-tp-ann-callout { + background: var(--gd-tp-ann-bg); + border: 1px solid var(--gd-tp-ann-border); + backdrop-filter: blur(4px); +} + +.gd-tp-ann-subtle { + background: rgba(30, 30, 46, 0.7); + font-size: clamp(9px, 1.8cqi, 12px); + backdrop-filter: blur(4px); +} + +.gd-tp-ann-highlight { + background: rgba(249, 226, 175, 0.15); + border: 1px solid rgba(249, 226, 175, 0.4); + color: #f9e2af; + backdrop-filter: blur(4px); +} + +/* Annotation positions */ +.gd-tp-ann-top-left { + top: clamp(6px, 1.8cqi, 14px); + left: clamp(6px, 1.8cqi, 14px); +} + +.gd-tp-ann-top-right { + top: clamp(6px, 1.8cqi, 14px); + right: clamp(6px, 1.8cqi, 14px); +} + +.gd-tp-ann-top { + top: clamp(6px, 1.8cqi, 14px); + left: 0; + right: 0; + margin-inline: auto; + width: fit-content; +} + +.gd-tp-ann-bottom-left { + bottom: clamp(6px, 1.8cqi, 14px); + left: clamp(6px, 1.8cqi, 14px); +} + +.gd-tp-ann-bottom-right { + bottom: clamp(6px, 1.8cqi, 14px); + right: clamp(6px, 1.8cqi, 14px); +} + +.gd-tp-ann-bottom { + bottom: clamp(6px, 1.8cqi, 14px); + left: 0; + right: 0; + margin-inline: auto; + width: fit-content; +} + +.gd-tp-ann-left { + top: 0; + bottom: 0; + left: clamp(6px, 1.8cqi, 14px); + margin-block: auto; + height: fit-content; +} + +.gd-tp-ann-right { + top: 0; + bottom: 0; + right: clamp(6px, 1.8cqi, 14px); + margin-block: auto; + height: fit-content; +} + +/* Annotation widths */ +.gd-tp-annotation { max-width: 50%; } +.gd-tp-ann-w-small { max-width: 25%; } +.gd-tp-ann-w-large { max-width: 75%; } + +/* Controls bar */ +.gd-tp-controls { + display: flex; + align-items: center; + gap: 10px; + padding: 8px 12px; + background: var(--gd-tp-controls-bg); + border-top: 1px solid var(--gd-tp-border); + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + font-size: 13px; + color: var(--gd-tp-fg); + user-select: none; + -webkit-user-select: none; +} + +.gd-tp-play-btn, +.gd-tp-speed-btn { + background: none; + border: none; + color: var(--gd-tp-fg); + cursor: pointer; + padding: 4px 8px; + border-radius: 4px; + font-size: 14px; + line-height: 1; + transition: background 0.15s; +} + +.gd-tp-play-btn { + width: 32px; + display: inline-flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + border: 1px solid var(--gd-tp-progress-bg); +} + +.gd-tp-play-btn:hover, +.gd-tp-speed-btn:hover { + background: var(--gd-tp-progress-bg); +} + +.gd-tp-speed-btn { + font-size: 12px; + font-weight: 600; + width: 40px; + text-align: center; + flex-shrink: 0; +} + +.gd-tp-time, +.gd-tp-duration { + font-size: 12px; + font-variant-numeric: tabular-nums; + opacity: 0.8; + min-width: 36px; +} + +/* Timeline */ +.gd-tp-timeline { + flex: 1; + height: 6px; + background: var(--gd-tp-progress-bg); + border-radius: 3px; + cursor: pointer; + position: relative; + transition: height 0.15s; +} + +.gd-tp-timeline:hover { + height: 8px; +} + +.gd-tp-progress { + height: 100%; + background: var(--gd-tp-accent); + border-radius: 0 3px 3px 0; + width: 0%; + transition: width 0.05s linear; + position: relative; +} + +/* Playhead handle */ +.gd-tp-progress::after { + content: ''; + position: absolute; + right: -5px; + top: 50%; + width: 10px; + height: 10px; + border-radius: 50%; + background: #b4d0fc; + border: 2px solid #ffffff; + transform: translateY(-50%) scale(0); + transition: transform 0.15s ease, box-shadow 0.15s ease; + box-shadow: 0 0 0 2px rgba(137, 180, 250, 0.4); +} + +.gd-tp-timeline:hover .gd-tp-progress::after, +.gd-tp-timeline.gd-tp-dragging .gd-tp-progress::after { + transform: translateY(-50%) scale(1); +} + +.gd-tp-timeline.gd-tp-dragging .gd-tp-progress::after { + width: 14px; + height: 14px; + right: -7px; + box-shadow: 0 0 0 3px rgba(137, 180, 250, 0.5); +} + +.gd-tp-timeline.gd-tp-dragging { + height: 8px; +} + +.gd-tp-timeline.gd-tp-dragging .gd-tp-progress { + transition: none; +} + +/* Chapter markers */ +.gd-tp-chapter-marker { + position: absolute; + top: -2px; + width: 3px; + height: calc(100% + 4px); + background: var(--gd-tp-chapter-color); + border-radius: 1px; + transform: translateX(-50%); + opacity: 0.8; + z-index: 1; +} + +/* Wider hit target for chapter markers */ +.gd-tp-chapter-marker::before { + content: ''; + position: absolute; + top: -4px; + left: -8px; + right: -8px; + bottom: -4px; + cursor: pointer; +} + +.gd-tp-chapter-marker:hover { + opacity: 1; + transform: translateX(-50%) scaleY(1.3); +} + +/* Center overlay button (play / replay) */ +.gd-tp-center-overlay { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + z-index: 5; + cursor: pointer; +} + +.gd-tp-center-overlay-btn { + width: 64px; + height: 64px; + border-radius: 50%; + background: rgba(0, 0, 0, 0.4); + border: 2px solid rgba(255, 255, 255, 0.2); + color: rgba(255, 255, 255, 0.75); + font-size: 28px; + display: flex; + align-items: center; + justify-content: center; + transition: background 0.2s, transform 0.15s, opacity 0.2s; + backdrop-filter: blur(2px); +} + +.gd-tp-center-overlay:hover .gd-tp-center-overlay-btn { + background: rgba(0, 0, 0, 0.55); + color: rgba(255, 255, 255, 0.9); + transform: scale(1.08); +} + +.gd-tp-center-overlay-btn .gd-tp-icon-play { + /* Shift right slightly to visually center the triangle */ + margin-left: 3px; +} + +/* Hide overlay while playing or when paused at a chapter */ +.gd-termshow.gd-tp-playing .gd-tp-center-overlay, +.gd-termshow.gd-tp-chapter-paused .gd-tp-center-overlay { + display: none; +} + +/* Show overlay only at initial state and ended state */ +.gd-termshow.gd-tp-ended .gd-tp-center-overlay { + display: flex; +} + +/* Reduced motion */ +@media (prefers-reduced-motion: reduce) { + .gd-tp-annotation { + transition: none; + } + + .gd-tp-progress { + transition: none; + } + + .gd-tp-cursor { + animation: none !important; + } +} + +/* Title bar */ +.gd-tp-chapter-bar { + position: relative; + padding: clamp(4px, 1cqi, 8px) clamp(8px, 1.8cqi, 14px); + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + font-size: clamp(10px, 2.2cqi, 14px); + font-weight: 500; + color: rgba(255, 255, 255, 0.85); + background: var(--gd-tp-bg); + border-bottom: 1px solid var(--gd-tp-border); + min-height: clamp(22px, 5cqi, 36px); + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + display: flex; + align-items: center; + justify-content: center; + user-select: none; + -webkit-user-select: none; +} + +.gd-tp-chapter-bar:empty:not(.gd-tp-has-chrome) { + display: none; +} + +.gd-tp-chapter-text { + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +/* Traffic light decorations */ +.gd-tp-traffic-lights { + position: absolute; + left: clamp(8px, 1.8cqi, 16px); + top: 0; + bottom: 0; + display: flex; + align-items: center; + gap: clamp(4px, 0.9cqi, 8px); +} + +.gd-tp-traffic-dot { + width: clamp(7px, 1.6cqi, 12px); + height: clamp(7px, 1.6cqi, 12px); + border-radius: 50%; +} + +.gd-tp-dot-close { background: #f38ba8; } +.gd-tp-dot-minimize { background: #f9e2af; } +.gd-tp-dot-maximize { background: #a6e3a1; } + +/* Minimal chrome: muted dots */ +.gd-tp-traffic-lights.gd-tp-chrome-minimal .gd-tp-dot-close, +.gd-tp-traffic-lights.gd-tp-chrome-minimal .gd-tp-dot-minimize, +.gd-tp-traffic-lights.gd-tp-chrome-minimal .gd-tp-dot-maximize { + background: #585b70; +} + +/* Light theme overrides (Quarto body[data-bs-theme="light"]) */ +body[data-bs-theme="light"] .gd-termshow, +:root:not([data-bs-theme="dark"]) .gd-termshow.gd-tp-light { + --gd-tp-bg: #eff1f5; + --gd-tp-fg: #4c4f69; + --gd-tp-border: #ccd0da; + --gd-tp-accent: #1e66f5; + --gd-tp-controls-bg: #e6e9ef; + --gd-tp-progress-bg: #ccd0da; + --gd-tp-chapter-color: #df8e1d; + --gd-tp-ann-bg: rgba(239, 241, 245, 0.92); + --gd-tp-ann-border: rgba(30, 102, 245, 0.3); +} + +/* Copy-snippet layer */ +.gd-tp-snippets { + position: absolute; + right: 0; + top: 0; + bottom: 0; + padding-right: clamp(8px, 1.8cqi, 14px); + pointer-events: none; + z-index: 4; + display: flex; + align-items: center; + justify-content: flex-end; + gap: 6px; +} + +.gd-tp-copy-snippet { + pointer-events: auto; + display: inline-flex; + align-items: center; + gap: 4px; + padding: 3px 8px; + border: 1px solid rgba(137, 180, 250, 0.4); + border-radius: 4px; + background: rgba(30, 30, 46, 0.7); + backdrop-filter: blur(4px); + color: var(--gd-tp-fg); + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + font-size: clamp(9px, 1.8cqi, 11px); + cursor: pointer; + transition: opacity 0.3s ease, background 0.15s, border-color 0.15s, transform 0.1s; + white-space: nowrap; +} + +.gd-tp-copy-snippet:hover { + background: rgba(30, 30, 46, 0.95); + border-color: var(--gd-tp-accent); + transform: scale(1.03); +} + +.gd-tp-copy-snippet:active { + transform: scale(0.97); +} + +.gd-tp-copy-snippet.gd-tp-copied { + border-color: #a6e3a1; + background: rgba(166, 227, 161, 0.15); +} + +.gd-tp-copy-snippet.gd-tp-copied .gd-tp-copy-label::after { + content: ' \2713'; +} + +.gd-tp-copy-label { + max-width: 120px; + overflow: hidden; + text-overflow: ellipsis; +} + +/* Light theme copy button */ +body[data-bs-theme="light"] .gd-tp-copy-snippet, +:root:not([data-bs-theme="dark"]) .gd-termshow.gd-tp-light .gd-tp-copy-snippet { + background: rgba(239, 241, 245, 0.92); + border-color: rgba(30, 102, 245, 0.3); + color: var(--gd-tp-fg); +} + +body[data-bs-theme="light"] .gd-tp-copy-snippet:hover, +:root:not([data-bs-theme="dark"]) .gd-termshow.gd-tp-light .gd-tp-copy-snippet:hover { + border-color: var(--gd-tp-accent); + background: rgba(239, 241, 245, 0.98); +} diff --git a/docs/termshow.js b/docs/termshow.js new file mode 100644 index 0000000..7fc7c2e --- /dev/null +++ b/docs/termshow.js @@ -0,0 +1,1035 @@ +/** + * Great Docs Termshow Player + * + * A lightweight player for pre-rendered SVG terminal recordings. + * Loads a manifest.json and displays keyframe SVGs with timeline navigation, + * chapter markers, annotations, and keyboard controls. + */ +(function () { + 'use strict'; + + const PLAYER_CLASS = 'gd-termshow'; + const ACTIVE_CLASS = 'gd-tp-active'; + + /** + * Fetch a resource as text or JSON, with file:// fallback via XHR. + */ + function fetchResource(url, asJson) { + if (window.location.protocol === 'file:') { + return new Promise(function (resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.onload = function () { + if (xhr.status === 0 || xhr.status === 200) { + resolve(asJson ? JSON.parse(xhr.responseText) : xhr.responseText); + } else { + reject(new Error('XHR ' + xhr.status)); + } + }; + xhr.onerror = function () { reject(new Error('XHR network error')); }; + xhr.send(); + }); + } + return fetch(url).then(function (r) { + if (!r.ok) throw new Error('HTTP ' + r.status); + return asJson ? r.json() : r.text(); + }); + } + + /** + * Initialize all termshow player instances on the page. + */ + function initAll() { + const players = document.querySelectorAll(`.${PLAYER_CLASS}`); + players.forEach((el) => initPlayer(el)); + } + + /** + * Initialize a single termshow player instance. + */ + function initPlayer(container) { + const manifestUrl = container.dataset.manifest; + if (!manifestUrl) return; + + // Prevent double-init + if (container.classList.contains(ACTIVE_CLASS)) return; + container.classList.add(ACTIVE_CLASS); + + const options = { + autoplay: container.dataset.autoplay === 'true', + speed: parseFloat(container.dataset.speed) || 1.0, + pauseOnChapters: container.dataset.pauseOnChapters === 'true', + loop: container.dataset.loop === 'true', + }; + + // Create player state + const state = { + manifest: null, + frames: null, + currentTime: 0, + playing: false, + ended: false, + chapterPaused: false, + currentKeyframeIdx: -1, + animFrameId: null, + lastTick: null, + speed: options.speed, + baseUrl: manifestUrl.substring(0, manifestUrl.lastIndexOf('/') + 1), + }; + + // Try to read inline manifest + frames (embedded by Lua filter) + var inlineManifest = null; + var inlineFrames = null; + var manifestEl = container.querySelector('script.gd-tp-manifest'); + var framesEl = container.querySelector('script.gd-tp-frames'); + if (manifestEl) { + try { inlineManifest = JSON.parse(manifestEl.textContent); } catch (e) {} + } + if (framesEl) { + try { inlineFrames = JSON.parse(framesEl.textContent); } catch (e) {} + } + + // Title bar (separate from viewport, above it) + const chapterBar = document.createElement('div'); + chapterBar.className = 'gd-tp-chapter-bar'; + + // Build player DOM + const viewport = document.createElement('div'); + viewport.className = 'gd-tp-viewport'; + // Defer tabindex until user interaction to prevent Safari from treating + // auto-playing players as scroll-restoration targets. + if (!options.autoplay) { + viewport.setAttribute('tabindex', '0'); + } + viewport.setAttribute('role', 'application'); + viewport.setAttribute('aria-label', 'Terminal recording player'); + + const svgContainer = document.createElement('div'); + svgContainer.className = 'gd-tp-svg'; + viewport.appendChild(svgContainer); + + const highlightLayer = document.createElement('div'); + highlightLayer.className = 'gd-tp-highlights'; + viewport.appendChild(highlightLayer); + state.highlightLayer = highlightLayer; + + const annotationLayer = document.createElement('div'); + annotationLayer.className = 'gd-tp-annotations'; + viewport.appendChild(annotationLayer); + + // Copy-snippet buttons (placed in chapter/title bar) + const snippetLayer = document.createElement('div'); + snippetLayer.className = 'gd-tp-snippets'; + chapterBar.appendChild(snippetLayer); + state.snippetLayer = snippetLayer; + + // Center overlay (play / replay) + const centerOverlay = document.createElement('div'); + centerOverlay.className = 'gd-tp-center-overlay'; + centerOverlay.setAttribute('aria-hidden', 'true'); + const centerBtn = document.createElement('div'); + centerBtn.className = 'gd-tp-center-overlay-btn'; + centerBtn.innerHTML = '\u25b6'; + centerOverlay.appendChild(centerBtn); + viewport.appendChild(centerOverlay); + + const controls = buildControls(); + + // Replace container content with player structure + container.innerHTML = ''; + container.appendChild(chapterBar); + container.appendChild(viewport); + container.appendChild(controls.root); + + // Initialize with manifest (inline or fetched) + function activate(manifest, frames) { + state.manifest = manifest; + state.frames = frames; + controls.duration.textContent = formatTime(manifest.duration); + renderChapterMarkers(controls.timeline, manifest); + + // Add traffic light decorations if window_chrome is set + var chrome = manifest.window_chrome || 'none'; + var hasChapters = manifest.chapters && manifest.chapters.length > 0; + var hasSnippets = manifest.snippets && manifest.snippets.length > 0; + if (chrome === 'none' && !hasChapters && !hasSnippets) { + chapterBar.style.display = 'none'; + } else if (chrome !== 'none') { + chapterBar.classList.add('gd-tp-has-chrome'); + var lights = document.createElement('div'); + lights.className = 'gd-tp-traffic-lights' + (chrome === 'minimal' ? ' gd-tp-chrome-minimal' : ''); + lights.innerHTML = '' + + '' + + ''; + chapterBar.appendChild(lights); + } + + // Add a span for chapter text (so traffic lights aren't overwritten) + var chapterText = document.createElement('span'); + chapterText.className = 'gd-tp-chapter-text'; + chapterBar.appendChild(chapterText); + state.chapterText = chapterText; + + updateChapterBar(chapterBar, manifest, 0); + // Show initial frame + showFrame(state, svgContainer, 0); + if (options.autoplay) { + play(state, svgContainer, annotationLayer, controls, options, container, centerOverlay, chapterBar); + } + } + + if (inlineManifest) { + // Always try fetching the external manifest first (it reflects the latest + // termshow render without requiring an HTML rebuild). Fall back to inline + // data if the fetch fails (file:// protocol, offline, etc.). + fetchResource(manifestUrl, true) + .then(function (manifest) { activate(manifest, null); }) + .catch(function () { activate(inlineManifest, inlineFrames); }); + } else { + // No inline data: fetch is the only option + fetchResource(manifestUrl, true) + .then(function (manifest) { activate(manifest, null); }) + .catch(function (err) { + console.warn('[termshow] Failed to load manifest:', manifestUrl, err); + }); + } + + // Restore tabindex on first user interaction (for keyboard nav) + function ensureTabindex() { + if (!viewport.hasAttribute('tabindex')) { + viewport.setAttribute('tabindex', '0'); + } + } + + // Event listeners + controls.playBtn.addEventListener('click', () => { + ensureTabindex(); + if (state.playing) { + pause(state, controls, container, centerOverlay); + } else if (state.ended) { + // Return to initial state (don't autoplay) + state.ended = false; + state.currentTime = 0; + state.currentKeyframeIdx = -1; + controls.playBtn.textContent = '\u25b6'; + controls.playBtn.setAttribute('aria-label', 'Play'); + centerBtn.innerHTML = '\u25b6'; + container.classList.remove('gd-tp-ended'); + updateDisplay(state, svgContainer, annotationLayer, controls); + updateChapterBar(chapterBar, state.manifest, state.currentTime); + } else { + play(state, svgContainer, annotationLayer, controls, options, container, centerOverlay, chapterBar); + } + }); + + centerOverlay.addEventListener('click', () => { + ensureTabindex(); + if (state.ended) { + // Return to initial state (don't autoplay) + state.ended = false; + state.currentTime = 0; + state.currentKeyframeIdx = -1; + controls.playBtn.textContent = '\u25b6'; + controls.playBtn.setAttribute('aria-label', 'Play'); + centerBtn.innerHTML = '\u25b6'; + container.classList.remove('gd-tp-ended'); + updateDisplay(state, svgContainer, annotationLayer, controls); + updateChapterBar(chapterBar, state.manifest, state.currentTime); + return; + } + play(state, svgContainer, annotationLayer, controls, options, container, centerOverlay, chapterBar); + }); + + // Double-click/tap on viewport: left 30% rewinds 5s, right 30% fast-forwards 5s + // Uses pointerdown for immediate, reliable detection unaffected by overlay state + var vpTapTime = 0; + var vpTapX = 0; + + function handleViewportSeek(clientX) { + if (!state.manifest) return; + var rect = viewport.getBoundingClientRect(); + var x = clientX - rect.left; + var w = rect.width; + var newTime; + if (x < w * 0.3) { + newTime = Math.max(0, state.currentTime - 5); + } else if (x > w * 0.7) { + newTime = Math.min(state.manifest.duration, state.currentTime + 5); + } else { + return; // Middle 40% — no action + } + if (state.ended) { + state.ended = false; + controls.playBtn.textContent = '\u25b6'; + controls.playBtn.setAttribute('aria-label', 'Play'); + centerBtn.innerHTML = '\u25b6'; + container.classList.remove('gd-tp-ended'); + } + seek(state, newTime, svgContainer, annotationLayer, controls); + updateChapterBar(chapterBar, state.manifest, state.currentTime); + } + + viewport.addEventListener('pointerdown', (e) => { + if (!state.manifest) return; + if (e.target.closest('.gd-tp-controls')) return; + if (!state.playing && !state.ended) return; // Let center overlay handle paused state + var now = Date.now(); + var dx = Math.abs(e.clientX - vpTapX); + if (now - vpTapTime < 400 && dx < 50) { + vpTapTime = 0; + handleViewportSeek(e.clientX); + } else { + vpTapTime = now; + vpTapX = e.clientX; + } + }); + + controls.timeline.addEventListener('mousedown', (e) => { + if (!state.manifest) return; + // If the click landed on a chapter marker, snap to it instead of starting drag + var markerEl = e.target.closest('.gd-tp-chapter-marker'); + if (markerEl) { + var chapterTime = parseFloat(markerEl.dataset.time); + if (!isNaN(chapterTime)) { + if (state.ended) { + state.ended = false; + controls.playBtn.textContent = '\u25b6'; + controls.playBtn.setAttribute('aria-label', 'Play'); + centerBtn.innerHTML = '\u25b6'; + container.classList.remove('gd-tp-ended'); + } + state.chapterPaused = false; + container.classList.remove('gd-tp-chapter-paused'); + seek(state, chapterTime, svgContainer, annotationLayer, controls); + updateChapterBar(chapterBar, state.manifest, state.currentTime); + } + return; + } + e.preventDefault(); + var wasPlaying = state.playing; + if (state.playing) { + pause(state, controls, container, centerOverlay); + } + controls.timeline.classList.add('gd-tp-dragging'); + // Reset ended/chapter-paused state + if (state.ended) { + state.ended = false; + controls.playBtn.textContent = '\u25b6'; + controls.playBtn.setAttribute('aria-label', 'Play'); + centerBtn.innerHTML = '\u25b6'; + container.classList.remove('gd-tp-ended'); + } + state.chapterPaused = false; + container.classList.remove('gd-tp-chapter-paused'); + + function seekFromEvent(ev) { + var rect = controls.timeline.getBoundingClientRect(); + var ratio = Math.max(0, Math.min(1, (ev.clientX - rect.left) / rect.width)); + seek(state, ratio * state.manifest.duration, svgContainer, annotationLayer, controls); + updateChapterBar(chapterBar, state.manifest, state.currentTime); + } + + seekFromEvent(e); + + function onMove(ev) { + ev.preventDefault(); + seekFromEvent(ev); + } + + function onUp() { + controls.timeline.classList.remove('gd-tp-dragging'); + document.removeEventListener('mousemove', onMove); + document.removeEventListener('mouseup', onUp); + if (wasPlaying) { + play(state, svgContainer, annotationLayer, controls, options, container, centerOverlay, chapterBar); + } + } + + document.addEventListener('mousemove', onMove); + document.addEventListener('mouseup', onUp); + }); + + // Touch support for timeline drag + controls.timeline.addEventListener('touchstart', (e) => { + if (!state.manifest) return; + e.preventDefault(); + var wasPlaying = state.playing; + if (state.playing) { + pause(state, controls, container, centerOverlay); + } + controls.timeline.classList.add('gd-tp-dragging'); + if (state.ended) { + state.ended = false; + controls.playBtn.textContent = '\u25b6'; + controls.playBtn.setAttribute('aria-label', 'Play'); + centerBtn.innerHTML = '\u25b6'; + container.classList.remove('gd-tp-ended'); + } + state.chapterPaused = false; + container.classList.remove('gd-tp-chapter-paused'); + + function seekFromTouch(ev) { + var touch = ev.touches[0] || ev.changedTouches[0]; + var rect = controls.timeline.getBoundingClientRect(); + var ratio = Math.max(0, Math.min(1, (touch.clientX - rect.left) / rect.width)); + seek(state, ratio * state.manifest.duration, svgContainer, annotationLayer, controls); + updateChapterBar(chapterBar, state.manifest, state.currentTime); + } + + seekFromTouch(e); + + function onTouchMove(ev) { + ev.preventDefault(); + seekFromTouch(ev); + } + + function onTouchEnd() { + controls.timeline.classList.remove('gd-tp-dragging'); + document.removeEventListener('touchmove', onTouchMove); + document.removeEventListener('touchend', onTouchEnd); + if (wasPlaying) { + play(state, svgContainer, annotationLayer, controls, options, container, centerOverlay, chapterBar); + } + } + + document.addEventListener('touchmove', onTouchMove, { passive: false }); + document.addEventListener('touchend', onTouchEnd); + }, { passive: false }); + + // Speed control + controls.speedBtn.addEventListener('click', () => { + const speeds = [0.5, 1, 1.5, 2, 3]; + const idx = speeds.indexOf(state.speed); + state.speed = speeds[(idx + 1) % speeds.length]; + controls.speedBtn.textContent = state.speed + '\u00d7'; + }); + + // Keyboard navigation + viewport.addEventListener('keydown', (e) => { + if (!state.manifest) return; + + switch (e.key) { + case ' ': + e.preventDefault(); + if (state.playing) pause(state, controls, container, centerOverlay); + else if (state.ended) { + state.ended = false; + state.currentTime = 0; + state.currentKeyframeIdx = -1; + controls.playBtn.textContent = '\u25b6'; + controls.playBtn.setAttribute('aria-label', 'Play'); + centerBtn.innerHTML = '\u25b6'; + container.classList.remove('gd-tp-ended'); + updateDisplay(state, svgContainer, annotationLayer, controls); + updateChapterBar(chapterBar, state.manifest, state.currentTime); + } else { + play(state, svgContainer, annotationLayer, controls, options, container, centerOverlay, chapterBar); + } + break; + case 'ArrowRight': + e.preventDefault(); + seek(state, state.currentTime + 5, svgContainer, annotationLayer, controls); + break; + case 'ArrowLeft': + e.preventDefault(); + seek(state, state.currentTime - 5, svgContainer, annotationLayer, controls); + break; + case '.': + e.preventDefault(); + nextChapter(state, svgContainer, annotationLayer, controls); + break; + case ',': + e.preventDefault(); + prevChapter(state, svgContainer, annotationLayer, controls); + break; + } + }); + } + + // --- Playback --- + + function play(state, svgContainer, annotationLayer, controls, options, container, centerOverlay, chapterBar) { + state.playing = true; + state.ended = false; + state.chapterPaused = false; + state.lastTick = performance.now(); + controls.playBtn.innerHTML = ''; + controls.playBtn.setAttribute('aria-label', 'Pause'); + container.classList.add('gd-tp-playing'); + container.classList.remove('gd-tp-ended'); + container.classList.remove('gd-tp-chapter-paused'); + + function tick(now) { + if (!state.playing) return; + + const dt = ((now - state.lastTick) / 1000) * state.speed; + state.lastTick = now; + state.currentTime += dt; + + const manifest = state.manifest; + if (state.currentTime >= manifest.duration) { + if (options.loop) { + state.currentTime = 0; + } else { + state.currentTime = manifest.duration; + state.ended = true; + pause(state, controls, container, centerOverlay); + // Show replay icon in controls and overlay + controls.playBtn.textContent = '\u21ba'; // ↺ + controls.playBtn.setAttribute('aria-label', 'Replay'); + centerOverlay.querySelector('.gd-tp-center-overlay-btn').innerHTML = + '\u21ba'; + container.classList.remove('gd-tp-playing'); + container.classList.add('gd-tp-ended'); + return; + } + } + + // Check chapter pause + if (options.pauseOnChapters && manifest.chapters.length > 0) { + const prevTime = state.currentTime - dt; + for (const ch of manifest.chapters) { + if (ch.time > 0 && prevTime < ch.time && state.currentTime >= ch.time) { + state.currentTime = ch.time; + state.chapterPaused = true; + pause(state, controls, container, centerOverlay); + updateDisplay(state, svgContainer, annotationLayer, controls); + updateChapterBar(chapterBar, manifest, state.currentTime); + return; + } + } + } + + updateDisplay(state, svgContainer, annotationLayer, controls); + updateChapterBar(chapterBar, manifest, state.currentTime); + state.animFrameId = requestAnimationFrame(tick); + } + + state.animFrameId = requestAnimationFrame(tick); + } + + function pause(state, controls, container, centerOverlay) { + state.playing = false; + if (state.animFrameId) { + cancelAnimationFrame(state.animFrameId); + state.animFrameId = null; + } + if (!state.ended) { + controls.playBtn.textContent = '\u25b6'; // ▶ + controls.playBtn.setAttribute('aria-label', 'Play'); + } + if (container) { + container.classList.remove('gd-tp-playing'); + // Hide center overlay on chapter pauses (only show at start/end) + if (state.chapterPaused) { + container.classList.add('gd-tp-chapter-paused'); + } else { + container.classList.remove('gd-tp-chapter-paused'); + } + } + } + + function seek(state, time, svgContainer, annotationLayer, controls) { + state.currentTime = Math.max(0, Math.min(time, state.manifest.duration)); + updateDisplay(state, svgContainer, annotationLayer, controls); + } + + function nextChapter(state, svgContainer, annotationLayer, controls) { + if (!state.manifest || !state.manifest.chapters.length) return; + for (const ch of state.manifest.chapters) { + if (ch.time > state.currentTime + 0.1) { + seek(state, ch.time, svgContainer, annotationLayer, controls); + return; + } + } + } + + function prevChapter(state, svgContainer, annotationLayer, controls) { + if (!state.manifest || !state.manifest.chapters.length) return; + const chapters = state.manifest.chapters; + for (let i = chapters.length - 1; i >= 0; i--) { + if (chapters[i].time < state.currentTime - 0.5) { + seek(state, chapters[i].time, svgContainer, annotationLayer, controls); + return; + } + } + seek(state, 0, svgContainer, annotationLayer, controls); + } + + // --- Display --- + + function updateDisplay(state, svgContainer, annotationLayer, controls) { + const manifest = state.manifest; + if (!manifest) return; + + // Update timeline progress + const progress = manifest.duration > 0 ? state.currentTime / manifest.duration : 0; + controls.progress.style.width = (progress * 100) + '%'; + controls.time.textContent = formatTime(state.currentTime); + controls.duration.textContent = formatTime(manifest.duration - state.currentTime); + + // Find the correct keyframe for current time + const kfIdx = findKeyframeIndex(manifest.keyframes, state.currentTime); + if (kfIdx !== state.currentKeyframeIdx) { + state.currentKeyframeIdx = kfIdx; + showFrame(state, svgContainer, kfIdx); + } + + // Update annotations + updateAnnotations(annotationLayer, manifest.annotations, state.currentTime); + + // Update highlights + if (state.highlightLayer) { + updateHighlights(state.highlightLayer, manifest.highlights, state.currentTime, svgContainer); + } + + // Update copy-snippet buttons + updateSnippets(state.snippetLayer, manifest.snippets, state.currentTime, svgContainer); + } + + function updateChapterBar(chapterBar, manifest, time) { + var textEl = chapterBar.querySelector('.gd-tp-chapter-text'); + if (!textEl) return; + if (!manifest || !manifest.chapters || manifest.chapters.length === 0) { + textEl.textContent = ''; + return; + } + // Find the current chapter (last one at or before current time) + var label = ''; + for (let i = manifest.chapters.length - 1; i >= 0; i--) { + if (manifest.chapters[i].time <= time + 0.05) { + label = manifest.chapters[i].label || ''; + break; + } + } + textEl.textContent = label; + } + + function showFrame(state, svgContainer, idx) { + const manifest = state.manifest; + if (!manifest || idx < 0 || idx >= manifest.keyframes.length) return; + + // Pin height before replacing innerHTML to prevent layout collapse. + // All frames in a recording share the same dimensions, so we pin once + // and keep it for the lifetime of playback. This prevents Safari's + // scroll-preservation heuristic from firing on the last player where + // even a sub-frame height flicker affects scrollHeight. + if (!svgContainer.style.minHeight) { + var pinHeight = svgContainer.offsetHeight; + if (pinHeight > 0) { + svgContainer.style.minHeight = pinHeight + 'px'; + } + } + + // Use inline frames if available (no fetch needed) + if (state.frames && state.frames[idx]) { + svgContainer.innerHTML = state.frames[idx]; + return; + } + + // Fallback: fetch the SVG file + const kf = manifest.keyframes[idx]; + const svgUrl = state.baseUrl + kf.file; + + fetchResource(svgUrl, false) + .then((svg) => { + svgContainer.innerHTML = svg; + }) + .catch(() => {}); + } + + function findKeyframeIndex(keyframes, time) { + // Find the last keyframe at or before the current time + let idx = 0; + for (let i = keyframes.length - 1; i >= 0; i--) { + if (keyframes[i].time <= time) { + idx = i; + break; + } + } + return idx; + } + + function updateAnnotations(layer, annotations, time) { + if (!annotations || annotations.length === 0) { + for (var i = 0; i < layer.children.length; i++) { + layer.children[i].style.opacity = '0'; + } + return; + } + + // Pre-create elements with full styling at init time. Once created, ONLY + // opacity is mutated per-frame. This prevents Safari from re-evaluating + // position styles (top/bottom/margin-block) during playback, which triggers + // its scroll-position recalculation bug. + if (!layer._annEls) { + layer._annEls = []; + for (var j = 0; j < annotations.length; j++) { + var ann0 = annotations[j]; + var el = document.createElement('div'); + var wCls = ann0.width && ann0.width !== 'medium' ? ' gd-tp-ann-w-' + ann0.width : ''; + el.className = 'gd-tp-annotation gd-tp-ann-' + ann0.position + ' gd-tp-ann-' + ann0.style + wCls; + el.textContent = ann0.text; + el.style.opacity = '0'; + el.setAttribute('aria-hidden', 'true'); + layer.appendChild(el); + layer._annEls.push(el); + } + } + + for (var k = 0; k < annotations.length; k++) { + var ann = annotations[k]; + var node = layer._annEls[k]; + if (time >= ann.time && time <= ann.time + ann.duration) { + // Fade progress (for smooth entry/exit) + var elapsed = time - ann.time; + var fadeIn = Math.min(1, elapsed / 0.3); + var fadeOut = Math.min(1, (ann.duration - elapsed) / 0.3); + node.style.opacity = Math.min(fadeIn, fadeOut); + } else { + if (node.style.opacity !== '0') node.style.opacity = '0'; + } + } + } + + function updateHighlights(layer, highlights, time, svgContainer) { + if (!highlights || highlights.length === 0) { + if (layer._hlEls) { + for (var i = 0; i < layer._hlEls.length; i++) { + layer._hlEls[i].style.opacity = '0'; + } + } + return; + } + + // Pre-create highlight elements once + if (!layer._hlEls) { + layer._hlEls = []; + for (var j = 0; j < highlights.length; j++) { + var hl = highlights[j]; + var el = document.createElement('div'); + el.className = 'gd-tp-highlight gd-tp-hl-' + hl.style; + el.style.cssText = 'position:absolute;pointer-events:none;opacity:0;'; + if (hl.color) { + el.style.setProperty('--hl-color', hl.color); + } + if (hl.pulse) { + el.classList.add('gd-tp-hl-pulse'); + } + // Badge content + if ((hl.style === 'badge-before' || hl.style === 'badge-after') && (hl.badge_text || hl.badge_icon)) { + var badge = document.createElement('span'); + badge.className = 'gd-tp-hl-badge'; + badge.textContent = (hl.badge_icon || '') + (hl.badge_text || ''); + el.appendChild(badge); + } + el.setAttribute('aria-hidden', 'true'); + layer.appendChild(el); + layer._hlEls.push(el); + } + } + + // Measure grid in viewBox coordinates (cacheable — never changes with resize) + var grid = layer._grid; + if (!grid) { + grid = measureViewBoxGrid(svgContainer); + if (grid) layer._grid = grid; + } + + for (var k = 0; k < highlights.length; k++) { + var h = highlights[k]; + var node = layer._hlEls[k]; + if (time >= h.time && time <= h.time + h.duration) { + var elapsed = time - h.time; + var fadeInDur = h.fade_in != null ? h.fade_in : 0.3; + var fadeOutDur = h.fade_out != null ? h.fade_out : 0.3; + var fadeIn = fadeInDur > 0 ? Math.min(1, elapsed / fadeInDur) : 1; + var fadeOut = fadeOutDur > 0 ? Math.min(1, (h.duration - elapsed) / fadeOutDur) : 1; + node.style.opacity = Math.min(fadeIn, fadeOut); + + // Position using percentage of viewBox (scales with SVG responsively) + if (grid && h.target && h.target.region) { + var r = h.target.region; + var x = grid.translateX + r.col * grid.cellW; + var y = grid.translateY + r.row * grid.cellH; + var w = r.width * grid.cellW; + var hh = r.height * grid.cellH; + node.style.left = (x / grid.vbW * 100) + '%'; + node.style.top = (y / grid.vbH * 100) + '%'; + node.style.width = (w / grid.vbW * 100) + '%'; + node.style.height = (hh / grid.vbH * 100) + '%'; + } else if (grid && h.target && h.target.lines) { + var lines = h.target.lines; + var minLine = Math.min.apply(null, lines); + var maxLine = Math.max.apply(null, lines); + var ly = grid.translateY + minLine * grid.cellH; + var lh = (maxLine - minLine + 1) * grid.cellH; + node.style.left = '0%'; + node.style.top = (ly / grid.vbH * 100) + '%'; + node.style.width = '100%'; + node.style.height = (lh / grid.vbH * 100) + '%'; + } + } else { + if (node.style.opacity !== '0') node.style.opacity = '0'; + } + } + } + + /** + * Measure character grid in viewBox coordinates (SVG units). + * Returns {vbW, vbH, cellW, cellH, translateX, translateY} or null. + * These values are resolution-independent and never change with browser width. + */ + function measureViewBoxGrid(svgContainer) { + var svg = svgContainer.querySelector('svg'); + if (!svg) return null; + + // Get viewBox dimensions + var viewBox = svg.getAttribute('viewBox'); + if (!viewBox) return null; + var parts = viewBox.split(/\s+|,/); + var vbW = parseFloat(parts[2]); + var vbH = parseFloat(parts[3]); + if (!vbW || !vbH) return null; + + // Find the that wraps text content + var g = svg.querySelector('g[transform]'); + var translateX = 0, translateY = 0; + if (g) { + var m = g.getAttribute('transform').match(/translate\(\s*([\d.]+)\s*[,\s]\s*([\d.]+)\s*\)/); + if (m) { + translateX = parseFloat(m[1]); + translateY = parseFloat(m[2]); + } + } + + // Determine cell size from cursor rect or text elements (in SVG units) + var cursor = svg.querySelector('rect.gd-tp-cursor'); + var cellW, cellH; + if (cursor) { + cellW = parseFloat(cursor.getAttribute('width')) || 8.4; + cellH = parseFloat(cursor.getAttribute('height')) || 21; + } else { + var textEls = svg.querySelectorAll('.gd-tp-text'); + if (textEls.length < 2) return null; + var ys = [], xs = []; + for (var i = 0; i < Math.min(textEls.length, 50); i++) { + var y = parseFloat(textEls[i].getAttribute('y')); + var x = parseFloat(textEls[i].getAttribute('x')); + if (!isNaN(y) && ys.indexOf(y) < 0) ys.push(y); + if (!isNaN(x) && xs.indexOf(x) < 0) xs.push(x); + } + ys.sort(function(a, b) { return a - b; }); + xs.sort(function(a, b) { return a - b; }); + cellH = ys.length >= 2 ? ys[1] - ys[0] : 21; + cellW = xs.length >= 2 ? xs[1] - xs[0] : 8.4; + } + + return { + vbW: vbW, + vbH: vbH, + cellW: cellW, + cellH: cellH, + translateX: translateX, + translateY: translateY + }; + } + + function updateSnippets(layer, snippets, time, svgContainer) { + if (!snippets || snippets.length === 0) { + if (layer._cmdEls) { + for (var i = 0; i < layer._cmdEls.length; i++) { + layer._cmdEls[i].style.display = 'none'; + layer._cmdEls[i].style.opacity = '0'; + } + } + return; + } + + // Pre-create snippet copy buttons at init time + if (!layer._cmdEls) { + layer._cmdEls = []; + for (var j = 0; j < snippets.length; j++) { + var snip = snippets[j]; + var el = document.createElement('button'); + el.className = 'gd-tp-copy-snippet'; + el.setAttribute('type', 'button'); + el.setAttribute('aria-label', 'Copy snippet: ' + (snip.text || snip.match)); + el.dataset.text = snip.text; + el.dataset.match = snip.match || ''; + el.innerHTML = '' + + '' + (snip.label || 'Copy') + ''; + el.style.display = 'none'; + el.addEventListener('click', (function(btn, idx) { + return function(e) { + e.stopPropagation(); + var copyText = resolveSnippetText(snippets[idx], svgContainer); + if (copyText) { + navigator.clipboard.writeText(copyText).then(function() { + btn.classList.add('gd-tp-copied'); + setTimeout(function() { btn.classList.remove('gd-tp-copied'); }, 1500); + }); + } + }; + })(el, j)); + layer.appendChild(el); + layer._cmdEls.push(el); + } + } + + // Show only one snippet at a time (first active wins; overlaps are clipped) + var activeIdx = -1; + for (var k = 0; k < snippets.length; k++) { + var c = snippets[k]; + if (activeIdx < 0 && time >= c.time && time <= c.time + c.duration) { + activeIdx = k; + var elapsed = time - c.time; + var fadeIn = Math.min(1, elapsed / 0.3); + var fadeOut = Math.min(1, (c.duration - elapsed) / 0.3); + layer._cmdEls[k].style.display = 'inline-flex'; + layer._cmdEls[k].style.opacity = Math.min(fadeIn, fadeOut); + } else { + layer._cmdEls[k].style.display = 'none'; + layer._cmdEls[k].style.opacity = '0'; + } + } + } + + /** + * Resolve the text to copy for a snippet. + * If `match` is set, extract text from the SVG and run the regex. + * If regex has a capture group, use group(1); otherwise use group(0). + * Falls back to literal `text` field. + */ + function resolveSnippetText(snip, svgContainer) { + if (snip.match) { + var buffer = extractSvgText(svgContainer); + try { + var re = new RegExp(snip.match); + var m = re.exec(buffer); + if (m) return m[1] !== undefined ? m[1] : m[0]; + } catch (e) { /* invalid regex — fall through */ } + } + return snip.text || ''; + } + + /** + * Extract the plain-text content of the current SVG frame. + * Groups elements by y-coordinate to reconstruct terminal lines. + */ + function extractSvgText(svgContainer) { + var svg = svgContainer.querySelector('svg'); + if (!svg) return ''; + var textEls = svg.querySelectorAll('.gd-tp-text'); + if (!textEls.length) return ''; + // Group by y-coordinate (row) + var rows = {}; + for (var i = 0; i < textEls.length; i++) { + var el = textEls[i]; + var y = parseFloat(el.getAttribute('y')) || 0; + var x = parseFloat(el.getAttribute('x')) || 0; + var key = Math.round(y * 10); // quantize y to avoid float drift + if (!rows[key]) rows[key] = []; + rows[key].push({ x: x, text: el.textContent || '' }); + } + // Sort rows by y, spans within rows by x + var keys = Object.keys(rows).map(Number).sort(function(a, b) { return a - b; }); + var lines = []; + for (var k = 0; k < keys.length; k++) { + var spans = rows[keys[k]].sort(function(a, b) { return a.x - b.x; }); + var line = ''; + for (var s = 0; s < spans.length; s++) line += spans[s].text; + lines.push(line); + } + return lines.join('\n'); + } + + // --- Controls UI --- + + function buildControls() { + const root = document.createElement('div'); + root.className = 'gd-tp-controls'; + + const playBtn = document.createElement('button'); + playBtn.className = 'gd-tp-play-btn'; + playBtn.textContent = '\u25b6'; // ▶ + playBtn.setAttribute('aria-label', 'Play'); + + const time = document.createElement('span'); + time.className = 'gd-tp-time'; + time.textContent = '0:00'; + + const timeline = document.createElement('div'); + timeline.className = 'gd-tp-timeline'; + timeline.setAttribute('role', 'slider'); + timeline.setAttribute('aria-label', 'Playback position'); + + const progress = document.createElement('div'); + progress.className = 'gd-tp-progress'; + timeline.appendChild(progress); + + const duration = document.createElement('span'); + duration.className = 'gd-tp-duration'; + duration.textContent = '0:00'; + + const speedBtn = document.createElement('button'); + speedBtn.className = 'gd-tp-speed-btn'; + speedBtn.textContent = '1\u00d7'; + speedBtn.setAttribute('aria-label', 'Playback speed'); + + root.appendChild(playBtn); + root.appendChild(time); + root.appendChild(timeline); + root.appendChild(duration); + root.appendChild(speedBtn); + + return { root, playBtn, time, timeline, progress, duration, speedBtn }; + } + + function renderChapterMarkers(timeline, manifest) { + if (!manifest.chapters || manifest.chapters.length === 0) return; + + for (const ch of manifest.chapters) { + if (ch.time > manifest.duration) continue; + const pct = manifest.duration > 0 ? (ch.time / manifest.duration) * 100 : 0; + const marker = document.createElement('div'); + marker.className = 'gd-tp-chapter-marker'; + marker.style.left = pct + '%'; + marker.setAttribute('title', ch.label || 'Chapter'); + marker.dataset.time = ch.time; + timeline.appendChild(marker); + } + } + + // --- Utilities --- + + function formatTime(seconds) { + const m = Math.floor(seconds / 60); + const s = Math.floor(seconds % 60); + return m + ':' + (s < 10 ? '0' : '') + s; + } + + // --- Initialization --- + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initAll); + } else { + initAll(); + } + + // Also handle Quarto's dynamic content loading + const observer = new MutationObserver((mutations) => { + for (const mutation of mutations) { + for (const node of mutation.addedNodes) { + if (node.nodeType === 1) { + if (node.classList && node.classList.contains(PLAYER_CLASS)) { + initPlayer(node); + } + const nested = node.querySelectorAll && node.querySelectorAll(`.${PLAYER_CLASS}`); + if (nested) nested.forEach((el) => initPlayer(el)); + } + } + } + }); + observer.observe(document.body, { childList: true, subtree: true }); +})(); diff --git a/docs/theme-init.js b/docs/theme-init.js new file mode 100644 index 0000000..344f2fa --- /dev/null +++ b/docs/theme-init.js @@ -0,0 +1,54 @@ +// Early theme initialization to prevent flash of wrong theme +(function() { + // When dark mode toggle is disabled, always use light mode + var dmMeta = document.querySelector('meta[name="gd-dark-mode"]'); + var darkModeDisabled = dmMeta && dmMeta.getAttribute('content') === 'disabled'; + + var stored = darkModeDisabled ? null : localStorage.getItem('great-docs-theme'); + var theme = stored || (darkModeDisabled ? 'light' : (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')); + var html = document.documentElement; + + // Hide body until theme is fully applied to prevent flash + html.classList.add('theme-loading'); + + if (theme === 'dark') { + html.classList.add('quarto-dark'); + html.setAttribute('data-bs-theme', 'dark'); + } else { + html.classList.add('quarto-light'); + html.setAttribute('data-bs-theme', 'light'); + } + + // Detect page type from URL for page-specific styling + var path = window.location.pathname; + var pageName = path.endsWith('/') || path.endsWith('/index.html') || path === '/' ? 'index' : null; + if (!pageName) { + var filename = path.split('/').pop().replace('.html', ''); + if (filename === 'index' || filename === '') { + pageName = 'index'; + } + } + + // Set page identifier on body when DOM is ready + function setPageIdentifier() { + if (pageName && document.body) { + document.body.setAttribute('data-page', pageName); + } + } + + // Reveal page once DOM is ready and styles are applied + function revealPage() { + setPageIdentifier(); + // Small delay to ensure CSS is processed + requestAnimationFrame(function() { + html.classList.remove('theme-loading'); + html.classList.add('theme-loaded'); + }); + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', revealPage); + } else { + revealPage(); + } +})(); diff --git a/docs/tooltips.js b/docs/tooltips.js new file mode 100644 index 0000000..a7ba62c --- /dev/null +++ b/docs/tooltips.js @@ -0,0 +1,347 @@ +/** + * Custom Tooltips for Great Docs + * + * Replaces native browser title tooltips with styled Tippy.js tooltips. + * + * Features: + * - Instant appearance (no 400ms delay) + * - Consistent styling across all browsers + * - Dark mode support + * - Smart positioning (avoids viewport edges) + * - Material Filling Effect animation + * - Converts existing title attributes site-wide + * + * NOTE: Quarto already bundles Popper.js and Tippy.js, so we use those instead + * of loading from CDN. Falls back to CDN if they're not available. + */ + +(function () { + "use strict"; + + // Configuration + var CONFIG = { + // Tippy.js CDN URLs (fallback if not bundled by Quarto) + popperUrl: "https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js", + tippyUrl: "https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.min.js", + + // Default tooltip options + defaultOptions: { + animation: "shift-away", + duration: [200, 150], + delay: [0, 0], // Instant appearance + arrow: true, + placement: "top", + theme: "gd-material", + maxWidth: 300, + // Tooltips are a hover affordance so we suppress them on touch devices + // (phones/tablets) where there is no hover and a tap/long-press would + // otherwise pop a stray tooltip (e.g., the version badge on the brand). + touch: false, + // Smart positioning: flip if not enough space + popperOptions: { + modifiers: [ + { + name: "flip", + options: { + fallbackPlacements: ["bottom", "right", "left"], + }, + }, + { + name: "preventOverflow", + options: { + boundary: "viewport", + padding: 8, + }, + }, + ], + }, + }, + + // Selectors for elements to skip (already have custom tooltips) + skipSelectors: [ + "[data-tippy-content]", // Already has Tippy + ".tippy-box", // Tippy element itself + ".gd-tooltip-skip", // Explicit skip class + ], + }; + + // Track loaded state + var tippyReady = false; + var tippyInstance = null; + + /** + * Load an external script dynamically. + * @param {string} url - Script URL + * @returns {Promise} - Resolves when loaded + */ + function loadScript(url) { + return new Promise(function (resolve, reject) { + // Check if already loaded + var existing = document.querySelector('script[src="' + url + '"]'); + if (existing) { + resolve(); + return; + } + + var script = document.createElement("script"); + script.src = url; + script.async = true; + script.onload = resolve; + script.onerror = function () { + reject(new Error("Failed to load script: " + url)); + }; + document.head.appendChild(script); + }); + } + + /** + * Load Tippy.js and its dependencies. + * Quarto bundles Popper and Tippy, so check for them first. + * @returns {Promise} - Resolves when Tippy is ready + */ + function loadTippy() { + // If Tippy is already available (Quarto bundles it), use it directly + if (window.tippy) { + tippyReady = true; + return Promise.resolve(); + } + + // Quarto might have loaded tippy but not exposed it globally yet + // Wait a tick and check again + return new Promise(function (resolve) { + setTimeout(function () { + if (window.tippy) { + tippyReady = true; + resolve(); + return; + } + + // Fall back to CDN loading if Quarto's tippy isn't available + loadScript(CONFIG.popperUrl) + .then(function () { + return loadScript(CONFIG.tippyUrl); + }) + .then(function () { + tippyReady = true; + resolve(); + }) + .catch(function (err) { + console.warn("Failed to load Tippy.js from CDN:", err); + resolve(); // Continue without tooltips + }); + }, 50); + }); + } + + /** + * Determine if dark mode is active. + * @returns {boolean} + */ + function isDarkMode() { + return ( + document.documentElement.classList.contains("quarto-dark") || + document.body.classList.contains("quarto-dark") || + document.documentElement.getAttribute("data-bs-theme") === "dark" + ); + } + + /** + * Get theme name based on current mode. + * @returns {string} + */ + function getThemeName() { + return isDarkMode() ? "gd-material-dark" : "gd-material"; + } + + /** + * Convert title attributes to data-tippy-content. + * This prevents native tooltips from appearing. + */ + function convertTitleAttributes() { + var skipSelector = CONFIG.skipSelectors.join(", "); + + // Find all elements with title attributes + var elements = document.querySelectorAll("[title]"); + + elements.forEach(function (el) { + // Skip if matches any skip selector + if (skipSelector && el.matches(skipSelector)) { + return; + } + + var title = el.getAttribute("title"); + if (title && title.trim()) { + // Store the title as data-tippy-content + el.setAttribute("data-tippy-content", title); + // Remove the native title to prevent browser tooltip + el.removeAttribute("title"); + } + }); + } + + /** + * Initialize or reinitialize all tooltips. + */ + function initTooltips() { + if (!window.tippy) { + console.warn("Tippy.js not loaded"); + return; + } + + // First convert any title attributes + convertTitleAttributes(); + + // Find all elements with data-tippy-content + var elements = document.querySelectorAll("[data-tippy-content]"); + + if (elements.length === 0) { + return; + } + + // Create options with current theme + var options = Object.assign({}, CONFIG.defaultOptions, { + theme: getThemeName(), + allowHTML: true, + // Read content from data-tippy-content so HTML tags are rendered + content: function (el) { + return el.getAttribute("data-tippy-content") || ""; + }, + // Material filling effect via CSS + onMount: function (instance) { + instance.popper.classList.add("gd-tooltip-mounted"); + }, + onHidden: function (instance) { + instance.popper.classList.remove("gd-tooltip-mounted"); + }, + }); + + // Destroy existing instances to avoid duplicates + elements.forEach(function (el) { + if (el._tippy) { + el._tippy.destroy(); + } + }); + + // Initialize Tippy on all elements + tippyInstance = window.tippy(elements, options); + } + + /** + * Update tooltip themes when dark mode changes. + */ + function updateTooltipThemes() { + if (!tippyInstance) return; + + var newTheme = getThemeName(); + + // Update all active tippy instances + var instances = Array.isArray(tippyInstance) ? tippyInstance : [tippyInstance]; + instances.forEach(function (instance) { + if (instance && instance.setProps) { + instance.setProps({ theme: newTheme }); + } + }); + } + + /** + * Observe for dynamically added elements. + */ + function observeNewElements() { + if (!window.MutationObserver) return; + + var observer = new MutationObserver(function (mutations) { + var needsReinit = false; + + mutations.forEach(function (mutation) { + // Check added nodes for title or data-tippy-content attributes + mutation.addedNodes.forEach(function (node) { + if (node.nodeType === Node.ELEMENT_NODE) { + if (node.hasAttribute && (node.hasAttribute("title") || node.hasAttribute("data-tippy-content"))) { + needsReinit = true; + } + // Also check descendants + if (node.querySelectorAll) { + var withTitle = node.querySelectorAll("[title], [data-tippy-content]"); + if (withTitle.length > 0) { + needsReinit = true; + } + } + } + }); + + // Check for attribute changes (title or data-tippy-content being set) + if (mutation.type === "attributes" && + (mutation.attributeName === "title" || mutation.attributeName === "data-tippy-content")) { + needsReinit = true; + } + }); + + if (needsReinit) { + // Debounce re-initialization + clearTimeout(observeNewElements.timeout); + observeNewElements.timeout = setTimeout(initTooltips, 100); + } + }); + + observer.observe(document.body, { + childList: true, + subtree: true, + attributes: true, + attributeFilter: ["title", "data-tippy-content"], + }); + } + + /** + * Observe dark mode changes. + */ + function observeDarkMode() { + if (!window.MutationObserver) return; + + var observer = new MutationObserver(function (mutations) { + mutations.forEach(function (mutation) { + if (mutation.attributeName === "class" || mutation.attributeName === "data-bs-theme") { + updateTooltipThemes(); + } + }); + }); + + // Observe both html and body for class changes + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ["class", "data-bs-theme"], + }); + observer.observe(document.body, { + attributes: true, + attributeFilter: ["class"], + }); + } + + /** + * Main initialization function. + */ + function init() { + loadTippy() + .then(function () { + initTooltips(); + observeNewElements(); + observeDarkMode(); + }) + .catch(function (err) { + console.error("Failed to initialize tooltips:", err); + }); + } + + // Initialize when DOM is ready + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", init); + } else { + init(); + } + + // Expose API for programmatic use + window.GDTooltips = { + init: init, + refresh: initTooltips, + updateTheme: updateTooltipThemes, + }; +})(); diff --git a/docs/video-embed.js b/docs/video-embed.js new file mode 100644 index 0000000..2e8a0dd --- /dev/null +++ b/docs/video-embed.js @@ -0,0 +1,72 @@ +/** + * Video embedding enhancements for Great Docs + * + * Improves performance and UX for embedded videos: + * - YouTube: uses the standard YouTube embedded player with native controls + * - Vimeo / other service iframes: IntersectionObserver lazy loading + * - Local