From ebcf41c1afa8e65e5c2af14c5b70641ad74f8922 Mon Sep 17 00:00:00 2001 From: Casey Schneider-Mizell Date: Wed, 10 Jul 2024 11:53:52 -0700 Subject: [PATCH] Segment props (#34) * initial conversion to hatch * successfully convert to hatch * unpin neuroglancer * basic working seg props * validated inline properties attr * allow tag descriptions * use better contrast controls for mainline * initial working segment prop map * working version of mapping sets * tests + associated changes * Improve targetsite robustness * update changelog --- -/LICENSE.txt | 9 + -/README.md | 21 + -/pyproject.toml | 61 + -/src/_/__about__.py | 4 + -/src/_/__init__.py | 3 + -/tests/__init__.py | 3 + .gitignore | 2 +- LICENSE.license | 201 -- docs/.gitignore | 1 - docs/_quarto.yml | 91 - docs/_sidebar.yml | 54 - docs/_site/about.html | 381 ---- docs/_site/index.html | 382 ---- .../reference/AnnotationLayerConfig.html | 433 ---- docs/_site/reference/ChainedStateBuilder.html | 419 ---- docs/_site/reference/ImageLayerConfig.html | 428 ---- .../reference/SegmentationLayerConfig.html | 536 ----- docs/_site/reference/get_object.html | 481 ---- docs/_site/reference/index.html | 874 ------- .../layers.AnnotationLayerConfig.html | 433 ---- .../reference/layers.ImageLayerConfig.html | 428 ---- .../layers.SegmentationLayerConfig.html | 536 ----- docs/_site/reference/layers.html | 756 ------ ...ebuilder.layers.AnnotationLayerConfig.html | 433 ---- ....statebuilder.layers.ImageLayerConfig.html | 428 ---- ...i.statebuilder.layers.LayerConfigBase.html | 421 ---- ...uilder.layers.SegmentationLayerConfig.html | 536 ----- ...builder.StateBuilder.initialize_state.html | 397 ---- ...tatebuilder.StateBuilder.render_state.html | 442 ---- .../parser.base.annotation_dataframe.html | 726 ------ .../parser.base.annotation_layers.html | 726 ------ .../parser.base.extract_multicut.html | 754 ------ .../reference/parser.base.get_layer.html | 738 ------ .../parser.base.get_selected_ids.html | 738 ------ .../parser.base.group_annotations.html | 776 ------- .../reference/parser.base.image_layers.html | 726 ------ .../reference/parser.base.layer_names.html | 726 ------ .../parser.base.line_annotations.html | 780 ------- .../parser.base.point_annotations.html | 776 ------- .../parser.base.segmentation_layers.html | 726 ------ .../parser.base.sphere_annotations.html | 780 ------- .../reference/parser.base.tag_dictionary.html | 732 ------ .../reference/parser.base.view_settings.html | 730 ------ docs/_site/reference/preview.html | 413 ---- .../statebuilder.AnnotationLayerConfig.html | 751 ------ .../statebuilder.BoundingBoxMapper.html | 769 ------- .../statebuilder.ChainedStateBuilder.html | 715 ------ .../statebuilder.ImageLayerConfig.html | 746 ------ .../reference/statebuilder.LineMapper.html | 769 ------- .../reference/statebuilder.PointMapper.html | 763 ------- .../statebuilder.SegmentationLayerConfig.html | 787 ------- .../reference/statebuilder.SphereMapper.html | 769 ------- .../statebuilder.SplitPointMapper.html | 766 ------- .../reference/statebuilder.StateBuilder.html | 751 ------ .../statebuilder.helpers.from_client.html | 758 ------- ...uilder.helpers.make_line_statebuilder.html | 786 ------- ...helpers.make_neuron_neuroglancer_link.html | 877 ------- ...ilder.helpers.make_point_statebuilder.html | 780 ------- ...er.helpers.make_pre_post_statebuilder.html | 796 ------- .../statebuilder.helpers.make_state_url.html | 756 ------ ...elpers.make_synapse_neuroglancer_link.html | 847 ------- .../statebuilder.helpers.make_url_robust.html | 768 ------- .../statebuilder.helpers.package_state.html | 781 ------- ...der.helpers.sort_dataframe_by_root_id.html | 756 ------ docs/_site/reference/statebuilder.html | 563 ----- docs/_site/search.json | 1073 --------- .../site_libs/bootstrap/bootstrap-icons.css | 2018 ----------------- .../site_libs/bootstrap/bootstrap-icons.woff | Bin 164168 -> 0 bytes .../site_libs/bootstrap/bootstrap.min.css | 10 - .../site_libs/bootstrap/bootstrap.min.js | 7 - .../site_libs/clipboard/clipboard.min.js | 7 - .../_site/site_libs/quarto-html/anchor.min.js | 9 - .../_site/site_libs/quarto-html/popper.min.js | 6 - .../quarto-syntax-highlighting.css | 203 -- docs/_site/site_libs/quarto-html/quarto.js | 902 -------- docs/_site/site_libs/quarto-html/tippy.css | 1 - .../site_libs/quarto-html/tippy.umd.min.js | 2 - .../site_libs/quarto-nav/headroom.min.js | 7 - docs/_site/site_libs/quarto-nav/quarto-nav.js | 277 --- .../quarto-search/autocomplete.umd.js | 3 - .../_site/site_libs/quarto-search/fuse.min.js | 9 - .../site_libs/quarto-search/quarto-search.js | 1140 ---------- docs/_site/tutorials/index.html | 369 --- docs/_site/tutorials/parser.html | 369 --- docs/_site/tutorials/statebuilder.html | 449 ---- docs/about.qmd | 5 - CHANGELOG.md => docs/changelog.md | 17 + docs/index.md | 46 + docs/index.qmd | 7 - docs/objects.json | 1 - docs/reference/AnnotationLayerConfig.qmd | 17 - docs/reference/ChainedStateBuilder.qmd | 34 - docs/reference/ImageLayerConfig.qmd | 18 - docs/reference/SegmentationLayerConfig.qmd | 44 - docs/reference/_api_index.qmd | 74 - docs/reference/easyviewer.md | 19 + docs/reference/get_object.qmd | 32 - docs/reference/index.qmd | 21 - .../layers.AnnotationLayerConfig.qmd | 17 - docs/reference/layers.ImageLayerConfig.qmd | 18 - .../layers.SegmentationLayerConfig.qmd | 44 - docs/reference/layers.qmd | 112 - ...tebuilder.layers.AnnotationLayerConfig.qmd | 17 - ...i.statebuilder.layers.ImageLayerConfig.qmd | 18 - ...ui.statebuilder.layers.LayerConfigBase.qmd | 15 - ...builder.layers.SegmentationLayerConfig.qmd | 44 - ...ebuilder.StateBuilder.initialize_state.qmd | 11 - ...statebuilder.StateBuilder.render_state.qmd | 21 - .../parser.base.annotation_dataframe.qmd | 17 - .../parser.base.annotation_layers.qmd | 17 - .../parser.base.extract_multicut.qmd | 21 - docs/reference/parser.base.get_layer.qmd | 18 - .../parser.base.get_selected_ids.qmd | 18 - .../parser.base.group_annotations.qmd | 25 - docs/reference/parser.base.image_layers.qmd | 17 - docs/reference/parser.base.layer_names.qmd | 17 - .../parser.base.line_annotations.qmd | 26 - .../parser.base.point_annotations.qmd | 25 - .../parser.base.segmentation_layers.qmd | 17 - .../parser.base.sphere_annotations.qmd | 26 - docs/reference/parser.base.tag_dictionary.qmd | 18 - docs/reference/parser.base.view_settings.qmd | 18 - docs/reference/parser.md | 8 + docs/reference/preview.qmd | 22 - docs/reference/segprops.md | 13 + .../statebuilder.AnnotationLayerConfig.qmd | 17 - .../statebuilder.BoundingBoxMapper.qmd | 20 - .../statebuilder.ChainedStateBuilder.qmd | 11 - .../statebuilder.ImageLayerConfig.qmd | 18 - docs/reference/statebuilder.LineMapper.qmd | 20 - docs/reference/statebuilder.PointMapper.qmd | 19 - .../statebuilder.SegmentationLayerConfig.qmd | 23 - docs/reference/statebuilder.SphereMapper.qmd | 20 - .../statebuilder.SplitPointMapper.qmd | 22 - docs/reference/statebuilder.StateBuilder.qmd | 17 - .../statebuilder.helpers.from_client.qmd | 21 - ...builder.helpers.make_line_statebuilder.qmd | 26 - ....helpers.make_neuron_neuroglancer_link.qmd | 43 - ...uilder.helpers.make_point_statebuilder.qmd | 25 - ...der.helpers.make_pre_post_statebuilder.qmd | 28 - .../statebuilder.helpers.make_state_url.qmd | 21 - ...helpers.make_synapse_neuroglancer_link.qmd | 38 - .../statebuilder.helpers.make_url_robust.qmd | 24 - .../statebuilder.helpers.package_state.qmd | 27 - ...lder.helpers.sort_dataframe_by_root_id.qmd | 21 - docs/reference/statebuilder.md | 23 + docs/reference/statebuilder.qmd | 58 - docs/styles.css | 1 - docs/tutorials/index.qmd | 7 - docs/tutorials/parser.qmd | 7 - docs/tutorials/statebuilder.qmd | 36 - docs/usage/parser.md | 3 + docs/usage/segprops.md | 5 + docs/usage/statebuilder.md | 3 + examples/dash_with_statebuilder.py | 2 +- mkdocs.yml | 87 + pyproject.toml | 53 + setup.py | 15 +- src/nglui/__init__.py | 3 +- src/nglui/easyviewer/__init__.py | 17 +- src/nglui/easyviewer/ev_base/__init__.py | 2 +- .../ev_base/annotation_compatibility.py | 4 +- src/nglui/easyviewer/ev_base/base.py | 70 +- src/nglui/easyviewer/ev_base/mainline.py | 127 +- .../easyviewer/ev_base/nglite/__init__.py | 2 +- .../ev_base/nglite/equivalence_map.py | 3 +- .../easyviewer/ev_base/nglite/json_utils.py | 5 +- .../ev_base/nglite/json_wrappers.py | 11 +- .../easyviewer/ev_base/nglite/skeleton.py | 5 +- .../ev_base/nglite/trackable_state.py | 5 +- .../easyviewer/ev_base/nglite/url_state.py | 41 +- src/nglui/easyviewer/ev_base/nglite/viewer.py | 5 +- .../easyviewer/ev_base/nglite/viewer_base.py | 3 +- .../ev_base/nglite/viewer_config_state.py | 3 +- .../easyviewer/ev_base/nglite/viewer_state.py | 24 +- .../ev_base/nglite_compatibility/__init__.py | 2 +- .../ev_base/nglite_compatibility/base.py | 3 - src/nglui/easyviewer/ev_base/seunglab.py | 27 +- src/nglui/easyviewer/ev_base/utils.py | 36 +- src/nglui/parser/base.py | 2 +- src/nglui/parser/info.py | 2 +- src/nglui/segmentprops/__init__.py | 7 + src/nglui/segmentprops/base.py | 432 ++++ src/nglui/statebuilder/helpers.py | 76 +- src/nglui/statebuilder/layers.py | 187 +- src/nglui/statebuilder/mappers.py | 86 +- src/nglui/statebuilder/statebuilder.py | 127 +- src/nglui/statebuilder/utils.py | 21 +- tests/conftest.py | 20 +- tests/test_parser.py | 2 +- tests/test_segment_props.py | 40 + tests/test_statebuilder.py | 30 +- tests/test_viewer.py | 1 - 193 files changed, 1479 insertions(+), 44644 deletions(-) create mode 100644 -/LICENSE.txt create mode 100644 -/README.md create mode 100644 -/pyproject.toml create mode 100644 -/src/_/__about__.py create mode 100644 -/src/_/__init__.py create mode 100644 -/tests/__init__.py delete mode 100644 LICENSE.license delete mode 100644 docs/.gitignore delete mode 100644 docs/_quarto.yml delete mode 100644 docs/_sidebar.yml delete mode 100644 docs/_site/about.html delete mode 100644 docs/_site/index.html delete mode 100644 docs/_site/reference/AnnotationLayerConfig.html delete mode 100644 docs/_site/reference/ChainedStateBuilder.html delete mode 100644 docs/_site/reference/ImageLayerConfig.html delete mode 100644 docs/_site/reference/SegmentationLayerConfig.html delete mode 100644 docs/_site/reference/get_object.html delete mode 100644 docs/_site/reference/index.html delete mode 100644 docs/_site/reference/layers.AnnotationLayerConfig.html delete mode 100644 docs/_site/reference/layers.ImageLayerConfig.html delete mode 100644 docs/_site/reference/layers.SegmentationLayerConfig.html delete mode 100644 docs/_site/reference/layers.html delete mode 100644 docs/_site/reference/nglui.statebuilder.layers.AnnotationLayerConfig.html delete mode 100644 docs/_site/reference/nglui.statebuilder.layers.ImageLayerConfig.html delete mode 100644 docs/_site/reference/nglui.statebuilder.layers.LayerConfigBase.html delete mode 100644 docs/_site/reference/nglui.statebuilder.layers.SegmentationLayerConfig.html delete mode 100644 docs/_site/reference/nglui.statebuilder.statebuilder.StateBuilder.initialize_state.html delete mode 100644 docs/_site/reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.html delete mode 100644 docs/_site/reference/parser.base.annotation_dataframe.html delete mode 100644 docs/_site/reference/parser.base.annotation_layers.html delete mode 100644 docs/_site/reference/parser.base.extract_multicut.html delete mode 100644 docs/_site/reference/parser.base.get_layer.html delete mode 100644 docs/_site/reference/parser.base.get_selected_ids.html delete mode 100644 docs/_site/reference/parser.base.group_annotations.html delete mode 100644 docs/_site/reference/parser.base.image_layers.html delete mode 100644 docs/_site/reference/parser.base.layer_names.html delete mode 100644 docs/_site/reference/parser.base.line_annotations.html delete mode 100644 docs/_site/reference/parser.base.point_annotations.html delete mode 100644 docs/_site/reference/parser.base.segmentation_layers.html delete mode 100644 docs/_site/reference/parser.base.sphere_annotations.html delete mode 100644 docs/_site/reference/parser.base.tag_dictionary.html delete mode 100644 docs/_site/reference/parser.base.view_settings.html delete mode 100644 docs/_site/reference/preview.html delete mode 100644 docs/_site/reference/statebuilder.AnnotationLayerConfig.html delete mode 100644 docs/_site/reference/statebuilder.BoundingBoxMapper.html delete mode 100644 docs/_site/reference/statebuilder.ChainedStateBuilder.html delete mode 100644 docs/_site/reference/statebuilder.ImageLayerConfig.html delete mode 100644 docs/_site/reference/statebuilder.LineMapper.html delete mode 100644 docs/_site/reference/statebuilder.PointMapper.html delete mode 100644 docs/_site/reference/statebuilder.SegmentationLayerConfig.html delete mode 100644 docs/_site/reference/statebuilder.SphereMapper.html delete mode 100644 docs/_site/reference/statebuilder.SplitPointMapper.html delete mode 100644 docs/_site/reference/statebuilder.StateBuilder.html delete mode 100644 docs/_site/reference/statebuilder.helpers.from_client.html delete mode 100644 docs/_site/reference/statebuilder.helpers.make_line_statebuilder.html delete mode 100644 docs/_site/reference/statebuilder.helpers.make_neuron_neuroglancer_link.html delete mode 100644 docs/_site/reference/statebuilder.helpers.make_point_statebuilder.html delete mode 100644 docs/_site/reference/statebuilder.helpers.make_pre_post_statebuilder.html delete mode 100644 docs/_site/reference/statebuilder.helpers.make_state_url.html delete mode 100644 docs/_site/reference/statebuilder.helpers.make_synapse_neuroglancer_link.html delete mode 100644 docs/_site/reference/statebuilder.helpers.make_url_robust.html delete mode 100644 docs/_site/reference/statebuilder.helpers.package_state.html delete mode 100644 docs/_site/reference/statebuilder.helpers.sort_dataframe_by_root_id.html delete mode 100644 docs/_site/reference/statebuilder.html delete mode 100644 docs/_site/search.json delete mode 100644 docs/_site/site_libs/bootstrap/bootstrap-icons.css delete mode 100644 docs/_site/site_libs/bootstrap/bootstrap-icons.woff delete mode 100644 docs/_site/site_libs/bootstrap/bootstrap.min.css delete mode 100644 docs/_site/site_libs/bootstrap/bootstrap.min.js delete mode 100644 docs/_site/site_libs/clipboard/clipboard.min.js delete mode 100644 docs/_site/site_libs/quarto-html/anchor.min.js delete mode 100644 docs/_site/site_libs/quarto-html/popper.min.js delete mode 100644 docs/_site/site_libs/quarto-html/quarto-syntax-highlighting.css delete mode 100644 docs/_site/site_libs/quarto-html/quarto.js delete mode 100644 docs/_site/site_libs/quarto-html/tippy.css delete mode 100644 docs/_site/site_libs/quarto-html/tippy.umd.min.js delete mode 100644 docs/_site/site_libs/quarto-nav/headroom.min.js delete mode 100644 docs/_site/site_libs/quarto-nav/quarto-nav.js delete mode 100644 docs/_site/site_libs/quarto-search/autocomplete.umd.js delete mode 100644 docs/_site/site_libs/quarto-search/fuse.min.js delete mode 100644 docs/_site/site_libs/quarto-search/quarto-search.js delete mode 100644 docs/_site/tutorials/index.html delete mode 100644 docs/_site/tutorials/parser.html delete mode 100644 docs/_site/tutorials/statebuilder.html delete mode 100644 docs/about.qmd rename CHANGELOG.md => docs/changelog.md (91%) create mode 100644 docs/index.md delete mode 100644 docs/index.qmd delete mode 100644 docs/objects.json delete mode 100644 docs/reference/AnnotationLayerConfig.qmd delete mode 100644 docs/reference/ChainedStateBuilder.qmd delete mode 100644 docs/reference/ImageLayerConfig.qmd delete mode 100644 docs/reference/SegmentationLayerConfig.qmd delete mode 100644 docs/reference/_api_index.qmd create mode 100644 docs/reference/easyviewer.md delete mode 100644 docs/reference/get_object.qmd delete mode 100644 docs/reference/index.qmd delete mode 100644 docs/reference/layers.AnnotationLayerConfig.qmd delete mode 100644 docs/reference/layers.ImageLayerConfig.qmd delete mode 100644 docs/reference/layers.SegmentationLayerConfig.qmd delete mode 100644 docs/reference/layers.qmd delete mode 100644 docs/reference/nglui.statebuilder.layers.AnnotationLayerConfig.qmd delete mode 100644 docs/reference/nglui.statebuilder.layers.ImageLayerConfig.qmd delete mode 100644 docs/reference/nglui.statebuilder.layers.LayerConfigBase.qmd delete mode 100644 docs/reference/nglui.statebuilder.layers.SegmentationLayerConfig.qmd delete mode 100644 docs/reference/nglui.statebuilder.statebuilder.StateBuilder.initialize_state.qmd delete mode 100644 docs/reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.qmd delete mode 100644 docs/reference/parser.base.annotation_dataframe.qmd delete mode 100644 docs/reference/parser.base.annotation_layers.qmd delete mode 100644 docs/reference/parser.base.extract_multicut.qmd delete mode 100644 docs/reference/parser.base.get_layer.qmd delete mode 100644 docs/reference/parser.base.get_selected_ids.qmd delete mode 100644 docs/reference/parser.base.group_annotations.qmd delete mode 100644 docs/reference/parser.base.image_layers.qmd delete mode 100644 docs/reference/parser.base.layer_names.qmd delete mode 100644 docs/reference/parser.base.line_annotations.qmd delete mode 100644 docs/reference/parser.base.point_annotations.qmd delete mode 100644 docs/reference/parser.base.segmentation_layers.qmd delete mode 100644 docs/reference/parser.base.sphere_annotations.qmd delete mode 100644 docs/reference/parser.base.tag_dictionary.qmd delete mode 100644 docs/reference/parser.base.view_settings.qmd create mode 100644 docs/reference/parser.md delete mode 100644 docs/reference/preview.qmd create mode 100644 docs/reference/segprops.md delete mode 100644 docs/reference/statebuilder.AnnotationLayerConfig.qmd delete mode 100644 docs/reference/statebuilder.BoundingBoxMapper.qmd delete mode 100644 docs/reference/statebuilder.ChainedStateBuilder.qmd delete mode 100644 docs/reference/statebuilder.ImageLayerConfig.qmd delete mode 100644 docs/reference/statebuilder.LineMapper.qmd delete mode 100644 docs/reference/statebuilder.PointMapper.qmd delete mode 100644 docs/reference/statebuilder.SegmentationLayerConfig.qmd delete mode 100644 docs/reference/statebuilder.SphereMapper.qmd delete mode 100644 docs/reference/statebuilder.SplitPointMapper.qmd delete mode 100644 docs/reference/statebuilder.StateBuilder.qmd delete mode 100644 docs/reference/statebuilder.helpers.from_client.qmd delete mode 100644 docs/reference/statebuilder.helpers.make_line_statebuilder.qmd delete mode 100644 docs/reference/statebuilder.helpers.make_neuron_neuroglancer_link.qmd delete mode 100644 docs/reference/statebuilder.helpers.make_point_statebuilder.qmd delete mode 100644 docs/reference/statebuilder.helpers.make_pre_post_statebuilder.qmd delete mode 100644 docs/reference/statebuilder.helpers.make_state_url.qmd delete mode 100644 docs/reference/statebuilder.helpers.make_synapse_neuroglancer_link.qmd delete mode 100644 docs/reference/statebuilder.helpers.make_url_robust.qmd delete mode 100644 docs/reference/statebuilder.helpers.package_state.qmd delete mode 100644 docs/reference/statebuilder.helpers.sort_dataframe_by_root_id.qmd create mode 100644 docs/reference/statebuilder.md delete mode 100644 docs/reference/statebuilder.qmd delete mode 100644 docs/styles.css delete mode 100644 docs/tutorials/index.qmd delete mode 100644 docs/tutorials/parser.qmd delete mode 100644 docs/tutorials/statebuilder.qmd create mode 100644 docs/usage/parser.md create mode 100644 docs/usage/segprops.md create mode 100644 docs/usage/statebuilder.md create mode 100644 mkdocs.yml create mode 100644 pyproject.toml create mode 100644 src/nglui/segmentprops/__init__.py create mode 100644 src/nglui/segmentprops/base.py create mode 100644 tests/test_segment_props.py diff --git a/-/LICENSE.txt b/-/LICENSE.txt new file mode 100644 index 0000000..d18dcf9 --- /dev/null +++ b/-/LICENSE.txt @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2024-present Casey Schneider-Mizell + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/-/README.md b/-/README.md new file mode 100644 index 0000000..f8a094b --- /dev/null +++ b/-/README.md @@ -0,0 +1,21 @@ +# . + +[![PyPI - Version](https://img.shields.io/pypi/v/-.svg)](https://pypi.org/project/-) +[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/-.svg)](https://pypi.org/project/-) + +----- + +## Table of Contents + +- [Installation](#installation) +- [License](#license) + +## Installation + +```console +pip install - +``` + +## License + +`-` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license. diff --git a/-/pyproject.toml b/-/pyproject.toml new file mode 100644 index 0000000..c0433a8 --- /dev/null +++ b/-/pyproject.toml @@ -0,0 +1,61 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "-" +dynamic = ["version"] +description = '' +readme = "README.md" +requires-python = ">=3.8" +license = "MIT" +keywords = [] +authors = [ + { name = "Casey Schneider-Mizell", email = "caseysm@gmail.com" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Programming Language :: Python", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] +dependencies = [] + +[project.urls] +Documentation = "https://github.com/Casey Schneider-Mizell/-#readme" +Issues = "https://github.com/Casey Schneider-Mizell/-/issues" +Source = "https://github.com/Casey Schneider-Mizell/-" + +[tool.hatch.version] +path = "src/_/__about__.py" + +[tool.hatch.envs.types] +extra-dependencies = [ + "mypy>=1.0.0", +] +[tool.hatch.envs.types.scripts] +check = "mypy --install-types --non-interactive {args:src/_ tests}" + +[tool.coverage.run] +source_pkgs = ["_", "tests"] +branch = true +parallel = true +omit = [ + "src/_/__about__.py", +] + +[tool.coverage.paths] +_ = ["src/_", "*/-/src/_"] +tests = ["tests", "*/-/tests"] + +[tool.coverage.report] +exclude_lines = [ + "no cov", + "if __name__ == .__main__.:", + "if TYPE_CHECKING:", +] diff --git a/-/src/_/__about__.py b/-/src/_/__about__.py new file mode 100644 index 0000000..2851601 --- /dev/null +++ b/-/src/_/__about__.py @@ -0,0 +1,4 @@ +# SPDX-FileCopyrightText: 2024-present Casey Schneider-Mizell +# +# SPDX-License-Identifier: MIT +__version__ = "0.0.1" diff --git a/-/src/_/__init__.py b/-/src/_/__init__.py new file mode 100644 index 0000000..832729e --- /dev/null +++ b/-/src/_/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2024-present Casey Schneider-Mizell +# +# SPDX-License-Identifier: MIT diff --git a/-/tests/__init__.py b/-/tests/__init__.py new file mode 100644 index 0000000..832729e --- /dev/null +++ b/-/tests/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2024-present Casey Schneider-Mizell +# +# SPDX-License-Identifier: MIT diff --git a/.gitignore b/.gitignore index 8b76f7d..1800b33 100644 --- a/.gitignore +++ b/.gitignore @@ -110,4 +110,4 @@ var/ *.orig *.sublime-workspace -docs/.quarto/ +docs/_site \ No newline at end of file diff --git a/LICENSE.license b/LICENSE.license deleted file mode 100644 index f49a4e1..0000000 --- a/LICENSE.license +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 075b254..0000000 --- a/docs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/.quarto/ diff --git a/docs/_quarto.yml b/docs/_quarto.yml deleted file mode 100644 index 1d812b9..0000000 --- a/docs/_quarto.yml +++ /dev/null @@ -1,91 +0,0 @@ -project: - type: website - -website: - title: "NGLui Documentation" - page-navigation: true - navbar: - left: - - href: index.qmd - text: About - - text: Tutorials - menu: - - tutorials/statebuilder.qmd - - tutorials/parser.qmd - - href: reference/index.qmd - text: Function Reference - tools: - - icon: github - text: Github - href: http://github.com/seung-lab/NeuroglancerAnnotationUI - -theme: - - flatly - -metadata-files: - - _sidebar.yml - -quartodoc: - style: 'pkgdown' - title: '' - sidebar: _sidebar.yml - dir: reference - out_index: _api_index.qmd - package: nglui - - sections: - - title: StateBuilder Functions - - subtitle: Layers - desc: Instantiating types of layers - contents: - - name: statebuilder.ImageLayerConfig - - name: statebuilder.SegmentationLayerConfig - children: embedded - - name: statebuilder.AnnotationLayerConfig - children: embedded - - subtitle: Mapping Rules - desc: Rules for mapping data to annotations - contents: - - statebuilder.PointMapper - - statebuilder.LineMapper - - statebuilder.SphereMapper - - statebuilder.BoundingBoxMapper - - statebuilder.SplitPointMapper - - subtitle: StateBuilder Classes - desc: Tools for data-generated neuroglancer state creation - contents: - - name: statebuilder.StateBuilder - children: embedded - - name: statebuilder.ChainedStateBuilder - children: embedded - - subtitle: Helpers - desc: Tools for common types of states - contents: - - statebuilder.helpers.from_client - - statebuilder.helpers.sort_dataframe_by_root_id - - statebuilder.helpers.make_line_statebuilder - - statebuilder.helpers.make_point_statebuilder - - statebuilder.helpers.make_pre_post_statebuilder - - statebuilder.helpers.make_state_url - - statebuilder.helpers.make_url_robust - - statebuilder.helpers.package_state - - statebuilder.helpers.make_synapse_neuroglancer_link - - statebuilder.helpers.make_neuron_neuroglancer_link - - title: Parser - - subtitle: Parser Tools - desc: Simple tools for parsing neuroglancer states - contents: - - parser.base.layer_names - - parser.base.image_layers - - parser.base.segmentation_layers - - parser.base.annotation_layers - - parser.base.tag_dictionary - - parser.base.get_layer - - parser.base.view_settings - - parser.base.get_selected_ids - - parser.base.point_annotations - - parser.base.line_annotations - - parser.base.sphere_annotations - - parser.base.group_annotations - - parser.base.extract_multicut - - parser.base.annotation_dataframe diff --git a/docs/_sidebar.yml b/docs/_sidebar.yml deleted file mode 100644 index 94d9c89..0000000 --- a/docs/_sidebar.yml +++ /dev/null @@ -1,54 +0,0 @@ -website: - sidebar: - - contents: - - reference/index.qmd - - contents: - - contents: - - reference/statebuilder.ImageLayerConfig.qmd - - reference/statebuilder.SegmentationLayerConfig.qmd - - reference/statebuilder.AnnotationLayerConfig.qmd - section: Layers - - contents: - - reference/statebuilder.PointMapper.qmd - - reference/statebuilder.LineMapper.qmd - - reference/statebuilder.SphereMapper.qmd - - reference/statebuilder.BoundingBoxMapper.qmd - - reference/statebuilder.SplitPointMapper.qmd - section: Mapping Rules - - contents: - - reference/statebuilder.StateBuilder.qmd - - reference/statebuilder.ChainedStateBuilder.qmd - section: StateBuilder Classes - - contents: - - reference/statebuilder.helpers.from_client.qmd - - reference/statebuilder.helpers.sort_dataframe_by_root_id.qmd - - reference/statebuilder.helpers.make_line_statebuilder.qmd - - reference/statebuilder.helpers.make_point_statebuilder.qmd - - reference/statebuilder.helpers.make_pre_post_statebuilder.qmd - - reference/statebuilder.helpers.make_state_url.qmd - - reference/statebuilder.helpers.make_url_robust.qmd - - reference/statebuilder.helpers.package_state.qmd - - reference/statebuilder.helpers.make_synapse_neuroglancer_link.qmd - - reference/statebuilder.helpers.make_neuron_neuroglancer_link.qmd - section: Helpers - section: StateBuilder Functions - - contents: - - contents: - - reference/parser.base.layer_names.qmd - - reference/parser.base.image_layers.qmd - - reference/parser.base.segmentation_layers.qmd - - reference/parser.base.annotation_layers.qmd - - reference/parser.base.tag_dictionary.qmd - - reference/parser.base.get_layer.qmd - - reference/parser.base.view_settings.qmd - - reference/parser.base.get_selected_ids.qmd - - reference/parser.base.point_annotations.qmd - - reference/parser.base.line_annotations.qmd - - reference/parser.base.sphere_annotations.qmd - - reference/parser.base.group_annotations.qmd - - reference/parser.base.extract_multicut.qmd - - reference/parser.base.annotation_dataframe.qmd - section: Parser Tools - section: Parser - id: reference - - id: dummy-sidebar diff --git a/docs/_site/about.html b/docs/_site/about.html deleted file mode 100644 index 968c43b..0000000 --- a/docs/_site/about.html +++ /dev/null @@ -1,381 +0,0 @@ - - - - - - - - - -NGLui Documentation - About - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- -
-
-

About

-
- - - -
- - - - -
- - -
- -

About this site

- - - -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/index.html b/docs/_site/index.html deleted file mode 100644 index aa23d0b..0000000 --- a/docs/_site/index.html +++ /dev/null @@ -1,382 +0,0 @@ - - - - - - - - - -NGLui Documentation - Docs - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- -
-
-

Docs

-
- - - -
- - - - -
- - -
- -

This is a Quarto website.

-

To learn more about Quarto websites visit https://quarto.org/docs/websites.

- - - -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/AnnotationLayerConfig.html b/docs/_site/reference/AnnotationLayerConfig.html deleted file mode 100644 index 7baecc0..0000000 --- a/docs/_site/reference/AnnotationLayerConfig.html +++ /dev/null @@ -1,433 +0,0 @@ - - - - - - - - - -NGLui Documentation – annotationlayerconfig - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

AnnotationLayerConfig

-

statebuilder.layers.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)

-

Configuration class for annotation layers

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
namestrLayer name. By default, ‘annos’None
colorstrHex color code with an initial #. By default, NoneNone
linked_segmentation_layerstrName of a linked segmentation layer for selected ids. By default, NoneNone
mapping_rules(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)One rule or a list of rules mapping data to annotations. By default, [][]
array_databoolIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.False
tagslistList of tags for the layer.None
activeboolIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).True
- - -
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/ChainedStateBuilder.html b/docs/_site/reference/ChainedStateBuilder.html deleted file mode 100644 index d9060c7..0000000 --- a/docs/_site/reference/ChainedStateBuilder.html +++ /dev/null @@ -1,419 +0,0 @@ - - - - - - - - - -NGLui Documentation – chainedstatebuilder - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

ChainedStateBuilder

-

statebuilder.statebuilder.ChainedStateBuilder(self, statebuilders)

-

Builds a collection of states that sequentially add annotations based on a sequence of dataframes.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statebuilderslistList of DataStateBuilders, in same order as dataframes will be passedrequired
-
-
-

Methods

- - - - - - - - - - - - - -
NameDescription
render_stateGenerate a single neuroglancer state by addatively applying an ordered collection of
-
-

render_state

-

statebuilder.statebuilder.ChainedStateBuilder.render_state(data_list=None, base_state=None, return_as='url', url_prefix=default_neuroglancer_base, link_text='Neuroglancer Link', target_site=None)

-

Generate a single neuroglancer state by addatively applying an ordered collection of dataframes to an collection of StateBuilder renders. Parameters data_list : Collection of DataFrame. The order must match the order of StateBuilders contained in the class on creation. base_state : JSON neuroglancer state (optional, default is None). Used as a base state for adding everything else to. return_as: [‘url’, ‘viewer’, ‘html’, ‘json’]. optional, default=‘url’. Sets how the state is returned. Note that if a viewer is returned, the state is not reset to default. url_prefix: string, optional (default is https://neuromancer-seung-import.appspot.com). Overrides the default neuroglancer url for url generation.

- - -
-
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/ImageLayerConfig.html b/docs/_site/reference/ImageLayerConfig.html deleted file mode 100644 index bb63bd4..0000000 --- a/docs/_site/reference/ImageLayerConfig.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - - - - - - -NGLui Documentation – imagelayerconfig - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

ImageLayerConfig

-

statebuilder.layers.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)

-

Image layer configuration class.

-

This provides the rules for setting up an image layer in neuroglancer.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
sourcestrCloudpath to an image sourcerequired
namestrName of the image layer. By default, ‘img’.None
activeboolIf True, makes the layer active in neuroglancer. Default is False.False
contrast_controlsboolIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.False
blackfloatIf contrast_controls is True, sets the default black level. Default is 0.0.0.0
whitefloatIf contrast_controls is True, sets the default white level. Default is 1.0.1.0
- - -
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/SegmentationLayerConfig.html b/docs/_site/reference/SegmentationLayerConfig.html deleted file mode 100644 index 735f708..0000000 --- a/docs/_site/reference/SegmentationLayerConfig.html +++ /dev/null @@ -1,536 +0,0 @@ - - - - - - - - - -NGLui Documentation – segmentationlayerconfig - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

SegmentationLayerConfig

-

statebuilder.layers.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)

-

Configuration class for segmentation layers

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
sourcestrSegmentation sourcerequired
name(str, optional)Layer name.None
selected_ids_columnstr or list-like, optional.Column name (or list of column names) to use for selected ids.None
fixed_idslist-like, optional.List of root ids to select directly.None
fixed_id_colorslist-like, optional.List of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.None
color_columnstr, optional.# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with aNone
activebool, optional.If True, makes the layer selected. Default is False.False
alpha_selectedOpacity of selected segmentations in the image layer. Optional, default is 0.3.0.3
alpha_3dOpacity of meshes. Optional, default is 1.1
alpha_unselectedOpacity of unselected segments. Optional, default is 0.0
split_point_mapIf not None, provides an object to map the dataframe input to multicut points. Default is None.None
view_kwsdict, optional.Keyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.None
timestampfloat or datetime, optional.Timestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.None
-
-
-

Methods

- - - - - - - - - - - - - -
NameDescription
add_selection_mapAdd rules for selecting active segment ids and their colors
-
-

add_selection_map

-

statebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)

-

Add rules for selecting active segment ids and their colors

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
selected_ids_columnstrDataframe column to use for adding selected segment ids to the segmentation layer, by default NoneNone
fixed_idsint or listAdd one or more segment ids to be active, independent of the data, by default NoneNone
fixed_id_colorslistAdd a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default NoneNone
color_columnstrDataframe column to use for adding selected segment colors, by default NoneNone
- - -
-
-
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/get_object.html b/docs/_site/reference/get_object.html deleted file mode 100644 index d12aabd..0000000 --- a/docs/_site/reference/get_object.html +++ /dev/null @@ -1,481 +0,0 @@ - - - - - - - - - -NGLui Documentation – get_object - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

get_object

-

get_object(path, object_name=None, parser='numpy', load_aliases=True, dynamic=False, loader=None)

-

Fetch a griffe object.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
pathstrAn import path to the object. This should have the form path.to.module:object. For example, quartodoc:get_object or quartodoc:MdRenderer.render.required
object_name‘str | None’(Deprecated). A function name.None
parserstrA docstring parser to use.'numpy'
load_aliasesFor aliases that were imported from other modules, should we load that module?True
dynamicWhether to dynamically import object. Useful if docstring is not hard-coded, but was set on object by running python code.False
-
-
-

See Also

-

preview: print a user-friendly preview of a griffe object.

-
-
-

Examples

-
>>> get_function("quartodoc", "get_function")
-<Function('get_function', ...
-
-
-

Returns

- - - - - - - - - - - - - -
TypeDescription
griffe.dataclasses.griffe.dataclasses.Objectabc
- - -
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/index.html b/docs/_site/reference/index.html deleted file mode 100644 index bf857c4..0000000 --- a/docs/_site/reference/index.html +++ /dev/null @@ -1,874 +0,0 @@ - - - - - - - - - -NGLui Documentation – index - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

Function Intro

-

This site provides basic documentation for the functions in NGLui. Please see the tutorials for more information about how to use them.

-

Note that nglui spans two public submodules responsible for different tasks.

-
    -
  • StateBuilder handles data-driven Neuroglancer state generation (hence the package name).
  • -
  • Parser extracts information from Neuroglancer states, as represented by dictionaries.
  • -
-
-
-
-

-
-

StateBuilder Functions

-
-

Layers

-

Instantiating types of layers

- - - - - - - - - - - - - - - -
statebuilder.ImageLayerConfigImage layer configuration class.
statebuilder.SegmentationLayerConfigConfiguration class for segmentation layers
statebuilder.AnnotationLayerConfigConfiguration class for annotation layers
-
-
-

Mapping Rules

-

Rules for mapping data to annotations

- - - - - - - - - - - - - - - - - - - - - - - -
statebuilder.PointMapperSets rules to map dataframes to point annotations
statebuilder.LineMapperSets rules to map dataframes to line annotations
statebuilder.SphereMapperSets rules to map dataframes to sphere annotations
statebuilder.BoundingBoxMapperSets rules to map dataframes to bounding box annotations
statebuilder.SplitPointMapperMapper to create split points in a segmentation layer.
-
-
-

StateBuilder Classes

-

Tools for data-generated neuroglancer state creation

- - - - - - - - - - - -
statebuilder.StateBuilderA class for schematic mapping data frames into neuroglancer states.
statebuilder.ChainedStateBuilderBuilds a collection of states that sequentially add annotations based on a sequence of dataframes.
-
-
-

Helpers

-

Tools for common types of states

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
statebuilder.helpers.from_clientGenerate basic image and segmentation layers from a FrameworkClient
statebuilder.helpers.sort_dataframe_by_root_idSort a dataframe so that rows belonging to the same root id are together, ordered by how many times the root id appears.
statebuilder.helpers.make_line_statebuilderGenerate a state builder that puts points on a single column with a linked segmentaton id
statebuilder.helpers.make_point_statebuilderGenerate a state builder that puts points on a single column with a linked segmentaton id
statebuilder.helpers.make_pre_post_statebuilderFunction to generate ChainedStateBuilder with optional pre and post synaptic
statebuilder.helpers.make_state_urlGenerate a url from a neuroglancer state via a state server.
statebuilder.helpers.make_url_robustGenerate a url from a neuroglancer state. If too long, return through state server,
statebuilder.helpers.package_stateAutomate creating a state from a statebuilder and
statebuilder.helpers.make_synapse_neuroglancer_linkGenerate a neuroglancer link from a synapse dataframe as returned from CAVEclient.materialize.synapse_query.
statebuilder.helpers.make_neuron_neuroglancer_linkfunction to create a neuroglancer link view of a neuron, optionally including inputs and outputs
-
-
-
-

Parser

-
-

Parser Tools

-

Simple tools for parsing neuroglancer states

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
parser.base.layer_namesGet all layer names in the state
parser.base.image_layersGet all image layer names in the state
parser.base.segmentation_layersGet all segmentation layer names in the state
parser.base.annotation_layersGet all annotation layer names in the state
parser.base.tag_dictionaryGet the tag id to string dictionary for a layer
parser.base.get_layerGets the contents of the layer based on the layer name.
parser.base.view_settingsGet all data about the view state in neuroglancer: position,
parser.base.get_selected_idsGet a list of selected ids in a segmentation layer
parser.base.point_annotationsGet all point annotation points and other info from a layer.
parser.base.line_annotationsGet all line annotation points and other info from a layer.
parser.base.sphere_annotationsGet all sphere annotation points and other info from a layer.
parser.base.group_annotationsAll group annotations and their associated points
parser.base.extract_multicutExtract information entered into the multicut graph operation
parser.base.annotation_dataframeReturn all annotations across all annotation layers in the state.
- - -
-
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/layers.AnnotationLayerConfig.html b/docs/_site/reference/layers.AnnotationLayerConfig.html deleted file mode 100644 index e5d0bd1..0000000 --- a/docs/_site/reference/layers.AnnotationLayerConfig.html +++ /dev/null @@ -1,433 +0,0 @@ - - - - - - - - - -NGLui Documentation – layers.annotationlayerconfig - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

layers.AnnotationLayerConfig

-

statebuilder.layers.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)

-

Configuration class for annotation layers

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
namestrLayer name. By default, ‘annos’None
colorstrHex color code with an initial #. By default, NoneNone
linked_segmentation_layerstrName of a linked segmentation layer for selected ids. By default, NoneNone
mapping_rules(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)One rule or a list of rules mapping data to annotations. By default, [][]
array_databoolIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.False
tagslistList of tags for the layer.None
activeboolIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).True
- - -
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/layers.ImageLayerConfig.html b/docs/_site/reference/layers.ImageLayerConfig.html deleted file mode 100644 index 1cbc0bd..0000000 --- a/docs/_site/reference/layers.ImageLayerConfig.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - - - - - - -NGLui Documentation – layers.imagelayerconfig - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

layers.ImageLayerConfig

-

statebuilder.layers.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)

-

Image layer configuration class.

-

This provides the rules for setting up an image layer in neuroglancer.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
sourcestrCloudpath to an image sourcerequired
namestrName of the image layer. By default, ‘img’.None
activeboolIf True, makes the layer active in neuroglancer. Default is False.False
contrast_controlsboolIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.False
blackfloatIf contrast_controls is True, sets the default black level. Default is 0.0.0.0
whitefloatIf contrast_controls is True, sets the default white level. Default is 1.0.1.0
- - -
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/layers.SegmentationLayerConfig.html b/docs/_site/reference/layers.SegmentationLayerConfig.html deleted file mode 100644 index b5db61e..0000000 --- a/docs/_site/reference/layers.SegmentationLayerConfig.html +++ /dev/null @@ -1,536 +0,0 @@ - - - - - - - - - -NGLui Documentation – layers.segmentationlayerconfig - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

layers.SegmentationLayerConfig

-

statebuilder.layers.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)

-

Configuration class for segmentation layers

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
sourcestrSegmentation sourcerequired
name(str, optional)Layer name.None
selected_ids_columnstr or list-like, optional.Column name (or list of column names) to use for selected ids.None
fixed_idslist-like, optional.List of root ids to select directly.None
fixed_id_colorslist-like, optional.List of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.None
color_columnstr, optional.# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with aNone
activebool, optional.If True, makes the layer selected. Default is False.False
alpha_selectedOpacity of selected segmentations in the image layer. Optional, default is 0.3.0.3
alpha_3dOpacity of meshes. Optional, default is 1.1
alpha_unselectedOpacity of unselected segments. Optional, default is 0.0
split_point_mapIf not None, provides an object to map the dataframe input to multicut points. Default is None.None
view_kwsdict, optional.Keyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.None
timestampfloat or datetime, optional.Timestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.None
-
-
-

Methods

- - - - - - - - - - - - - -
NameDescription
add_selection_mapAdd rules for selecting active segment ids and their colors
-
-

add_selection_map

-

statebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)

-

Add rules for selecting active segment ids and their colors

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
selected_ids_columnstrDataframe column to use for adding selected segment ids to the segmentation layer, by default NoneNone
fixed_idsint or listAdd one or more segment ids to be active, independent of the data, by default NoneNone
fixed_id_colorslistAdd a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default NoneNone
color_columnstrDataframe column to use for adding selected segment colors, by default NoneNone
- - -
-
-
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/layers.html b/docs/_site/reference/layers.html deleted file mode 100644 index e4bd904..0000000 --- a/docs/_site/reference/layers.html +++ /dev/null @@ -1,756 +0,0 @@ - - - - - - - - - -NGLui Documentation – layers - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

layers

-

statebuilder.layers

-
-

Classes

- - - - - - - - - - - - - - - - - - - - - - - - - -
NameDescription
AnnotationLayerConfigConfiguration class for annotation layers
ImageLayerConfigImage layer configuration class.
LayerConfigBaseBase class for configuring layers
SegmentationLayerConfigConfiguration class for segmentation layers
-
-
-

AnnotationLayerConfig

-

statebuilder.layers.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)

-

Configuration class for annotation layers

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
namestrLayer name. By default, ‘annos’None
colorstrHex color code with an initial #. By default, NoneNone
linked_segmentation_layerstrName of a linked segmentation layer for selected ids. By default, NoneNone
mapping_rules(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)One rule or a list of rules mapping data to annotations. By default, [][]
array_databoolIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.False
tagslistList of tags for the layer.None
activeboolIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).True
-
-
-
-

ImageLayerConfig

-

statebuilder.layers.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)

-

Image layer configuration class.

-

This provides the rules for setting up an image layer in neuroglancer.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
sourcestrCloudpath to an image sourcerequired
namestrName of the image layer. By default, ‘img’.None
activeboolIf True, makes the layer active in neuroglancer. Default is False.False
contrast_controlsboolIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.False
blackfloatIf contrast_controls is True, sets the default black level. Default is 0.0.0.0
whitefloatIf contrast_controls is True, sets the default white level. Default is 1.0.1.0
-
-
-
-

LayerConfigBase

-

statebuilder.layers.LayerConfigBase(self, name, type, source, color, active)

-

Base class for configuring layers

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
namestrLayer name for reference and displayrequired
typestrLayer type. Usually handled by the subclassrequired
sourcestrDatasource for the layerrequired
colorstrHex string (with starting hash).required
active(bool)If True, becomes a selected layer.required
-
-
-
-

SegmentationLayerConfig

-

statebuilder.layers.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)

-

Configuration class for segmentation layers

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
sourcestrSegmentation sourcerequired
name(str, optional)Layer name.None
selected_ids_columnstr or list-like, optional.Column name (or list of column names) to use for selected ids.None
fixed_idslist-like, optional.List of root ids to select directly.None
fixed_id_colorslist-like, optional.List of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.None
color_columnstr, optional.# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with aNone
activebool, optional.If True, makes the layer selected. Default is False.False
alpha_selectedOpacity of selected segmentations in the image layer. Optional, default is 0.3.0.3
alpha_3dOpacity of meshes. Optional, default is 1.1
alpha_unselectedOpacity of unselected segments. Optional, default is 0.0
split_point_mapIf not None, provides an object to map the dataframe input to multicut points. Default is None.None
view_kwsdict, optional.Keyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.None
timestampfloat or datetime, optional.Timestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.None
-
-
-

Methods

- - - - - - - - - - - - - -
NameDescription
add_selection_mapAdd rules for selecting active segment ids and their colors
-
-

add_selection_map

-

statebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)

-

Add rules for selecting active segment ids and their colors

-
-
Parameters
- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
selected_ids_columnstrDataframe column to use for adding selected segment ids to the segmentation layer, by default NoneNone
fixed_idsint or listAdd one or more segment ids to be active, independent of the data, by default NoneNone
fixed_id_colorslistAdd a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default NoneNone
color_columnstrDataframe column to use for adding selected segment colors, by default NoneNone
- - -
-
-
-
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/nglui.statebuilder.layers.AnnotationLayerConfig.html b/docs/_site/reference/nglui.statebuilder.layers.AnnotationLayerConfig.html deleted file mode 100644 index 7ab5378..0000000 --- a/docs/_site/reference/nglui.statebuilder.layers.AnnotationLayerConfig.html +++ /dev/null @@ -1,433 +0,0 @@ - - - - - - - - - -NGLui Documentation – nglui.statebuilder.layers.annotationlayerconfig - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

AnnotationLayerConfig

-

statebuilder.layers.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)

-

Configuration class for annotation layers

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
namestrLayer name. By default, ‘annos’None
colorstrHex color code with an initial #. By default, NoneNone
linked_segmentation_layerstrName of a linked segmentation layer for selected ids. By default, NoneNone
mapping_rules(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)One rule or a list of rules mapping data to annotations. By default, [][]
array_databoolIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.False
tagslistList of tags for the layer.None
activeboolIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).True
- - -
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/nglui.statebuilder.layers.ImageLayerConfig.html b/docs/_site/reference/nglui.statebuilder.layers.ImageLayerConfig.html deleted file mode 100644 index 39539cf..0000000 --- a/docs/_site/reference/nglui.statebuilder.layers.ImageLayerConfig.html +++ /dev/null @@ -1,428 +0,0 @@ - - - - - - - - - -NGLui Documentation – nglui.statebuilder.layers.imagelayerconfig - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

ImageLayerConfig

-

statebuilder.layers.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)

-

Image layer configuration class.

-

This provides the rules for setting up an image layer in neuroglancer.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
sourcestrCloudpath to an image sourcerequired
namestrName of the image layer. By default, ‘img’.None
activeboolIf True, makes the layer active in neuroglancer. Default is False.False
contrast_controlsboolIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.False
blackfloatIf contrast_controls is True, sets the default black level. Default is 0.0.0.0
whitefloatIf contrast_controls is True, sets the default white level. Default is 1.0.1.0
- - -
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/nglui.statebuilder.layers.LayerConfigBase.html b/docs/_site/reference/nglui.statebuilder.layers.LayerConfigBase.html deleted file mode 100644 index 011e923..0000000 --- a/docs/_site/reference/nglui.statebuilder.layers.LayerConfigBase.html +++ /dev/null @@ -1,421 +0,0 @@ - - - - - - - - - -NGLui Documentation – nglui.statebuilder.layers.layerconfigbase - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

LayerConfigBase

-

statebuilder.layers.LayerConfigBase(self, name, type, source, color, active)

-

Base class for configuring layers

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
namestrLayer name for reference and displayrequired
typestrLayer type. Usually handled by the subclassrequired
sourcestrDatasource for the layerrequired
colorstrHex string (with starting hash).required
active(bool)If True, becomes a selected layer.required
- - -
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/nglui.statebuilder.layers.SegmentationLayerConfig.html b/docs/_site/reference/nglui.statebuilder.layers.SegmentationLayerConfig.html deleted file mode 100644 index a68f795..0000000 --- a/docs/_site/reference/nglui.statebuilder.layers.SegmentationLayerConfig.html +++ /dev/null @@ -1,536 +0,0 @@ - - - - - - - - - -NGLui Documentation – nglui.statebuilder.layers.segmentationlayerconfig - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

SegmentationLayerConfig

-

statebuilder.layers.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)

-

Configuration class for segmentation layers

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
sourcestrSegmentation sourcerequired
name(str, optional)Layer name.None
selected_ids_columnstr or list-like, optional.Column name (or list of column names) to use for selected ids.None
fixed_idslist-like, optional.List of root ids to select directly.None
fixed_id_colorslist-like, optional.List of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.None
color_columnstr, optional.# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with aNone
activebool, optional.If True, makes the layer selected. Default is False.False
alpha_selectedOpacity of selected segmentations in the image layer. Optional, default is 0.3.0.3
alpha_3dOpacity of meshes. Optional, default is 1.1
alpha_unselectedOpacity of unselected segments. Optional, default is 0.0
split_point_mapIf not None, provides an object to map the dataframe input to multicut points. Default is None.None
view_kwsdict, optional.Keyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.None
timestampfloat or datetime, optional.Timestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.None
-
-
-

Methods

- - - - - - - - - - - - - -
NameDescription
add_selection_mapAdd rules for selecting active segment ids and their colors
-
-

add_selection_map

-

statebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)

-

Add rules for selecting active segment ids and their colors

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
selected_ids_columnstrDataframe column to use for adding selected segment ids to the segmentation layer, by default NoneNone
fixed_idsint or listAdd one or more segment ids to be active, independent of the data, by default NoneNone
fixed_id_colorslistAdd a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default NoneNone
color_columnstrDataframe column to use for adding selected segment colors, by default NoneNone
- - -
-
-
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/nglui.statebuilder.statebuilder.StateBuilder.initialize_state.html b/docs/_site/reference/nglui.statebuilder.statebuilder.StateBuilder.initialize_state.html deleted file mode 100644 index 7045289..0000000 --- a/docs/_site/reference/nglui.statebuilder.statebuilder.StateBuilder.initialize_state.html +++ /dev/null @@ -1,397 +0,0 @@ - - - - - - - - - -NGLui Documentation – nglui.statebuilder.statebuilder.statebuilder.initialize_state - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

initialize_state

-

statebuilder.statebuilder.StateBuilder.initialize_state(base_state=None, target_site=None)

-

Generate a new Neuroglancer state with layers as needed for the schema.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
base_statestrOptional initial state to build on, described by its JSON. By default None.None
- - -
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.html b/docs/_site/reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.html deleted file mode 100644 index d1606f0..0000000 --- a/docs/_site/reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.html +++ /dev/null @@ -1,442 +0,0 @@ - - - - - - - - - -NGLui Documentation – nglui.statebuilder.statebuilder.statebuilder.render_state - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

render_state

-

statebuilder.statebuilder.StateBuilder.render_state(data=None, base_state=None, return_as='url', url_prefix=None, link_text='Neuroglancer Link', target_site=None)

-

Build a Neuroglancer state out of a DataFrame.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
datapandas.pandas.DataFrameDataFrame to use as a point source. By default None, for which it will return only the base_state and any fixed values.None
base_statedictInitial state to build on, expressed as Neuroglancer JSON. By default NoneNone
return_as[url, nglui.statebuilder.statebuilder.StateBuilder.viewer, html, json, dict, shared]Choice of output types. Note that if a viewer is returned, the state is not reset. url : Returns the raw url describing the state viewer : Returns an EasyViewer object holding the state information html : Returns an HTML link to the url, useful for notebooks. json : Returns a JSON string describing the state. dict : Returns a dict version of the JSON state. By default ‘url’'url'
url_prefixstrNeuroglancer URL prefix to use. By default None, for which it will open with the class default.None
link_textstrText to use for the link when returning as html, by default ‘Neuroglancer Link’'Neuroglancer Link'
-
-
-

Returns

- ---- - - - - - - - - - - - - -
TypeDescription
string or neuroglancer.neuroglancer.ViewerA link to or viewer for a Neuroglancer state with layers, annotations, and selected objects determined by the data.
- - -
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.annotation_dataframe.html b/docs/_site/reference/parser.base.annotation_dataframe.html deleted file mode 100644 index 7a6b2e1..0000000 --- a/docs/_site/reference/parser.base.annotation_dataframe.html +++ /dev/null @@ -1,726 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.annotation_dataframe - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.annotation_dataframe

-

parser.base.annotation_dataframe(state)

-

Return all annotations across all annotation layers in the state.

-
-

Parameters

- - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictNeuroglancer state dictionaryrequired
-
-
-

Returns

- ---- - - - - - - - - - - - - -
TypeDescription
pandas.pandas.DataFrameDataframe with columns layer, anno_type, point, pointB, linked_segmentation, tags, anno_id, group_id, description.
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.annotation_layers.html b/docs/_site/reference/parser.base.annotation_layers.html deleted file mode 100644 index ac3e879..0000000 --- a/docs/_site/reference/parser.base.annotation_layers.html +++ /dev/null @@ -1,726 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.annotation_layers - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.annotation_layers

-

parser.base.annotation_layers(state)

-

Get all annotation layer names in the state

-
-

Parameters

- - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictNeuroglancer state as a JSON dictrequired
-
-
-

Returns

- - - - - - - - - - - - - -
TypeDescription
listList of layer names
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.extract_multicut.html b/docs/_site/reference/parser.base.extract_multicut.html deleted file mode 100644 index caef81a..0000000 --- a/docs/_site/reference/parser.base.extract_multicut.html +++ /dev/null @@ -1,754 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.extract_multicut - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.extract_multicut

-

parser.base.extract_multicut(state, seg_layer=None)

-

Extract information entered into the multicut graph operation

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictNeuroglancer staterequired
seg_layerstrName of a segmentation layer or None. If None, the function will check how many segmentation layers there are and, if only one exits, choose it. If more than one segmentation layer is present, it errors. By default NoneNone
-
-
-

Returns

- ---- - - - - - - - - - - - - - - - - - - - - - - - - -
TypeDescription
numpy.numpy.arrayNx3 array of points selected
numpy.numpy.arrayN array with ‘source’ or ‘sink’, depending on which side the point is on.
numpy.numpy.arrayN array with selected supervoxel. If only points are selected (e.g. via clicking on the mesh), the value will be NaN.
intRoot id of the object to split
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.get_layer.html b/docs/_site/reference/parser.base.get_layer.html deleted file mode 100644 index 6cdd478..0000000 --- a/docs/_site/reference/parser.base.get_layer.html +++ /dev/null @@ -1,738 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.get_layer - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.get_layer

-

parser.base.get_layer(state, layer_name)

-

Gets the contents of the layer based on the layer name.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictNeuroglancer state as a JSON dictrequired
layer_namestrName of layerrequired
-
-
-

Returns

- - - - - - - - - - - - - -
TypeDescription
dictLayer data contents
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.get_selected_ids.html b/docs/_site/reference/parser.base.get_selected_ids.html deleted file mode 100644 index 700d6b5..0000000 --- a/docs/_site/reference/parser.base.get_selected_ids.html +++ /dev/null @@ -1,738 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.get_selected_ids - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.get_selected_ids

-

parser.base.get_selected_ids(state, layer=None)

-

Get a list of selected ids in a segmentation layer

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictState dictrequired
layerstrSegmentation layer name, if needed. If None and only one segmentation layer is present, default to it. By default NoneNone
-
-
-

Returns

- - - - - - - - - - - - - -
TypeDescription
listList of root ids.
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.group_annotations.html b/docs/_site/reference/parser.base.group_annotations.html deleted file mode 100644 index 48d6efe..0000000 --- a/docs/_site/reference/parser.base.group_annotations.html +++ /dev/null @@ -1,776 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.group_annotations - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.group_annotations

-

parser.base.group_annotations(state, layer_name, description=False, linked_segmentations=False, tags=False)

-

All group annotations and their associated points

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictNeuroglancer state as JSON dictrequired
layer_namestrAnnotation layer namerequired
descriptionboolIf True, also returns descriptions as well. By default FalseFalse
linked_segmentationsboolIf True, also returns list of linked segmentations, by default FalseFalse
tagsboolIf True, also returns list of tags, by default FalseFalse
-
-
-

Returns

- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeDescription
listList of N 3-element points
listList of N id strings for groups.
listList of N strings (or None), only returned if description=True.
listList of N lists of object ids. Only returned if linked_segmentations=True.
listList of N lists of tag ids. Only returned if tags=True.
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.image_layers.html b/docs/_site/reference/parser.base.image_layers.html deleted file mode 100644 index aca32ae..0000000 --- a/docs/_site/reference/parser.base.image_layers.html +++ /dev/null @@ -1,726 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.image_layers - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.image_layers

-

parser.base.image_layers(state)

-

Get all image layer names in the state

-
-

Parameters

- - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictNeuroglancer state as a JSON dictrequired
-
-
-

Returns

- - - - - - - - - - - - - -
TypeDescription
listList of layer names
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.layer_names.html b/docs/_site/reference/parser.base.layer_names.html deleted file mode 100644 index eefd224..0000000 --- a/docs/_site/reference/parser.base.layer_names.html +++ /dev/null @@ -1,726 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.layer_names - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.layer_names

-

parser.base.layer_names(state)

-

Get all layer names in the state

-
-

Parameters

- - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictNeuroglancer state as a JSON dictrequired
-
-
-

Returns

- - - - - - - - - - - - - -
TypeDescription
listList of layer names
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.line_annotations.html b/docs/_site/reference/parser.base.line_annotations.html deleted file mode 100644 index 2cf3015..0000000 --- a/docs/_site/reference/parser.base.line_annotations.html +++ /dev/null @@ -1,780 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.line_annotations - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.line_annotations

-

parser.base.line_annotations(state, layer_name, description=False, linked_segmentations=False, tags=False, group=False)

-

Get all line annotation points and other info from a layer.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictNeuroglancer state as JSON dictrequired
layer_namestrLayer namerequired
descriptionboolIf True, also returns descriptions as well. By default FalseFalse
linked_segmentationsboolIf True, also returns list of linked segmentations, by default FalseFalse
tagsboolIf True, also returns list of tags, by default FalseFalse
-
-
-

Returns

- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeDescription
listList of N 3-element points (as list) of the first point in each line.
listList of N 3-element points (as list) of the second point in each line.
listList of N strings (or None), only returned if description=True.
listList of N lists of object ids. Only returned if linked_segmentations=True.
listList of N lists of tag ids. Only returned if tags=True.
listList of group ids (as string) or None for annotations. Only returned if group=True
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.point_annotations.html b/docs/_site/reference/parser.base.point_annotations.html deleted file mode 100644 index 8c57d22..0000000 --- a/docs/_site/reference/parser.base.point_annotations.html +++ /dev/null @@ -1,776 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.point_annotations - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.point_annotations

-

parser.base.point_annotations(state, layer_name, description=False, linked_segmentations=False, tags=False, group=False)

-

Get all point annotation points and other info from a layer.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictNeuroglancer state as JSON dictrequired
layer_namestrLayer namerequired
descriptionboolIf True, also returns descriptions as well. By default FalseFalse
linked_segmentationsboolIf True, also returns list of linked segmentations, by default FalseFalse
tagsboolIf True, also returns list of tags, by default FalseFalse
-
-
-

Returns

- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeDescription
listList of N 3-element points (as list)
listList of N strings (or None), only returned if description=True.
listList of N lists of object ids. Only returned if linked_segmentations=True.
listList of N lists of tag ids. Only returned if tags=True.
listList of group ids (as string) or None for annotations. Only returned if group=True
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.segmentation_layers.html b/docs/_site/reference/parser.base.segmentation_layers.html deleted file mode 100644 index f19a908..0000000 --- a/docs/_site/reference/parser.base.segmentation_layers.html +++ /dev/null @@ -1,726 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.segmentation_layers - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.segmentation_layers

-

parser.base.segmentation_layers(state)

-

Get all segmentation layer names in the state

-
-

Parameters

- - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictNeuroglancer state as a JSON dictrequired
-
-
-

Returns

- - - - - - - - - - - - - -
TypeDescription
listList of layer names
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.sphere_annotations.html b/docs/_site/reference/parser.base.sphere_annotations.html deleted file mode 100644 index d8ab7d1..0000000 --- a/docs/_site/reference/parser.base.sphere_annotations.html +++ /dev/null @@ -1,780 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.sphere_annotations - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.sphere_annotations

-

parser.base.sphere_annotations(state, layer_name, description=False, linked_segmentations=False, tags=False, group=False)

-

Get all sphere annotation points and other info from a layer.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictNeuroglancer state as JSON dictrequired
layer_namestrLayer namerequired
descriptionboolIf True, also returns descriptions as well. By default FalseFalse
linked_segmentationsboolIf True, also returns list of linked segmentations, by default FalseFalse
tagsboolIf True, also returns list of tags, by default FalseFalse
-
-
-

Returns

- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeDescription
listList of N 3-element center points (as list)
listList of N 3-element radii for each axis of the ellipsoid.
listList of N strings (or None), only returned if description=True.
listList of N lists of object ids. Only returned if linked_segmentations=True.
listList of N lists of tag ids. Only returned if tags=True.
listList of group ids (as string) or None for annotations. Only returned if group=True
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.tag_dictionary.html b/docs/_site/reference/parser.base.tag_dictionary.html deleted file mode 100644 index 4c858d4..0000000 --- a/docs/_site/reference/parser.base.tag_dictionary.html +++ /dev/null @@ -1,732 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.tag_dictionary - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.tag_dictionary

-

parser.base.tag_dictionary(state, layer_name)

-

Get the tag id to string dictionary for a layer

-
-

Parameters

- - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictrequired
layer_name[type][description]required
-
-
-

Returns

- - - - - - - - - - - - - -
TypeDescription
[type][description]
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/parser.base.view_settings.html b/docs/_site/reference/parser.base.view_settings.html deleted file mode 100644 index 2c68a62..0000000 --- a/docs/_site/reference/parser.base.view_settings.html +++ /dev/null @@ -1,730 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser.base.view_settings - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

parser.base.view_settings

-

parser.base.view_settings(state)

-

Get all data about the view state in neuroglancer: position, image zoom, orientation and zoom of the 3d view, and voxel size.

-
-

Parameters

- - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statedictNeuroglancer state as JSON dictrequired
-
-
-

Returns

- ---- - - - - - - - - - - - - -
TypeDescription
dictDictionary with keys: position, zoomFactor, perspectiveOrientation, perspectiveZoom, and voxelSize
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/preview.html b/docs/_site/reference/preview.html deleted file mode 100644 index dd6eed7..0000000 --- a/docs/_site/reference/preview.html +++ /dev/null @@ -1,413 +0,0 @@ - - - - - - - - - -NGLui Documentation – preview - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

preview

-

preview(ast, max_depth=999, compact=False, as_string=False)

-

Print a friendly representation of a griffe object (e.g. function, docstring)

-
-

Examples

-
>>> from quartodoc import get_object
->>> obj = get_object("quartodoc", "get_object")
-
>>> preview(obj.docstring.parsed)
- ...
-
>>> preview(obj)
- ...
- - -
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.AnnotationLayerConfig.html b/docs/_site/reference/statebuilder.AnnotationLayerConfig.html deleted file mode 100644 index c0a5c59..0000000 --- a/docs/_site/reference/statebuilder.AnnotationLayerConfig.html +++ /dev/null @@ -1,751 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.annotationlayerconfig - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.AnnotationLayerConfig

-

statebuilder.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)

-

Configuration class for annotation layers

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
namestrLayer name. By default, ‘annos’None
colorstrHex color code with an initial #. By default, NoneNone
linked_segmentation_layerstrName of a linked segmentation layer for selected ids. By default, NoneNone
mapping_rules(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)One rule or a list of rules mapping data to annotations. By default, [][]
array_databoolIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.False
tagslistList of tags for the layer.None
activeboolIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).True
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.BoundingBoxMapper.html b/docs/_site/reference/statebuilder.BoundingBoxMapper.html deleted file mode 100644 index bf22d53..0000000 --- a/docs/_site/reference/statebuilder.BoundingBoxMapper.html +++ /dev/null @@ -1,769 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.boundingboxmapper - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.BoundingBoxMapper

-

statebuilder.BoundingBoxMapper(self, point_column_a=None, point_column_b=None, description_column=None, linked_segmentation_column=None, tag_column=None, group_column=None, gather_linked_segmentations=True, share_linked_segmentations=False, set_position=True, multipoint=False, collapse_groups=False, split_positions=False, mapping_set=None)

-

Sets rules to map dataframes to bounding box annotations

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
point_column_astrColumn name with 3d position data for the first point of the bounding box. Must be set if array_data is False (the default)None
point_column_bstrColumn name with 3d position data for the second point of the bounding box. Must be set if array_data is False (the default)None
description_columnstrColumn name with string data for annotation descriptionsNone
linked_segmentation_columnstrColumn name for root ids to link to annotationsNone
tag_columnstrColumn name for categorical tag data. Tags must match those set in the annotation layer.None
group_columnstrColumn name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation.None
set_positionboolIf set to True, moves the position to center on the first point in the data (using point_column_a).True
multipointIf True, permits multiple points in a given row, sharing data in other columns. Each point row must have the same number of points. Default is False.False
collapse_groupsIf True, groups are toggled closed in the annotation view.False
mapping_setIf set, assumes data is passed as a dictionary and uses this string to as the key for the data to use.None
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.ChainedStateBuilder.html b/docs/_site/reference/statebuilder.ChainedStateBuilder.html deleted file mode 100644 index b319ea5..0000000 --- a/docs/_site/reference/statebuilder.ChainedStateBuilder.html +++ /dev/null @@ -1,715 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.chainedstatebuilder - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.ChainedStateBuilder

-

statebuilder.ChainedStateBuilder(self, statebuilders)

-

Builds a collection of states that sequentially add annotations based on a sequence of dataframes.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
statebuilderslistList of DataStateBuilders, in same order as dataframes will be passedrequired
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.ImageLayerConfig.html b/docs/_site/reference/statebuilder.ImageLayerConfig.html deleted file mode 100644 index ed6d1ff..0000000 --- a/docs/_site/reference/statebuilder.ImageLayerConfig.html +++ /dev/null @@ -1,746 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.imagelayerconfig - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.ImageLayerConfig

-

statebuilder.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)

-

Image layer configuration class.

-

This provides the rules for setting up an image layer in neuroglancer.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
sourcestrCloudpath to an image sourcerequired
namestrName of the image layer. By default, ‘img’.None
activeboolIf True, makes the layer active in neuroglancer. Default is False.False
contrast_controlsboolIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.False
blackfloatIf contrast_controls is True, sets the default black level. Default is 0.0.0.0
whitefloatIf contrast_controls is True, sets the default white level. Default is 1.0.1.0
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.LineMapper.html b/docs/_site/reference/statebuilder.LineMapper.html deleted file mode 100644 index 80e4ffa..0000000 --- a/docs/_site/reference/statebuilder.LineMapper.html +++ /dev/null @@ -1,769 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.linemapper - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.LineMapper

-

statebuilder.LineMapper(self, point_column_a=None, point_column_b=None, description_column=None, linked_segmentation_column=None, tag_column=None, group_column=None, gather_linked_segmentations=True, share_linked_segmentations=False, set_position=True, multipoint=False, collapse_groups=False, split_positions=False, mapping_set=None)

-

Sets rules to map dataframes to line annotations

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
point_column_astrColumn name with 3d position data for the first point of the line. Must be set if array_data is False (the default)None
point_column_bstrColumn name with 3d position data for the first point of the line. Must be set if array_data is False (the default)None
description_columnstrColumn name with string data for annotation descriptionsNone
linked_segmentation_columnstrColumn name for root ids to link to annotationsNone
tag_columnstrColumn name for categorical tag data. Tags must match those set in the annotation layer.None
group_columnstrColumn name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation.None
set_positionboolIf set to True, moves the position to center on the first point in the data (using point_column_a).True
multipointIf True, permits multiple points in a given row, sharing data in other columns. Each point row must have the same number of points. Default is False.False
collapse_groupsIf True, groups are toggled closed in the annotation view.False
mapping_setIf set, assumes data is passed as a dictionary and uses this string to as the key for the data to use.None
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.PointMapper.html b/docs/_site/reference/statebuilder.PointMapper.html deleted file mode 100644 index c8a61e5..0000000 --- a/docs/_site/reference/statebuilder.PointMapper.html +++ /dev/null @@ -1,763 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.pointmapper - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.PointMapper

-

statebuilder.PointMapper(self, point_column=None, description_column=None, linked_segmentation_column=None, tag_column=None, group_column=None, gather_linked_segmentations=True, share_linked_segmentations=False, set_position=True, multipoint=False, collapse_groups=False, split_positions=False, mapping_set=None)

-

Sets rules to map dataframes to point annotations

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
point_columnstrColumn name with 3d position dataNone
description_columnstrColumn name with string data for annotation descriptionsNone
linked_segmentation_columnstrColumn name for root ids to link to annotationsNone
tag_columnstrColumn name for categorical tag data. Tags must match those set in the annotation layer.None
group_columnstrColumn name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation.None
set_positionboolIf set to True, moves the position to center on the first point in the data.True
multipointIf True, permits multiple points in a given row, sharing data in other columns. Default is False.False
collapse_groupsIf True, groups are toggled closed in the annotation view.False
mapping_setIf given, assumes data is passed as a dictionary and uses this string to as the key for the data to use.None
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.SegmentationLayerConfig.html b/docs/_site/reference/statebuilder.SegmentationLayerConfig.html deleted file mode 100644 index 5be13ee..0000000 --- a/docs/_site/reference/statebuilder.SegmentationLayerConfig.html +++ /dev/null @@ -1,787 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.segmentationlayerconfig - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.SegmentationLayerConfig

-

statebuilder.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)

-

Configuration class for segmentation layers

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
sourcestrSegmentation sourcerequired
name(str, optional)Layer name.None
selected_ids_columnstr or list-like, optional.Column name (or list of column names) to use for selected ids.None
fixed_idslist-like, optional.List of root ids to select directly.None
fixed_id_colorslist-like, optional.List of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.None
color_columnstr, optional.# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with aNone
activebool, optional.If True, makes the layer selected. Default is False.False
alpha_selectedOpacity of selected segmentations in the image layer. Optional, default is 0.3.0.3
alpha_3dOpacity of meshes. Optional, default is 1.1
alpha_unselectedOpacity of unselected segments. Optional, default is 0.0
split_point_mapIf not None, provides an object to map the dataframe input to multicut points. Default is None.None
view_kwsdict, optional.Keyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.None
timestampfloat or datetime, optional.Timestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.None
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.SphereMapper.html b/docs/_site/reference/statebuilder.SphereMapper.html deleted file mode 100644 index 7ae705c..0000000 --- a/docs/_site/reference/statebuilder.SphereMapper.html +++ /dev/null @@ -1,769 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.spheremapper - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.SphereMapper

-

statebuilder.SphereMapper(self, center_column=None, radius_column=None, description_column=None, linked_segmentation_column=None, tag_column=None, group_column=None, gather_linked_segmentations=True, share_linked_segmentations=False, z_multiplier=0.1, set_position=True, multipoint=False, collapse_groups=False, split_positions=False, mapping_set=None)

-

Sets rules to map dataframes to sphere annotations

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
center_columnstrColumn name with 3d position data for the center of the sphereNone
radius_columnstrColumn name with a radius for the sphere (in nm)None
description_columnstrColumn name with string data for annotation descriptionsNone
linked_segmentation_columnstrColumn name for root ids to link to annotationsNone
tag_columnstrColumn name for categorical tag data. Tags must match those set in the annotation layer.None
group_columnstrColumn name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation.None
set_positionboolIf set to True, moves the position to center on the first point in the data.True
multipointIf True, permits multiple points in a given row, sharing data in other columns. Each point row must have the same number of points. Default is False.False
collapse_groupsIf True, groups are toggled closed in the annotation view.False
mapping_setIf set, assumes data is passed as a dictionary and uses this string to as the key for the data to use.None
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.SplitPointMapper.html b/docs/_site/reference/statebuilder.SplitPointMapper.html deleted file mode 100644 index e841d5d..0000000 --- a/docs/_site/reference/statebuilder.SplitPointMapper.html +++ /dev/null @@ -1,766 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.splitpointmapper - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.SplitPointMapper

-

statebuilder.SplitPointMapper(self, id_column, point_column, team_column, team_names=['red', 'blue'], supervoxel_column=None, focus=True, mapping_set=None)

-

Mapper to create split points in a segmentation layer.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
id_columnstrColumn name for segment ids. The id column must contain the same id in all rows.required
point_columnstrName of the column containing points in space.required
team_columnstrName of the column describing the team for the points. The contents of the column should have two values, by default “red” and “blue”.required
team_nameslistList of two values for the team names used in the team column. The first is mapped to red points, the second blue. Default is [“red”, “blue”].['red', 'blue']
supervoxel_columnstr or NoneName of a column providing supervoxel ids. If None (default), the supervoxel must be looked up on the server.None
focusboolIf True, sets the focus on the split tool and sets the position to the center of split points. Default is True.True
-
-
-

Returns

- ---- - - - - - - - - - - - - -
TypeDescription
SplitPointMapper instance to pass to a segmentation layer.
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.StateBuilder.html b/docs/_site/reference/statebuilder.StateBuilder.html deleted file mode 100644 index f700347..0000000 --- a/docs/_site/reference/statebuilder.StateBuilder.html +++ /dev/null @@ -1,751 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.statebuilder - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.StateBuilder

-

statebuilder.StateBuilder(self, layers=[], base_state=None, url_prefix=None, state_server=None, resolution=None, view_kws={}, client=None, target_site=None)

-

A class for schematic mapping data frames into neuroglancer states.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
layers[]
base_stateNone
url_prefixDefaults to None, which will use https://neuromancer-seung-import.appspot.comNone
state_serverNone
resolutionNone
view_kwskeys are: show_slices: Boolean sets if slices are shown in the 3d view. Defaults to False. layout: str xy-3d/xz-3d/yz-3d (sections plus 3d pane), xy/yz/xz/3d (only one pane), or 4panel (all panes). Default is xy-3d. show_axis_lines: Boolean determines if the axis lines are shown in the middle of each view. show_scale_bar: Boolean toggles showing the scale bar. orthographic : Boolean toggles orthographic view in the 3d pane. position* : 3-element vector determines the centered location. zoom_image : float Zoom level for the imagery in units of nm per voxel. Defaults to 8. zoom_3d : float Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are more zoomed in. background_color : str or list Sets the background color of the 3d view. Arguments can be rgb values, hex colors, or named web colors. Defaults to black.{}
clientNone
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.helpers.from_client.html b/docs/_site/reference/statebuilder.helpers.from_client.html deleted file mode 100644 index 9147416..0000000 --- a/docs/_site/reference/statebuilder.helpers.from_client.html +++ /dev/null @@ -1,758 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.helpers.from_client - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.helpers.from_client

-

statebuilder.helpers.from_client(client, image_name=None, segmentation_name=None, contrast=None)

-

Generate basic image and segmentation layers from a FrameworkClient

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
clientcaveclient.caveclient.CAVEclientA CAVEclient with a specified datastackrequired
image_namestrName for the image layer, by default None.None
segmentation_namestrName for the segmentation layer, by default NoneNone
contrastlist - likeTwo elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set.None
-
-
-

Returns

- ---- - - - - - - - - - - - - - - - - -
TypeDescription
nglui.statebuilder.layers.ImageLayerConfigImage layer with default values from the client
nglui.statebuilder.layers.ImageLayerConfigSegmentation layer with default values from the client
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.helpers.make_line_statebuilder.html b/docs/_site/reference/statebuilder.helpers.make_line_statebuilder.html deleted file mode 100644 index e15602a..0000000 --- a/docs/_site/reference/statebuilder.helpers.make_line_statebuilder.html +++ /dev/null @@ -1,786 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.helpers.make_line_statebuilder - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.helpers.make_line_statebuilder

-

statebuilder.helpers.make_line_statebuilder(client, point_column_a='pre_pt_position', point_column_b='post_pt_position', linked_seg_column='pt_root_id', description_column=None, tag_column=None, data_resolution=None, group_column=None, contrast=None, view_kws=None, point_layer_name='lines', color=None, split_positions=False)

-

Generate a state builder that puts points on a single column with a linked segmentaton id

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
clientcaveclient.CAVEclientCAVEclient configured for the datastack desiredrequired
point_column_astrcolumn in dataframe to pull points from. Defaults to “pre_pt_position”.'pre_pt_position'
point_column_bstrcolumn in dataframe to pull points from. Defaults to “post_pt_position”.'post_pt_position'
linked_seg_columnstrcolumn to link to segmentation, None for no column. Defaults to “pt_root_id”.'pt_root_id'
group_columnstr, or listcolumn(s) to group annotations by, None for no grouping (default=None)None
tag_columnstrcolumn to use for tags, None for no tags (default=None)None
description_columnstrcolumn to use for descriptions, None for no descriptions (default=None)None
contrastlistTwo elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set.None
view_kwsdictdictionary of view keywords to configure neuroglancer viewNone
split_positionsboolwhether the position column into x,y,z columns. Defaults to False.False
-
-
-

Returns

- - - - - - - - - - - - - -
TypeDescription
A statebuilder to make points with linked segmentations
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.helpers.make_neuron_neuroglancer_link.html b/docs/_site/reference/statebuilder.helpers.make_neuron_neuroglancer_link.html deleted file mode 100644 index 596fe8a..0000000 --- a/docs/_site/reference/statebuilder.helpers.make_neuron_neuroglancer_link.html +++ /dev/null @@ -1,877 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.helpers.make_neuron_neuroglancer_link - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - - - -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.helpers.make_point_statebuilder.html b/docs/_site/reference/statebuilder.helpers.make_point_statebuilder.html deleted file mode 100644 index 053ef80..0000000 --- a/docs/_site/reference/statebuilder.helpers.make_point_statebuilder.html +++ /dev/null @@ -1,780 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.helpers.make_point_statebuilder - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.helpers.make_point_statebuilder

-

statebuilder.helpers.make_point_statebuilder(client, point_column='pt_position', linked_seg_column='pt_root_id', data_resolution=None, group_column=None, tag_column=None, description_column=None, contrast=None, view_kws=None, point_layer_name='pts', color=None, split_positions=False)

-

Generate a state builder that puts points on a single column with a linked segmentaton id

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
clientcaveclient.CAVEclientCAVEclient configured for the datastack desiredrequired
point_columnstrColumn in dataframe to pull points from. Defaults to “pt_position”.'pt_position'
linked_seg_columnstrcolumn to link to segmentation, None for no column. Defaults to “pt_root_id”.'pt_root_id'
group_columnstr, or listcolumn(s) to group annotations by, None for no grouping (default=None)None
tag_columnstr, optional)column to use for tags, None for no tags (default=None)None
description_columnstrcolumn to use for descriptions, None for no descriptions (default=None)None
contrastlistTwo elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set.None
view_kwsdictdictionary of view keywords to configure neuroglancer viewNone
split_positionsboolwhether the position column into x,y,z columns. Defaults to False.False
-
-
-

Returns

- - - - - - - - - - - - - -
TypeDescription
A statebuilder to make points with linked segmentations
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.helpers.make_pre_post_statebuilder.html b/docs/_site/reference/statebuilder.helpers.make_pre_post_statebuilder.html deleted file mode 100644 index 797a1e7..0000000 --- a/docs/_site/reference/statebuilder.helpers.make_pre_post_statebuilder.html +++ /dev/null @@ -1,796 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.helpers.make_pre_post_statebuilder - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.helpers.make_pre_post_statebuilder

-

statebuilder.helpers.make_pre_post_statebuilder(client, show_inputs=False, show_outputs=False, contrast=None, view_kws=None, point_column='ctr_pt_position', pre_pt_root_id_col='pre_pt_root_id', post_pt_root_id_col='post_pt_root_id', dataframe_resolution_pre=None, dataframe_resolution_post=None, input_layer_name='syns_in', output_layer_name='syns_out', input_layer_color=DEFAULT_POSTSYN_COLOR, output_layer_color=DEFAULT_PRESYN_COLOR, split_positions=False)

-

Function to generate ChainedStateBuilder with optional pre and post synaptic annotation layers

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
clientcaveclient.CAVEclienta CAVEclient configured for datastack to visualizerequired
show_inputsboolwhether to show input synapses. Defaults to False.False
show_outputsboolwhether to show output synapses.. Defaults to False.False
contrastlistTwo elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set.None
view_kwsdictview_kws to configure statebuilder, see nglui.StateBuilder. Defaults to None. keys are: show_slices: Boolean sets if slices are shown in the 3d view. Defaults to False. layout: str xy-3d/xz-3d/yz-3d (sections plus 3d pane), xy/yz/xz/3d (only one pane), or 4panel (all panes). Default is xy-3d. show_axis_lines: Boolean determines if the axis lines are shown in the middle of each view. show_scale_bar: Boolean toggles showing the scale bar. orthographic : Boolean toggles orthographic view in the 3d pane. position* : 3-element vector determines the centered location. zoom_image : float Zoom level for the imagery in units of nm per voxel. Defaults to 8. zoom_3d : float Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are more zoomed in.None
point_columnstrcolumn to pull points for synapses from. Defaults to “ctr_pt_position”.'ctr_pt_position'
pre_pt_root_id_colstrcolumn to pull pre synaptic ids for synapses from. Defaults to “pre_pt_root_id”.'pre_pt_root_id'
post_pt_root_id_colstrcolumn to pull post synaptic ids for synapses from. Defaults to “post_pt_root_id”.'post_pt_root_id'
input_layer_namestrname of layer for inputs. Defaults to “syns_in”.'syns_in'
output_layer_namestrname of layer for outputs. Defaults to “syns_out”.'syns_out'
split_positionsboolwhether the position column is split into x,y,z columns. Defaults to False.False
-
-
-

Returns

- ---- - - - - - - - - - - - - -
TypeDescription
An instance of a ChainedStateBuilder configured to accept a list starting with None followed by optionally synapse input dataframe followed by optionally synapse output dataframe.
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.helpers.make_state_url.html b/docs/_site/reference/statebuilder.helpers.make_state_url.html deleted file mode 100644 index c070e30..0000000 --- a/docs/_site/reference/statebuilder.helpers.make_state_url.html +++ /dev/null @@ -1,756 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.helpers.make_state_url - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.helpers.make_state_url

-

statebuilder.helpers.make_state_url(df, sb, client, ngl_url=None, target_site=None)

-

Generate a url from a neuroglancer state via a state server.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
dfpandas.pandas.DataFrameDataframe to pass through statebuilderrequired
sbnglui.statebuilder.statebuilder.nglui.statebuilder.statebuilder.StateBuilderStatebuilder to use to render data for linkrequired
clientcaveclient.CAVEclientCAVEclient configured with a state serverrequired
ngl_urlstrNeuroglancer deployment URL, by default NoneNone
target_sitestrType of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use seunglab for a Seung-lab branch and either mainline or cave-explorer for the Cave Explorer or main Google branch.None
-
-
-

Returns

- - - - - - - - - - - - - -
TypeDescription
strUrl to the uploaded neuroglancer state.
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.helpers.make_synapse_neuroglancer_link.html b/docs/_site/reference/statebuilder.helpers.make_synapse_neuroglancer_link.html deleted file mode 100644 index 16ddd42..0000000 --- a/docs/_site/reference/statebuilder.helpers.make_synapse_neuroglancer_link.html +++ /dev/null @@ -1,847 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.helpers.make_synapse_neuroglancer_link - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - - - -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.helpers.make_url_robust.html b/docs/_site/reference/statebuilder.helpers.make_url_robust.html deleted file mode 100644 index 46d7468..0000000 --- a/docs/_site/reference/statebuilder.helpers.make_url_robust.html +++ /dev/null @@ -1,768 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.helpers.make_url_robust - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.helpers.make_url_robust

-

statebuilder.helpers.make_url_robust(df, sb, client, shorten='if_long', ngl_url=None, max_url_length=MAX_URL_LENGTH, target_site=None)

-

Generate a url from a neuroglancer state. If too long, return through state server, othewise return a url containing the data directly.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
dfpandas.pandas.DataFrameDataframe to pass through statebuilderrequired
sbnglui.statebuilder.statebuilder.nglui.statebuilder.statebuilder.StateBuilderStatebuilder to use to render data for linkrequired
clientcaveclient.CAVEclientCAVEclient configured with a state serverrequired
shortenstrHow to shorten link. one of ‘if_long’, ‘always’, ‘never’. ‘if_long’ will use the state server to shorten links longer than nglui.statebuilder.MAX_URL_LENGTH (set to 1,750,000). ‘always’ will always use the state server to shorten the url ‘never’ will always return the full url. Defaults to “if_long”.'if_long'
ngl_urlstrNeuroglancer deployment URL, by default NoneNone
max_url_lengthintMaximum length of url to return directly, by default 1_750_000MAX_URL_LENGTH
target_sitestrType of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use seunglab for a Seung-lab branch and either mainline or cave-explorer for the Cave Explorer or main Google branch.None
-
-
-

Returns

- - - - - - - - - - - - - -
TypeDescription
strURL containing the state created by the statebuilder.
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.helpers.package_state.html b/docs/_site/reference/statebuilder.helpers.package_state.html deleted file mode 100644 index 030cf49..0000000 --- a/docs/_site/reference/statebuilder.helpers.package_state.html +++ /dev/null @@ -1,781 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.helpers.package_state - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.helpers.package_state

-

statebuilder.helpers.package_state(df, sb, client, shorten='if_long', return_as='url', ngl_url=None, link_text='Neuroglancer Link', target_site=None)

-

Automate creating a state from a statebuilder and a dataframe, return it in the desired format, shortening if desired.

-
-
-

Convert below to numpydoc

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
dfpandas.pandas.DataFrameDataframe to pass through statebuilderrequired
sbnglui.statebuilder.statebuilder.nglui.statebuilder.statebuilder.StateBuilderStatebuilder to use to render data for linkrequired
clientcaveclient.CAVEclientCAVEclient configured with a state serverrequired
shortenstrHow to shorten link. one of ‘if_long’, ‘always’, ‘never’. ‘if_long’ will use the state server to shorten links longer than nglui.statebuilder.MAX_URL_LENGTH (set to 1,750,000). ‘always’ will always use the state server to shorten the url ‘never’ will always return the full url. Defaults to “if_long”.'if_long'
return_asstrHow to return the state. one of ‘html’, ‘url’, ‘json’. ‘html’ will return an ipython clickable link ‘url’ will return a string with the url ‘json’ will return the state as a dictionary'url'
ngl_urlstrNeuroglancer deployment URL, by default NoneNone
link_textstrText to use for the link, by default “Neuroglancer Link”'Neuroglancer Link'
target_sitestrType of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use seunglab for a Seung-lab branch and either mainline or cave-explorer for the Cave Explorer or main Google branch.None
-
-
-

Returns

- ---- - - - - - - - - - - - - -
TypeDescription
(IPython.display.HTML, str or dict)state in format specified by return_as
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.helpers.sort_dataframe_by_root_id.html b/docs/_site/reference/statebuilder.helpers.sort_dataframe_by_root_id.html deleted file mode 100644 index 996c1ef..0000000 --- a/docs/_site/reference/statebuilder.helpers.sort_dataframe_by_root_id.html +++ /dev/null @@ -1,756 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder.helpers.sort_dataframe_by_root_id - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- -
- - -
- - - -
- - - -
-

statebuilder.helpers.sort_dataframe_by_root_id

-

statebuilder.helpers.sort_dataframe_by_root_id(df, root_id_column, ascending=False, num_column='n_times', drop=False)

-

Sort a dataframe so that rows belonging to the same root id are together, ordered by how many times the root id appears.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
dfpandas.pandas.DataFramedataframe to sortrequired
root_id_columnstrColumn name to use for sorting root idsrequired
ascendingboolWhether to sort ascending (lowest count to highest) or not, by default FalseFalse
num_columnstrTemporary column name to use for count information, by default ‘n_times’'n_times'
dropboolIf True, drop the additional column when returning.False
-
-
-

Returns

- - - - - - - - - - - - - -
TypeDescription
pandas.pandas.DataFrame
- - -
-
- -
- - -
- - - - \ No newline at end of file diff --git a/docs/_site/reference/statebuilder.html b/docs/_site/reference/statebuilder.html deleted file mode 100644 index 1b9f76b..0000000 --- a/docs/_site/reference/statebuilder.html +++ /dev/null @@ -1,563 +0,0 @@ - - - - - - - - - -NGLui Documentation – statebuilder - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - -
- - - -
-

StateBuilder

-

statebuilder.statebuilder.StateBuilder(self, layers=[], base_state=None, url_prefix=None, state_server=None, resolution=None, view_kws={}, client=None, target_site=None)

-

A class for schematic mapping data frames into neuroglancer states.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
layers[]
base_stateNone
url_prefixDefaults to None, which will use https://neuromancer-seung-import.appspot.comNone
state_serverNone
resolutionNone
view_kwskeys are: show_slices: Boolean sets if slices are shown in the 3d view. Defaults to False. layout: str xy-3d/xz-3d/yz-3d (sections plus 3d pane), xy/yz/xz/3d (only one pane), or 4panel (all panes). Default is xy-3d. show_axis_lines: Boolean determines if the axis lines are shown in the middle of each view. show_scale_bar: Boolean toggles showing the scale bar. orthographic : Boolean toggles orthographic view in the 3d pane. position* : 3-element vector determines the centered location. zoom_image : float Zoom level for the imagery in units of nm per voxel. Defaults to 8. zoom_3d : float Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are more zoomed in. background_color : str or list Sets the background color of the 3d view. Arguments can be rgb values, hex colors, or named web colors. Defaults to black.{}
clientNone
-
-
-

Methods

- - - - - - - - - - - - - - - - - -
NameDescription
initialize_stateGenerate a new Neuroglancer state with layers as needed for the schema.
render_stateBuild a Neuroglancer state out of a DataFrame.
-
-

initialize_state

-

statebuilder.statebuilder.StateBuilder.initialize_state(base_state=None, target_site=None)

-

Generate a new Neuroglancer state with layers as needed for the schema.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
base_statestrOptional initial state to build on, described by its JSON. By default None.None
-
-
-
-

render_state

-

statebuilder.statebuilder.StateBuilder.render_state(data=None, base_state=None, return_as='url', url_prefix=None, link_text='Neuroglancer Link', target_site=None)

-

Build a Neuroglancer state out of a DataFrame.

-
-

Parameters

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescriptionDefault
datapandas.pandas.DataFrameDataFrame to use as a point source. By default None, for which it will return only the base_state and any fixed values.None
base_statedictInitial state to build on, expressed as Neuroglancer JSON. By default NoneNone
return_as[url, nglui.statebuilder.statebuilder.StateBuilder.viewer, html, json, dict, shared]Choice of output types. Note that if a viewer is returned, the state is not reset. url : Returns the raw url describing the state viewer : Returns an EasyViewer object holding the state information html : Returns an HTML link to the url, useful for notebooks. json : Returns a JSON string describing the state. dict : Returns a dict version of the JSON state. By default ‘url’'url'
url_prefixstrNeuroglancer URL prefix to use. By default None, for which it will open with the class default.None
link_textstrText to use for the link when returning as html, by default ‘Neuroglancer Link’'Neuroglancer Link'
-
-
-

Returns

- ---- - - - - - - - - - - - - -
TypeDescription
string or neuroglancer.neuroglancer.ViewerA link to or viewer for a Neuroglancer state with layers, annotations, and selected objects determined by the data.
- - -
-
-
-
- -
- -
- - - - \ No newline at end of file diff --git a/docs/_site/search.json b/docs/_site/search.json deleted file mode 100644 index 42d8c2a..0000000 --- a/docs/_site/search.json +++ /dev/null @@ -1,1073 +0,0 @@ -[ - { - "objectID": "reference/nglui.statebuilder.layers.ImageLayerConfig.html", - "href": "reference/nglui.statebuilder.layers.ImageLayerConfig.html", - "title": "ImageLayerConfig", - "section": "", - "text": "statebuilder.layers.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)\nImage layer configuration class.\nThis provides the rules for setting up an image layer in neuroglancer.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nCloudpath to an image source\nrequired\n\n\nname\nstr\nName of the image layer. By default, ‘img’.\nNone\n\n\nactive\nbool\nIf True, makes the layer active in neuroglancer. Default is False.\nFalse\n\n\ncontrast_controls\nbool\nIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.\nFalse\n\n\nblack\nfloat\nIf contrast_controls is True, sets the default black level. Default is 0.0.\n0.0\n\n\nwhite\nfloat\nIf contrast_controls is True, sets the default white level. Default is 1.0.\n1.0" - }, - { - "objectID": "reference/nglui.statebuilder.layers.ImageLayerConfig.html#parameters", - "href": "reference/nglui.statebuilder.layers.ImageLayerConfig.html#parameters", - "title": "ImageLayerConfig", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nCloudpath to an image source\nrequired\n\n\nname\nstr\nName of the image layer. By default, ‘img’.\nNone\n\n\nactive\nbool\nIf True, makes the layer active in neuroglancer. Default is False.\nFalse\n\n\ncontrast_controls\nbool\nIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.\nFalse\n\n\nblack\nfloat\nIf contrast_controls is True, sets the default black level. Default is 0.0.\n0.0\n\n\nwhite\nfloat\nIf contrast_controls is True, sets the default white level. Default is 1.0.\n1.0" - }, - { - "objectID": "reference/parser.base.view_settings.html", - "href": "reference/parser.base.view_settings.html", - "title": "parser.base.view_settings", - "section": "", - "text": "parser.base.view_settings(state)\nGet all data about the view state in neuroglancer: position, image zoom, orientation and zoom of the 3d view, and voxel size.\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as JSON dict\nrequired\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\ndict\nDictionary with keys: position, zoomFactor, perspectiveOrientation, perspectiveZoom, and voxelSize" - }, - { - "objectID": "reference/parser.base.view_settings.html#parameters", - "href": "reference/parser.base.view_settings.html#parameters", - "title": "parser.base.view_settings", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as JSON dict\nrequired" - }, - { - "objectID": "reference/parser.base.view_settings.html#returns", - "href": "reference/parser.base.view_settings.html#returns", - "title": "parser.base.view_settings", - "section": "", - "text": "Type\nDescription\n\n\n\n\ndict\nDictionary with keys: position, zoomFactor, perspectiveOrientation, perspectiveZoom, and voxelSize" - }, - { - "objectID": "reference/statebuilder.PointMapper.html", - "href": "reference/statebuilder.PointMapper.html", - "title": "statebuilder.PointMapper", - "section": "", - "text": "statebuilder.PointMapper(self, point_column=None, description_column=None, linked_segmentation_column=None, tag_column=None, group_column=None, gather_linked_segmentations=True, share_linked_segmentations=False, set_position=True, multipoint=False, collapse_groups=False, split_positions=False, mapping_set=None)\nSets rules to map dataframes to point annotations\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\npoint_column\nstr\nColumn name with 3d position data\nNone\n\n\ndescription_column\nstr\nColumn name with string data for annotation descriptions\nNone\n\n\nlinked_segmentation_column\nstr\nColumn name for root ids to link to annotations\nNone\n\n\ntag_column\nstr\nColumn name for categorical tag data. Tags must match those set in the annotation layer.\nNone\n\n\ngroup_column\nstr\nColumn name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation.\nNone\n\n\nset_position\nbool\nIf set to True, moves the position to center on the first point in the data.\nTrue\n\n\nmultipoint\n\nIf True, permits multiple points in a given row, sharing data in other columns. Default is False.\nFalse\n\n\ncollapse_groups\n\nIf True, groups are toggled closed in the annotation view.\nFalse\n\n\nmapping_set\n\nIf given, assumes data is passed as a dictionary and uses this string to as the key for the data to use.\nNone" - }, - { - "objectID": "reference/statebuilder.PointMapper.html#parameters", - "href": "reference/statebuilder.PointMapper.html#parameters", - "title": "statebuilder.PointMapper", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\npoint_column\nstr\nColumn name with 3d position data\nNone\n\n\ndescription_column\nstr\nColumn name with string data for annotation descriptions\nNone\n\n\nlinked_segmentation_column\nstr\nColumn name for root ids to link to annotations\nNone\n\n\ntag_column\nstr\nColumn name for categorical tag data. Tags must match those set in the annotation layer.\nNone\n\n\ngroup_column\nstr\nColumn name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation.\nNone\n\n\nset_position\nbool\nIf set to True, moves the position to center on the first point in the data.\nTrue\n\n\nmultipoint\n\nIf True, permits multiple points in a given row, sharing data in other columns. Default is False.\nFalse\n\n\ncollapse_groups\n\nIf True, groups are toggled closed in the annotation view.\nFalse\n\n\nmapping_set\n\nIf given, assumes data is passed as a dictionary and uses this string to as the key for the data to use.\nNone" - }, - { - "objectID": "reference/parser.base.group_annotations.html", - "href": "reference/parser.base.group_annotations.html", - "title": "parser.base.group_annotations", - "section": "", - "text": "parser.base.group_annotations(state, layer_name, description=False, linked_segmentations=False, tags=False)\nAll group annotations and their associated points\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as JSON dict\nrequired\n\n\nlayer_name\nstr\nAnnotation layer name\nrequired\n\n\ndescription\nbool\nIf True, also returns descriptions as well. By default False\nFalse\n\n\nlinked_segmentations\nbool\nIf True, also returns list of linked segmentations, by default False\nFalse\n\n\ntags\nbool\nIf True, also returns list of tags, by default False\nFalse\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nlist\nList of N 3-element points\n\n\nlist\nList of N id strings for groups.\n\n\nlist\nList of N strings (or None), only returned if description=True.\n\n\nlist\nList of N lists of object ids. Only returned if linked_segmentations=True.\n\n\nlist\nList of N lists of tag ids. Only returned if tags=True." - }, - { - "objectID": "reference/parser.base.group_annotations.html#parameters", - "href": "reference/parser.base.group_annotations.html#parameters", - "title": "parser.base.group_annotations", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as JSON dict\nrequired\n\n\nlayer_name\nstr\nAnnotation layer name\nrequired\n\n\ndescription\nbool\nIf True, also returns descriptions as well. By default False\nFalse\n\n\nlinked_segmentations\nbool\nIf True, also returns list of linked segmentations, by default False\nFalse\n\n\ntags\nbool\nIf True, also returns list of tags, by default False\nFalse" - }, - { - "objectID": "reference/parser.base.group_annotations.html#returns", - "href": "reference/parser.base.group_annotations.html#returns", - "title": "parser.base.group_annotations", - "section": "", - "text": "Type\nDescription\n\n\n\n\nlist\nList of N 3-element points\n\n\nlist\nList of N id strings for groups.\n\n\nlist\nList of N strings (or None), only returned if description=True.\n\n\nlist\nList of N lists of object ids. Only returned if linked_segmentations=True.\n\n\nlist\nList of N lists of tag ids. Only returned if tags=True." - }, - { - "objectID": "reference/statebuilder.html", - "href": "reference/statebuilder.html", - "title": "StateBuilder", - "section": "", - "text": "statebuilder.statebuilder.StateBuilder(self, layers=[], base_state=None, url_prefix=None, state_server=None, resolution=None, view_kws={}, client=None, target_site=None)\nA class for schematic mapping data frames into neuroglancer states.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nlayers\n\n\n[]\n\n\nbase_state\n\n\nNone\n\n\nurl_prefix\n\nDefaults to None, which will use https://neuromancer-seung-import.appspot.com\nNone\n\n\nstate_server\n\n\nNone\n\n\nresolution\n\n\nNone\n\n\nview_kws\n\nkeys are: show_slices: Boolean sets if slices are shown in the 3d view. Defaults to False. layout: str xy-3d/xz-3d/yz-3d (sections plus 3d pane), xy/yz/xz/3d (only one pane), or 4panel (all panes). Default is xy-3d. show_axis_lines: Boolean determines if the axis lines are shown in the middle of each view. show_scale_bar: Boolean toggles showing the scale bar. orthographic : Boolean toggles orthographic view in the 3d pane. position* : 3-element vector determines the centered location. zoom_image : float Zoom level for the imagery in units of nm per voxel. Defaults to 8. zoom_3d : float Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are more zoomed in. background_color : str or list Sets the background color of the 3d view. Arguments can be rgb values, hex colors, or named web colors. Defaults to black.\n{}\n\n\nclient\n\n\nNone\n\n\n\n\n\n\n\n\n\nName\nDescription\n\n\n\n\ninitialize_state\nGenerate a new Neuroglancer state with layers as needed for the schema.\n\n\nrender_state\nBuild a Neuroglancer state out of a DataFrame.\n\n\n\n\n\nstatebuilder.statebuilder.StateBuilder.initialize_state(base_state=None, target_site=None)\nGenerate a new Neuroglancer state with layers as needed for the schema.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nbase_state\nstr\nOptional initial state to build on, described by its JSON. By default None.\nNone\n\n\n\n\n\n\n\nstatebuilder.statebuilder.StateBuilder.render_state(data=None, base_state=None, return_as='url', url_prefix=None, link_text='Neuroglancer Link', target_site=None)\nBuild a Neuroglancer state out of a DataFrame.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\ndata\npandas.pandas.DataFrame\nDataFrame to use as a point source. By default None, for which it will return only the base_state and any fixed values.\nNone\n\n\nbase_state\ndict\nInitial state to build on, expressed as Neuroglancer JSON. By default None\nNone\n\n\nreturn_as\n[url, nglui.statebuilder.statebuilder.StateBuilder.viewer, html, json, dict, shared]\nChoice of output types. Note that if a viewer is returned, the state is not reset. url : Returns the raw url describing the state viewer : Returns an EasyViewer object holding the state information html : Returns an HTML link to the url, useful for notebooks. json : Returns a JSON string describing the state. dict : Returns a dict version of the JSON state. By default ‘url’\n'url'\n\n\nurl_prefix\nstr\nNeuroglancer URL prefix to use. By default None, for which it will open with the class default.\nNone\n\n\nlink_text\nstr\nText to use for the link when returning as html, by default ‘Neuroglancer Link’\n'Neuroglancer Link'\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nstring or neuroglancer.neuroglancer.Viewer\nA link to or viewer for a Neuroglancer state with layers, annotations, and selected objects determined by the data." - }, - { - "objectID": "reference/statebuilder.html#parameters", - "href": "reference/statebuilder.html#parameters", - "title": "StateBuilder", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nlayers\n\n\n[]\n\n\nbase_state\n\n\nNone\n\n\nurl_prefix\n\nDefaults to None, which will use https://neuromancer-seung-import.appspot.com\nNone\n\n\nstate_server\n\n\nNone\n\n\nresolution\n\n\nNone\n\n\nview_kws\n\nkeys are: show_slices: Boolean sets if slices are shown in the 3d view. Defaults to False. layout: str xy-3d/xz-3d/yz-3d (sections plus 3d pane), xy/yz/xz/3d (only one pane), or 4panel (all panes). Default is xy-3d. show_axis_lines: Boolean determines if the axis lines are shown in the middle of each view. show_scale_bar: Boolean toggles showing the scale bar. orthographic : Boolean toggles orthographic view in the 3d pane. position* : 3-element vector determines the centered location. zoom_image : float Zoom level for the imagery in units of nm per voxel. Defaults to 8. zoom_3d : float Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are more zoomed in. background_color : str or list Sets the background color of the 3d view. Arguments can be rgb values, hex colors, or named web colors. Defaults to black.\n{}\n\n\nclient\n\n\nNone" - }, - { - "objectID": "reference/statebuilder.html#methods", - "href": "reference/statebuilder.html#methods", - "title": "StateBuilder", - "section": "", - "text": "Name\nDescription\n\n\n\n\ninitialize_state\nGenerate a new Neuroglancer state with layers as needed for the schema.\n\n\nrender_state\nBuild a Neuroglancer state out of a DataFrame.\n\n\n\n\n\nstatebuilder.statebuilder.StateBuilder.initialize_state(base_state=None, target_site=None)\nGenerate a new Neuroglancer state with layers as needed for the schema.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nbase_state\nstr\nOptional initial state to build on, described by its JSON. By default None.\nNone\n\n\n\n\n\n\n\nstatebuilder.statebuilder.StateBuilder.render_state(data=None, base_state=None, return_as='url', url_prefix=None, link_text='Neuroglancer Link', target_site=None)\nBuild a Neuroglancer state out of a DataFrame.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\ndata\npandas.pandas.DataFrame\nDataFrame to use as a point source. By default None, for which it will return only the base_state and any fixed values.\nNone\n\n\nbase_state\ndict\nInitial state to build on, expressed as Neuroglancer JSON. By default None\nNone\n\n\nreturn_as\n[url, nglui.statebuilder.statebuilder.StateBuilder.viewer, html, json, dict, shared]\nChoice of output types. Note that if a viewer is returned, the state is not reset. url : Returns the raw url describing the state viewer : Returns an EasyViewer object holding the state information html : Returns an HTML link to the url, useful for notebooks. json : Returns a JSON string describing the state. dict : Returns a dict version of the JSON state. By default ‘url’\n'url'\n\n\nurl_prefix\nstr\nNeuroglancer URL prefix to use. By default None, for which it will open with the class default.\nNone\n\n\nlink_text\nstr\nText to use for the link when returning as html, by default ‘Neuroglancer Link’\n'Neuroglancer Link'\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nstring or neuroglancer.neuroglancer.Viewer\nA link to or viewer for a Neuroglancer state with layers, annotations, and selected objects determined by the data." - }, - { - "objectID": "reference/parser.base.layer_names.html", - "href": "reference/parser.base.layer_names.html", - "title": "parser.base.layer_names", - "section": "", - "text": "parser.base.layer_names(state)\nGet all layer names in the state\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as a JSON dict\nrequired\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nlist\nList of layer names" - }, - { - "objectID": "reference/parser.base.layer_names.html#parameters", - "href": "reference/parser.base.layer_names.html#parameters", - "title": "parser.base.layer_names", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as a JSON dict\nrequired" - }, - { - "objectID": "reference/parser.base.layer_names.html#returns", - "href": "reference/parser.base.layer_names.html#returns", - "title": "parser.base.layer_names", - "section": "", - "text": "Type\nDescription\n\n\n\n\nlist\nList of layer names" - }, - { - "objectID": "reference/statebuilder.helpers.sort_dataframe_by_root_id.html", - "href": "reference/statebuilder.helpers.sort_dataframe_by_root_id.html", - "title": "statebuilder.helpers.sort_dataframe_by_root_id", - "section": "", - "text": "statebuilder.helpers.sort_dataframe_by_root_id(df, root_id_column, ascending=False, num_column='n_times', drop=False)\nSort a dataframe so that rows belonging to the same root id are together, ordered by how many times the root id appears.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\ndf\npandas.pandas.DataFrame\ndataframe to sort\nrequired\n\n\nroot_id_column\nstr\nColumn name to use for sorting root ids\nrequired\n\n\nascending\nbool\nWhether to sort ascending (lowest count to highest) or not, by default False\nFalse\n\n\nnum_column\nstr\nTemporary column name to use for count information, by default ‘n_times’\n'n_times'\n\n\ndrop\nbool\nIf True, drop the additional column when returning.\nFalse\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\npandas.pandas.DataFrame" - }, - { - "objectID": "reference/statebuilder.helpers.sort_dataframe_by_root_id.html#parameters", - "href": "reference/statebuilder.helpers.sort_dataframe_by_root_id.html#parameters", - "title": "statebuilder.helpers.sort_dataframe_by_root_id", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\ndf\npandas.pandas.DataFrame\ndataframe to sort\nrequired\n\n\nroot_id_column\nstr\nColumn name to use for sorting root ids\nrequired\n\n\nascending\nbool\nWhether to sort ascending (lowest count to highest) or not, by default False\nFalse\n\n\nnum_column\nstr\nTemporary column name to use for count information, by default ‘n_times’\n'n_times'\n\n\ndrop\nbool\nIf True, drop the additional column when returning.\nFalse" - }, - { - "objectID": "reference/statebuilder.helpers.sort_dataframe_by_root_id.html#returns", - "href": "reference/statebuilder.helpers.sort_dataframe_by_root_id.html#returns", - "title": "statebuilder.helpers.sort_dataframe_by_root_id", - "section": "", - "text": "Type\nDescription\n\n\n\n\npandas.pandas.DataFrame" - }, - { - "objectID": "reference/statebuilder.ChainedStateBuilder.html", - "href": "reference/statebuilder.ChainedStateBuilder.html", - "title": "statebuilder.ChainedStateBuilder", - "section": "", - "text": "statebuilder.ChainedStateBuilder(self, statebuilders)\nBuilds a collection of states that sequentially add annotations based on a sequence of dataframes.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstatebuilders\nlist\nList of DataStateBuilders, in same order as dataframes will be passed\nrequired" - }, - { - "objectID": "reference/statebuilder.ChainedStateBuilder.html#parameters", - "href": "reference/statebuilder.ChainedStateBuilder.html#parameters", - "title": "statebuilder.ChainedStateBuilder", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstatebuilders\nlist\nList of DataStateBuilders, in same order as dataframes will be passed\nrequired" - }, - { - "objectID": "reference/parser.base.annotation_dataframe.html", - "href": "reference/parser.base.annotation_dataframe.html", - "title": "parser.base.annotation_dataframe", - "section": "", - "text": "parser.base.annotation_dataframe(state)\nReturn all annotations across all annotation layers in the state.\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state dictionary\nrequired\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\npandas.pandas.DataFrame\nDataframe with columns layer, anno_type, point, pointB, linked_segmentation, tags, anno_id, group_id, description." - }, - { - "objectID": "reference/parser.base.annotation_dataframe.html#parameters", - "href": "reference/parser.base.annotation_dataframe.html#parameters", - "title": "parser.base.annotation_dataframe", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state dictionary\nrequired" - }, - { - "objectID": "reference/parser.base.annotation_dataframe.html#returns", - "href": "reference/parser.base.annotation_dataframe.html#returns", - "title": "parser.base.annotation_dataframe", - "section": "", - "text": "Type\nDescription\n\n\n\n\npandas.pandas.DataFrame\nDataframe with columns layer, anno_type, point, pointB, linked_segmentation, tags, anno_id, group_id, description." - }, - { - "objectID": "reference/nglui.statebuilder.layers.SegmentationLayerConfig.html", - "href": "reference/nglui.statebuilder.layers.SegmentationLayerConfig.html", - "title": "SegmentationLayerConfig", - "section": "", - "text": "statebuilder.layers.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)\nConfiguration class for segmentation layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nSegmentation source\nrequired\n\n\nname\n(str, optional)\nLayer name.\nNone\n\n\nselected_ids_column\nstr or list-like, optional.\nColumn name (or list of column names) to use for selected ids.\nNone\n\n\nfixed_ids\nlist-like, optional.\nList of root ids to select directly.\nNone\n\n\nfixed_id_colors\nlist-like, optional.\nList of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.\nNone\n\n\ncolor_column\nstr, optional.\n# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a\nNone\n\n\nactive\nbool, optional.\nIf True, makes the layer selected. Default is False.\nFalse\n\n\nalpha_selected\n\nOpacity of selected segmentations in the image layer. Optional, default is 0.3.\n0.3\n\n\nalpha_3d\n\nOpacity of meshes. Optional, default is 1.\n1\n\n\nalpha_unselected\n\nOpacity of unselected segments. Optional, default is 0.\n0\n\n\nsplit_point_map\n\nIf not None, provides an object to map the dataframe input to multicut points. Default is None.\nNone\n\n\nview_kws\ndict, optional.\nKeyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.\nNone\n\n\ntimestamp\nfloat or datetime, optional.\nTimestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.\nNone\n\n\n\n\n\n\n\n\n\nName\nDescription\n\n\n\n\nadd_selection_map\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\nstatebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nselected_ids_column\nstr\nDataframe column to use for adding selected segment ids to the segmentation layer, by default None\nNone\n\n\nfixed_ids\nint or list\nAdd one or more segment ids to be active, independent of the data, by default None\nNone\n\n\nfixed_id_colors\nlist\nAdd a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default None\nNone\n\n\ncolor_column\nstr\nDataframe column to use for adding selected segment colors, by default None\nNone" - }, - { - "objectID": "reference/nglui.statebuilder.layers.SegmentationLayerConfig.html#parameters", - "href": "reference/nglui.statebuilder.layers.SegmentationLayerConfig.html#parameters", - "title": "SegmentationLayerConfig", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nSegmentation source\nrequired\n\n\nname\n(str, optional)\nLayer name.\nNone\n\n\nselected_ids_column\nstr or list-like, optional.\nColumn name (or list of column names) to use for selected ids.\nNone\n\n\nfixed_ids\nlist-like, optional.\nList of root ids to select directly.\nNone\n\n\nfixed_id_colors\nlist-like, optional.\nList of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.\nNone\n\n\ncolor_column\nstr, optional.\n# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a\nNone\n\n\nactive\nbool, optional.\nIf True, makes the layer selected. Default is False.\nFalse\n\n\nalpha_selected\n\nOpacity of selected segmentations in the image layer. Optional, default is 0.3.\n0.3\n\n\nalpha_3d\n\nOpacity of meshes. Optional, default is 1.\n1\n\n\nalpha_unselected\n\nOpacity of unselected segments. Optional, default is 0.\n0\n\n\nsplit_point_map\n\nIf not None, provides an object to map the dataframe input to multicut points. Default is None.\nNone\n\n\nview_kws\ndict, optional.\nKeyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.\nNone\n\n\ntimestamp\nfloat or datetime, optional.\nTimestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.\nNone" - }, - { - "objectID": "reference/nglui.statebuilder.layers.SegmentationLayerConfig.html#methods", - "href": "reference/nglui.statebuilder.layers.SegmentationLayerConfig.html#methods", - "title": "SegmentationLayerConfig", - "section": "", - "text": "Name\nDescription\n\n\n\n\nadd_selection_map\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\nstatebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nselected_ids_column\nstr\nDataframe column to use for adding selected segment ids to the segmentation layer, by default None\nNone\n\n\nfixed_ids\nint or list\nAdd one or more segment ids to be active, independent of the data, by default None\nNone\n\n\nfixed_id_colors\nlist\nAdd a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default None\nNone\n\n\ncolor_column\nstr\nDataframe column to use for adding selected segment colors, by default None\nNone" - }, - { - "objectID": "reference/nglui.statebuilder.layers.LayerConfigBase.html", - "href": "reference/nglui.statebuilder.layers.LayerConfigBase.html", - "title": "LayerConfigBase", - "section": "", - "text": "statebuilder.layers.LayerConfigBase(self, name, type, source, color, active)\nBase class for configuring layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name for reference and display\nrequired\n\n\ntype\nstr\nLayer type. Usually handled by the subclass\nrequired\n\n\nsource\nstr\nDatasource for the layer\nrequired\n\n\ncolor\nstr\nHex string (with starting hash).\nrequired\n\n\nactive\n(bool)\nIf True, becomes a selected layer.\nrequired" - }, - { - "objectID": "reference/nglui.statebuilder.layers.LayerConfigBase.html#parameters", - "href": "reference/nglui.statebuilder.layers.LayerConfigBase.html#parameters", - "title": "LayerConfigBase", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name for reference and display\nrequired\n\n\ntype\nstr\nLayer type. Usually handled by the subclass\nrequired\n\n\nsource\nstr\nDatasource for the layer\nrequired\n\n\ncolor\nstr\nHex string (with starting hash).\nrequired\n\n\nactive\n(bool)\nIf True, becomes a selected layer.\nrequired" - }, - { - "objectID": "reference/parser.base.point_annotations.html", - "href": "reference/parser.base.point_annotations.html", - "title": "parser.base.point_annotations", - "section": "", - "text": "parser.base.point_annotations(state, layer_name, description=False, linked_segmentations=False, tags=False, group=False)\nGet all point annotation points and other info from a layer.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as JSON dict\nrequired\n\n\nlayer_name\nstr\nLayer name\nrequired\n\n\ndescription\nbool\nIf True, also returns descriptions as well. By default False\nFalse\n\n\nlinked_segmentations\nbool\nIf True, also returns list of linked segmentations, by default False\nFalse\n\n\ntags\nbool\nIf True, also returns list of tags, by default False\nFalse\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nlist\nList of N 3-element points (as list)\n\n\nlist\nList of N strings (or None), only returned if description=True.\n\n\nlist\nList of N lists of object ids. Only returned if linked_segmentations=True.\n\n\nlist\nList of N lists of tag ids. Only returned if tags=True.\n\n\nlist\nList of group ids (as string) or None for annotations. Only returned if group=True" - }, - { - "objectID": "reference/parser.base.point_annotations.html#parameters", - "href": "reference/parser.base.point_annotations.html#parameters", - "title": "parser.base.point_annotations", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as JSON dict\nrequired\n\n\nlayer_name\nstr\nLayer name\nrequired\n\n\ndescription\nbool\nIf True, also returns descriptions as well. By default False\nFalse\n\n\nlinked_segmentations\nbool\nIf True, also returns list of linked segmentations, by default False\nFalse\n\n\ntags\nbool\nIf True, also returns list of tags, by default False\nFalse" - }, - { - "objectID": "reference/parser.base.point_annotations.html#returns", - "href": "reference/parser.base.point_annotations.html#returns", - "title": "parser.base.point_annotations", - "section": "", - "text": "Type\nDescription\n\n\n\n\nlist\nList of N 3-element points (as list)\n\n\nlist\nList of N strings (or None), only returned if description=True.\n\n\nlist\nList of N lists of object ids. Only returned if linked_segmentations=True.\n\n\nlist\nList of N lists of tag ids. Only returned if tags=True.\n\n\nlist\nList of group ids (as string) or None for annotations. Only returned if group=True" - }, - { - "objectID": "reference/parser.base.get_layer.html", - "href": "reference/parser.base.get_layer.html", - "title": "parser.base.get_layer", - "section": "", - "text": "parser.base.get_layer(state, layer_name)\nGets the contents of the layer based on the layer name.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as a JSON dict\nrequired\n\n\nlayer_name\nstr\nName of layer\nrequired\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\ndict\nLayer data contents" - }, - { - "objectID": "reference/parser.base.get_layer.html#parameters", - "href": "reference/parser.base.get_layer.html#parameters", - "title": "parser.base.get_layer", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as a JSON dict\nrequired\n\n\nlayer_name\nstr\nName of layer\nrequired" - }, - { - "objectID": "reference/parser.base.get_layer.html#returns", - "href": "reference/parser.base.get_layer.html#returns", - "title": "parser.base.get_layer", - "section": "", - "text": "Type\nDescription\n\n\n\n\ndict\nLayer data contents" - }, - { - "objectID": "reference/index.html", - "href": "reference/index.html", - "title": "Function Intro", - "section": "", - "text": "This site provides basic documentation for the functions in NGLui. Please see the tutorials for more information about how to use them.\nNote that nglui spans two public submodules responsible for different tasks.\n\nStateBuilder handles data-driven Neuroglancer state generation (hence the package name).\nParser extracts information from Neuroglancer states, as represented by dictionaries." - }, - { - "objectID": "reference/index.html#statebuilder-functions", - "href": "reference/index.html#statebuilder-functions", - "title": "Function Intro", - "section": "StateBuilder Functions", - "text": "StateBuilder Functions\n\nLayers\nInstantiating types of layers\n\n\n\nstatebuilder.ImageLayerConfig\nImage layer configuration class.\n\n\nstatebuilder.SegmentationLayerConfig\nConfiguration class for segmentation layers\n\n\nstatebuilder.AnnotationLayerConfig\nConfiguration class for annotation layers\n\n\n\n\n\nMapping Rules\nRules for mapping data to annotations\n\n\n\nstatebuilder.PointMapper\nSets rules to map dataframes to point annotations\n\n\nstatebuilder.LineMapper\nSets rules to map dataframes to line annotations\n\n\nstatebuilder.SphereMapper\nSets rules to map dataframes to sphere annotations\n\n\nstatebuilder.BoundingBoxMapper\nSets rules to map dataframes to bounding box annotations\n\n\nstatebuilder.SplitPointMapper\nMapper to create split points in a segmentation layer.\n\n\n\n\n\nStateBuilder Classes\nTools for data-generated neuroglancer state creation\n\n\n\nstatebuilder.StateBuilder\nA class for schematic mapping data frames into neuroglancer states.\n\n\nstatebuilder.ChainedStateBuilder\nBuilds a collection of states that sequentially add annotations based on a sequence of dataframes.\n\n\n\n\n\nHelpers\nTools for common types of states\n\n\n\nstatebuilder.helpers.from_client\nGenerate basic image and segmentation layers from a FrameworkClient\n\n\nstatebuilder.helpers.sort_dataframe_by_root_id\nSort a dataframe so that rows belonging to the same root id are together, ordered by how many times the root id appears.\n\n\nstatebuilder.helpers.make_line_statebuilder\nGenerate a state builder that puts points on a single column with a linked segmentaton id\n\n\nstatebuilder.helpers.make_point_statebuilder\nGenerate a state builder that puts points on a single column with a linked segmentaton id\n\n\nstatebuilder.helpers.make_pre_post_statebuilder\nFunction to generate ChainedStateBuilder with optional pre and post synaptic\n\n\nstatebuilder.helpers.make_state_url\nGenerate a url from a neuroglancer state via a state server.\n\n\nstatebuilder.helpers.make_url_robust\nGenerate a url from a neuroglancer state. If too long, return through state server,\n\n\nstatebuilder.helpers.package_state\nAutomate creating a state from a statebuilder and\n\n\nstatebuilder.helpers.make_synapse_neuroglancer_link\nGenerate a neuroglancer link from a synapse dataframe as returned from CAVEclient.materialize.synapse_query.\n\n\nstatebuilder.helpers.make_neuron_neuroglancer_link\nfunction to create a neuroglancer link view of a neuron, optionally including inputs and outputs" - }, - { - "objectID": "reference/index.html#parser", - "href": "reference/index.html#parser", - "title": "Function Intro", - "section": "Parser", - "text": "Parser\n\nParser Tools\nSimple tools for parsing neuroglancer states\n\n\n\nparser.base.layer_names\nGet all layer names in the state\n\n\nparser.base.image_layers\nGet all image layer names in the state\n\n\nparser.base.segmentation_layers\nGet all segmentation layer names in the state\n\n\nparser.base.annotation_layers\nGet all annotation layer names in the state\n\n\nparser.base.tag_dictionary\nGet the tag id to string dictionary for a layer\n\n\nparser.base.get_layer\nGets the contents of the layer based on the layer name.\n\n\nparser.base.view_settings\nGet all data about the view state in neuroglancer: position,\n\n\nparser.base.get_selected_ids\nGet a list of selected ids in a segmentation layer\n\n\nparser.base.point_annotations\nGet all point annotation points and other info from a layer.\n\n\nparser.base.line_annotations\nGet all line annotation points and other info from a layer.\n\n\nparser.base.sphere_annotations\nGet all sphere annotation points and other info from a layer.\n\n\nparser.base.group_annotations\nAll group annotations and their associated points\n\n\nparser.base.extract_multicut\nExtract information entered into the multicut graph operation\n\n\nparser.base.annotation_dataframe\nReturn all annotations across all annotation layers in the state." - }, - { - "objectID": "reference/AnnotationLayerConfig.html", - "href": "reference/AnnotationLayerConfig.html", - "title": "AnnotationLayerConfig", - "section": "", - "text": "statebuilder.layers.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)\nConfiguration class for annotation layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name. By default, ‘annos’\nNone\n\n\ncolor\nstr\nHex color code with an initial #. By default, None\nNone\n\n\nlinked_segmentation_layer\nstr\nName of a linked segmentation layer for selected ids. By default, None\nNone\n\n\nmapping_rules\n(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)\nOne rule or a list of rules mapping data to annotations. By default, []\n[]\n\n\narray_data\nbool\nIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.\nFalse\n\n\ntags\nlist\nList of tags for the layer.\nNone\n\n\nactive\nbool\nIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).\nTrue" - }, - { - "objectID": "reference/AnnotationLayerConfig.html#parameters", - "href": "reference/AnnotationLayerConfig.html#parameters", - "title": "AnnotationLayerConfig", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name. By default, ‘annos’\nNone\n\n\ncolor\nstr\nHex color code with an initial #. By default, None\nNone\n\n\nlinked_segmentation_layer\nstr\nName of a linked segmentation layer for selected ids. By default, None\nNone\n\n\nmapping_rules\n(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)\nOne rule or a list of rules mapping data to annotations. By default, []\n[]\n\n\narray_data\nbool\nIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.\nFalse\n\n\ntags\nlist\nList of tags for the layer.\nNone\n\n\nactive\nbool\nIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).\nTrue" - }, - { - "objectID": "reference/parser.base.get_selected_ids.html", - "href": "reference/parser.base.get_selected_ids.html", - "title": "parser.base.get_selected_ids", - "section": "", - "text": "parser.base.get_selected_ids(state, layer=None)\nGet a list of selected ids in a segmentation layer\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nState dict\nrequired\n\n\nlayer\nstr\nSegmentation layer name, if needed. If None and only one segmentation layer is present, default to it. By default None\nNone\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nlist\nList of root ids." - }, - { - "objectID": "reference/parser.base.get_selected_ids.html#parameters", - "href": "reference/parser.base.get_selected_ids.html#parameters", - "title": "parser.base.get_selected_ids", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nState dict\nrequired\n\n\nlayer\nstr\nSegmentation layer name, if needed. If None and only one segmentation layer is present, default to it. By default None\nNone" - }, - { - "objectID": "reference/parser.base.get_selected_ids.html#returns", - "href": "reference/parser.base.get_selected_ids.html#returns", - "title": "parser.base.get_selected_ids", - "section": "", - "text": "Type\nDescription\n\n\n\n\nlist\nList of root ids." - }, - { - "objectID": "reference/statebuilder.SplitPointMapper.html", - "href": "reference/statebuilder.SplitPointMapper.html", - "title": "statebuilder.SplitPointMapper", - "section": "", - "text": "statebuilder.SplitPointMapper(self, id_column, point_column, team_column, team_names=['red', 'blue'], supervoxel_column=None, focus=True, mapping_set=None)\nMapper to create split points in a segmentation layer.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nid_column\nstr\nColumn name for segment ids. The id column must contain the same id in all rows.\nrequired\n\n\npoint_column\nstr\nName of the column containing points in space.\nrequired\n\n\nteam_column\nstr\nName of the column describing the team for the points. The contents of the column should have two values, by default “red” and “blue”.\nrequired\n\n\nteam_names\nlist\nList of two values for the team names used in the team column. The first is mapped to red points, the second blue. Default is [“red”, “blue”].\n['red', 'blue']\n\n\nsupervoxel_column\nstr or None\nName of a column providing supervoxel ids. If None (default), the supervoxel must be looked up on the server.\nNone\n\n\nfocus\nbool\nIf True, sets the focus on the split tool and sets the position to the center of split points. Default is True.\nTrue\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nSplitPointMapper instance to pass to a segmentation layer." - }, - { - "objectID": "reference/statebuilder.SplitPointMapper.html#parameters", - "href": "reference/statebuilder.SplitPointMapper.html#parameters", - "title": "statebuilder.SplitPointMapper", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nid_column\nstr\nColumn name for segment ids. The id column must contain the same id in all rows.\nrequired\n\n\npoint_column\nstr\nName of the column containing points in space.\nrequired\n\n\nteam_column\nstr\nName of the column describing the team for the points. The contents of the column should have two values, by default “red” and “blue”.\nrequired\n\n\nteam_names\nlist\nList of two values for the team names used in the team column. The first is mapped to red points, the second blue. Default is [“red”, “blue”].\n['red', 'blue']\n\n\nsupervoxel_column\nstr or None\nName of a column providing supervoxel ids. If None (default), the supervoxel must be looked up on the server.\nNone\n\n\nfocus\nbool\nIf True, sets the focus on the split tool and sets the position to the center of split points. Default is True.\nTrue" - }, - { - "objectID": "reference/statebuilder.SplitPointMapper.html#returns", - "href": "reference/statebuilder.SplitPointMapper.html#returns", - "title": "statebuilder.SplitPointMapper", - "section": "", - "text": "Type\nDescription\n\n\n\n\nSplitPointMapper instance to pass to a segmentation layer." - }, - { - "objectID": "reference/statebuilder.helpers.make_synapse_neuroglancer_link.html", - "href": "reference/statebuilder.helpers.make_synapse_neuroglancer_link.html", - "title": "statebuilder.helpers.make_synapse_neuroglancer_link", - "section": "", - "text": "statebuilder.helpers.make_synapse_neuroglancer_link(synapse_df, client, return_as='html', shorten='always', contrast=None, point_column='ctr_pt_position', dataframe_resolution=None, group_connections=True, link_pre_and_post=True, ngl_url=None, view_kws=None, pre_post_columns=None, neuroglancer_link_text='Neuroglancer Link', color=None, split_positions=False, target_site=None)\nGenerate a neuroglancer link from a synapse dataframe as returned from CAVEclient.materialize.synapse_query.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nsynapse_df\npandas.pandas.DataFrame\nDataFrame where each row represents a synapse.\nrequired\n\n\nclient\ncaveclient.caveclient.CAVEclient\nA CAVEclient instance.\nrequired\n\n\nreturn_as\nstr\nHow to return the URL. Valid options are: - ‘html’: Returns an IPython HTML element. - ‘url’: Returns a URL string. - ‘json’: Returns a dictionary representing the Neuroglancer state. Defaults to ‘html’.\n'html'\n\n\nshorten\nstr\nWhether to shorten the link. Valid options are: - ‘always’: Always shorten the link. - ‘if_long’: Shorten the link if it exceeds MAX_URL_LENGTH. - ‘never’: Never shorten the link. Defaults to ‘always’.\n'always'\n\n\ncontrast\nlist\nList of two floats between 0 and 1, specifying the black and white levels. If None, no contrast is set.\nNone\n\n\npoint_column\nstr\nColumn in the DataFrame containing synapse positions. Defaults to ‘ctr_pt_position’.\n'ctr_pt_position'\n\n\ndataframe_resolution\nlist\nList of length 3, specifying the resolution units of the position column. If None, attempts to get the resolution from DataFrame metadata or client.info.viewer_resolution().\nNone\n\n\ngroup_connections\nbool\nWhether to group synapses within the same connection (between the same neurons). Defaults to True.\nTrue\n\n\nlink_pre_and_post\nbool\nWhether to link the synapse annotations to the pre- and post-synaptic partners. Defaults to True.\nTrue\n\n\nngl_url\nstr\nURL of the Neuroglancer instance to use. Defaults to client.info.viewer_site() or DEFAULT_NGL.\nNone\n\n\nview_kws\ndict\nDictionary containing viewer settings for Neuroglancer. Available keys: - show_slices: Boolean, sets if slices are shown in the 3D view. - layout: str, specifies the viewer layout (e.g., ‘xy-3d’, ‘4panel’). - show_axis_lines: Boolean, determines if axis lines are shown. - show_scale_bar: Boolean, toggles the scale bar. - orthographic: Boolean, toggles orthographic view in the 3D pane. - position: 3-element vector, sets the centered location. - zoom_image: float, zoom level for the imagery in nm per voxel. - zoom_3d: float, zoom level for the 3D pane.\nNone\n\n\npre_post_columns\nlist\nList of two strings, specifying the column names for pre- and post-synaptic root_ids. Defaults to [‘pre_pt_root_id’, ‘post_pt_root_id’].\nNone\n\n\nneuroglancer_link_text\nstr\nText to use in the returned HTML link. Defaults to ‘Neuroglancer Link’.\n'Neuroglancer Link'\n\n\ncolor\nlist(float) or str\nColor of synapse points as an RGB list [0, 1], hex string, or common name.\nNone\n\n\nsplit_positions\nbool\nWhether the position column is split into x, y, and z columns.\nFalse\n\n\ntarget_site\nstr\nType of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use seunglab for a Seung-lab branch and either mainline or cave-explorer for the Cave Explorer or main Google branch.\nNone\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nIPython.HTML, str, or dict\nRepresentation of the Neuroglancer state, depending on the return_as parameter.\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nValueError\nIf the specified point_column is not found in the DataFrame." - }, - { - "objectID": "reference/statebuilder.helpers.make_synapse_neuroglancer_link.html#parameters", - "href": "reference/statebuilder.helpers.make_synapse_neuroglancer_link.html#parameters", - "title": "statebuilder.helpers.make_synapse_neuroglancer_link", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nsynapse_df\npandas.pandas.DataFrame\nDataFrame where each row represents a synapse.\nrequired\n\n\nclient\ncaveclient.caveclient.CAVEclient\nA CAVEclient instance.\nrequired\n\n\nreturn_as\nstr\nHow to return the URL. Valid options are: - ‘html’: Returns an IPython HTML element. - ‘url’: Returns a URL string. - ‘json’: Returns a dictionary representing the Neuroglancer state. Defaults to ‘html’.\n'html'\n\n\nshorten\nstr\nWhether to shorten the link. Valid options are: - ‘always’: Always shorten the link. - ‘if_long’: Shorten the link if it exceeds MAX_URL_LENGTH. - ‘never’: Never shorten the link. Defaults to ‘always’.\n'always'\n\n\ncontrast\nlist\nList of two floats between 0 and 1, specifying the black and white levels. If None, no contrast is set.\nNone\n\n\npoint_column\nstr\nColumn in the DataFrame containing synapse positions. Defaults to ‘ctr_pt_position’.\n'ctr_pt_position'\n\n\ndataframe_resolution\nlist\nList of length 3, specifying the resolution units of the position column. If None, attempts to get the resolution from DataFrame metadata or client.info.viewer_resolution().\nNone\n\n\ngroup_connections\nbool\nWhether to group synapses within the same connection (between the same neurons). Defaults to True.\nTrue\n\n\nlink_pre_and_post\nbool\nWhether to link the synapse annotations to the pre- and post-synaptic partners. Defaults to True.\nTrue\n\n\nngl_url\nstr\nURL of the Neuroglancer instance to use. Defaults to client.info.viewer_site() or DEFAULT_NGL.\nNone\n\n\nview_kws\ndict\nDictionary containing viewer settings for Neuroglancer. Available keys: - show_slices: Boolean, sets if slices are shown in the 3D view. - layout: str, specifies the viewer layout (e.g., ‘xy-3d’, ‘4panel’). - show_axis_lines: Boolean, determines if axis lines are shown. - show_scale_bar: Boolean, toggles the scale bar. - orthographic: Boolean, toggles orthographic view in the 3D pane. - position: 3-element vector, sets the centered location. - zoom_image: float, zoom level for the imagery in nm per voxel. - zoom_3d: float, zoom level for the 3D pane.\nNone\n\n\npre_post_columns\nlist\nList of two strings, specifying the column names for pre- and post-synaptic root_ids. Defaults to [‘pre_pt_root_id’, ‘post_pt_root_id’].\nNone\n\n\nneuroglancer_link_text\nstr\nText to use in the returned HTML link. Defaults to ‘Neuroglancer Link’.\n'Neuroglancer Link'\n\n\ncolor\nlist(float) or str\nColor of synapse points as an RGB list [0, 1], hex string, or common name.\nNone\n\n\nsplit_positions\nbool\nWhether the position column is split into x, y, and z columns.\nFalse\n\n\ntarget_site\nstr\nType of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use seunglab for a Seung-lab branch and either mainline or cave-explorer for the Cave Explorer or main Google branch.\nNone" - }, - { - "objectID": "reference/statebuilder.helpers.make_synapse_neuroglancer_link.html#returns", - "href": "reference/statebuilder.helpers.make_synapse_neuroglancer_link.html#returns", - "title": "statebuilder.helpers.make_synapse_neuroglancer_link", - "section": "", - "text": "Type\nDescription\n\n\n\n\nIPython.HTML, str, or dict\nRepresentation of the Neuroglancer state, depending on the return_as parameter." - }, - { - "objectID": "reference/statebuilder.helpers.make_synapse_neuroglancer_link.html#raises", - "href": "reference/statebuilder.helpers.make_synapse_neuroglancer_link.html#raises", - "title": "statebuilder.helpers.make_synapse_neuroglancer_link", - "section": "", - "text": "Type\nDescription\n\n\n\n\nValueError\nIf the specified point_column is not found in the DataFrame." - }, - { - "objectID": "reference/nglui.statebuilder.statebuilder.StateBuilder.initialize_state.html", - "href": "reference/nglui.statebuilder.statebuilder.StateBuilder.initialize_state.html", - "title": "initialize_state", - "section": "", - "text": "statebuilder.statebuilder.StateBuilder.initialize_state(base_state=None, target_site=None)\nGenerate a new Neuroglancer state with layers as needed for the schema.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nbase_state\nstr\nOptional initial state to build on, described by its JSON. By default None.\nNone" - }, - { - "objectID": "reference/nglui.statebuilder.statebuilder.StateBuilder.initialize_state.html#parameters", - "href": "reference/nglui.statebuilder.statebuilder.StateBuilder.initialize_state.html#parameters", - "title": "initialize_state", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nbase_state\nstr\nOptional initial state to build on, described by its JSON. By default None.\nNone" - }, - { - "objectID": "reference/statebuilder.helpers.package_state.html", - "href": "reference/statebuilder.helpers.package_state.html", - "title": "statebuilder.helpers.package_state", - "section": "", - "text": "statebuilder.helpers.package_state(df, sb, client, shorten='if_long', return_as='url', ngl_url=None, link_text='Neuroglancer Link', target_site=None)\nAutomate creating a state from a statebuilder and a dataframe, return it in the desired format, shortening if desired." - }, - { - "objectID": "reference/statebuilder.helpers.package_state.html#parameters", - "href": "reference/statebuilder.helpers.package_state.html#parameters", - "title": "statebuilder.helpers.package_state", - "section": "Parameters", - "text": "Parameters\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\ndf\npandas.pandas.DataFrame\nDataframe to pass through statebuilder\nrequired\n\n\nsb\nnglui.statebuilder.statebuilder.nglui.statebuilder.statebuilder.StateBuilder\nStatebuilder to use to render data for link\nrequired\n\n\nclient\ncaveclient.CAVEclient\nCAVEclient configured with a state server\nrequired\n\n\nshorten\nstr\nHow to shorten link. one of ‘if_long’, ‘always’, ‘never’. ‘if_long’ will use the state server to shorten links longer than nglui.statebuilder.MAX_URL_LENGTH (set to 1,750,000). ‘always’ will always use the state server to shorten the url ‘never’ will always return the full url. Defaults to “if_long”.\n'if_long'\n\n\nreturn_as\nstr\nHow to return the state. one of ‘html’, ‘url’, ‘json’. ‘html’ will return an ipython clickable link ‘url’ will return a string with the url ‘json’ will return the state as a dictionary\n'url'\n\n\nngl_url\nstr\nNeuroglancer deployment URL, by default None\nNone\n\n\nlink_text\nstr\nText to use for the link, by default “Neuroglancer Link”\n'Neuroglancer Link'\n\n\ntarget_site\nstr\nType of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use seunglab for a Seung-lab branch and either mainline or cave-explorer for the Cave Explorer or main Google branch.\nNone" - }, - { - "objectID": "reference/statebuilder.helpers.package_state.html#returns", - "href": "reference/statebuilder.helpers.package_state.html#returns", - "title": "statebuilder.helpers.package_state", - "section": "Returns", - "text": "Returns\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\n(IPython.display.HTML, str or dict)\nstate in format specified by return_as" - }, - { - "objectID": "reference/parser.base.line_annotations.html", - "href": "reference/parser.base.line_annotations.html", - "title": "parser.base.line_annotations", - "section": "", - "text": "parser.base.line_annotations(state, layer_name, description=False, linked_segmentations=False, tags=False, group=False)\nGet all line annotation points and other info from a layer.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as JSON dict\nrequired\n\n\nlayer_name\nstr\nLayer name\nrequired\n\n\ndescription\nbool\nIf True, also returns descriptions as well. By default False\nFalse\n\n\nlinked_segmentations\nbool\nIf True, also returns list of linked segmentations, by default False\nFalse\n\n\ntags\nbool\nIf True, also returns list of tags, by default False\nFalse\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nlist\nList of N 3-element points (as list) of the first point in each line.\n\n\nlist\nList of N 3-element points (as list) of the second point in each line.\n\n\nlist\nList of N strings (or None), only returned if description=True.\n\n\nlist\nList of N lists of object ids. Only returned if linked_segmentations=True.\n\n\nlist\nList of N lists of tag ids. Only returned if tags=True.\n\n\nlist\nList of group ids (as string) or None for annotations. Only returned if group=True" - }, - { - "objectID": "reference/parser.base.line_annotations.html#parameters", - "href": "reference/parser.base.line_annotations.html#parameters", - "title": "parser.base.line_annotations", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as JSON dict\nrequired\n\n\nlayer_name\nstr\nLayer name\nrequired\n\n\ndescription\nbool\nIf True, also returns descriptions as well. By default False\nFalse\n\n\nlinked_segmentations\nbool\nIf True, also returns list of linked segmentations, by default False\nFalse\n\n\ntags\nbool\nIf True, also returns list of tags, by default False\nFalse" - }, - { - "objectID": "reference/parser.base.line_annotations.html#returns", - "href": "reference/parser.base.line_annotations.html#returns", - "title": "parser.base.line_annotations", - "section": "", - "text": "Type\nDescription\n\n\n\n\nlist\nList of N 3-element points (as list) of the first point in each line.\n\n\nlist\nList of N 3-element points (as list) of the second point in each line.\n\n\nlist\nList of N strings (or None), only returned if description=True.\n\n\nlist\nList of N lists of object ids. Only returned if linked_segmentations=True.\n\n\nlist\nList of N lists of tag ids. Only returned if tags=True.\n\n\nlist\nList of group ids (as string) or None for annotations. Only returned if group=True" - }, - { - "objectID": "reference/statebuilder.AnnotationLayerConfig.html", - "href": "reference/statebuilder.AnnotationLayerConfig.html", - "title": "statebuilder.AnnotationLayerConfig", - "section": "", - "text": "statebuilder.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)\nConfiguration class for annotation layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name. By default, ‘annos’\nNone\n\n\ncolor\nstr\nHex color code with an initial #. By default, None\nNone\n\n\nlinked_segmentation_layer\nstr\nName of a linked segmentation layer for selected ids. By default, None\nNone\n\n\nmapping_rules\n(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)\nOne rule or a list of rules mapping data to annotations. By default, []\n[]\n\n\narray_data\nbool\nIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.\nFalse\n\n\ntags\nlist\nList of tags for the layer.\nNone\n\n\nactive\nbool\nIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).\nTrue" - }, - { - "objectID": "reference/statebuilder.AnnotationLayerConfig.html#parameters", - "href": "reference/statebuilder.AnnotationLayerConfig.html#parameters", - "title": "statebuilder.AnnotationLayerConfig", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name. By default, ‘annos’\nNone\n\n\ncolor\nstr\nHex color code with an initial #. By default, None\nNone\n\n\nlinked_segmentation_layer\nstr\nName of a linked segmentation layer for selected ids. By default, None\nNone\n\n\nmapping_rules\n(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)\nOne rule or a list of rules mapping data to annotations. By default, []\n[]\n\n\narray_data\nbool\nIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.\nFalse\n\n\ntags\nlist\nList of tags for the layer.\nNone\n\n\nactive\nbool\nIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).\nTrue" - }, - { - "objectID": "reference/statebuilder.LineMapper.html", - "href": "reference/statebuilder.LineMapper.html", - "title": "statebuilder.LineMapper", - "section": "", - "text": "statebuilder.LineMapper(self, point_column_a=None, point_column_b=None, description_column=None, linked_segmentation_column=None, tag_column=None, group_column=None, gather_linked_segmentations=True, share_linked_segmentations=False, set_position=True, multipoint=False, collapse_groups=False, split_positions=False, mapping_set=None)\nSets rules to map dataframes to line annotations\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\npoint_column_a\nstr\nColumn name with 3d position data for the first point of the line. Must be set if array_data is False (the default)\nNone\n\n\npoint_column_b\nstr\nColumn name with 3d position data for the first point of the line. Must be set if array_data is False (the default)\nNone\n\n\ndescription_column\nstr\nColumn name with string data for annotation descriptions\nNone\n\n\nlinked_segmentation_column\nstr\nColumn name for root ids to link to annotations\nNone\n\n\ntag_column\nstr\nColumn name for categorical tag data. Tags must match those set in the annotation layer.\nNone\n\n\ngroup_column\nstr\nColumn name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation.\nNone\n\n\nset_position\nbool\nIf set to True, moves the position to center on the first point in the data (using point_column_a).\nTrue\n\n\nmultipoint\n\nIf True, permits multiple points in a given row, sharing data in other columns. Each point row must have the same number of points. Default is False.\nFalse\n\n\ncollapse_groups\n\nIf True, groups are toggled closed in the annotation view.\nFalse\n\n\nmapping_set\n\nIf set, assumes data is passed as a dictionary and uses this string to as the key for the data to use.\nNone" - }, - { - "objectID": "reference/statebuilder.LineMapper.html#parameters", - "href": "reference/statebuilder.LineMapper.html#parameters", - "title": "statebuilder.LineMapper", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\npoint_column_a\nstr\nColumn name with 3d position data for the first point of the line. Must be set if array_data is False (the default)\nNone\n\n\npoint_column_b\nstr\nColumn name with 3d position data for the first point of the line. Must be set if array_data is False (the default)\nNone\n\n\ndescription_column\nstr\nColumn name with string data for annotation descriptions\nNone\n\n\nlinked_segmentation_column\nstr\nColumn name for root ids to link to annotations\nNone\n\n\ntag_column\nstr\nColumn name for categorical tag data. Tags must match those set in the annotation layer.\nNone\n\n\ngroup_column\nstr\nColumn name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation.\nNone\n\n\nset_position\nbool\nIf set to True, moves the position to center on the first point in the data (using point_column_a).\nTrue\n\n\nmultipoint\n\nIf True, permits multiple points in a given row, sharing data in other columns. Each point row must have the same number of points. Default is False.\nFalse\n\n\ncollapse_groups\n\nIf True, groups are toggled closed in the annotation view.\nFalse\n\n\nmapping_set\n\nIf set, assumes data is passed as a dictionary and uses this string to as the key for the data to use.\nNone" - }, - { - "objectID": "reference/SegmentationLayerConfig.html", - "href": "reference/SegmentationLayerConfig.html", - "title": "SegmentationLayerConfig", - "section": "", - "text": "statebuilder.layers.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)\nConfiguration class for segmentation layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nSegmentation source\nrequired\n\n\nname\n(str, optional)\nLayer name.\nNone\n\n\nselected_ids_column\nstr or list-like, optional.\nColumn name (or list of column names) to use for selected ids.\nNone\n\n\nfixed_ids\nlist-like, optional.\nList of root ids to select directly.\nNone\n\n\nfixed_id_colors\nlist-like, optional.\nList of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.\nNone\n\n\ncolor_column\nstr, optional.\n# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a\nNone\n\n\nactive\nbool, optional.\nIf True, makes the layer selected. Default is False.\nFalse\n\n\nalpha_selected\n\nOpacity of selected segmentations in the image layer. Optional, default is 0.3.\n0.3\n\n\nalpha_3d\n\nOpacity of meshes. Optional, default is 1.\n1\n\n\nalpha_unselected\n\nOpacity of unselected segments. Optional, default is 0.\n0\n\n\nsplit_point_map\n\nIf not None, provides an object to map the dataframe input to multicut points. Default is None.\nNone\n\n\nview_kws\ndict, optional.\nKeyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.\nNone\n\n\ntimestamp\nfloat or datetime, optional.\nTimestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.\nNone\n\n\n\n\n\n\n\n\n\nName\nDescription\n\n\n\n\nadd_selection_map\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\nstatebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nselected_ids_column\nstr\nDataframe column to use for adding selected segment ids to the segmentation layer, by default None\nNone\n\n\nfixed_ids\nint or list\nAdd one or more segment ids to be active, independent of the data, by default None\nNone\n\n\nfixed_id_colors\nlist\nAdd a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default None\nNone\n\n\ncolor_column\nstr\nDataframe column to use for adding selected segment colors, by default None\nNone" - }, - { - "objectID": "reference/SegmentationLayerConfig.html#parameters", - "href": "reference/SegmentationLayerConfig.html#parameters", - "title": "SegmentationLayerConfig", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nSegmentation source\nrequired\n\n\nname\n(str, optional)\nLayer name.\nNone\n\n\nselected_ids_column\nstr or list-like, optional.\nColumn name (or list of column names) to use for selected ids.\nNone\n\n\nfixed_ids\nlist-like, optional.\nList of root ids to select directly.\nNone\n\n\nfixed_id_colors\nlist-like, optional.\nList of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.\nNone\n\n\ncolor_column\nstr, optional.\n# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a\nNone\n\n\nactive\nbool, optional.\nIf True, makes the layer selected. Default is False.\nFalse\n\n\nalpha_selected\n\nOpacity of selected segmentations in the image layer. Optional, default is 0.3.\n0.3\n\n\nalpha_3d\n\nOpacity of meshes. Optional, default is 1.\n1\n\n\nalpha_unselected\n\nOpacity of unselected segments. Optional, default is 0.\n0\n\n\nsplit_point_map\n\nIf not None, provides an object to map the dataframe input to multicut points. Default is None.\nNone\n\n\nview_kws\ndict, optional.\nKeyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.\nNone\n\n\ntimestamp\nfloat or datetime, optional.\nTimestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.\nNone" - }, - { - "objectID": "reference/SegmentationLayerConfig.html#methods", - "href": "reference/SegmentationLayerConfig.html#methods", - "title": "SegmentationLayerConfig", - "section": "", - "text": "Name\nDescription\n\n\n\n\nadd_selection_map\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\nstatebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nselected_ids_column\nstr\nDataframe column to use for adding selected segment ids to the segmentation layer, by default None\nNone\n\n\nfixed_ids\nint or list\nAdd one or more segment ids to be active, independent of the data, by default None\nNone\n\n\nfixed_id_colors\nlist\nAdd a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default None\nNone\n\n\ncolor_column\nstr\nDataframe column to use for adding selected segment colors, by default None\nNone" - }, - { - "objectID": "reference/statebuilder.helpers.make_line_statebuilder.html", - "href": "reference/statebuilder.helpers.make_line_statebuilder.html", - "title": "statebuilder.helpers.make_line_statebuilder", - "section": "", - "text": "statebuilder.helpers.make_line_statebuilder(client, point_column_a='pre_pt_position', point_column_b='post_pt_position', linked_seg_column='pt_root_id', description_column=None, tag_column=None, data_resolution=None, group_column=None, contrast=None, view_kws=None, point_layer_name='lines', color=None, split_positions=False)\nGenerate a state builder that puts points on a single column with a linked segmentaton id\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nclient\ncaveclient.CAVEclient\nCAVEclient configured for the datastack desired\nrequired\n\n\npoint_column_a\nstr\ncolumn in dataframe to pull points from. Defaults to “pre_pt_position”.\n'pre_pt_position'\n\n\npoint_column_b\nstr\ncolumn in dataframe to pull points from. Defaults to “post_pt_position”.\n'post_pt_position'\n\n\nlinked_seg_column\nstr\ncolumn to link to segmentation, None for no column. Defaults to “pt_root_id”.\n'pt_root_id'\n\n\ngroup_column\nstr, or list\ncolumn(s) to group annotations by, None for no grouping (default=None)\nNone\n\n\ntag_column\nstr\ncolumn to use for tags, None for no tags (default=None)\nNone\n\n\ndescription_column\nstr\ncolumn to use for descriptions, None for no descriptions (default=None)\nNone\n\n\ncontrast\nlist\nTwo elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set.\nNone\n\n\nview_kws\ndict\ndictionary of view keywords to configure neuroglancer view\nNone\n\n\nsplit_positions\nbool\nwhether the position column into x,y,z columns. Defaults to False.\nFalse\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\n\nA statebuilder to make points with linked segmentations" - }, - { - "objectID": "reference/statebuilder.helpers.make_line_statebuilder.html#parameters", - "href": "reference/statebuilder.helpers.make_line_statebuilder.html#parameters", - "title": "statebuilder.helpers.make_line_statebuilder", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nclient\ncaveclient.CAVEclient\nCAVEclient configured for the datastack desired\nrequired\n\n\npoint_column_a\nstr\ncolumn in dataframe to pull points from. Defaults to “pre_pt_position”.\n'pre_pt_position'\n\n\npoint_column_b\nstr\ncolumn in dataframe to pull points from. Defaults to “post_pt_position”.\n'post_pt_position'\n\n\nlinked_seg_column\nstr\ncolumn to link to segmentation, None for no column. Defaults to “pt_root_id”.\n'pt_root_id'\n\n\ngroup_column\nstr, or list\ncolumn(s) to group annotations by, None for no grouping (default=None)\nNone\n\n\ntag_column\nstr\ncolumn to use for tags, None for no tags (default=None)\nNone\n\n\ndescription_column\nstr\ncolumn to use for descriptions, None for no descriptions (default=None)\nNone\n\n\ncontrast\nlist\nTwo elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set.\nNone\n\n\nview_kws\ndict\ndictionary of view keywords to configure neuroglancer view\nNone\n\n\nsplit_positions\nbool\nwhether the position column into x,y,z columns. Defaults to False.\nFalse" - }, - { - "objectID": "reference/statebuilder.helpers.make_line_statebuilder.html#returns", - "href": "reference/statebuilder.helpers.make_line_statebuilder.html#returns", - "title": "statebuilder.helpers.make_line_statebuilder", - "section": "", - "text": "Type\nDescription\n\n\n\n\n\nA statebuilder to make points with linked segmentations" - }, - { - "objectID": "reference/parser.base.extract_multicut.html", - "href": "reference/parser.base.extract_multicut.html", - "title": "parser.base.extract_multicut", - "section": "", - "text": "parser.base.extract_multicut(state, seg_layer=None)\nExtract information entered into the multicut graph operation\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state\nrequired\n\n\nseg_layer\nstr\nName of a segmentation layer or None. If None, the function will check how many segmentation layers there are and, if only one exits, choose it. If more than one segmentation layer is present, it errors. By default None\nNone\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nnumpy.numpy.array\nNx3 array of points selected\n\n\nnumpy.numpy.array\nN array with ‘source’ or ‘sink’, depending on which side the point is on.\n\n\nnumpy.numpy.array\nN array with selected supervoxel. If only points are selected (e.g. via clicking on the mesh), the value will be NaN.\n\n\nint\nRoot id of the object to split" - }, - { - "objectID": "reference/parser.base.extract_multicut.html#parameters", - "href": "reference/parser.base.extract_multicut.html#parameters", - "title": "parser.base.extract_multicut", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state\nrequired\n\n\nseg_layer\nstr\nName of a segmentation layer or None. If None, the function will check how many segmentation layers there are and, if only one exits, choose it. If more than one segmentation layer is present, it errors. By default None\nNone" - }, - { - "objectID": "reference/parser.base.extract_multicut.html#returns", - "href": "reference/parser.base.extract_multicut.html#returns", - "title": "parser.base.extract_multicut", - "section": "", - "text": "Type\nDescription\n\n\n\n\nnumpy.numpy.array\nNx3 array of points selected\n\n\nnumpy.numpy.array\nN array with ‘source’ or ‘sink’, depending on which side the point is on.\n\n\nnumpy.numpy.array\nN array with selected supervoxel. If only points are selected (e.g. via clicking on the mesh), the value will be NaN.\n\n\nint\nRoot id of the object to split" - }, - { - "objectID": "tutorials/statebuilder.html", - "href": "tutorials/statebuilder.html", - "title": "StateBuilder Tutorial", - "section": "", - "text": "The StateBuilder module is designed to allow rules-based generation of Neuroglancer states based on DataFrames or numpy arrays." - }, - { - "objectID": "tutorials/statebuilder.html#background", - "href": "tutorials/statebuilder.html#background", - "title": "StateBuilder Tutorial", - "section": "Background", - "text": "Background\nNeuroglancer is a web application for viewing large volumetric imagery and segmentation data, as well as meshes and annotations like points or lines. Data in Neuroglancer is organized into layers, where each layer is configured to show information like images, segmentation, or annotations. Each layer can show one type of data and has different properties associated with it. In addition, Neuroglancer also stores the exact view that the user sees — what location in the data is centered, the orientation and zoom level of the camera, and more. Collectively, the information underlying both layers and the user view is refered to as the “state,” which is stored as a collection of key/value pairs.\nStateBuilder follows this model by defining a set of rules for initializing layers. For layers that contain properties like selected segment ids or annotations, this configuration involves specifying how to map DataFrame columns to selected segmentations or annotations such as synapses. The general pattern is that you build up a collection of configurations for individual layers, assemble them into a StateBuilder object, and then pass a dataframe through this object to render out a state." - }, - { - "objectID": "tutorials/statebuilder.html#simple-layers-and-statebuilder", - "href": "tutorials/statebuilder.html#simple-layers-and-statebuilder", - "title": "StateBuilder Tutorial", - "section": "Simple Layers and StateBuilder", - "text": "Simple Layers and StateBuilder\nfrom nglui import statebuilder\n\nimg = statebuilder.ImageLayerConfig(\n source=client.info.image_source(),\n contrast_controls=True, # this just puts in the code needed to manually adjust contrast\n)\n\nseg = statebuilder.SegmentationLayerConfig(\n source=client.info.segmentation_source(),\n)" - }, - { - "objectID": "tutorials/statebuilder.html#data-driven-states", - "href": "tutorials/statebuilder.html#data-driven-states", - "title": "StateBuilder Tutorial", - "section": "Data-driven States", - "text": "Data-driven States" - }, - { - "objectID": "tutorials/parser.html", - "href": "tutorials/parser.html", - "title": "Parser Tutorial", - "section": "", - "text": "Parser Tutorial\nBasics of how to use nglui parser." - }, - { - "objectID": "index.html", - "href": "index.html", - "title": "Docs", - "section": "", - "text": "This is a Quarto website.\nTo learn more about Quarto websites visit https://quarto.org/docs/websites." - }, - { - "objectID": "about.html", - "href": "about.html", - "title": "About", - "section": "", - "text": "About this site" - }, - { - "objectID": "tutorials/index.html", - "href": "tutorials/index.html", - "title": "Tutorials", - "section": "", - "text": "Tutorials\nDo one thing, then another." - }, - { - "objectID": "reference/parser.base.segmentation_layers.html", - "href": "reference/parser.base.segmentation_layers.html", - "title": "parser.base.segmentation_layers", - "section": "", - "text": "parser.base.segmentation_layers(state)\nGet all segmentation layer names in the state\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as a JSON dict\nrequired\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nlist\nList of layer names" - }, - { - "objectID": "reference/parser.base.segmentation_layers.html#parameters", - "href": "reference/parser.base.segmentation_layers.html#parameters", - "title": "parser.base.segmentation_layers", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as a JSON dict\nrequired" - }, - { - "objectID": "reference/parser.base.segmentation_layers.html#returns", - "href": "reference/parser.base.segmentation_layers.html#returns", - "title": "parser.base.segmentation_layers", - "section": "", - "text": "Type\nDescription\n\n\n\n\nlist\nList of layer names" - }, - { - "objectID": "reference/ChainedStateBuilder.html", - "href": "reference/ChainedStateBuilder.html", - "title": "ChainedStateBuilder", - "section": "", - "text": "statebuilder.statebuilder.ChainedStateBuilder(self, statebuilders)\nBuilds a collection of states that sequentially add annotations based on a sequence of dataframes.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstatebuilders\nlist\nList of DataStateBuilders, in same order as dataframes will be passed\nrequired\n\n\n\n\n\n\n\n\n\nName\nDescription\n\n\n\n\nrender_state\nGenerate a single neuroglancer state by addatively applying an ordered collection of\n\n\n\n\n\nstatebuilder.statebuilder.ChainedStateBuilder.render_state(data_list=None, base_state=None, return_as='url', url_prefix=default_neuroglancer_base, link_text='Neuroglancer Link', target_site=None)\nGenerate a single neuroglancer state by addatively applying an ordered collection of dataframes to an collection of StateBuilder renders. Parameters data_list : Collection of DataFrame. The order must match the order of StateBuilders contained in the class on creation. base_state : JSON neuroglancer state (optional, default is None). Used as a base state for adding everything else to. return_as: [‘url’, ‘viewer’, ‘html’, ‘json’]. optional, default=‘url’. Sets how the state is returned. Note that if a viewer is returned, the state is not reset to default. url_prefix: string, optional (default is https://neuromancer-seung-import.appspot.com). Overrides the default neuroglancer url for url generation." - }, - { - "objectID": "reference/ChainedStateBuilder.html#parameters", - "href": "reference/ChainedStateBuilder.html#parameters", - "title": "ChainedStateBuilder", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstatebuilders\nlist\nList of DataStateBuilders, in same order as dataframes will be passed\nrequired" - }, - { - "objectID": "reference/ChainedStateBuilder.html#methods", - "href": "reference/ChainedStateBuilder.html#methods", - "title": "ChainedStateBuilder", - "section": "", - "text": "Name\nDescription\n\n\n\n\nrender_state\nGenerate a single neuroglancer state by addatively applying an ordered collection of\n\n\n\n\n\nstatebuilder.statebuilder.ChainedStateBuilder.render_state(data_list=None, base_state=None, return_as='url', url_prefix=default_neuroglancer_base, link_text='Neuroglancer Link', target_site=None)\nGenerate a single neuroglancer state by addatively applying an ordered collection of dataframes to an collection of StateBuilder renders. Parameters data_list : Collection of DataFrame. The order must match the order of StateBuilders contained in the class on creation. base_state : JSON neuroglancer state (optional, default is None). Used as a base state for adding everything else to. return_as: [‘url’, ‘viewer’, ‘html’, ‘json’]. optional, default=‘url’. Sets how the state is returned. Note that if a viewer is returned, the state is not reset to default. url_prefix: string, optional (default is https://neuromancer-seung-import.appspot.com). Overrides the default neuroglancer url for url generation." - }, - { - "objectID": "reference/statebuilder.helpers.make_pre_post_statebuilder.html", - "href": "reference/statebuilder.helpers.make_pre_post_statebuilder.html", - "title": "statebuilder.helpers.make_pre_post_statebuilder", - "section": "", - "text": "statebuilder.helpers.make_pre_post_statebuilder(client, show_inputs=False, show_outputs=False, contrast=None, view_kws=None, point_column='ctr_pt_position', pre_pt_root_id_col='pre_pt_root_id', post_pt_root_id_col='post_pt_root_id', dataframe_resolution_pre=None, dataframe_resolution_post=None, input_layer_name='syns_in', output_layer_name='syns_out', input_layer_color=DEFAULT_POSTSYN_COLOR, output_layer_color=DEFAULT_PRESYN_COLOR, split_positions=False)\nFunction to generate ChainedStateBuilder with optional pre and post synaptic annotation layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nclient\ncaveclient.CAVEclient\na CAVEclient configured for datastack to visualize\nrequired\n\n\nshow_inputs\nbool\nwhether to show input synapses. Defaults to False.\nFalse\n\n\nshow_outputs\nbool\nwhether to show output synapses.. Defaults to False.\nFalse\n\n\ncontrast\nlist\nTwo elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set.\nNone\n\n\nview_kws\ndict\nview_kws to configure statebuilder, see nglui.StateBuilder. Defaults to None. keys are: show_slices: Boolean sets if slices are shown in the 3d view. Defaults to False. layout: str xy-3d/xz-3d/yz-3d (sections plus 3d pane), xy/yz/xz/3d (only one pane), or 4panel (all panes). Default is xy-3d. show_axis_lines: Boolean determines if the axis lines are shown in the middle of each view. show_scale_bar: Boolean toggles showing the scale bar. orthographic : Boolean toggles orthographic view in the 3d pane. position* : 3-element vector determines the centered location. zoom_image : float Zoom level for the imagery in units of nm per voxel. Defaults to 8. zoom_3d : float Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are more zoomed in.\nNone\n\n\npoint_column\nstr\ncolumn to pull points for synapses from. Defaults to “ctr_pt_position”.\n'ctr_pt_position'\n\n\npre_pt_root_id_col\nstr\ncolumn to pull pre synaptic ids for synapses from. Defaults to “pre_pt_root_id”.\n'pre_pt_root_id'\n\n\npost_pt_root_id_col\nstr\ncolumn to pull post synaptic ids for synapses from. Defaults to “post_pt_root_id”.\n'post_pt_root_id'\n\n\ninput_layer_name\nstr\nname of layer for inputs. Defaults to “syns_in”.\n'syns_in'\n\n\noutput_layer_name\nstr\nname of layer for outputs. Defaults to “syns_out”.\n'syns_out'\n\n\nsplit_positions\nbool\nwhether the position column is split into x,y,z columns. Defaults to False.\nFalse\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\n\nAn instance of a ChainedStateBuilder configured to accept a list starting with None followed by optionally synapse input dataframe followed by optionally synapse output dataframe." - }, - { - "objectID": "reference/statebuilder.helpers.make_pre_post_statebuilder.html#parameters", - "href": "reference/statebuilder.helpers.make_pre_post_statebuilder.html#parameters", - "title": "statebuilder.helpers.make_pre_post_statebuilder", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nclient\ncaveclient.CAVEclient\na CAVEclient configured for datastack to visualize\nrequired\n\n\nshow_inputs\nbool\nwhether to show input synapses. Defaults to False.\nFalse\n\n\nshow_outputs\nbool\nwhether to show output synapses.. Defaults to False.\nFalse\n\n\ncontrast\nlist\nTwo elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set.\nNone\n\n\nview_kws\ndict\nview_kws to configure statebuilder, see nglui.StateBuilder. Defaults to None. keys are: show_slices: Boolean sets if slices are shown in the 3d view. Defaults to False. layout: str xy-3d/xz-3d/yz-3d (sections plus 3d pane), xy/yz/xz/3d (only one pane), or 4panel (all panes). Default is xy-3d. show_axis_lines: Boolean determines if the axis lines are shown in the middle of each view. show_scale_bar: Boolean toggles showing the scale bar. orthographic : Boolean toggles orthographic view in the 3d pane. position* : 3-element vector determines the centered location. zoom_image : float Zoom level for the imagery in units of nm per voxel. Defaults to 8. zoom_3d : float Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are more zoomed in.\nNone\n\n\npoint_column\nstr\ncolumn to pull points for synapses from. Defaults to “ctr_pt_position”.\n'ctr_pt_position'\n\n\npre_pt_root_id_col\nstr\ncolumn to pull pre synaptic ids for synapses from. Defaults to “pre_pt_root_id”.\n'pre_pt_root_id'\n\n\npost_pt_root_id_col\nstr\ncolumn to pull post synaptic ids for synapses from. Defaults to “post_pt_root_id”.\n'post_pt_root_id'\n\n\ninput_layer_name\nstr\nname of layer for inputs. Defaults to “syns_in”.\n'syns_in'\n\n\noutput_layer_name\nstr\nname of layer for outputs. Defaults to “syns_out”.\n'syns_out'\n\n\nsplit_positions\nbool\nwhether the position column is split into x,y,z columns. Defaults to False.\nFalse" - }, - { - "objectID": "reference/statebuilder.helpers.make_pre_post_statebuilder.html#returns", - "href": "reference/statebuilder.helpers.make_pre_post_statebuilder.html#returns", - "title": "statebuilder.helpers.make_pre_post_statebuilder", - "section": "", - "text": "Type\nDescription\n\n\n\n\n\nAn instance of a ChainedStateBuilder configured to accept a list starting with None followed by optionally synapse input dataframe followed by optionally synapse output dataframe." - }, - { - "objectID": "reference/statebuilder.helpers.make_point_statebuilder.html", - "href": "reference/statebuilder.helpers.make_point_statebuilder.html", - "title": "statebuilder.helpers.make_point_statebuilder", - "section": "", - "text": "statebuilder.helpers.make_point_statebuilder(client, point_column='pt_position', linked_seg_column='pt_root_id', data_resolution=None, group_column=None, tag_column=None, description_column=None, contrast=None, view_kws=None, point_layer_name='pts', color=None, split_positions=False)\nGenerate a state builder that puts points on a single column with a linked segmentaton id\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nclient\ncaveclient.CAVEclient\nCAVEclient configured for the datastack desired\nrequired\n\n\npoint_column\nstr\nColumn in dataframe to pull points from. Defaults to “pt_position”.\n'pt_position'\n\n\nlinked_seg_column\nstr\ncolumn to link to segmentation, None for no column. Defaults to “pt_root_id”.\n'pt_root_id'\n\n\ngroup_column\nstr, or list\ncolumn(s) to group annotations by, None for no grouping (default=None)\nNone\n\n\ntag_column\nstr, optional)\ncolumn to use for tags, None for no tags (default=None)\nNone\n\n\ndescription_column\nstr\ncolumn to use for descriptions, None for no descriptions (default=None)\nNone\n\n\ncontrast\nlist\nTwo elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set.\nNone\n\n\nview_kws\ndict\ndictionary of view keywords to configure neuroglancer view\nNone\n\n\nsplit_positions\nbool\nwhether the position column into x,y,z columns. Defaults to False.\nFalse\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\n\nA statebuilder to make points with linked segmentations" - }, - { - "objectID": "reference/statebuilder.helpers.make_point_statebuilder.html#parameters", - "href": "reference/statebuilder.helpers.make_point_statebuilder.html#parameters", - "title": "statebuilder.helpers.make_point_statebuilder", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nclient\ncaveclient.CAVEclient\nCAVEclient configured for the datastack desired\nrequired\n\n\npoint_column\nstr\nColumn in dataframe to pull points from. Defaults to “pt_position”.\n'pt_position'\n\n\nlinked_seg_column\nstr\ncolumn to link to segmentation, None for no column. Defaults to “pt_root_id”.\n'pt_root_id'\n\n\ngroup_column\nstr, or list\ncolumn(s) to group annotations by, None for no grouping (default=None)\nNone\n\n\ntag_column\nstr, optional)\ncolumn to use for tags, None for no tags (default=None)\nNone\n\n\ndescription_column\nstr\ncolumn to use for descriptions, None for no descriptions (default=None)\nNone\n\n\ncontrast\nlist\nTwo elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set.\nNone\n\n\nview_kws\ndict\ndictionary of view keywords to configure neuroglancer view\nNone\n\n\nsplit_positions\nbool\nwhether the position column into x,y,z columns. Defaults to False.\nFalse" - }, - { - "objectID": "reference/statebuilder.helpers.make_point_statebuilder.html#returns", - "href": "reference/statebuilder.helpers.make_point_statebuilder.html#returns", - "title": "statebuilder.helpers.make_point_statebuilder", - "section": "", - "text": "Type\nDescription\n\n\n\n\n\nA statebuilder to make points with linked segmentations" - }, - { - "objectID": "reference/parser.base.annotation_layers.html", - "href": "reference/parser.base.annotation_layers.html", - "title": "parser.base.annotation_layers", - "section": "", - "text": "parser.base.annotation_layers(state)\nGet all annotation layer names in the state\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as a JSON dict\nrequired\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nlist\nList of layer names" - }, - { - "objectID": "reference/parser.base.annotation_layers.html#parameters", - "href": "reference/parser.base.annotation_layers.html#parameters", - "title": "parser.base.annotation_layers", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as a JSON dict\nrequired" - }, - { - "objectID": "reference/parser.base.annotation_layers.html#returns", - "href": "reference/parser.base.annotation_layers.html#returns", - "title": "parser.base.annotation_layers", - "section": "", - "text": "Type\nDescription\n\n\n\n\nlist\nList of layer names" - }, - { - "objectID": "reference/layers.html", - "href": "reference/layers.html", - "title": "layers", - "section": "", - "text": "statebuilder.layers\n\n\n\n\n\nName\nDescription\n\n\n\n\nAnnotationLayerConfig\nConfiguration class for annotation layers\n\n\nImageLayerConfig\nImage layer configuration class.\n\n\nLayerConfigBase\nBase class for configuring layers\n\n\nSegmentationLayerConfig\nConfiguration class for segmentation layers\n\n\n\n\n\n\nstatebuilder.layers.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)\nConfiguration class for annotation layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name. By default, ‘annos’\nNone\n\n\ncolor\nstr\nHex color code with an initial #. By default, None\nNone\n\n\nlinked_segmentation_layer\nstr\nName of a linked segmentation layer for selected ids. By default, None\nNone\n\n\nmapping_rules\n(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)\nOne rule or a list of rules mapping data to annotations. By default, []\n[]\n\n\narray_data\nbool\nIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.\nFalse\n\n\ntags\nlist\nList of tags for the layer.\nNone\n\n\nactive\nbool\nIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).\nTrue\n\n\n\n\n\n\n\nstatebuilder.layers.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)\nImage layer configuration class.\nThis provides the rules for setting up an image layer in neuroglancer.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nCloudpath to an image source\nrequired\n\n\nname\nstr\nName of the image layer. By default, ‘img’.\nNone\n\n\nactive\nbool\nIf True, makes the layer active in neuroglancer. Default is False.\nFalse\n\n\ncontrast_controls\nbool\nIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.\nFalse\n\n\nblack\nfloat\nIf contrast_controls is True, sets the default black level. Default is 0.0.\n0.0\n\n\nwhite\nfloat\nIf contrast_controls is True, sets the default white level. Default is 1.0.\n1.0\n\n\n\n\n\n\n\nstatebuilder.layers.LayerConfigBase(self, name, type, source, color, active)\nBase class for configuring layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name for reference and display\nrequired\n\n\ntype\nstr\nLayer type. Usually handled by the subclass\nrequired\n\n\nsource\nstr\nDatasource for the layer\nrequired\n\n\ncolor\nstr\nHex string (with starting hash).\nrequired\n\n\nactive\n(bool)\nIf True, becomes a selected layer.\nrequired\n\n\n\n\n\n\n\nstatebuilder.layers.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)\nConfiguration class for segmentation layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nSegmentation source\nrequired\n\n\nname\n(str, optional)\nLayer name.\nNone\n\n\nselected_ids_column\nstr or list-like, optional.\nColumn name (or list of column names) to use for selected ids.\nNone\n\n\nfixed_ids\nlist-like, optional.\nList of root ids to select directly.\nNone\n\n\nfixed_id_colors\nlist-like, optional.\nList of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.\nNone\n\n\ncolor_column\nstr, optional.\n# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a\nNone\n\n\nactive\nbool, optional.\nIf True, makes the layer selected. Default is False.\nFalse\n\n\nalpha_selected\n\nOpacity of selected segmentations in the image layer. Optional, default is 0.3.\n0.3\n\n\nalpha_3d\n\nOpacity of meshes. Optional, default is 1.\n1\n\n\nalpha_unselected\n\nOpacity of unselected segments. Optional, default is 0.\n0\n\n\nsplit_point_map\n\nIf not None, provides an object to map the dataframe input to multicut points. Default is None.\nNone\n\n\nview_kws\ndict, optional.\nKeyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.\nNone\n\n\ntimestamp\nfloat or datetime, optional.\nTimestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.\nNone\n\n\n\n\n\n\n\n\n\nName\nDescription\n\n\n\n\nadd_selection_map\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\nstatebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nselected_ids_column\nstr\nDataframe column to use for adding selected segment ids to the segmentation layer, by default None\nNone\n\n\nfixed_ids\nint or list\nAdd one or more segment ids to be active, independent of the data, by default None\nNone\n\n\nfixed_id_colors\nlist\nAdd a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default None\nNone\n\n\ncolor_column\nstr\nDataframe column to use for adding selected segment colors, by default None\nNone" - }, - { - "objectID": "reference/layers.html#classes", - "href": "reference/layers.html#classes", - "title": "layers", - "section": "", - "text": "Name\nDescription\n\n\n\n\nAnnotationLayerConfig\nConfiguration class for annotation layers\n\n\nImageLayerConfig\nImage layer configuration class.\n\n\nLayerConfigBase\nBase class for configuring layers\n\n\nSegmentationLayerConfig\nConfiguration class for segmentation layers" - }, - { - "objectID": "reference/layers.html#nglui.statebuilder.layers.AnnotationLayerConfig", - "href": "reference/layers.html#nglui.statebuilder.layers.AnnotationLayerConfig", - "title": "layers", - "section": "", - "text": "statebuilder.layers.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)\nConfiguration class for annotation layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name. By default, ‘annos’\nNone\n\n\ncolor\nstr\nHex color code with an initial #. By default, None\nNone\n\n\nlinked_segmentation_layer\nstr\nName of a linked segmentation layer for selected ids. By default, None\nNone\n\n\nmapping_rules\n(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)\nOne rule or a list of rules mapping data to annotations. By default, []\n[]\n\n\narray_data\nbool\nIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.\nFalse\n\n\ntags\nlist\nList of tags for the layer.\nNone\n\n\nactive\nbool\nIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).\nTrue" - }, - { - "objectID": "reference/layers.html#nglui.statebuilder.layers.ImageLayerConfig", - "href": "reference/layers.html#nglui.statebuilder.layers.ImageLayerConfig", - "title": "layers", - "section": "", - "text": "statebuilder.layers.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)\nImage layer configuration class.\nThis provides the rules for setting up an image layer in neuroglancer.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nCloudpath to an image source\nrequired\n\n\nname\nstr\nName of the image layer. By default, ‘img’.\nNone\n\n\nactive\nbool\nIf True, makes the layer active in neuroglancer. Default is False.\nFalse\n\n\ncontrast_controls\nbool\nIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.\nFalse\n\n\nblack\nfloat\nIf contrast_controls is True, sets the default black level. Default is 0.0.\n0.0\n\n\nwhite\nfloat\nIf contrast_controls is True, sets the default white level. Default is 1.0.\n1.0" - }, - { - "objectID": "reference/layers.html#nglui.statebuilder.layers.LayerConfigBase", - "href": "reference/layers.html#nglui.statebuilder.layers.LayerConfigBase", - "title": "layers", - "section": "", - "text": "statebuilder.layers.LayerConfigBase(self, name, type, source, color, active)\nBase class for configuring layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name for reference and display\nrequired\n\n\ntype\nstr\nLayer type. Usually handled by the subclass\nrequired\n\n\nsource\nstr\nDatasource for the layer\nrequired\n\n\ncolor\nstr\nHex string (with starting hash).\nrequired\n\n\nactive\n(bool)\nIf True, becomes a selected layer.\nrequired" - }, - { - "objectID": "reference/layers.html#nglui.statebuilder.layers.SegmentationLayerConfig", - "href": "reference/layers.html#nglui.statebuilder.layers.SegmentationLayerConfig", - "title": "layers", - "section": "", - "text": "statebuilder.layers.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)\nConfiguration class for segmentation layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nSegmentation source\nrequired\n\n\nname\n(str, optional)\nLayer name.\nNone\n\n\nselected_ids_column\nstr or list-like, optional.\nColumn name (or list of column names) to use for selected ids.\nNone\n\n\nfixed_ids\nlist-like, optional.\nList of root ids to select directly.\nNone\n\n\nfixed_id_colors\nlist-like, optional.\nList of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.\nNone\n\n\ncolor_column\nstr, optional.\n# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a\nNone\n\n\nactive\nbool, optional.\nIf True, makes the layer selected. Default is False.\nFalse\n\n\nalpha_selected\n\nOpacity of selected segmentations in the image layer. Optional, default is 0.3.\n0.3\n\n\nalpha_3d\n\nOpacity of meshes. Optional, default is 1.\n1\n\n\nalpha_unselected\n\nOpacity of unselected segments. Optional, default is 0.\n0\n\n\nsplit_point_map\n\nIf not None, provides an object to map the dataframe input to multicut points. Default is None.\nNone\n\n\nview_kws\ndict, optional.\nKeyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.\nNone\n\n\ntimestamp\nfloat or datetime, optional.\nTimestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.\nNone\n\n\n\n\n\n\n\n\n\nName\nDescription\n\n\n\n\nadd_selection_map\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\nstatebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nselected_ids_column\nstr\nDataframe column to use for adding selected segment ids to the segmentation layer, by default None\nNone\n\n\nfixed_ids\nint or list\nAdd one or more segment ids to be active, independent of the data, by default None\nNone\n\n\nfixed_id_colors\nlist\nAdd a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default None\nNone\n\n\ncolor_column\nstr\nDataframe column to use for adding selected segment colors, by default None\nNone" - }, - { - "objectID": "reference/preview.html", - "href": "reference/preview.html", - "title": "preview", - "section": "", - "text": "preview(ast, max_depth=999, compact=False, as_string=False)\nPrint a friendly representation of a griffe object (e.g. function, docstring)\n\n\n>>> from quartodoc import get_object\n>>> obj = get_object(\"quartodoc\", \"get_object\")\n>>> preview(obj.docstring.parsed)\n ...\n>>> preview(obj)\n ..." - }, - { - "objectID": "reference/preview.html#examples", - "href": "reference/preview.html#examples", - "title": "preview", - "section": "", - "text": ">>> from quartodoc import get_object\n>>> obj = get_object(\"quartodoc\", \"get_object\")\n>>> preview(obj.docstring.parsed)\n ...\n>>> preview(obj)\n ..." - }, - { - "objectID": "reference/statebuilder.helpers.make_neuron_neuroglancer_link.html", - "href": "reference/statebuilder.helpers.make_neuron_neuroglancer_link.html", - "title": "statebuilder.helpers.make_neuron_neuroglancer_link", - "section": "", - "text": "statebuilder.helpers.make_neuron_neuroglancer_link(client, root_ids, return_as='html', shorten='always', show_inputs=False, show_outputs=False, sort_inputs=True, sort_outputs=True, sort_ascending=False, input_color=DEFAULT_POSTSYN_COLOR, output_color=DEFAULT_PRESYN_COLOR, contrast=None, timestamp=None, view_kws=None, point_column='ctr_pt_position', pre_pt_root_id_col='pre_pt_root_id', post_pt_root_id_col='post_pt_root_id', input_layer_name='syns_in', output_layer_name='syns_out', ngl_url=None, link_text='Neuroglancer Link', target_site=None)\nfunction to create a neuroglancer link view of a neuron, optionally including inputs and outputs\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nclient\ncaveclient.CAVEclient\nA CAVEclient configured for the datastack to visualize.\nrequired\n\n\nroot_ids\ntyping.Iterable[int]\nThe root_ids to build the visualization around.\nrequired\n\n\nreturn_as\nstr\nHow to return the URL or state. Valid options are: - ‘html’: Returns an IPython HTML element. - ‘json’: Returns a dictionary representing the Neuroglancer state. - ‘url’: Returns a URL string. Defaults to ‘html’.\n'html'\n\n\nshorten\nstr\nWhether to shorten the link. Valid options are: - ‘always’: Always shorten the link. - ‘if_long’: Shorten the link if it exceeds MAX_URL_LENGTH. - ‘never’: Never shorten the link. Defaults to ‘if_long’.\n'always'\n\n\nshow_inputs\nbool\nWhether to include input synapses. Defaults to False.\nFalse\n\n\nshow_outputs\nbool\nWhether to include output synapses. Defaults to False.\nFalse\n\n\nsort_inputs\nbool\nWhether to sort input synapses by presynaptic root id, ordered by synapse count. Defaults to True.\nTrue\n\n\nsort_outputs\nbool\nWhether to sort output synapses by presynaptic root id, ordered by postsynaptic synapse count. Defaults to True.\nTrue\n\n\nsort_ascending\nbool\nIf sorting, whether to sort ascending (lowest synapse count to highest). Defaults to False.\nFalse\n\n\ninput_color\nlist(float) or str\nColor of input synapse points as an RGB list [0, 1], hex string, or common name.\nDEFAULT_POSTSYN_COLOR\n\n\noutput_color\nlist(float) or str\nColor of output synapse points as an RGB list [0, 1], hex string, or common name.\nDEFAULT_PRESYN_COLOR\n\n\ncontrast\nlist\nList of two floats between 0 and 1, specifying the black and white levels. If None, no contrast is set.\nNone\n\n\ntimestamp\ndatetime.datetime.datetime\nTimestamp to use for the query. Defaults to None, which will use the materialized version.\nNone\n\n\nview_kws\ndict\nDictionary containing viewer settings for Neuroglancer. See nglui.StateBuilder for options. See the previous docstring for details on available keys.\nNone\n\n\npoint_column\nstr\nColumn to pull synapse positions from. Defaults to “ctr_pt_position”.\n'ctr_pt_position'\n\n\npre_pt_root_id_col\nstr\nColumn to pull presynaptic IDs for synapses from. Defaults to “pre_pt_root_id”.\n'pre_pt_root_id'\n\n\npost_pt_root_id_col\nstr\nColumn to pull postsynaptic IDs for synapses from. Defaults to “post_pt_root_id”.\n'post_pt_root_id'\n\n\ninput_layer_name\nstr\nName of the layer for input synapses. Defaults to “syns_in”.\n'syns_in'\n\n\noutput_layer_name\nstr\nName of the layer for output synapses. Defaults to “syns_out”.\n'syns_out'\n\n\nngl_url\nstr\nURL of the Neuroglancer instance to use. Defaults to the default viewer set in the datastack.\nNone\n\n\nlink_text\nstr\nText to use for the HTML return. Defaults to ‘Neuroglancer Link’.\n'Neuroglancer Link'\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nValueError\nIf the specified point column is not present in the synapse table.\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nIPython.HTML, str, or dict\nRepresentation of the Neuroglancer state, depending on the return_as parameter." - }, - { - "objectID": "reference/statebuilder.helpers.make_neuron_neuroglancer_link.html#parameters", - "href": "reference/statebuilder.helpers.make_neuron_neuroglancer_link.html#parameters", - "title": "statebuilder.helpers.make_neuron_neuroglancer_link", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nclient\ncaveclient.CAVEclient\nA CAVEclient configured for the datastack to visualize.\nrequired\n\n\nroot_ids\ntyping.Iterable[int]\nThe root_ids to build the visualization around.\nrequired\n\n\nreturn_as\nstr\nHow to return the URL or state. Valid options are: - ‘html’: Returns an IPython HTML element. - ‘json’: Returns a dictionary representing the Neuroglancer state. - ‘url’: Returns a URL string. Defaults to ‘html’.\n'html'\n\n\nshorten\nstr\nWhether to shorten the link. Valid options are: - ‘always’: Always shorten the link. - ‘if_long’: Shorten the link if it exceeds MAX_URL_LENGTH. - ‘never’: Never shorten the link. Defaults to ‘if_long’.\n'always'\n\n\nshow_inputs\nbool\nWhether to include input synapses. Defaults to False.\nFalse\n\n\nshow_outputs\nbool\nWhether to include output synapses. Defaults to False.\nFalse\n\n\nsort_inputs\nbool\nWhether to sort input synapses by presynaptic root id, ordered by synapse count. Defaults to True.\nTrue\n\n\nsort_outputs\nbool\nWhether to sort output synapses by presynaptic root id, ordered by postsynaptic synapse count. Defaults to True.\nTrue\n\n\nsort_ascending\nbool\nIf sorting, whether to sort ascending (lowest synapse count to highest). Defaults to False.\nFalse\n\n\ninput_color\nlist(float) or str\nColor of input synapse points as an RGB list [0, 1], hex string, or common name.\nDEFAULT_POSTSYN_COLOR\n\n\noutput_color\nlist(float) or str\nColor of output synapse points as an RGB list [0, 1], hex string, or common name.\nDEFAULT_PRESYN_COLOR\n\n\ncontrast\nlist\nList of two floats between 0 and 1, specifying the black and white levels. If None, no contrast is set.\nNone\n\n\ntimestamp\ndatetime.datetime.datetime\nTimestamp to use for the query. Defaults to None, which will use the materialized version.\nNone\n\n\nview_kws\ndict\nDictionary containing viewer settings for Neuroglancer. See nglui.StateBuilder for options. See the previous docstring for details on available keys.\nNone\n\n\npoint_column\nstr\nColumn to pull synapse positions from. Defaults to “ctr_pt_position”.\n'ctr_pt_position'\n\n\npre_pt_root_id_col\nstr\nColumn to pull presynaptic IDs for synapses from. Defaults to “pre_pt_root_id”.\n'pre_pt_root_id'\n\n\npost_pt_root_id_col\nstr\nColumn to pull postsynaptic IDs for synapses from. Defaults to “post_pt_root_id”.\n'post_pt_root_id'\n\n\ninput_layer_name\nstr\nName of the layer for input synapses. Defaults to “syns_in”.\n'syns_in'\n\n\noutput_layer_name\nstr\nName of the layer for output synapses. Defaults to “syns_out”.\n'syns_out'\n\n\nngl_url\nstr\nURL of the Neuroglancer instance to use. Defaults to the default viewer set in the datastack.\nNone\n\n\nlink_text\nstr\nText to use for the HTML return. Defaults to ‘Neuroglancer Link’.\n'Neuroglancer Link'" - }, - { - "objectID": "reference/statebuilder.helpers.make_neuron_neuroglancer_link.html#raises", - "href": "reference/statebuilder.helpers.make_neuron_neuroglancer_link.html#raises", - "title": "statebuilder.helpers.make_neuron_neuroglancer_link", - "section": "", - "text": "Type\nDescription\n\n\n\n\nValueError\nIf the specified point column is not present in the synapse table." - }, - { - "objectID": "reference/statebuilder.helpers.make_neuron_neuroglancer_link.html#returns", - "href": "reference/statebuilder.helpers.make_neuron_neuroglancer_link.html#returns", - "title": "statebuilder.helpers.make_neuron_neuroglancer_link", - "section": "", - "text": "Type\nDescription\n\n\n\n\nIPython.HTML, str, or dict\nRepresentation of the Neuroglancer state, depending on the return_as parameter." - }, - { - "objectID": "reference/layers.ImageLayerConfig.html", - "href": "reference/layers.ImageLayerConfig.html", - "title": "layers.ImageLayerConfig", - "section": "", - "text": "statebuilder.layers.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)\nImage layer configuration class.\nThis provides the rules for setting up an image layer in neuroglancer.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nCloudpath to an image source\nrequired\n\n\nname\nstr\nName of the image layer. By default, ‘img’.\nNone\n\n\nactive\nbool\nIf True, makes the layer active in neuroglancer. Default is False.\nFalse\n\n\ncontrast_controls\nbool\nIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.\nFalse\n\n\nblack\nfloat\nIf contrast_controls is True, sets the default black level. Default is 0.0.\n0.0\n\n\nwhite\nfloat\nIf contrast_controls is True, sets the default white level. Default is 1.0.\n1.0" - }, - { - "objectID": "reference/layers.ImageLayerConfig.html#parameters", - "href": "reference/layers.ImageLayerConfig.html#parameters", - "title": "layers.ImageLayerConfig", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nCloudpath to an image source\nrequired\n\n\nname\nstr\nName of the image layer. By default, ‘img’.\nNone\n\n\nactive\nbool\nIf True, makes the layer active in neuroglancer. Default is False.\nFalse\n\n\ncontrast_controls\nbool\nIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.\nFalse\n\n\nblack\nfloat\nIf contrast_controls is True, sets the default black level. Default is 0.0.\n0.0\n\n\nwhite\nfloat\nIf contrast_controls is True, sets the default white level. Default is 1.0.\n1.0" - }, - { - "objectID": "reference/parser.base.image_layers.html", - "href": "reference/parser.base.image_layers.html", - "title": "parser.base.image_layers", - "section": "", - "text": "parser.base.image_layers(state)\nGet all image layer names in the state\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as a JSON dict\nrequired\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nlist\nList of layer names" - }, - { - "objectID": "reference/parser.base.image_layers.html#parameters", - "href": "reference/parser.base.image_layers.html#parameters", - "title": "parser.base.image_layers", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as a JSON dict\nrequired" - }, - { - "objectID": "reference/parser.base.image_layers.html#returns", - "href": "reference/parser.base.image_layers.html#returns", - "title": "parser.base.image_layers", - "section": "", - "text": "Type\nDescription\n\n\n\n\nlist\nList of layer names" - }, - { - "objectID": "reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.html", - "href": "reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.html", - "title": "render_state", - "section": "", - "text": "statebuilder.statebuilder.StateBuilder.render_state(data=None, base_state=None, return_as='url', url_prefix=None, link_text='Neuroglancer Link', target_site=None)\nBuild a Neuroglancer state out of a DataFrame.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\ndata\npandas.pandas.DataFrame\nDataFrame to use as a point source. By default None, for which it will return only the base_state and any fixed values.\nNone\n\n\nbase_state\ndict\nInitial state to build on, expressed as Neuroglancer JSON. By default None\nNone\n\n\nreturn_as\n[url, nglui.statebuilder.statebuilder.StateBuilder.viewer, html, json, dict, shared]\nChoice of output types. Note that if a viewer is returned, the state is not reset. url : Returns the raw url describing the state viewer : Returns an EasyViewer object holding the state information html : Returns an HTML link to the url, useful for notebooks. json : Returns a JSON string describing the state. dict : Returns a dict version of the JSON state. By default ‘url’\n'url'\n\n\nurl_prefix\nstr\nNeuroglancer URL prefix to use. By default None, for which it will open with the class default.\nNone\n\n\nlink_text\nstr\nText to use for the link when returning as html, by default ‘Neuroglancer Link’\n'Neuroglancer Link'\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nstring or neuroglancer.neuroglancer.Viewer\nA link to or viewer for a Neuroglancer state with layers, annotations, and selected objects determined by the data." - }, - { - "objectID": "reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.html#parameters", - "href": "reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.html#parameters", - "title": "render_state", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\ndata\npandas.pandas.DataFrame\nDataFrame to use as a point source. By default None, for which it will return only the base_state and any fixed values.\nNone\n\n\nbase_state\ndict\nInitial state to build on, expressed as Neuroglancer JSON. By default None\nNone\n\n\nreturn_as\n[url, nglui.statebuilder.statebuilder.StateBuilder.viewer, html, json, dict, shared]\nChoice of output types. Note that if a viewer is returned, the state is not reset. url : Returns the raw url describing the state viewer : Returns an EasyViewer object holding the state information html : Returns an HTML link to the url, useful for notebooks. json : Returns a JSON string describing the state. dict : Returns a dict version of the JSON state. By default ‘url’\n'url'\n\n\nurl_prefix\nstr\nNeuroglancer URL prefix to use. By default None, for which it will open with the class default.\nNone\n\n\nlink_text\nstr\nText to use for the link when returning as html, by default ‘Neuroglancer Link’\n'Neuroglancer Link'" - }, - { - "objectID": "reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.html#returns", - "href": "reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.html#returns", - "title": "render_state", - "section": "", - "text": "Type\nDescription\n\n\n\n\nstring or neuroglancer.neuroglancer.Viewer\nA link to or viewer for a Neuroglancer state with layers, annotations, and selected objects determined by the data." - }, - { - "objectID": "reference/statebuilder.helpers.make_url_robust.html", - "href": "reference/statebuilder.helpers.make_url_robust.html", - "title": "statebuilder.helpers.make_url_robust", - "section": "", - "text": "statebuilder.helpers.make_url_robust(df, sb, client, shorten='if_long', ngl_url=None, max_url_length=MAX_URL_LENGTH, target_site=None)\nGenerate a url from a neuroglancer state. If too long, return through state server, othewise return a url containing the data directly.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\ndf\npandas.pandas.DataFrame\nDataframe to pass through statebuilder\nrequired\n\n\nsb\nnglui.statebuilder.statebuilder.nglui.statebuilder.statebuilder.StateBuilder\nStatebuilder to use to render data for link\nrequired\n\n\nclient\ncaveclient.CAVEclient\nCAVEclient configured with a state server\nrequired\n\n\nshorten\nstr\nHow to shorten link. one of ‘if_long’, ‘always’, ‘never’. ‘if_long’ will use the state server to shorten links longer than nglui.statebuilder.MAX_URL_LENGTH (set to 1,750,000). ‘always’ will always use the state server to shorten the url ‘never’ will always return the full url. Defaults to “if_long”.\n'if_long'\n\n\nngl_url\nstr\nNeuroglancer deployment URL, by default None\nNone\n\n\nmax_url_length\nint\nMaximum length of url to return directly, by default 1_750_000\nMAX_URL_LENGTH\n\n\ntarget_site\nstr\nType of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use seunglab for a Seung-lab branch and either mainline or cave-explorer for the Cave Explorer or main Google branch.\nNone\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nstr\nURL containing the state created by the statebuilder." - }, - { - "objectID": "reference/statebuilder.helpers.make_url_robust.html#parameters", - "href": "reference/statebuilder.helpers.make_url_robust.html#parameters", - "title": "statebuilder.helpers.make_url_robust", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\ndf\npandas.pandas.DataFrame\nDataframe to pass through statebuilder\nrequired\n\n\nsb\nnglui.statebuilder.statebuilder.nglui.statebuilder.statebuilder.StateBuilder\nStatebuilder to use to render data for link\nrequired\n\n\nclient\ncaveclient.CAVEclient\nCAVEclient configured with a state server\nrequired\n\n\nshorten\nstr\nHow to shorten link. one of ‘if_long’, ‘always’, ‘never’. ‘if_long’ will use the state server to shorten links longer than nglui.statebuilder.MAX_URL_LENGTH (set to 1,750,000). ‘always’ will always use the state server to shorten the url ‘never’ will always return the full url. Defaults to “if_long”.\n'if_long'\n\n\nngl_url\nstr\nNeuroglancer deployment URL, by default None\nNone\n\n\nmax_url_length\nint\nMaximum length of url to return directly, by default 1_750_000\nMAX_URL_LENGTH\n\n\ntarget_site\nstr\nType of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use seunglab for a Seung-lab branch and either mainline or cave-explorer for the Cave Explorer or main Google branch.\nNone" - }, - { - "objectID": "reference/statebuilder.helpers.make_url_robust.html#returns", - "href": "reference/statebuilder.helpers.make_url_robust.html#returns", - "title": "statebuilder.helpers.make_url_robust", - "section": "", - "text": "Type\nDescription\n\n\n\n\nstr\nURL containing the state created by the statebuilder." - }, - { - "objectID": "reference/get_object.html", - "href": "reference/get_object.html", - "title": "get_object", - "section": "", - "text": "get_object(path, object_name=None, parser='numpy', load_aliases=True, dynamic=False, loader=None)\nFetch a griffe object.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\npath\nstr\nAn import path to the object. This should have the form path.to.module:object. For example, quartodoc:get_object or quartodoc:MdRenderer.render.\nrequired\n\n\nobject_name\n‘str | None’\n(Deprecated). A function name.\nNone\n\n\nparser\nstr\nA docstring parser to use.\n'numpy'\n\n\nload_aliases\n\nFor aliases that were imported from other modules, should we load that module?\nTrue\n\n\ndynamic\n\nWhether to dynamically import object. Useful if docstring is not hard-coded, but was set on object by running python code.\nFalse\n\n\n\n\n\n\npreview: print a user-friendly preview of a griffe object.\n\n\n\n>>> get_function(\"quartodoc\", \"get_function\")\n<Function('get_function', ...\n\n\n\n\n\n\nType\nDescription\n\n\n\n\ngriffe.dataclasses.griffe.dataclasses.Object\nabc" - }, - { - "objectID": "reference/get_object.html#parameters", - "href": "reference/get_object.html#parameters", - "title": "get_object", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\npath\nstr\nAn import path to the object. This should have the form path.to.module:object. For example, quartodoc:get_object or quartodoc:MdRenderer.render.\nrequired\n\n\nobject_name\n‘str | None’\n(Deprecated). A function name.\nNone\n\n\nparser\nstr\nA docstring parser to use.\n'numpy'\n\n\nload_aliases\n\nFor aliases that were imported from other modules, should we load that module?\nTrue\n\n\ndynamic\n\nWhether to dynamically import object. Useful if docstring is not hard-coded, but was set on object by running python code.\nFalse" - }, - { - "objectID": "reference/get_object.html#see-also", - "href": "reference/get_object.html#see-also", - "title": "get_object", - "section": "", - "text": "preview: print a user-friendly preview of a griffe object." - }, - { - "objectID": "reference/get_object.html#examples", - "href": "reference/get_object.html#examples", - "title": "get_object", - "section": "", - "text": ">>> get_function(\"quartodoc\", \"get_function\")\n<Function('get_function', ..." - }, - { - "objectID": "reference/get_object.html#returns", - "href": "reference/get_object.html#returns", - "title": "get_object", - "section": "", - "text": "Type\nDescription\n\n\n\n\ngriffe.dataclasses.griffe.dataclasses.Object\nabc" - }, - { - "objectID": "reference/statebuilder.helpers.from_client.html", - "href": "reference/statebuilder.helpers.from_client.html", - "title": "statebuilder.helpers.from_client", - "section": "", - "text": "statebuilder.helpers.from_client(client, image_name=None, segmentation_name=None, contrast=None)\nGenerate basic image and segmentation layers from a FrameworkClient\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nclient\ncaveclient.caveclient.CAVEclient\nA CAVEclient with a specified datastack\nrequired\n\n\nimage_name\nstr\nName for the image layer, by default None.\nNone\n\n\nsegmentation_name\nstr\nName for the segmentation layer, by default None\nNone\n\n\ncontrast\nlist - like\nTwo elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set.\nNone\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nnglui.statebuilder.layers.ImageLayerConfig\nImage layer with default values from the client\n\n\nnglui.statebuilder.layers.ImageLayerConfig\nSegmentation layer with default values from the client" - }, - { - "objectID": "reference/statebuilder.helpers.from_client.html#parameters", - "href": "reference/statebuilder.helpers.from_client.html#parameters", - "title": "statebuilder.helpers.from_client", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nclient\ncaveclient.caveclient.CAVEclient\nA CAVEclient with a specified datastack\nrequired\n\n\nimage_name\nstr\nName for the image layer, by default None.\nNone\n\n\nsegmentation_name\nstr\nName for the segmentation layer, by default None\nNone\n\n\ncontrast\nlist - like\nTwo elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set.\nNone" - }, - { - "objectID": "reference/statebuilder.helpers.from_client.html#returns", - "href": "reference/statebuilder.helpers.from_client.html#returns", - "title": "statebuilder.helpers.from_client", - "section": "", - "text": "Type\nDescription\n\n\n\n\nnglui.statebuilder.layers.ImageLayerConfig\nImage layer with default values from the client\n\n\nnglui.statebuilder.layers.ImageLayerConfig\nSegmentation layer with default values from the client" - }, - { - "objectID": "reference/ImageLayerConfig.html", - "href": "reference/ImageLayerConfig.html", - "title": "ImageLayerConfig", - "section": "", - "text": "statebuilder.layers.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)\nImage layer configuration class.\nThis provides the rules for setting up an image layer in neuroglancer.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nCloudpath to an image source\nrequired\n\n\nname\nstr\nName of the image layer. By default, ‘img’.\nNone\n\n\nactive\nbool\nIf True, makes the layer active in neuroglancer. Default is False.\nFalse\n\n\ncontrast_controls\nbool\nIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.\nFalse\n\n\nblack\nfloat\nIf contrast_controls is True, sets the default black level. Default is 0.0.\n0.0\n\n\nwhite\nfloat\nIf contrast_controls is True, sets the default white level. Default is 1.0.\n1.0" - }, - { - "objectID": "reference/ImageLayerConfig.html#parameters", - "href": "reference/ImageLayerConfig.html#parameters", - "title": "ImageLayerConfig", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nCloudpath to an image source\nrequired\n\n\nname\nstr\nName of the image layer. By default, ‘img’.\nNone\n\n\nactive\nbool\nIf True, makes the layer active in neuroglancer. Default is False.\nFalse\n\n\ncontrast_controls\nbool\nIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.\nFalse\n\n\nblack\nfloat\nIf contrast_controls is True, sets the default black level. Default is 0.0.\n0.0\n\n\nwhite\nfloat\nIf contrast_controls is True, sets the default white level. Default is 1.0.\n1.0" - }, - { - "objectID": "reference/statebuilder.SphereMapper.html", - "href": "reference/statebuilder.SphereMapper.html", - "title": "statebuilder.SphereMapper", - "section": "", - "text": "statebuilder.SphereMapper(self, center_column=None, radius_column=None, description_column=None, linked_segmentation_column=None, tag_column=None, group_column=None, gather_linked_segmentations=True, share_linked_segmentations=False, z_multiplier=0.1, set_position=True, multipoint=False, collapse_groups=False, split_positions=False, mapping_set=None)\nSets rules to map dataframes to sphere annotations\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\ncenter_column\nstr\nColumn name with 3d position data for the center of the sphere\nNone\n\n\nradius_column\nstr\nColumn name with a radius for the sphere (in nm)\nNone\n\n\ndescription_column\nstr\nColumn name with string data for annotation descriptions\nNone\n\n\nlinked_segmentation_column\nstr\nColumn name for root ids to link to annotations\nNone\n\n\ntag_column\nstr\nColumn name for categorical tag data. Tags must match those set in the annotation layer.\nNone\n\n\ngroup_column\nstr\nColumn name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation.\nNone\n\n\nset_position\nbool\nIf set to True, moves the position to center on the first point in the data.\nTrue\n\n\nmultipoint\n\nIf True, permits multiple points in a given row, sharing data in other columns. Each point row must have the same number of points. Default is False.\nFalse\n\n\ncollapse_groups\n\nIf True, groups are toggled closed in the annotation view.\nFalse\n\n\nmapping_set\n\nIf set, assumes data is passed as a dictionary and uses this string to as the key for the data to use.\nNone" - }, - { - "objectID": "reference/statebuilder.SphereMapper.html#parameters", - "href": "reference/statebuilder.SphereMapper.html#parameters", - "title": "statebuilder.SphereMapper", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\ncenter_column\nstr\nColumn name with 3d position data for the center of the sphere\nNone\n\n\nradius_column\nstr\nColumn name with a radius for the sphere (in nm)\nNone\n\n\ndescription_column\nstr\nColumn name with string data for annotation descriptions\nNone\n\n\nlinked_segmentation_column\nstr\nColumn name for root ids to link to annotations\nNone\n\n\ntag_column\nstr\nColumn name for categorical tag data. Tags must match those set in the annotation layer.\nNone\n\n\ngroup_column\nstr\nColumn name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation.\nNone\n\n\nset_position\nbool\nIf set to True, moves the position to center on the first point in the data.\nTrue\n\n\nmultipoint\n\nIf True, permits multiple points in a given row, sharing data in other columns. Each point row must have the same number of points. Default is False.\nFalse\n\n\ncollapse_groups\n\nIf True, groups are toggled closed in the annotation view.\nFalse\n\n\nmapping_set\n\nIf set, assumes data is passed as a dictionary and uses this string to as the key for the data to use.\nNone" - }, - { - "objectID": "reference/statebuilder.ImageLayerConfig.html", - "href": "reference/statebuilder.ImageLayerConfig.html", - "title": "statebuilder.ImageLayerConfig", - "section": "", - "text": "statebuilder.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)\nImage layer configuration class.\nThis provides the rules for setting up an image layer in neuroglancer.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nCloudpath to an image source\nrequired\n\n\nname\nstr\nName of the image layer. By default, ‘img’.\nNone\n\n\nactive\nbool\nIf True, makes the layer active in neuroglancer. Default is False.\nFalse\n\n\ncontrast_controls\nbool\nIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.\nFalse\n\n\nblack\nfloat\nIf contrast_controls is True, sets the default black level. Default is 0.0.\n0.0\n\n\nwhite\nfloat\nIf contrast_controls is True, sets the default white level. Default is 1.0.\n1.0" - }, - { - "objectID": "reference/statebuilder.ImageLayerConfig.html#parameters", - "href": "reference/statebuilder.ImageLayerConfig.html#parameters", - "title": "statebuilder.ImageLayerConfig", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nCloudpath to an image source\nrequired\n\n\nname\nstr\nName of the image layer. By default, ‘img’.\nNone\n\n\nactive\nbool\nIf True, makes the layer active in neuroglancer. Default is False.\nFalse\n\n\ncontrast_controls\nbool\nIf True, gives the layer a user-controllable brightness and contrast shader. Default is False.\nFalse\n\n\nblack\nfloat\nIf contrast_controls is True, sets the default black level. Default is 0.0.\n0.0\n\n\nwhite\nfloat\nIf contrast_controls is True, sets the default white level. Default is 1.0.\n1.0" - }, - { - "objectID": "reference/statebuilder.StateBuilder.html", - "href": "reference/statebuilder.StateBuilder.html", - "title": "statebuilder.StateBuilder", - "section": "", - "text": "statebuilder.StateBuilder(self, layers=[], base_state=None, url_prefix=None, state_server=None, resolution=None, view_kws={}, client=None, target_site=None)\nA class for schematic mapping data frames into neuroglancer states.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nlayers\n\n\n[]\n\n\nbase_state\n\n\nNone\n\n\nurl_prefix\n\nDefaults to None, which will use https://neuromancer-seung-import.appspot.com\nNone\n\n\nstate_server\n\n\nNone\n\n\nresolution\n\n\nNone\n\n\nview_kws\n\nkeys are: show_slices: Boolean sets if slices are shown in the 3d view. Defaults to False. layout: str xy-3d/xz-3d/yz-3d (sections plus 3d pane), xy/yz/xz/3d (only one pane), or 4panel (all panes). Default is xy-3d. show_axis_lines: Boolean determines if the axis lines are shown in the middle of each view. show_scale_bar: Boolean toggles showing the scale bar. orthographic : Boolean toggles orthographic view in the 3d pane. position* : 3-element vector determines the centered location. zoom_image : float Zoom level for the imagery in units of nm per voxel. Defaults to 8. zoom_3d : float Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are more zoomed in. background_color : str or list Sets the background color of the 3d view. Arguments can be rgb values, hex colors, or named web colors. Defaults to black.\n{}\n\n\nclient\n\n\nNone" - }, - { - "objectID": "reference/statebuilder.StateBuilder.html#parameters", - "href": "reference/statebuilder.StateBuilder.html#parameters", - "title": "statebuilder.StateBuilder", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nlayers\n\n\n[]\n\n\nbase_state\n\n\nNone\n\n\nurl_prefix\n\nDefaults to None, which will use https://neuromancer-seung-import.appspot.com\nNone\n\n\nstate_server\n\n\nNone\n\n\nresolution\n\n\nNone\n\n\nview_kws\n\nkeys are: show_slices: Boolean sets if slices are shown in the 3d view. Defaults to False. layout: str xy-3d/xz-3d/yz-3d (sections plus 3d pane), xy/yz/xz/3d (only one pane), or 4panel (all panes). Default is xy-3d. show_axis_lines: Boolean determines if the axis lines are shown in the middle of each view. show_scale_bar: Boolean toggles showing the scale bar. orthographic : Boolean toggles orthographic view in the 3d pane. position* : 3-element vector determines the centered location. zoom_image : float Zoom level for the imagery in units of nm per voxel. Defaults to 8. zoom_3d : float Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are more zoomed in. background_color : str or list Sets the background color of the 3d view. Arguments can be rgb values, hex colors, or named web colors. Defaults to black.\n{}\n\n\nclient\n\n\nNone" - }, - { - "objectID": "reference/layers.AnnotationLayerConfig.html", - "href": "reference/layers.AnnotationLayerConfig.html", - "title": "layers.AnnotationLayerConfig", - "section": "", - "text": "statebuilder.layers.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)\nConfiguration class for annotation layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name. By default, ‘annos’\nNone\n\n\ncolor\nstr\nHex color code with an initial #. By default, None\nNone\n\n\nlinked_segmentation_layer\nstr\nName of a linked segmentation layer for selected ids. By default, None\nNone\n\n\nmapping_rules\n(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)\nOne rule or a list of rules mapping data to annotations. By default, []\n[]\n\n\narray_data\nbool\nIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.\nFalse\n\n\ntags\nlist\nList of tags for the layer.\nNone\n\n\nactive\nbool\nIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).\nTrue" - }, - { - "objectID": "reference/layers.AnnotationLayerConfig.html#parameters", - "href": "reference/layers.AnnotationLayerConfig.html#parameters", - "title": "layers.AnnotationLayerConfig", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name. By default, ‘annos’\nNone\n\n\ncolor\nstr\nHex color code with an initial #. By default, None\nNone\n\n\nlinked_segmentation_layer\nstr\nName of a linked segmentation layer for selected ids. By default, None\nNone\n\n\nmapping_rules\n(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)\nOne rule or a list of rules mapping data to annotations. By default, []\n[]\n\n\narray_data\nbool\nIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.\nFalse\n\n\ntags\nlist\nList of tags for the layer.\nNone\n\n\nactive\nbool\nIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).\nTrue" - }, - { - "objectID": "reference/parser.base.tag_dictionary.html", - "href": "reference/parser.base.tag_dictionary.html", - "title": "parser.base.tag_dictionary", - "section": "", - "text": "parser.base.tag_dictionary(state, layer_name)\nGet the tag id to string dictionary for a layer\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\n\nrequired\n\n\nlayer_name\n[type]\n[description]\nrequired\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\n[type]\n[description]" - }, - { - "objectID": "reference/parser.base.tag_dictionary.html#parameters", - "href": "reference/parser.base.tag_dictionary.html#parameters", - "title": "parser.base.tag_dictionary", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\n\nrequired\n\n\nlayer_name\n[type]\n[description]\nrequired" - }, - { - "objectID": "reference/parser.base.tag_dictionary.html#returns", - "href": "reference/parser.base.tag_dictionary.html#returns", - "title": "parser.base.tag_dictionary", - "section": "", - "text": "Type\nDescription\n\n\n\n\n[type]\n[description]" - }, - { - "objectID": "reference/statebuilder.SegmentationLayerConfig.html", - "href": "reference/statebuilder.SegmentationLayerConfig.html", - "title": "statebuilder.SegmentationLayerConfig", - "section": "", - "text": "statebuilder.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)\nConfiguration class for segmentation layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nSegmentation source\nrequired\n\n\nname\n(str, optional)\nLayer name.\nNone\n\n\nselected_ids_column\nstr or list-like, optional.\nColumn name (or list of column names) to use for selected ids.\nNone\n\n\nfixed_ids\nlist-like, optional.\nList of root ids to select directly.\nNone\n\n\nfixed_id_colors\nlist-like, optional.\nList of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.\nNone\n\n\ncolor_column\nstr, optional.\n# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a\nNone\n\n\nactive\nbool, optional.\nIf True, makes the layer selected. Default is False.\nFalse\n\n\nalpha_selected\n\nOpacity of selected segmentations in the image layer. Optional, default is 0.3.\n0.3\n\n\nalpha_3d\n\nOpacity of meshes. Optional, default is 1.\n1\n\n\nalpha_unselected\n\nOpacity of unselected segments. Optional, default is 0.\n0\n\n\nsplit_point_map\n\nIf not None, provides an object to map the dataframe input to multicut points. Default is None.\nNone\n\n\nview_kws\ndict, optional.\nKeyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.\nNone\n\n\ntimestamp\nfloat or datetime, optional.\nTimestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.\nNone" - }, - { - "objectID": "reference/statebuilder.SegmentationLayerConfig.html#parameters", - "href": "reference/statebuilder.SegmentationLayerConfig.html#parameters", - "title": "statebuilder.SegmentationLayerConfig", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nSegmentation source\nrequired\n\n\nname\n(str, optional)\nLayer name.\nNone\n\n\nselected_ids_column\nstr or list-like, optional.\nColumn name (or list of column names) to use for selected ids.\nNone\n\n\nfixed_ids\nlist-like, optional.\nList of root ids to select directly.\nNone\n\n\nfixed_id_colors\nlist-like, optional.\nList of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.\nNone\n\n\ncolor_column\nstr, optional.\n# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a\nNone\n\n\nactive\nbool, optional.\nIf True, makes the layer selected. Default is False.\nFalse\n\n\nalpha_selected\n\nOpacity of selected segmentations in the image layer. Optional, default is 0.3.\n0.3\n\n\nalpha_3d\n\nOpacity of meshes. Optional, default is 1.\n1\n\n\nalpha_unselected\n\nOpacity of unselected segments. Optional, default is 0.\n0\n\n\nsplit_point_map\n\nIf not None, provides an object to map the dataframe input to multicut points. Default is None.\nNone\n\n\nview_kws\ndict, optional.\nKeyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.\nNone\n\n\ntimestamp\nfloat or datetime, optional.\nTimestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.\nNone" - }, - { - "objectID": "reference/nglui.statebuilder.layers.AnnotationLayerConfig.html", - "href": "reference/nglui.statebuilder.layers.AnnotationLayerConfig.html", - "title": "AnnotationLayerConfig", - "section": "", - "text": "statebuilder.layers.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)\nConfiguration class for annotation layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name. By default, ‘annos’\nNone\n\n\ncolor\nstr\nHex color code with an initial #. By default, None\nNone\n\n\nlinked_segmentation_layer\nstr\nName of a linked segmentation layer for selected ids. By default, None\nNone\n\n\nmapping_rules\n(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)\nOne rule or a list of rules mapping data to annotations. By default, []\n[]\n\n\narray_data\nbool\nIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.\nFalse\n\n\ntags\nlist\nList of tags for the layer.\nNone\n\n\nactive\nbool\nIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).\nTrue" - }, - { - "objectID": "reference/nglui.statebuilder.layers.AnnotationLayerConfig.html#parameters", - "href": "reference/nglui.statebuilder.layers.AnnotationLayerConfig.html#parameters", - "title": "AnnotationLayerConfig", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nname\nstr\nLayer name. By default, ‘annos’\nNone\n\n\ncolor\nstr\nHex color code with an initial #. By default, None\nNone\n\n\nlinked_segmentation_layer\nstr\nName of a linked segmentation layer for selected ids. By default, None\nNone\n\n\nmapping_rules\n(nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list)\nOne rule or a list of rules mapping data to annotations. By default, []\n[]\n\n\narray_data\nbool\nIf True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features.\nFalse\n\n\ntags\nlist\nList of tags for the layer.\nNone\n\n\nactive\nbool\nIf True, makes the layer selected. Default is True (unlike for image/segmentation layers).\nTrue" - }, - { - "objectID": "reference/statebuilder.helpers.make_state_url.html", - "href": "reference/statebuilder.helpers.make_state_url.html", - "title": "statebuilder.helpers.make_state_url", - "section": "", - "text": "statebuilder.helpers.make_state_url(df, sb, client, ngl_url=None, target_site=None)\nGenerate a url from a neuroglancer state via a state server.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\ndf\npandas.pandas.DataFrame\nDataframe to pass through statebuilder\nrequired\n\n\nsb\nnglui.statebuilder.statebuilder.nglui.statebuilder.statebuilder.StateBuilder\nStatebuilder to use to render data for link\nrequired\n\n\nclient\ncaveclient.CAVEclient\nCAVEclient configured with a state server\nrequired\n\n\nngl_url\nstr\nNeuroglancer deployment URL, by default None\nNone\n\n\ntarget_site\nstr\nType of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use seunglab for a Seung-lab branch and either mainline or cave-explorer for the Cave Explorer or main Google branch.\nNone\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nstr\nUrl to the uploaded neuroglancer state." - }, - { - "objectID": "reference/statebuilder.helpers.make_state_url.html#parameters", - "href": "reference/statebuilder.helpers.make_state_url.html#parameters", - "title": "statebuilder.helpers.make_state_url", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\ndf\npandas.pandas.DataFrame\nDataframe to pass through statebuilder\nrequired\n\n\nsb\nnglui.statebuilder.statebuilder.nglui.statebuilder.statebuilder.StateBuilder\nStatebuilder to use to render data for link\nrequired\n\n\nclient\ncaveclient.CAVEclient\nCAVEclient configured with a state server\nrequired\n\n\nngl_url\nstr\nNeuroglancer deployment URL, by default None\nNone\n\n\ntarget_site\nstr\nType of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use seunglab for a Seung-lab branch and either mainline or cave-explorer for the Cave Explorer or main Google branch.\nNone" - }, - { - "objectID": "reference/statebuilder.helpers.make_state_url.html#returns", - "href": "reference/statebuilder.helpers.make_state_url.html#returns", - "title": "statebuilder.helpers.make_state_url", - "section": "", - "text": "Type\nDescription\n\n\n\n\nstr\nUrl to the uploaded neuroglancer state." - }, - { - "objectID": "reference/statebuilder.BoundingBoxMapper.html", - "href": "reference/statebuilder.BoundingBoxMapper.html", - "title": "statebuilder.BoundingBoxMapper", - "section": "", - "text": "statebuilder.BoundingBoxMapper(self, point_column_a=None, point_column_b=None, description_column=None, linked_segmentation_column=None, tag_column=None, group_column=None, gather_linked_segmentations=True, share_linked_segmentations=False, set_position=True, multipoint=False, collapse_groups=False, split_positions=False, mapping_set=None)\nSets rules to map dataframes to bounding box annotations\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\npoint_column_a\nstr\nColumn name with 3d position data for the first point of the bounding box. Must be set if array_data is False (the default)\nNone\n\n\npoint_column_b\nstr\nColumn name with 3d position data for the second point of the bounding box. Must be set if array_data is False (the default)\nNone\n\n\ndescription_column\nstr\nColumn name with string data for annotation descriptions\nNone\n\n\nlinked_segmentation_column\nstr\nColumn name for root ids to link to annotations\nNone\n\n\ntag_column\nstr\nColumn name for categorical tag data. Tags must match those set in the annotation layer.\nNone\n\n\ngroup_column\nstr\nColumn name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation.\nNone\n\n\nset_position\nbool\nIf set to True, moves the position to center on the first point in the data (using point_column_a).\nTrue\n\n\nmultipoint\n\nIf True, permits multiple points in a given row, sharing data in other columns. Each point row must have the same number of points. Default is False.\nFalse\n\n\ncollapse_groups\n\nIf True, groups are toggled closed in the annotation view.\nFalse\n\n\nmapping_set\n\nIf set, assumes data is passed as a dictionary and uses this string to as the key for the data to use.\nNone" - }, - { - "objectID": "reference/statebuilder.BoundingBoxMapper.html#parameters", - "href": "reference/statebuilder.BoundingBoxMapper.html#parameters", - "title": "statebuilder.BoundingBoxMapper", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\npoint_column_a\nstr\nColumn name with 3d position data for the first point of the bounding box. Must be set if array_data is False (the default)\nNone\n\n\npoint_column_b\nstr\nColumn name with 3d position data for the second point of the bounding box. Must be set if array_data is False (the default)\nNone\n\n\ndescription_column\nstr\nColumn name with string data for annotation descriptions\nNone\n\n\nlinked_segmentation_column\nstr\nColumn name for root ids to link to annotations\nNone\n\n\ntag_column\nstr\nColumn name for categorical tag data. Tags must match those set in the annotation layer.\nNone\n\n\ngroup_column\nstr\nColumn name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation.\nNone\n\n\nset_position\nbool\nIf set to True, moves the position to center on the first point in the data (using point_column_a).\nTrue\n\n\nmultipoint\n\nIf True, permits multiple points in a given row, sharing data in other columns. Each point row must have the same number of points. Default is False.\nFalse\n\n\ncollapse_groups\n\nIf True, groups are toggled closed in the annotation view.\nFalse\n\n\nmapping_set\n\nIf set, assumes data is passed as a dictionary and uses this string to as the key for the data to use.\nNone" - }, - { - "objectID": "reference/layers.SegmentationLayerConfig.html", - "href": "reference/layers.SegmentationLayerConfig.html", - "title": "layers.SegmentationLayerConfig", - "section": "", - "text": "statebuilder.layers.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)\nConfiguration class for segmentation layers\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nSegmentation source\nrequired\n\n\nname\n(str, optional)\nLayer name.\nNone\n\n\nselected_ids_column\nstr or list-like, optional.\nColumn name (or list of column names) to use for selected ids.\nNone\n\n\nfixed_ids\nlist-like, optional.\nList of root ids to select directly.\nNone\n\n\nfixed_id_colors\nlist-like, optional.\nList of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.\nNone\n\n\ncolor_column\nstr, optional.\n# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a\nNone\n\n\nactive\nbool, optional.\nIf True, makes the layer selected. Default is False.\nFalse\n\n\nalpha_selected\n\nOpacity of selected segmentations in the image layer. Optional, default is 0.3.\n0.3\n\n\nalpha_3d\n\nOpacity of meshes. Optional, default is 1.\n1\n\n\nalpha_unselected\n\nOpacity of unselected segments. Optional, default is 0.\n0\n\n\nsplit_point_map\n\nIf not None, provides an object to map the dataframe input to multicut points. Default is None.\nNone\n\n\nview_kws\ndict, optional.\nKeyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.\nNone\n\n\ntimestamp\nfloat or datetime, optional.\nTimestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.\nNone\n\n\n\n\n\n\n\n\n\nName\nDescription\n\n\n\n\nadd_selection_map\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\nstatebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nselected_ids_column\nstr\nDataframe column to use for adding selected segment ids to the segmentation layer, by default None\nNone\n\n\nfixed_ids\nint or list\nAdd one or more segment ids to be active, independent of the data, by default None\nNone\n\n\nfixed_id_colors\nlist\nAdd a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default None\nNone\n\n\ncolor_column\nstr\nDataframe column to use for adding selected segment colors, by default None\nNone" - }, - { - "objectID": "reference/layers.SegmentationLayerConfig.html#parameters", - "href": "reference/layers.SegmentationLayerConfig.html#parameters", - "title": "layers.SegmentationLayerConfig", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nsource\nstr\nSegmentation source\nrequired\n\n\nname\n(str, optional)\nLayer name.\nNone\n\n\nselected_ids_column\nstr or list-like, optional.\nColumn name (or list of column names) to use for selected ids.\nNone\n\n\nfixed_ids\nlist-like, optional.\nList of root ids to select directly.\nNone\n\n\nfixed_id_colors\nlist-like, optional.\nList of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values.\nNone\n\n\ncolor_column\nstr, optional.\n# at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a\nNone\n\n\nactive\nbool, optional.\nIf True, makes the layer selected. Default is False.\nFalse\n\n\nalpha_selected\n\nOpacity of selected segmentations in the image layer. Optional, default is 0.3.\n0.3\n\n\nalpha_3d\n\nOpacity of meshes. Optional, default is 1.\n1\n\n\nalpha_unselected\n\nOpacity of unselected segments. Optional, default is 0.\n0\n\n\nsplit_point_map\n\nIf not None, provides an object to map the dataframe input to multicut points. Default is None.\nNone\n\n\nview_kws\ndict, optional.\nKeyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module.\nNone\n\n\ntimestamp\nfloat or datetime, optional.\nTimestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None.\nNone" - }, - { - "objectID": "reference/layers.SegmentationLayerConfig.html#methods", - "href": "reference/layers.SegmentationLayerConfig.html#methods", - "title": "layers.SegmentationLayerConfig", - "section": "", - "text": "Name\nDescription\n\n\n\n\nadd_selection_map\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\nstatebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)\nAdd rules for selecting active segment ids and their colors\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nselected_ids_column\nstr\nDataframe column to use for adding selected segment ids to the segmentation layer, by default None\nNone\n\n\nfixed_ids\nint or list\nAdd one or more segment ids to be active, independent of the data, by default None\nNone\n\n\nfixed_id_colors\nlist\nAdd a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default None\nNone\n\n\ncolor_column\nstr\nDataframe column to use for adding selected segment colors, by default None\nNone" - }, - { - "objectID": "reference/parser.base.sphere_annotations.html", - "href": "reference/parser.base.sphere_annotations.html", - "title": "parser.base.sphere_annotations", - "section": "", - "text": "parser.base.sphere_annotations(state, layer_name, description=False, linked_segmentations=False, tags=False, group=False)\nGet all sphere annotation points and other info from a layer.\n\n\n\n\n\n\n\n\n\n\n\nName\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as JSON dict\nrequired\n\n\nlayer_name\nstr\nLayer name\nrequired\n\n\ndescription\nbool\nIf True, also returns descriptions as well. By default False\nFalse\n\n\nlinked_segmentations\nbool\nIf True, also returns list of linked segmentations, by default False\nFalse\n\n\ntags\nbool\nIf True, also returns list of tags, by default False\nFalse\n\n\n\n\n\n\n\n\n\n\n\n\n\nType\nDescription\n\n\n\n\nlist\nList of N 3-element center points (as list)\n\n\nlist\nList of N 3-element radii for each axis of the ellipsoid.\n\n\nlist\nList of N strings (or None), only returned if description=True.\n\n\nlist\nList of N lists of object ids. Only returned if linked_segmentations=True.\n\n\nlist\nList of N lists of tag ids. Only returned if tags=True.\n\n\nlist\nList of group ids (as string) or None for annotations. Only returned if group=True" - }, - { - "objectID": "reference/parser.base.sphere_annotations.html#parameters", - "href": "reference/parser.base.sphere_annotations.html#parameters", - "title": "parser.base.sphere_annotations", - "section": "", - "text": "Name\nType\nDescription\nDefault\n\n\n\n\nstate\ndict\nNeuroglancer state as JSON dict\nrequired\n\n\nlayer_name\nstr\nLayer name\nrequired\n\n\ndescription\nbool\nIf True, also returns descriptions as well. By default False\nFalse\n\n\nlinked_segmentations\nbool\nIf True, also returns list of linked segmentations, by default False\nFalse\n\n\ntags\nbool\nIf True, also returns list of tags, by default False\nFalse" - }, - { - "objectID": "reference/parser.base.sphere_annotations.html#returns", - "href": "reference/parser.base.sphere_annotations.html#returns", - "title": "parser.base.sphere_annotations", - "section": "", - "text": "Type\nDescription\n\n\n\n\nlist\nList of N 3-element center points (as list)\n\n\nlist\nList of N 3-element radii for each axis of the ellipsoid.\n\n\nlist\nList of N strings (or None), only returned if description=True.\n\n\nlist\nList of N lists of object ids. Only returned if linked_segmentations=True.\n\n\nlist\nList of N lists of tag ids. Only returned if tags=True.\n\n\nlist\nList of group ids (as string) or None for annotations. Only returned if group=True" - } -] \ No newline at end of file diff --git a/docs/_site/site_libs/bootstrap/bootstrap-icons.css b/docs/_site/site_libs/bootstrap/bootstrap-icons.css deleted file mode 100644 index 94f1940..0000000 --- a/docs/_site/site_libs/bootstrap/bootstrap-icons.css +++ /dev/null @@ -1,2018 +0,0 @@ -@font-face { - font-display: block; - font-family: "bootstrap-icons"; - src: -url("./bootstrap-icons.woff?2ab2cbbe07fcebb53bdaa7313bb290f2") 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-1::before { content: "\f2a5"; } -.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-1::before { content: "\f68a"; } -.bi-envelope-check-fill::before { content: "\f68b"; } -.bi-envelope-check::before { content: "\f68c"; } -.bi-envelope-dash-1::before { content: "\f68d"; } -.bi-envelope-dash-fill::before { content: "\f68e"; } -.bi-envelope-dash::before { content: "\f68f"; } -.bi-envelope-exclamation-1::before { content: "\f690"; } -.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-1::before { content: "\f695"; } -.bi-envelope-slash-fill::before { content: "\f696"; } -.bi-envelope-slash::before { content: "\f697"; } -.bi-envelope-x-1::before { content: "\f698"; } -.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-mortorboard-fill::before { content: "\f6a2"; } -.bi-mortorboard::before { content: "\f6a3"; } -.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-1::before { content: "\f6b6"; } -.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-1::before { content: "\f6c2"; } -.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-1::before { content: "\f6e0"; } -.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-ssd-fill::before { content: "\f6ed"; } -.bi-ssd::before { content: "\f6ee"; } -.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-1::before { content: "\f759"; } -.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-1::before { content: "\f769"; } -.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-1::before { content: "\f794"; } -.bi-1-circle-fill-1::before { content: "\f795"; } -.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-1::before { content: "\f79a"; } -.bi-2-circle-fill-1::before { content: "\f79b"; } -.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-1::before { content: "\f7a0"; } -.bi-3-circle-fill-1::before { content: "\f7a1"; } -.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-1::before { content: "\f7a6"; } -.bi-4-circle-fill-1::before { content: "\f7a7"; } -.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-1::before { content: "\f7ac"; } -.bi-5-circle-fill-1::before { content: "\f7ad"; } -.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-1::before { content: "\f7b2"; } -.bi-6-circle-fill-1::before { content: "\f7b3"; } -.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-1::before { content: "\f7b8"; } -.bi-7-circle-fill-1::before { content: "\f7b9"; } -.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-1::before { content: "\f7be"; } -.bi-8-circle-fill-1::before { content: "\f7bf"; } -.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-1::before { content: "\f7c4"; } -.bi-9-circle-fill-1::before { content: "\f7c5"; } -.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-1::before { content: "\f7d8"; } -.bi-c-circle-fill-1::before { content: "\f7d9"; } -.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-1::before { content: "\f7e4"; } -.bi-cc-circle-fill-1::before { content: "\f7e5"; } -.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-1::before { content: "\f7f8"; } -.bi-h-circle-fill-1::before { content: "\f7f9"; } -.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-1::before { content: "\f802"; } -.bi-p-circle-fill-1::before { content: "\f803"; } -.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-1::before { content: "\f80c"; } -.bi-r-circle-fill-1::before { content: "\f80d"; } -.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"; } diff --git a/docs/_site/site_libs/bootstrap/bootstrap-icons.woff b/docs/_site/site_libs/bootstrap/bootstrap-icons.woff deleted file mode 100644 index 18d21d457558d4dc2e231a8f6ee585fada9c6bab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164168 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%0D{F7My?sp4b~Pd<-wWT`E3Pn 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%0Aub6*Q4?Lh?RzF3+=+IGMyc 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

    V5sL;~RGzKe44( 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࿣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

    E0Q>dwTHGr5Eml?v4A4cqksyc*{&0*B}<_UWD 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 N7Xi?h+IjWj{{hmn!3F>T diff --git a/docs/_site/site_libs/bootstrap/bootstrap.min.css b/docs/_site/site_libs/bootstrap/bootstrap.min.css deleted file mode 100644 index 2d28750..0000000 --- a/docs/_site/site_libs/bootstrap/bootstrap.min.css +++ /dev/null @@ -1,10 +0,0 @@ -/*! - * Bootstrap v5.1.3 (https://getbootstrap.com/) - * Copyright 2011-2021 The Bootstrap Authors - * Copyright 2011-2021 Twitter, Inc. - * 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{--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-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-white-rgb: 255, 255, 255;--bs-black-rgb: 0, 0, 0;--bs-body-color-rgb: 33, 37, 41;--bs-body-bg-rgb: 255, 255, 255;--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: var(--bs-font-sans-serif);--bs-body-font-size: 1rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #212529;--bs-body-bg: #fff}*,*::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;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}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}h1,.h1{font-size:calc(1.325rem + 0.9vw)}@media(min-width: 1200px){h1,.h1{font-size:2rem}}h2,.h2{font-size:calc(1.29rem + 0.48vw)}@media(min-width: 1200px){h2,.h2{font-size:1.65rem}}h3,.h3{font-size:calc(1.27rem + 0.24vw)}@media(min-width: 1200px){h3,.h3{font-size:1.45rem}}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],abbr[data-bs-original-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{font-size:0.875em}mark,.mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:0.75em;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}a{color:#18bc9c;text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}a:hover{color:#13967d}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr /* rtl:ignore */;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:0.875em;color:#000;background-color:#f6f6f6;padding:.5rem;border:1px solid #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:#9753b8;background-color:#f6f6f6;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;font-weight:700}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:#6c757d;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]::-webkit-calendar-picker-indicator{display:none}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]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-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:#6c757d}.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{--bs-table-bg: transparent;--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;color:#212529;vertical-align:top;border-color:#dee2e6}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid #9ba5ae}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>: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-accent-bg: var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg: var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg: var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg: #2c3e50;--bs-table-striped-bg: #374859;--bs-table-striped-color: #fff;--bs-table-active-bg: #415162;--bs-table-active-color: #fff;--bs-table-hover-bg: #3c4c5d;--bs-table-hover-color: #fff;color:#fff;border-color:#415162}.table-secondary{--bs-table-bg: #6c757d;--bs-table-striped-bg: #737c84;--bs-table-striped-color: #fff;--bs-table-active-bg: #7b838a;--bs-table-active-color: #fff;--bs-table-hover-bg: #777f87;--bs-table-hover-color: #fff;color:#fff;border-color:#7b838a}.table-success{--bs-table-bg: #18bc9c;--bs-table-striped-bg: #24bfa1;--bs-table-striped-color: #fff;--bs-table-active-bg: #2fc3a6;--bs-table-active-color: #fff;--bs-table-hover-bg: #29c1a3;--bs-table-hover-color: #fff;color:#fff;border-color:#2fc3a6}.table-info{--bs-table-bg: #3498db;--bs-table-striped-bg: #3e9ddd;--bs-table-striped-color: #fff;--bs-table-active-bg: #48a2df;--bs-table-active-color: #fff;--bs-table-hover-bg: #43a0de;--bs-table-hover-color: #fff;color:#fff;border-color:#48a2df}.table-warning{--bs-table-bg: #f39c12;--bs-table-striped-bg: #f4a11e;--bs-table-striped-color: #fff;--bs-table-active-bg: #f4a62a;--bs-table-active-color: #000;--bs-table-hover-bg: #f4a324;--bs-table-hover-color: #fff;color:#fff;border-color:#f4a62a}.table-danger{--bs-table-bg: #e74c3c;--bs-table-striped-bg: #e85546;--bs-table-striped-color: #fff;--bs-table-active-bg: #e95e50;--bs-table-active-color: #fff;--bs-table-hover-bg: #e9594b;--bs-table-hover-color: #fff;color:#fff;border-color:#e95e50}.table-light{--bs-table-bg: #ecf0f1;--bs-table-striped-bg: #e0e4e5;--bs-table-striped-color: #000;--bs-table-active-bg: #d4d8d9;--bs-table-active-color: #000;--bs-table-hover-bg: #dadedf;--bs-table-hover-color: #000;color:#000;border-color:#d4d8d9}.table-dark{--bs-table-bg: #7b8a8b;--bs-table-striped-bg: #829091;--bs-table-striped-color: #fff;--bs-table-active-bg: #889697;--bs-table-active-color: #fff;--bs-table-hover-bg: #859394;--bs-table-hover-color: #fff;color:#fff;border-color:#889697}.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:#6c757d}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;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:#969fa8;outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{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:#ecf0f1;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:#e0e4e5}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-0.375rem -0.75rem;margin-inline-end:.75rem;color:#212529;background-color:#ecf0f1;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::-webkit-file-upload-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#e0e4e5}.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.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 + 2px);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-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-0.25rem -0.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-0.5rem -1rem;margin-inline-end:1rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-0.5rem -1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + 0.75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + 0.5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:auto;padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.5em;border-radius:.25rem}.form-control-color::-webkit-color-swatch{height:1.5em;border-radius:.25rem}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-image: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 5l6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}@media(prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#969fa8;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:.3rem}.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-input,.shiny-input-container .checkbox input,.shiny-input-container .checkbox-inline input,.shiny-input-container .radio input,.shiny-input-container .radio-inline input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,.25);appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;color-adjust:exact;-webkit-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:#969fa8;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]{background-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 10l3 3l6-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]{background-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;background-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{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{width:2em;margin-left:-2.5em;background-image: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");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{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23969fa8'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image: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-check-inline,.shiny-input-container .checkbox-inline,.shiny-input-container .radio-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}.form-range{width:100%;height:1.5rem;padding:0;background-color:rgba(0,0,0,0);appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}.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;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;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}@media(prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#c0c5cb}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#dee2e6;border-color:rgba(0,0,0,0);border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;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;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}@media(prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#c0c5cb}.form-range::-moz-range-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#dee2e6;border-color:rgba(0,0,0,0);border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .75rem;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{padding:1rem .75rem}.form-floating>.form-control::placeholder{color:rgba(0,0,0,0)}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-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-select~label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.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{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{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.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:#ecf0f1;border:1px solid #ced4da;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:.3rem}.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),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3){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),.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4){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:-1px;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:rgba(24,188,156,.9);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.73L.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"]{padding-right:4.125rem;background-image: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 5l6 6 6-6'/%3e%3c/svg%3e"),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.73L.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-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-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:valid,.input-group .form-control.is-valid,.was-validated .input-group .form-select:valid,.input-group .form-select.is-valid{z-index:1}.was-validated .input-group .form-control:valid:focus,.input-group .form-control.is-valid:focus,.was-validated .input-group .form-select:valid:focus,.input-group .form-select.is-valid:focus{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:rgba(231,76,60,.9);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"]{padding-right:4.125rem;background-image: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 5l6 6 6-6'/%3e%3c/svg%3e"),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-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-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:invalid,.input-group .form-control.is-invalid,.was-validated .input-group .form-select:invalid,.input-group .form-select.is-invalid{z-index:2}.was-validated .input-group .form-control:invalid:focus,.input-group .form-control.is-invalid:focus,.was-validated .input-group .form-select:invalid:focus,.input-group .form-select.is-invalid:focus{z-index:3}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#212529;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;background-color:rgba(0,0,0,0);border:1px solid rgba(0,0,0,0);padding:.375rem .75rem;font-size:1rem;border-radius:.25rem;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:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{pointer-events:none;opacity:.65}.btn-default{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-default:hover{color:#fff;background-color:#5c636a;border-color:#565e64}.btn-check:focus+.btn-default,.btn-default:focus{color:#fff;background-color:#5c636a;border-color:#565e64;box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-check:checked+.btn-default,.btn-check:active+.btn-default,.btn-default:active,.btn-default.active,.show>.btn-default.dropdown-toggle{color:#fff;background-color:#565e64;border-color:#51585e}.btn-check:checked+.btn-default:focus,.btn-check:active+.btn-default:focus,.btn-default:active:focus,.btn-default.active:focus,.show>.btn-default.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-default:disabled,.btn-default.disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-primary{color:#fff;background-color:#2c3e50;border-color:#2c3e50}.btn-primary:hover{color:#fff;background-color:#253544;border-color:#233240}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#fff;background-color:#253544;border-color:#233240;box-shadow:0 0 0 .25rem rgba(76,91,106,.5)}.btn-check:checked+.btn-primary,.btn-check:active+.btn-primary,.btn-primary:active,.btn-primary.active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#233240;border-color:#212f3c}.btn-check:checked+.btn-primary:focus,.btn-check:active+.btn-primary:focus,.btn-primary:active:focus,.btn-primary.active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(76,91,106,.5)}.btn-primary:disabled,.btn-primary.disabled{color:#fff;background-color:#2c3e50;border-color:#2c3e50}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5c636a;border-color:#565e64}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#5c636a;border-color:#565e64;box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-check:checked+.btn-secondary,.btn-check:active+.btn-secondary,.btn-secondary:active,.btn-secondary.active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#565e64;border-color:#51585e}.btn-check:checked+.btn-secondary:focus,.btn-check:active+.btn-secondary:focus,.btn-secondary:active:focus,.btn-secondary.active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-secondary:disabled,.btn-secondary.disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-success{color:#fff;background-color:#18bc9c;border-color:#18bc9c}.btn-success:hover{color:#fff;background-color:#14a085;border-color:#13967d}.btn-check:focus+.btn-success,.btn-success:focus{color:#fff;background-color:#14a085;border-color:#13967d;box-shadow:0 0 0 .25rem rgba(59,198,171,.5)}.btn-check:checked+.btn-success,.btn-check:active+.btn-success,.btn-success:active,.btn-success.active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#13967d;border-color:#128d75}.btn-check:checked+.btn-success:focus,.btn-check:active+.btn-success:focus,.btn-success:active:focus,.btn-success.active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(59,198,171,.5)}.btn-success:disabled,.btn-success.disabled{color:#fff;background-color:#18bc9c;border-color:#18bc9c}.btn-info{color:#fff;background-color:#3498db;border-color:#3498db}.btn-info:hover{color:#fff;background-color:#2c81ba;border-color:#2a7aaf}.btn-check:focus+.btn-info,.btn-info:focus{color:#fff;background-color:#2c81ba;border-color:#2a7aaf;box-shadow:0 0 0 .25rem rgba(82,167,224,.5)}.btn-check:checked+.btn-info,.btn-check:active+.btn-info,.btn-info:active,.btn-info.active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#2a7aaf;border-color:#2772a4}.btn-check:checked+.btn-info:focus,.btn-check:active+.btn-info:focus,.btn-info:active:focus,.btn-info.active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(82,167,224,.5)}.btn-info:disabled,.btn-info.disabled{color:#fff;background-color:#3498db;border-color:#3498db}.btn-warning{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-warning:hover{color:#fff;background-color:#cf850f;border-color:#c27d0e}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#fff;background-color:#cf850f;border-color:#c27d0e;box-shadow:0 0 0 .25rem rgba(245,171,54,.5)}.btn-check:checked+.btn-warning,.btn-check:active+.btn-warning,.btn-warning:active,.btn-warning.active,.show>.btn-warning.dropdown-toggle{color:#fff;background-color:#c27d0e;border-color:#b6750e}.btn-check:checked+.btn-warning:focus,.btn-check:active+.btn-warning:focus,.btn-warning:active:focus,.btn-warning.active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(245,171,54,.5)}.btn-warning:disabled,.btn-warning.disabled{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-danger{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-danger:hover{color:#fff;background-color:#c44133;border-color:#b93d30}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#fff;background-color:#c44133;border-color:#b93d30;box-shadow:0 0 0 .25rem rgba(235,103,89,.5)}.btn-check:checked+.btn-danger,.btn-check:active+.btn-danger,.btn-danger:active,.btn-danger.active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#b93d30;border-color:#ad392d}.btn-check:checked+.btn-danger:focus,.btn-check:active+.btn-danger:focus,.btn-danger:active:focus,.btn-danger.active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(235,103,89,.5)}.btn-danger:disabled,.btn-danger.disabled{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-light{color:#000;background-color:#ecf0f1;border-color:#ecf0f1}.btn-light:hover{color:#000;background-color:#eff2f3;border-color:#eef2f2}.btn-check:focus+.btn-light,.btn-light:focus{color:#000;background-color:#eff2f3;border-color:#eef2f2;box-shadow:0 0 0 .25rem rgba(201,204,205,.5)}.btn-check:checked+.btn-light,.btn-check:active+.btn-light,.btn-light:active,.btn-light.active,.show>.btn-light.dropdown-toggle{color:#000;background-color:#f0f3f4;border-color:#eef2f2}.btn-check:checked+.btn-light:focus,.btn-check:active+.btn-light:focus,.btn-light:active:focus,.btn-light.active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(201,204,205,.5)}.btn-light:disabled,.btn-light.disabled{color:#000;background-color:#ecf0f1;border-color:#ecf0f1}.btn-dark{color:#fff;background-color:#7b8a8b;border-color:#7b8a8b}.btn-dark:hover{color:#fff;background-color:#697576;border-color:#626e6f}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#697576;border-color:#626e6f;box-shadow:0 0 0 .25rem rgba(143,156,156,.5)}.btn-check:checked+.btn-dark,.btn-check:active+.btn-dark,.btn-dark:active,.btn-dark.active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#626e6f;border-color:#5c6868}.btn-check:checked+.btn-dark:focus,.btn-check:active+.btn-dark:focus,.btn-dark:active:focus,.btn-dark.active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(143,156,156,.5)}.btn-dark:disabled,.btn-dark.disabled{color:#fff;background-color:#7b8a8b;border-color:#7b8a8b}.btn-outline-default{color:#6c757d;border-color:#6c757d;background-color:rgba(0,0,0,0)}.btn-outline-default:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:focus+.btn-outline-default,.btn-outline-default:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-check:checked+.btn-outline-default,.btn-check:active+.btn-outline-default,.btn-outline-default:active,.btn-outline-default.active,.btn-outline-default.dropdown-toggle.show{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:checked+.btn-outline-default:focus,.btn-check:active+.btn-outline-default:focus,.btn-outline-default:active:focus,.btn-outline-default.active:focus,.btn-outline-default.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-outline-default:disabled,.btn-outline-default.disabled{color:#6c757d;background-color:rgba(0,0,0,0)}.btn-outline-primary{color:#2c3e50;border-color:#2c3e50;background-color:rgba(0,0,0,0)}.btn-outline-primary:hover{color:#fff;background-color:#2c3e50;border-color:#2c3e50}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 .25rem rgba(44,62,80,.5)}.btn-check:checked+.btn-outline-primary,.btn-check:active+.btn-outline-primary,.btn-outline-primary:active,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show{color:#fff;background-color:#2c3e50;border-color:#2c3e50}.btn-check:checked+.btn-outline-primary:focus,.btn-check:active+.btn-outline-primary:focus,.btn-outline-primary:active:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(44,62,80,.5)}.btn-outline-primary:disabled,.btn-outline-primary.disabled{color:#2c3e50;background-color:rgba(0,0,0,0)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d;background-color:rgba(0,0,0,0)}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-check:checked+.btn-outline-secondary,.btn-check:active+.btn-outline-secondary,.btn-outline-secondary:active,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:checked+.btn-outline-secondary:focus,.btn-check:active+.btn-outline-secondary:focus,.btn-outline-secondary:active:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-outline-secondary:disabled,.btn-outline-secondary.disabled{color:#6c757d;background-color:rgba(0,0,0,0)}.btn-outline-success{color:#18bc9c;border-color:#18bc9c;background-color:rgba(0,0,0,0)}.btn-outline-success:hover{color:#fff;background-color:#18bc9c;border-color:#18bc9c}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 .25rem rgba(24,188,156,.5)}.btn-check:checked+.btn-outline-success,.btn-check:active+.btn-outline-success,.btn-outline-success:active,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show{color:#fff;background-color:#18bc9c;border-color:#18bc9c}.btn-check:checked+.btn-outline-success:focus,.btn-check:active+.btn-outline-success:focus,.btn-outline-success:active:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(24,188,156,.5)}.btn-outline-success:disabled,.btn-outline-success.disabled{color:#18bc9c;background-color:rgba(0,0,0,0)}.btn-outline-info{color:#3498db;border-color:#3498db;background-color:rgba(0,0,0,0)}.btn-outline-info:hover{color:#fff;background-color:#3498db;border-color:#3498db}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 .25rem rgba(52,152,219,.5)}.btn-check:checked+.btn-outline-info,.btn-check:active+.btn-outline-info,.btn-outline-info:active,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show{color:#fff;background-color:#3498db;border-color:#3498db}.btn-check:checked+.btn-outline-info:focus,.btn-check:active+.btn-outline-info:focus,.btn-outline-info:active:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(52,152,219,.5)}.btn-outline-info:disabled,.btn-outline-info.disabled{color:#3498db;background-color:rgba(0,0,0,0)}.btn-outline-warning{color:#f39c12;border-color:#f39c12;background-color:rgba(0,0,0,0)}.btn-outline-warning:hover{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 .25rem rgba(243,156,18,.5)}.btn-check:checked+.btn-outline-warning,.btn-check:active+.btn-outline-warning,.btn-outline-warning:active,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show{color:#fff;background-color:#f39c12;border-color:#f39c12}.btn-check:checked+.btn-outline-warning:focus,.btn-check:active+.btn-outline-warning:focus,.btn-outline-warning:active:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(243,156,18,.5)}.btn-outline-warning:disabled,.btn-outline-warning.disabled{color:#f39c12;background-color:rgba(0,0,0,0)}.btn-outline-danger{color:#e74c3c;border-color:#e74c3c;background-color:rgba(0,0,0,0)}.btn-outline-danger:hover{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 .25rem rgba(231,76,60,.5)}.btn-check:checked+.btn-outline-danger,.btn-check:active+.btn-outline-danger,.btn-outline-danger:active,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show{color:#fff;background-color:#e74c3c;border-color:#e74c3c}.btn-check:checked+.btn-outline-danger:focus,.btn-check:active+.btn-outline-danger:focus,.btn-outline-danger:active:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(231,76,60,.5)}.btn-outline-danger:disabled,.btn-outline-danger.disabled{color:#e74c3c;background-color:rgba(0,0,0,0)}.btn-outline-light{color:#ecf0f1;border-color:#ecf0f1;background-color:rgba(0,0,0,0)}.btn-outline-light:hover{color:#000;background-color:#ecf0f1;border-color:#ecf0f1}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 .25rem rgba(236,240,241,.5)}.btn-check:checked+.btn-outline-light,.btn-check:active+.btn-outline-light,.btn-outline-light:active,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show{color:#000;background-color:#ecf0f1;border-color:#ecf0f1}.btn-check:checked+.btn-outline-light:focus,.btn-check:active+.btn-outline-light:focus,.btn-outline-light:active:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(236,240,241,.5)}.btn-outline-light:disabled,.btn-outline-light.disabled{color:#ecf0f1;background-color:rgba(0,0,0,0)}.btn-outline-dark{color:#7b8a8b;border-color:#7b8a8b;background-color:rgba(0,0,0,0)}.btn-outline-dark:hover{color:#fff;background-color:#7b8a8b;border-color:#7b8a8b}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 .25rem rgba(123,138,139,.5)}.btn-check:checked+.btn-outline-dark,.btn-check:active+.btn-outline-dark,.btn-outline-dark:active,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show{color:#fff;background-color:#7b8a8b;border-color:#7b8a8b}.btn-check:checked+.btn-outline-dark:focus,.btn-check:active+.btn-outline-dark:focus,.btn-outline-dark:active:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(123,138,139,.5)}.btn-outline-dark:disabled,.btn-outline-dark.disabled{color:#7b8a8b;background-color:rgba(0,0,0,0)}.btn-link{font-weight:400;color:#18bc9c;text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}.btn-link:hover{color:#13967d}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.btn-sm,.btn-group-sm>.btn{padding:.25rem .5rem;font-size:0.875rem;border-radius:.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{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{position:absolute;z-index:1000;display:none;min-width:10rem;padding:.5rem 0;margin:0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.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:.125rem}.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:.125rem}.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:.125rem}.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:.5rem 0;overflow:hidden;border-top:1px solid rgba(0,0,0,.15)}.dropdown-item{display:block;width:100%;padding:.25rem 1rem;clear:both;font-weight:400;color:#7b8a8b;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}.dropdown-item:hover,.dropdown-item:focus{color:#fff;background-color:#2c3e50}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#2c3e50}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:rgba(0,0,0,0)}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:0.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#7b8a8b}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:hover,.dropdown-menu-dark .dropdown-item:focus{color:#fff;background-color:rgba(255,255,255,.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:#fff;background-color:#2c3e50}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .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>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.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:-1px}.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{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:.5rem 2rem;color:#18bc9c;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;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:#13967d}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #ecf0f1}.nav-tabs .nav-link{margin-bottom:-1px;background:none;border:1px solid rgba(0,0,0,0);border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:#ecf0f1 #ecf0f1 #ecf0f1;isolation:isolate}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0)}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:#7b8a8b;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:none;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#2c3e50}.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{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-top:1rem;padding-bottom:1rem}.navbar>.container-xxl,.navbar>.container-xl,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container,.navbar>.container-fluid{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:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;white-space:nowrap}.navbar-nav{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{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem}.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:.25 0;font-size:1.25rem;line-height:1;background-color:rgba(0,0,0,0);border:1px solid rgba(0,0,0,0);border-radius:.25rem;transition:box-shadow .15s ease-in-out}@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 .25rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;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:.5rem;padding-left:.5rem}.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-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-top,.navbar-expand-sm .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .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:.5rem;padding-left:.5rem}.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-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-top,.navbar-expand-md .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .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:.5rem;padding-left:.5rem}.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-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-top,.navbar-expand-lg .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .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:.5rem;padding-left:.5rem}.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-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-top,.navbar-expand-xl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .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:.5rem;padding-left:.5rem}.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-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-top,.navbar-expand-xxl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .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:.5rem;padding-left:.5rem}.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-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-top,.navbar-expand .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}.navbar-light{background-color:#2c3e50}.navbar-light .navbar-brand{color:#ccd1d5}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:#fff}.navbar-light .navbar-nav .nav-link{color:#ccd1d5}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:rgba(255,255,255,.8)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(204,209,213,.75)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .nav-link.active{color:#fff}.navbar-light .navbar-toggler{color:#ccd1d5;border-color:rgba(204,209,213,0)}.navbar-light .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='%23ccd1d5' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:#ccd1d5}.navbar-light .navbar-text a,.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:#fff}.navbar-dark{background-color:#2c3e50}.navbar-dark .navbar-brand{color:#ccd1d5}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:#fff}.navbar-dark .navbar-nav .nav-link{color:#ccd1d5}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:rgba(255,255,255,.8)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(204,209,213,.75)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active{color:#fff}.navbar-dark .navbar-toggler{color:#ccd1d5;border-color:rgba(204,209,213,0)}.navbar-dark .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='%23ccd1d5' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:#ccd1d5}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:#fff}.card{position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.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:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(0.25rem - 1px);border-bottom-left-radius:calc(0.25rem - 1px)}.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:1rem 1rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-0.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1rem}.card-header{padding:.5rem 1rem;margin-bottom:0;background-color:#adb5bd;border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.card-footer{padding:.5rem 1rem;background-color:#adb5bd;border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-img,.card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(0.25rem - 1px);border-bottom-left-radius:calc(0.25rem - 1px)}.card-group>.card{margin-bottom:.75rem}@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-button{position:relative;display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;width:100%;padding:1rem 1.25rem;font-size:1rem;color:#212529;text-align:left;background-color:#fff;border:0;border-radius:0;overflow-anchor:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,border-radius .15s ease}@media(prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:#283848;background-color:#eaecee;box-shadow:inset 0 -1px 0 rgba(0,0,0,.125)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23283848'%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");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;-webkit-flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image: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");background-repeat:no-repeat;background-size:1.25rem;transition:transform .2s ease-in-out}@media(prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#969fa8;outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:#fff;border:1px solid rgba(0,0,0,.125)}.accordion-item:first-of-type{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.accordion-item:first-of-type .accordion-button{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:calc(0.25rem - 1px);border-bottom-left-radius:calc(0.25rem - 1px)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-body{padding:1rem 1.25rem}.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{border-radius:0}.breadcrumb{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;padding:.375rem .75rem;margin-bottom:1rem;list-style:none;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, ">") /* rtl: var(--bs-breadcrumb-divider, ">") */}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;display:-webkit-flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:#fff;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:#18bc9c;border:0 solid rgba(0,0,0,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){.page-link{transition:none}}.page-link:hover{z-index:2;color:#fff;background-color:#0f7864;border-color:rgba(0,0,0,0)}.page-link:focus{z-index:3;color:#13967d;background-color:#ecf0f1;outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item.active .page-link{z-index:3;color:#fff;background-color:#0f7864;border-color:rgba(0,0,0,0)}.page-item.disabled .page-link{color:#ecf0f1;pointer-events:none;background-color:#3be6c4;border-color:rgba(0,0,0,0)}.page-link{padding:.375rem .75rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:0.875rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2em;border-bottom-left-radius:.2em}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2em;border-bottom-right-radius:.2em}.badge{display:inline-block;padding:.35em .65em;font-size:0.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{position:relative;padding:1rem 1rem;margin-bottom:1rem;border:1px solid rgba(0,0,0,0);border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-default{color:#41464b;background-color:#e2e3e5;border-color:#d3d6d8}.alert-default .alert-link{color:#34383c}.alert-primary{color:#1a2530;background-color:#d5d8dc;border-color:#c0c5cb}.alert-primary .alert-link{color:#151e26}.alert-secondary{color:#41464b;background-color:#e2e3e5;border-color:#d3d6d8}.alert-secondary .alert-link{color:#34383c}.alert-success{color:#0e715e;background-color:#d1f2eb;border-color:#baebe1}.alert-success .alert-link{color:#0b5a4b}.alert-info{color:#1f5b83;background-color:#d6eaf8;border-color:#c2e0f4}.alert-info .alert-link{color:#194969}.alert-warning{color:#925e0b;background-color:#fdebd0;border-color:#fbe1b8}.alert-warning .alert-link{color:#754b09}.alert-danger{color:#8b2e24;background-color:#fadbd8;border-color:#f8c9c5}.alert-danger .alert-link{color:#6f251d}.alert-light{color:#8e9091;background-color:#fbfcfc;border-color:#f9fbfb}.alert-light .alert-link{color:#727374}.alert-dark{color:#4a5353;background-color:#e5e8e8;border-color:#d7dcdc}.alert-dark .alert-link{color:#3b4242}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{display:flex;display:-webkit-flex;height:1rem;overflow:hidden;font-size:0.75rem;background-color:#ecf0f1;border-radius:.25rem}.progress-bar{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;justify-content:center;-webkit-justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#2c3e50;transition:width .6s ease}@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:1rem 1rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media(prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.list-group{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:#7b8a8b;text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:#7b8a8b;text-decoration:none;background-color:#ecf0f1}.list-group-item-action:active{color:#212529;background-color:#ecf0f1}.list-group-item{position:relative;display:block;padding:.5rem 1rem;color:#212529;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.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:#6c757d;pointer-events:none;background-color:#ecf0f1}.list-group-item.active{z-index:2;color:#fff;background-color:#2c3e50;border-color:#2c3e50}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;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:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media(min-width: 576px){.list-group-horizontal-sm{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;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:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 768px){.list-group-horizontal-md{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;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:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 992px){.list-group-horizontal-lg{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;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:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 1200px){.list-group-horizontal-xl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;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:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:.25rem;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:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-default{color:#41464b;background-color:#e2e3e5}.list-group-item-default.list-group-item-action:hover,.list-group-item-default.list-group-item-action:focus{color:#41464b;background-color:#cbccce}.list-group-item-default.list-group-item-action.active{color:#fff;background-color:#41464b;border-color:#41464b}.list-group-item-primary{color:#1a2530;background-color:#d5d8dc}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#1a2530;background-color:#c0c2c6}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#1a2530;border-color:#1a2530}.list-group-item-secondary{color:#41464b;background-color:#e2e3e5}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#41464b;background-color:#cbccce}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#41464b;border-color:#41464b}.list-group-item-success{color:#0e715e;background-color:#d1f2eb}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#0e715e;background-color:#bcdad4}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#0e715e;border-color:#0e715e}.list-group-item-info{color:#1f5b83;background-color:#d6eaf8}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#1f5b83;background-color:#c1d3df}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#1f5b83;border-color:#1f5b83}.list-group-item-warning{color:#925e0b;background-color:#fdebd0}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#925e0b;background-color:#e4d4bb}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#925e0b;border-color:#925e0b}.list-group-item-danger{color:#8b2e24;background-color:#fadbd8}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#8b2e24;background-color:#e1c5c2}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#8b2e24;border-color:#8b2e24}.list-group-item-light{color:#8e9091;background-color:#fbfcfc}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#8e9091;background-color:#e2e3e3}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#8e9091;border-color:#8e9091}.list-group-item-dark{color:#4a5353;background-color:#e5e8e8}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#4a5353;background-color:#ced1d1}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#4a5353;border-color:#4a5353}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#fff;background:rgba(0,0,0,0) 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 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.4}.btn-close:hover{color:#fff;text-decoration:none;opacity:1}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(44,62,80,.25);opacity:1}.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:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{width:350px;max-width:100%;font-size:0.875rem;pointer-events:auto;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.15);border-radius:.25rem}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{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:.75rem}.toast-header{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;padding:.5rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.toast-header .btn-close{margin-right:-0.375rem;margin-left:.75rem}.toast-body{padding:.75rem;word-wrap:break-word}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;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% - 1rem)}.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% - 1rem)}.modal-content{position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.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:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(0.3rem - 1px);border-top-right-radius:calc(0.3rem - 1px)}.modal-header .btn-close{padding:.5rem .5rem;margin:-0.5rem -0.5rem -0.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto;padding:1rem}.modal-footer{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-shrink:0;-webkit-flex-shrink:0;align-items:center;-webkit-align-items:center;justify-content:flex-end;-webkit-justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(0.3rem - 1px);border-bottom-left-radius:calc(0.3rem - 1px)}.modal-footer>*{margin:.25rem}@media(min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media(min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media(min-width: 1200px){.modal-xl{max-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{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@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{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@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{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@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{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@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{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@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{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:var(--bs-font-sans-serif);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;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:rgba(0,0,0,0);border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[data-popper-placement^=top]{padding:.4rem 0}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow{bottom:0}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-end,.bs-tooltip-auto[data-popper-placement^=right]{padding:0 .4rem}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-bottom,.bs-tooltip-auto[data-popper-placement^=bottom]{padding:.4rem 0}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow{top:0}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-start,.bs-tooltip-auto[data-popper-placement^=left]{padding:0 .4rem}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0 /* rtl:ignore */;z-index:1070;display:block;max-width:276px;font-family:var(--bs-font-sans-serif);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;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:rgba(0,0,0,0);border-style:solid}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow{bottom:calc(-0.5rem - 1px)}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow{left:calc(-0.5rem - 1px);width:.5rem;height:1rem}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow{top:calc(-0.5rem - 1px)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.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:1rem;margin-left:-0.5rem;content:"";border-bottom:1px solid #f0f0f0}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow{right:calc(-0.5rem - 1px);width:.5rem;height:1rem}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem 1rem;margin-bottom:0;font-size:1rem;background-color:#f0f0f0;border-bottom:1px solid rgba(0,0,0,.2);border-top-left-radius:calc(0.3rem - 1px);border-top-right-radius:calc(0.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:#212529}.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%;list-style:none}.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}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-0.125em;border:.25em solid currentColor;border-right-color:rgba(0,0,0,0);border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-0.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media(prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s;-webkit-animation-duration:1.5s;-moz-animation-duration:1.5s;-ms-animation-duration:1.5s;-o-animation-duration:1.5s}}.offcanvas{position:fixed;bottom:0;z-index:1045;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;visibility:hidden;background-color:#fff;background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media(prefers-reduced-motion: reduce){.offcanvas{transition:none}}.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:1rem 1rem}.offcanvas-header .btn-close{padding:.5rem .5rem;margin-top:-0.5rem;margin-right:-0.5rem;margin-bottom:-0.5rem}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;-webkit-flex-grow:1;padding:1rem 1rem;overflow-y:auto}.offcanvas-start{top:0;left:0;width:400px;border-right:1px solid rgba(0,0,0,.2);transform:translateX(-100%)}.offcanvas-end{top:0;right:0;width:400px;border-left:1px solid rgba(0,0,0,.2);transform:translateX(100%)}.offcanvas-top{top:0;right:0;left:0;height:30vh;max-height:100%;border-bottom:1px solid rgba(0,0,0,.2);transform:translateY(-100%)}.offcanvas-bottom{right:0;left:0;height:30vh;max-height:100%;border-top:1px solid rgba(0,0,0,.2);transform:translateY(100%)}.offcanvas.show{transform:none}.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:""}.link-default{color:#6c757d}.link-default:hover,.link-default:focus{color:#565e64}.link-primary{color:#2c3e50}.link-primary:hover,.link-primary:focus{color:#233240}.link-secondary{color:#6c757d}.link-secondary:hover,.link-secondary:focus{color:#565e64}.link-success{color:#18bc9c}.link-success:hover,.link-success:focus{color:#13967d}.link-info{color:#3498db}.link-info:hover,.link-info:focus{color:#2a7aaf}.link-warning{color:#f39c12}.link-warning:hover,.link-warning:focus{color:#c27d0e}.link-danger{color:#e74c3c}.link-danger:hover,.link-danger:focus{color:#b93d30}.link-light{color:#ecf0f1}.link-light:hover,.link-light:focus{color:#f0f3f4}.link-dark{color:#7b8a8b}.link-dark:hover,.link-dark:focus{color:#626e6f}.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}@media(min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}}@media(min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}}@media(min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}}@media(min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}}@media(min-width: 1400px){.sticky-xxl-top{position:sticky;top: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){position:absolute !important;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}.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}.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}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display: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}.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:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-top-0{border-top:0 !important}.border-end{border-right:1px solid #dee2e6 !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:1px solid #dee2e6 !important}.border-start-0{border-left:0 !important}.border-default{border-color:#6c757d !important}.border-primary{border-color:#2c3e50 !important}.border-secondary{border-color:#6c757d !important}.border-success{border-color:#18bc9c !important}.border-info{border-color:#3498db !important}.border-warning{border-color:#f39c12 !important}.border-danger{border-color:#e74c3c !important}.border-light{border-color:#ecf0f1 !important}.border-dark{border-color:#7b8a8b !important}.border-white{border-color:#fff !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}.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}.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}.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{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{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{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{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{padding:.25rem !important}.p-2{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{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{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{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{padding-left:1.5rem !important}.ps-5{padding-left: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.29rem + 0.48vw) !important}.fs-3{font-size:calc(1.27rem + 0.24vw) !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-light{font-weight:300 !important}.fw-lighter{font-weight:lighter !important}.fw-normal{font-weight:400 !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:#6c757d !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,.5) !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}.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-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-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:.25rem !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:.2em !important}.rounded-2{border-radius:.25rem !important}.rounded-3{border-radius:.3rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-end{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-start{border-bottom-left-radius:.25rem !important;border-top-left-radius:.25rem !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media(min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float: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-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}.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}.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}.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}.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-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}.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}.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}.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}.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-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}.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}.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}.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}.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-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}.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}.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}.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}.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-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}.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}.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}.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.65rem !important}.fs-3{font-size:1.45rem !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-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}}.quarto-container{min-height:calc(100vh - 132px)}footer.footer .nav-footer,#quarto-header>nav{padding-left:1em;padding-right:1em}nav[role=doc-toc]{padding-left:.5em}#quarto-content>*{padding-top:14px}@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-toggler{order:-1;margin-right:.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 div.dropdown{display:inline-block}.navbar .quarto-navbar-tools .quarto-navigation-tool{color:#ccd1d5}.navbar .quarto-navbar-tools .quarto-navigation-tool:hover{color:#fff}@media(max-width: 991.98px){.navbar .quarto-navbar-tools{margin-top:.25em;padding-top:.75em;display:block;color:solid #495259 1px;text-align:center;vertical-align:middle;margin-right:auto}}.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}.sidebar-section{margin-top:.2em;padding-left:.5em;padding-bottom:.2em}.sidebar-item .sidebar-item-container{display:flex;justify-content:space-between}.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-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-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-secondary-nav .quarto-btn-toggle{color:#595959}.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}.quarto-secondary-nav-title{margin-top:.3em;color:#595959;padding-top:4px}.quarto-secondary-nav nav.quarto-page-breadcrumbs{color:#595959}.quarto-secondary-nav nav.quarto-page-breadcrumbs a{color:#595959}.quarto-secondary-nav nav.quarto-page-breadcrumbs a:hover{color:rgba(13,100,83,.8)}.quarto-secondary-nav nav.quarto-page-breadcrumbs .breadcrumb-item::before{color:#8c8c8c}div.sidebar-item-container{color:#595959}div.sidebar-item-container:hover,div.sidebar-item-container:focus{color:rgba(13,100,83,.8)}div.sidebar-item-container.disabled{color:rgba(89,89,89,.75)}div.sidebar-item-container .active,div.sidebar-item-container .show>.nav-link,div.sidebar-item-container .sidebar-link>code{color:#0d6453}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}.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(max-width: 991.98px){#quarto-sidebar-glass{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(255,255,255,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:rgba(102,102,102,.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:#13967d}.toc-actions{display:flex}.toc-actions p{margin-block-start:0;margin-block-end:0}.toc-actions a{text-decoration:none;color:inherit;font-weight:400}.toc-actions a:hover{color:#13967d}.toc-actions .action-links{margin-left:4px}.sidebar nav[role=doc-toc] .toc-actions .bi{margin-left:-4px;font-size:.7rem;color:#6c757d}.sidebar nav[role=doc-toc] .toc-actions .bi:before{padding-top:3px}#quarto-margin-sidebar .toc-actions .bi:before{margin-top:.3rem;font-size:.7rem;color:#6c757d;vertical-align:top}.sidebar nav[role=doc-toc] .toc-actions>div:first-of-type{margin-top:-3px}#quarto-margin-sidebar .toc-actions p,.sidebar nav[role=doc-toc] .toc-actions p{font-size:.875rem}.nav-footer .toc-actions{padding-bottom:.5em;padding-top:.5em}.nav-footer .toc-actions :first-child{margin-left:auto}.nav-footer .toc-actions :last-child{margin-right:auto}.nav-footer .toc-actions .action-links{display:flex}.nav-footer .toc-actions .action-links p{padding-right:1.5em}.nav-footer .toc-actions .action-links p: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:#757575}.nav-footer a{color:#757575}.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}.nav-footer-left{flex:1 1 0px;text-align:left}.nav-footer-right{flex:1 1 0px;text-align:right}.nav-footer-center{flex:1 1 0px;min-height:3em;text-align:center}.nav-footer-center .footer-items{justify-content:center}@media(max-width: 767.98px){.nav-footer-center{margin-top:3em}}.navbar .quarto-reader-toggle.reader .quarto-reader-toggle-btn{background-color:#ccd1d5;border-radius:3px}.quarto-reader-toggle.reader.quarto-navigation-tool .quarto-reader-toggle-btn{background-color:#595959;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)}.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}}@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:#ccd1d5;opacity:1}.navbar #quarto-search.type-overlay .aa-Autocomplete svg.aa-SubmitIcon{width:26px;height:26px;color:#ccd1d5;opacity:1}.aa-Autocomplete .aa-Form,.aa-DetachedFormContainer .aa-Form{align-items:center;background-color:#fff;border:1px solid #ced4da;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 + 2px)}.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 #ced4da 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:#f2f2f2;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:#3a526a}.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:#90a9c2}.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:#ced4da;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:.1rem}.aa-DetachedOverlay .aa-Item .search-result-title-container,#quarto-search-results .aa-Item .search-result-title-container{font-size:1em;display:flex;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:44px}.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 #ced4da}.aa-DetachedSearchButton{background:none;border:none}.aa-DetachedSearchButton .aa-DetachedSearchButtonPlaceholder{display:none}.navbar .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon{color:#ccd1d5}.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:#595959}.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:rgba(255,255,255,.65);width:90%;bottom:0;box-shadow:rgba(206,212,218,.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 #ced4da;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-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:#212529;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:#adb5bd;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}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 a{color:#212529;display:flex;flex-direction:column;text-decoration:none}div.quarto-post a div.description{flex-shrink:0}div.quarto-post .metadata{display:flex;flex-direction:column;font-size:.8em;font-family:var(--bs-font-sans-serif);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:#4e5862;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:#4e5862;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:#4e5862;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:#4e5862;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:#4e5862;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}.hidden{display:none !important}.zindex-bottom{z-index:-1 !important}.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:inline-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}figure>p:empty{display:none}figure>p:first-child{margin-top:0;margin-bottom:0}figure>figcaption{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{caption-side:top;margin-bottom:1.5rem}caption,.table-caption{padding-top:.5rem;padding-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}pre.sourceCode,code.sourceCode{position:relative}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}.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}div.ansi-escaped-output{font-family:monospace;display:block}/*! -* -* ansi colors from IPython notebook's -* -*/.ansi-black-fg{color:#3e424d}.ansi-black-bg{background-color:#3e424d}.ansi-black-intense-fg{color:#282c36}.ansi-black-intense-bg{background-color:#282c36}.ansi-red-fg{color:#e75c58}.ansi-red-bg{background-color:#e75c58}.ansi-red-intense-fg{color:#b22b31}.ansi-red-intense-bg{background-color:#b22b31}.ansi-green-fg{color:#00a250}.ansi-green-bg{background-color:#00a250}.ansi-green-intense-fg{color:#007427}.ansi-green-intense-bg{background-color:#007427}.ansi-yellow-fg{color:#ddb62b}.ansi-yellow-bg{background-color:#ddb62b}.ansi-yellow-intense-fg{color:#b27d12}.ansi-yellow-intense-bg{background-color:#b27d12}.ansi-blue-fg{color:#208ffb}.ansi-blue-bg{background-color:#208ffb}.ansi-blue-intense-fg{color:#0065ca}.ansi-blue-intense-bg{background-color:#0065ca}.ansi-magenta-fg{color:#d160c4}.ansi-magenta-bg{background-color:#d160c4}.ansi-magenta-intense-fg{color:#a03196}.ansi-magenta-intense-bg{background-color:#a03196}.ansi-cyan-fg{color:#60c6c8}.ansi-cyan-bg{background-color:#60c6c8}.ansi-cyan-intense-fg{color:#258f8f}.ansi-cyan-intense-bg{background-color:#258f8f}.ansi-white-fg{color:#c5c1b4}.ansi-white-bg{background-color:#c5c1b4}.ansi-white-intense-fg{color:#a1a6b2}.ansi-white-intense-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:absolute;right:.5em;left:inherit;background-color:rgba(0,0,0,0)}:root{--mermaid-bg-color: #fff;--mermaid-edge-color: #6c757d;--mermaid-node-fg-color: #212529;--mermaid-fg-color: #212529;--mermaid-fg-color--lighter: #383f45;--mermaid-fg-color--lightest: #4e5862;--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}}.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:focus{outline:none}.code-copy-button-tooltip{font-size:.75em}pre.sourceCode:hover>.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}pre.sourceCode:hover>.code-copy-button-checked>.bi::before{background-image:url('data:image/svg+xml,')}pre.sourceCode:hover>.code-copy-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}pre.sourceCode:hover>.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>*{grid-column:page-start/body-content-end}.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;transform:translate3d(0, 0, 0)}.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;transform:translate3d(0, 0, 0)}.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;transform:translate3d(0, 0, 0)}.page-columns .column-body-outset-right table{background:#fff}.page-columns .column-page{grid-column:page-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page table{background:#fff}.page-columns .column-page-inset{grid-column:page-start-inset/page-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.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;transform:translate3d(0, 0, 0)}.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;transform:translate3d(0, 0, 0)}.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;transform:translate3d(0, 0, 0)}.page-columns .column-page-left table{background:#fff}.page-columns .column-page-right{grid-column:body-content-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.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;transform:translate3d(0, 0, 0)}.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;transform:translate3d(0, 0, 0)}.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;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:screen-start/screen-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:screen-start/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/screen-end;z-index:998;transform:translate3d(0, 0, 0)}.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;transform:translate3d(0, 0, 0);margin-bottom:1em}.zindex-content{z-index:998;transform:translate3d(0, 0, 0)}.zindex-modal{z-index:1055;transform:translate3d(0, 0, 0)}.zindex-over-content{z-index:999;transform:translate3d(0, 0, 0)}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,.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,.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,.page-columns.toc-left .column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;transform:translate3d(0, 0, 0)}.page-columns.toc-left .no-row-height{height:initial;overflow:initial}}@media(max-width: 767.98px){.margin-caption,div.aside,aside,.column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;transform:translate3d(0, 0, 0)}.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{opacity:.9;margin-top:2rem;margin-bottom:1rem;font-weight:600}h1.title,.title.h1{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:#5a6570}.nav-link.active .header-section-number{color:inherit}mark,.mark{padding:0em}.panel-caption,caption,.figure-caption{font-size:.9rem}.panel-caption,.figure-caption,figcaption{color:#5a6570}.table-caption,caption{color:#212529}.quarto-layout-cell[data-ref-parent] caption{color:#5a6570}.column-margin figcaption,.margin-caption,div.aside,aside,.column-margin{color:#5a6570;font-size:.825rem}.panel-caption.margin-caption{text-align:inherit}.column-margin.column-container p{margin-bottom:0}.column-margin.column-container>*:not(.collapse){padding-top:.5em;padding-bottom:.5em;display:block}.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:1em}.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:visible !important;padding:.4em}.callout pre.sourceCode{padding-left:0}div.sourceCode{overflow-y:hidden}.callout div.sourceCode{margin-left:initial}.blockquote{font-size:inherit;padding-left:1rem;padding-right:1.5rem;color:#5a6570}.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:not(.sourceCode),li code:not(.sourceCode),td code:not(.sourceCode){background-color:#f6f6f6;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.toc-left>*,.sidebar.margin-sidebar>*{padding-top:.5em}.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}.quarto-alternate-notebooks i.bi,.quarto-alternate-formats i.bi{margin-right:.4em}.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 h2,.quarto-notebook .h2{border-bottom:none}.sidebar .quarto-alternate-formats a,.sidebar .quarto-alternate-notebooks a{text-decoration:none}.sidebar .quarto-alternate-formats a:hover,.sidebar .quarto-alternate-notebooks a:hover{color:#18bc9c}.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-size:.875rem;font-weight:400;margin-bottom:.5rem;margin-top:.3rem;font-family:inherit;border-bottom:0;padding-bottom:0;padding-top:0px}.sidebar .quarto-alternate-notebooks h2,.sidebar .quarto-alternate-notebooks .h2,.sidebar .quarto-alternate-formats h2,.sidebar .quarto-alternate-formats .h2{margin-top:1rem}.sidebar nav[role=doc-toc]>ul a{border-left:1px solid #ecf0f1;padding-left:.6rem}.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 .quarto-alternate-notebooks ul a:empty,.sidebar .quarto-alternate-formats ul a:empty,.sidebar nav[role=doc-toc]>ul a:empty{display:none}.sidebar .quarto-alternate-notebooks ul,.sidebar .quarto-alternate-formats ul,.sidebar nav[role=doc-toc] ul{padding-left:0;list-style:none;font-size:.875rem;font-weight:300}.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}div.hanging-indent{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}.table a{word-break:break-word}.table>thead{border-top-width:1px;border-top-color:#dee2e6;border-bottom:1px solid #9ba5ae}.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}.callout.callout-style-default .callout-body{font-size:.9rem;font-weight:400}.callout.callout-titled .callout-body{margin-top:.2em}.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-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}.callout.callout-style-default div.callout-body{padding-left:.5em;padding-right:.5em}.callout.callout-style-default div.callout-body>:first-child{margin-top:.5em}.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){margin-bottom:.5rem}.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 .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:#eaecee}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:#e8f8f5}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:#fef5e7}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:#fff2e8}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:#fdedec}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 .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:#fafafa}#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}.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 .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{color:#fefefe;background-color:#6c757d;border-color:#6c757d}.btn.btn-quarto:hover,div.cell-output-display .btn-quarto:hover{color:#fefefe;background-color:#828a91;border-color:#7b838a}.btn-check:focus+.btn.btn-quarto,.btn.btn-quarto:focus,.btn-check:focus+div.cell-output-display .btn-quarto,div.cell-output-display .btn-quarto:focus{color:#fefefe;background-color:#828a91;border-color:#7b838a;box-shadow:0 0 0 .25rem rgba(130,138,144,.5)}.btn-check:checked+.btn.btn-quarto,.btn-check:active+.btn.btn-quarto,.btn.btn-quarto:active,.btn.btn-quarto.active,.show>.btn.btn-quarto.dropdown-toggle,.btn-check:checked+div.cell-output-display .btn-quarto,.btn-check:active+div.cell-output-display .btn-quarto,div.cell-output-display .btn-quarto:active,div.cell-output-display .btn-quarto.active,.show>div.cell-output-display .btn-quarto.dropdown-toggle{color:#fff;background-color:#899197;border-color:#7b838a}.btn-check:checked+.btn.btn-quarto:focus,.btn-check:active+.btn.btn-quarto:focus,.btn.btn-quarto:active:focus,.btn.btn-quarto.active:focus,.show>.btn.btn-quarto.dropdown-toggle:focus,.btn-check:checked+div.cell-output-display .btn-quarto:focus,.btn-check:active+div.cell-output-display .btn-quarto:focus,div.cell-output-display .btn-quarto:active:focus,div.cell-output-display .btn-quarto.active:focus,.show>div.cell-output-display .btn-quarto.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(130,138,144,.5)}.btn.btn-quarto:disabled,.btn.btn-quarto.disabled,div.cell-output-display .btn-quarto:disabled,div.cell-output-display .btn-quarto.disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}nav.quarto-secondary-nav.color-navbar{background-color:#2c3e50;color:#ccd1d5}nav.quarto-secondary-nav.color-navbar h1,nav.quarto-secondary-nav.color-navbar .h1,nav.quarto-secondary-nav.color-navbar .quarto-btn-toggle{color:#ccd1d5}@media(max-width: 991.98px){body.nav-sidebar .quarto-title-banner{margin-bottom:0;padding-bottom:0}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:var(--bs-font-monospace);color:#383f45;border:solid #383f45 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:var(--bs-font-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}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;transform:translate3d(0, 0, 0)}.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;transform:translate3d(0, 0, 0)}.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;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:page-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:page-start/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.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;transform:translate3d(0, 0, 0);margin-bottom:1em}}.quarto-video{margin-bottom:1em}.table>thead{border-top-width:0}.table>:not(caption)>*:not(:last-child)>*{border-bottom-color:#d3d8dc;border-bottom-style:solid;border-bottom-width:1px}.table>:not(:first-child){border-top:1px solid #9ba5ae;border-bottom:1px solid inherit}.table tbody{border-bottom-color:#9ba5ae}a.external:after{display:inline-block;height:.75rem;width:.75rem;margin-bottom:.15em;margin-left:.25em;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:.75rem .75rem}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,.code-with-filename .code-with-filename-file pre{background-color:rgba(219,219,219,.8)}.quarto-dark .code-with-filename .code-with-filename-file,.quarto-dark .code-with-filename .code-with-filename-file pre{background-color:#555}.code-with-filename .code-with-filename-file strong{font-weight:400}.quarto-title-banner{margin-bottom:1em;color:#ccd1d5;background:#2c3e50}.quarto-title-banner .code-tools-button{color:#949fa7}.quarto-title-banner .code-tools-button:hover{color:#ccd1d5}.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}}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}#title-block-header.quarto-title-block.default .quarto-title-meta{display:grid;grid-template-columns:repeat(2, 1fr)}#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:-5px}#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 a{color:#212529}#title-block-header.quarto-title-block.default .quarto-title-meta-contents p.affiliation:last-of-type{margin-bottom:.7em}#title-block-header.quarto-title-block.default p.affiliation{margin-bottom:.1em}#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 .description>p,#title-block-header.quarto-title-block.default .abstract>p{font-size:.9em}#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 .description .abstract-title,#title-block-header.quarto-title-block.default .abstract .abstract-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:1fr 1fr}.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{border:none;color:#fff}.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{background-image:url("data:image/svg+xml,")}/*# sourceMappingURL=d6b77e37a12f878a50f9f8a85e535bdc.css.map */ diff --git a/docs/_site/site_libs/bootstrap/bootstrap.min.js b/docs/_site/site_libs/bootstrap/bootstrap.min.js deleted file mode 100644 index cc0a255..0000000 --- a/docs/_site/site_libs/bootstrap/bootstrap.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v5.1.3 (https://getbootstrap.com/) - * Copyright 2011-2021 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="transitionend",e=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 e},i=t=>{const i=e(t);return i&&document.querySelector(i)?i:null},n=t=>{const i=e(t);return i?document.querySelector(i):null},s=e=>{e.dispatchEvent(new Event(t))},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(t):null,a=(t,e,i)=>{Object.keys(i).forEach((n=>{const s=i[n],r=e[n],a=r&&o(r)?"element":null==(l=r)?`${l}`:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();var l;if(!new RegExp(s).test(a))throw new TypeError(`${t.toUpperCase()}: Option "${n}" provided type "${a}" but expected type "${s}".`)}))},l=t=>!(!o(t)||0===t.getClientRects().length)&&"visible"===getComputedStyle(t).getPropertyValue("visibility"),c=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),h=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?h(t.parentNode):null},d=()=>{},u=t=>{t.offsetHeight},f=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},p=[],m=()=>"rtl"===document.documentElement.dir,g=t=>{var e;e=()=>{const e=f();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?(p.length||document.addEventListener("DOMContentLoaded",(()=>{p.forEach((t=>t()))})),p.push(e)):e()},_=t=>{"function"==typeof t&&t()},b=(e,i,n=!0)=>{if(!n)return void _(e);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})(i)+5;let r=!1;const a=({target:n})=>{n===i&&(r=!0,i.removeEventListener(t,a),_(e))};i.addEventListener(t,a),setTimeout((()=>{r||s(i)}),o)},v=(t,e,i,n)=>{let s=t.indexOf(e);if(-1===s)return t[!i&&n?t.length-1:0];const o=t.length;return s+=i?1:-1,n&&(s=(s+o)%o),t[Math.max(0,Math.min(s,o-1))]},y=/[^.]*(?=\..*)\.|.*/,w=/\..*/,E=/::\d+$/,A={};let T=1;const O={mouseenter:"mouseover",mouseleave:"mouseout"},C=/^(mouseenter|mouseleave)/i,k=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 L(t,e){return e&&`${e}::${T++}`||t.uidEvent||T++}function x(t){const e=L(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function D(t,e,i=null){const n=Object.keys(t);for(let s=0,o=n.length;sfunction(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};n?n=t(n):i=t(i)}const[o,r,a]=S(e,i,n),l=x(t),c=l[a]||(l[a]={}),h=D(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=L(r,e.replace(y,"")),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(let a=o.length;a--;)if(o[a]===r)return s.delegateTarget=r,n.oneOff&&j.off(t,s.type,e,i),i.apply(r,[s]);return null}}(t,i,n):function(t,e){return function i(n){return n.delegateTarget=t,i.oneOff&&j.off(t,n.type,e),e.apply(t,[n])}}(t,i);u.delegationSelector=o?i:null,u.originalHandler=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function I(t,e,i,n,s){const o=D(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function P(t){return t=t.replace(w,""),O[t]||t}const j={on(t,e,i,n){N(t,e,i,n,!1)},one(t,e,i,n){N(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=S(e,i,n),a=r!==e,l=x(t),c=e.startsWith(".");if(void 0!==o){if(!l||!l[r])return;return void I(t,l,r,o,s?i:null)}c&&Object.keys(l).forEach((i=>{!function(t,e,i,n){const s=e[i]||{};Object.keys(s).forEach((o=>{if(o.includes(n)){const n=s[o];I(t,e,i,n.originalHandler,n.delegationSelector)}}))}(t,l,i,e.slice(1))}));const h=l[r]||{};Object.keys(h).forEach((i=>{const n=i.replace(E,"");if(!a||e.includes(n)){const e=h[i];I(t,l,r,e.originalHandler,e.delegationSelector)}}))},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=f(),s=P(e),o=e!==s,r=k.has(s);let a,l=!0,c=!0,h=!1,d=null;return o&&n&&(a=n.Event(e,i),n(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),h=a.isDefaultPrevented()),r?(d=document.createEvent("HTMLEvents"),d.initEvent(s,l,!0)):d=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==i&&Object.keys(i).forEach((t=>{Object.defineProperty(d,t,{get:()=>i[t]})})),h&&d.preventDefault(),c&&t.dispatchEvent(d),d.defaultPrevented&&void 0!==a&&a.preventDefault(),d}},M=new Map,H={set(t,e,i){M.has(t)||M.set(t,new Map);const n=M.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>M.has(t)&&M.get(t).get(e)||null,remove(t,e){if(!M.has(t))return;const i=M.get(t);i.delete(e),0===i.size&&M.delete(t)}};class B{constructor(t){(t=r(t))&&(this._element=t,H.set(this._element,this.constructor.DATA_KEY,this))}dispose(){H.remove(this._element,this.constructor.DATA_KEY),j.off(this._element,this.constructor.EVENT_KEY),Object.getOwnPropertyNames(this).forEach((t=>{this[t]=null}))}_queueCallback(t,e,i=!0){b(t,e,i)}static getInstance(t){return H.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.1.3"}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}}const R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,s=t.NAME;j.on(document,i,`[data-bs-dismiss="${s}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),c(this))return;const o=n(this)||this.closest(`.${s}`);t.getOrCreateInstance(o)[e]()}))};class W extends B{static get NAME(){return"alert"}close(){if(j.trigger(this._element,"close.bs.alert").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(),j.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=W.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(W,"close"),g(W);const $='[data-bs-toggle="button"]';class z extends B{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=z.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}function q(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function F(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}j.on(document,"click.bs.button.data-api",$,(t=>{t.preventDefault();const e=t.target.closest($);z.getOrCreateInstance(e).toggle()})),g(z);const U={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${F(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${F(e)}`)},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter((t=>t.startsWith("bs"))).forEach((i=>{let n=i.replace(/^bs/,"");n=n.charAt(0).toLowerCase()+n.slice(1,n.length),e[n]=q(t.dataset[i])})),e},getDataAttribute:(t,e)=>q(t.getAttribute(`data-bs-${F(e)}`)),offset(t){const e=t.getBoundingClientRect();return{top:e.top+window.pageYOffset,left:e.left+window.pageXOffset}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},V={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;for(;n&&n.nodeType===Node.ELEMENT_NODE&&3!==n.nodeType;)n.matches(e)&&i.push(n),n=n.parentNode;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=>!c(t)&&l(t)))}},K="carousel",X={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},Y={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},Q="next",G="prev",Z="left",J="right",tt={ArrowLeft:J,ArrowRight:Z},et="slid.bs.carousel",it="active",nt=".active.carousel-item";class st extends B{constructor(t,e){super(t),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._indicatorsElement=V.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return X}static get NAME(){return K}next(){this._slide(Q)}nextWhenVisible(){!document.hidden&&l(this._element)&&this.next()}prev(){this._slide(G)}pause(t){t||(this._isPaused=!0),V.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(s(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(t){this._activeElement=V.findOne(nt,this._element);const e=this._getItemIndex(this._activeElement);if(t>this._items.length-1||t<0)return;if(this._isSliding)return void j.one(this._element,et,(()=>this.to(t)));if(e===t)return this.pause(),void this.cycle();const i=t>e?Q:G;this._slide(i,this._items[t])}_getConfig(t){return t={...X,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(K,t,Y),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?J:Z)}_addEventListeners(){this._config.keyboard&&j.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(j.on(this._element,"mouseenter.bs.carousel",(t=>this.pause(t))),j.on(this._element,"mouseleave.bs.carousel",(t=>this.cycle(t)))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const t=t=>this._pointerEvent&&("pen"===t.pointerType||"touch"===t.pointerType),e=e=>{t(e)?this.touchStartX=e.clientX:this._pointerEvent||(this.touchStartX=e.touches[0].clientX)},i=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},n=e=>{t(e)&&(this.touchDeltaX=e.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((t=>this.cycle(t)),500+this._config.interval))};V.find(".carousel-item img",this._element).forEach((t=>{j.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()))})),this._pointerEvent?(j.on(this._element,"pointerdown.bs.carousel",(t=>e(t))),j.on(this._element,"pointerup.bs.carousel",(t=>n(t))),this._element.classList.add("pointer-event")):(j.on(this._element,"touchstart.bs.carousel",(t=>e(t))),j.on(this._element,"touchmove.bs.carousel",(t=>i(t))),j.on(this._element,"touchend.bs.carousel",(t=>n(t))))}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=tt[t.key];e&&(t.preventDefault(),this._slide(e))}_getItemIndex(t){return this._items=t&&t.parentNode?V.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)}_getItemByOrder(t,e){const i=t===Q;return v(this._items,e,i,this._config.wrap)}_triggerSlideEvent(t,e){const i=this._getItemIndex(t),n=this._getItemIndex(V.findOne(nt,this._element));return j.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:n,to:i})}_setActiveIndicatorElement(t){if(this._indicatorsElement){const e=V.findOne(".active",this._indicatorsElement);e.classList.remove(it),e.removeAttribute("aria-current");const i=V.find("[data-bs-target]",this._indicatorsElement);for(let e=0;e{j.trigger(this._element,et,{relatedTarget:o,direction:d,from:s,to:r})};if(this._element.classList.contains("slide")){o.classList.add(h),u(o),n.classList.add(c),o.classList.add(c);const t=()=>{o.classList.remove(c,h),o.classList.add(it),n.classList.remove(it,h,c),this._isSliding=!1,setTimeout(f,0)};this._queueCallback(t,n,!0)}else n.classList.remove(it),o.classList.add(it),this._isSliding=!1,f();a&&this.cycle()}_directionToOrder(t){return[J,Z].includes(t)?m()?t===Z?G:Q:t===Z?Q:G:t}_orderToDirection(t){return[Q,G].includes(t)?m()?t===G?Z:J:t===G?J:Z:t}static carouselInterface(t,e){const i=st.getOrCreateInstance(t,e);let{_config:n}=i;"object"==typeof e&&(n={...n,...e});const s="string"==typeof e?e:n.slide;if("number"==typeof e)i.to(e);else if("string"==typeof s){if(void 0===i[s])throw new TypeError(`No method named "${s}"`);i[s]()}else n.interval&&n.ride&&(i.pause(),i.cycle())}static jQueryInterface(t){return this.each((function(){st.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=n(this);if(!e||!e.classList.contains("carousel"))return;const i={...U.getDataAttributes(e),...U.getDataAttributes(this)},s=this.getAttribute("data-bs-slide-to");s&&(i.interval=!1),st.carouselInterface(e,i),s&&st.getInstance(e).to(s),t.preventDefault()}}j.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",st.dataApiClickHandler),j.on(window,"load.bs.carousel.data-api",(()=>{const t=V.find('[data-bs-ride="carousel"]');for(let e=0,i=t.length;et===this._element));null!==s&&o.length&&(this._selector=s,this._triggerArray.push(e))}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return rt}static get NAME(){return ot}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t,e=[];if(this._config.parent){const t=V.find(ut,this._config.parent);e=V.find(".collapse.show, .collapse.collapsing",this._config.parent).filter((e=>!t.includes(e)))}const i=V.findOne(this._selector);if(e.length){const n=e.find((t=>i!==t));if(t=n?pt.getInstance(n):null,t&&t._isTransitioning)return}if(j.trigger(this._element,"show.bs.collapse").defaultPrevented)return;e.forEach((e=>{i!==e&&pt.getOrCreateInstance(e,{toggle:!1}).hide(),t||H.set(e,"bs.collapse",null)}));const n=this._getDimension();this._element.classList.remove(ct),this._element.classList.add(ht),this._element.style[n]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const s=`scroll${n[0].toUpperCase()+n.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct,lt),this._element.style[n]="",j.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[n]=`${this._element[s]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(j.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,u(this._element),this._element.classList.add(ht),this._element.classList.remove(ct,lt);const e=this._triggerArray.length;for(let t=0;t{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct),j.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(lt)}_getConfig(t){return(t={...rt,...U.getDataAttributes(this._element),...t}).toggle=Boolean(t.toggle),t.parent=r(t.parent),a(ot,t,at),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=V.find(ut,this._config.parent);V.find(ft,this._config.parent).filter((e=>!t.includes(e))).forEach((t=>{const e=n(t);e&&this._addAriaAndCollapsedClass([t],this._isShown(e))}))}_addAriaAndCollapsedClass(t,e){t.length&&t.forEach((t=>{e?t.classList.remove(dt):t.classList.add(dt),t.setAttribute("aria-expanded",e)}))}static jQueryInterface(t){return this.each((function(){const e={};"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1);const i=pt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}j.on(document,"click.bs.collapse.data-api",ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=i(this);V.find(e).forEach((t=>{pt.getOrCreateInstance(t,{toggle:!1}).toggle()}))})),g(pt);var mt="top",gt="bottom",_t="right",bt="left",vt="auto",yt=[mt,gt,_t,bt],wt="start",Et="end",At="clippingParents",Tt="viewport",Ot="popper",Ct="reference",kt=yt.reduce((function(t,e){return t.concat([e+"-"+wt,e+"-"+Et])}),[]),Lt=[].concat(yt,[vt]).reduce((function(t,e){return t.concat([e,e+"-"+wt,e+"-"+Et])}),[]),xt="beforeRead",Dt="read",St="afterRead",Nt="beforeMain",It="main",Pt="afterMain",jt="beforeWrite",Mt="write",Ht="afterWrite",Bt=[xt,Dt,St,Nt,It,Pt,jt,Mt,Ht];function Rt(t){return t?(t.nodeName||"").toLowerCase():null}function Wt(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function $t(t){return t instanceof Wt(t).Element||t instanceof Element}function zt(t){return t instanceof Wt(t).HTMLElement||t instanceof HTMLElement}function qt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof Wt(t).ShadowRoot||t instanceof ShadowRoot)}const Ft={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];zt(s)&&Rt(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}),{});zt(n)&&Rt(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function Ut(t){return t.split("-")[0]}function Vt(t,e){var i=t.getBoundingClientRect();return{width:i.width/1,height:i.height/1,top:i.top/1,right:i.right/1,bottom:i.bottom/1,left:i.left/1,x:i.left/1,y:i.top/1}}function Kt(t){var e=Vt(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 Xt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&qt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Yt(t){return Wt(t).getComputedStyle(t)}function Qt(t){return["table","td","th"].indexOf(Rt(t))>=0}function Gt(t){return(($t(t)?t.ownerDocument:t.document)||window.document).documentElement}function Zt(t){return"html"===Rt(t)?t:t.assignedSlot||t.parentNode||(qt(t)?t.host:null)||Gt(t)}function Jt(t){return zt(t)&&"fixed"!==Yt(t).position?t.offsetParent:null}function te(t){for(var e=Wt(t),i=Jt(t);i&&Qt(i)&&"static"===Yt(i).position;)i=Jt(i);return i&&("html"===Rt(i)||"body"===Rt(i)&&"static"===Yt(i).position)?e:i||function(t){var e=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&zt(t)&&"fixed"===Yt(t).position)return null;for(var i=Zt(t);zt(i)&&["html","body"].indexOf(Rt(i))<0;){var n=Yt(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 ee(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}var ie=Math.max,ne=Math.min,se=Math.round;function oe(t,e,i){return ie(t,ne(e,i))}function re(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function ae(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const le={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=Ut(i.placement),l=ee(a),c=[bt,_t].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return re("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:ae(t,yt))}(s.padding,i),d=Kt(o),u="y"===l?mt:bt,f="y"===l?gt:_t,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=te(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,E=oe(v,w,y),A=l;i.modifiersData[n]=((e={})[A]=E,e.centerOffset=E-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)))&&Xt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ce(t){return t.split("-")[1]}var he={top:"auto",right:"auto",bottom:"auto",left:"auto"};function de(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=!0===h?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:se(se(e*n)/n)||0,y:se(se(i*n)/n)||0}}(r):"function"==typeof h?h(r):r,u=d.x,f=void 0===u?0:u,p=d.y,m=void 0===p?0:p,g=r.hasOwnProperty("x"),_=r.hasOwnProperty("y"),b=bt,v=mt,y=window;if(c){var w=te(i),E="clientHeight",A="clientWidth";w===Wt(i)&&"static"!==Yt(w=Gt(i)).position&&"absolute"===a&&(E="scrollHeight",A="scrollWidth"),w=w,s!==mt&&(s!==bt&&s!==_t||o!==Et)||(v=gt,m-=w[E]-n.height,m*=l?1:-1),s!==bt&&(s!==mt&&s!==gt||o!==Et)||(b=_t,f-=w[A]-n.width,f*=l?1:-1)}var T,O=Object.assign({position:a},c&&he);return l?Object.assign({},O,((T={})[v]=_?"0":"",T[b]=g?"0":"",T.transform=(y.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",T)):Object.assign({},O,((e={})[v]=_?m+"px":"",e[b]=g?f+"px":"",e.transform="",e))}const ue={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:Ut(e.placement),variation:ce(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,de(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,de(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 fe={passive:!0};const pe={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=Wt(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,fe)})),a&&l.addEventListener("resize",i.update,fe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,fe)})),a&&l.removeEventListener("resize",i.update,fe)}},data:{}};var me={left:"right",right:"left",bottom:"top",top:"bottom"};function ge(t){return t.replace(/left|right|bottom|top/g,(function(t){return me[t]}))}var _e={start:"end",end:"start"};function be(t){return t.replace(/start|end/g,(function(t){return _e[t]}))}function ve(t){var e=Wt(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function ye(t){return Vt(Gt(t)).left+ve(t).scrollLeft}function we(t){var e=Yt(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ee(t){return["html","body","#document"].indexOf(Rt(t))>=0?t.ownerDocument.body:zt(t)&&we(t)?t:Ee(Zt(t))}function Ae(t,e){var i;void 0===e&&(e=[]);var n=Ee(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=Wt(n),r=s?[o].concat(o.visualViewport||[],we(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Ae(Zt(r)))}function Te(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Oe(t,e){return e===Tt?Te(function(t){var e=Wt(t),i=Gt(t),n=e.visualViewport,s=i.clientWidth,o=i.clientHeight,r=0,a=0;return n&&(s=n.width,o=n.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(r=n.offsetLeft,a=n.offsetTop)),{width:s,height:o,x:r+ye(t),y:a}}(t)):zt(e)?function(t){var e=Vt(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Te(function(t){var e,i=Gt(t),n=ve(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ie(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ie(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+ye(t),l=-n.scrollTop;return"rtl"===Yt(s||i).direction&&(a+=ie(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Gt(t)))}function Ce(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?Ut(s):null,r=s?ce(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case mt:e={x:a,y:i.y-n.height};break;case gt:e={x:a,y:i.y+i.height};break;case _t:e={x:i.x+i.width,y:l};break;case bt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?ee(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case wt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Et:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ke(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.boundary,r=void 0===o?At:o,a=i.rootBoundary,l=void 0===a?Tt:a,c=i.elementContext,h=void 0===c?Ot:c,d=i.altBoundary,u=void 0!==d&&d,f=i.padding,p=void 0===f?0:f,m=re("number"!=typeof p?p:ae(p,yt)),g=h===Ot?Ct:Ot,_=t.rects.popper,b=t.elements[u?g:h],v=function(t,e,i){var n="clippingParents"===e?function(t){var e=Ae(Zt(t)),i=["absolute","fixed"].indexOf(Yt(t).position)>=0&&zt(t)?te(t):t;return $t(i)?e.filter((function(t){return $t(t)&&Xt(t,i)&&"body"!==Rt(t)})):[]}(t):[].concat(e),s=[].concat(n,[i]),o=s[0],r=s.reduce((function(e,i){var n=Oe(t,i);return e.top=ie(n.top,e.top),e.right=ne(n.right,e.right),e.bottom=ne(n.bottom,e.bottom),e.left=ie(n.left,e.left),e}),Oe(t,o));return r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}($t(b)?b:b.contextElement||Gt(t.elements.popper),r,l),y=Vt(t.elements.reference),w=Ce({reference:y,element:_,strategy:"absolute",placement:s}),E=Te(Object.assign({},_,w)),A=h===Ot?E:y,T={top:v.top-A.top+m.top,bottom:A.bottom-v.bottom+m.bottom,left:v.left-A.left+m.left,right:A.right-v.right+m.right},O=t.modifiersData.offset;if(h===Ot&&O){var C=O[s];Object.keys(T).forEach((function(t){var e=[_t,gt].indexOf(t)>=0?1:-1,i=[mt,gt].indexOf(t)>=0?"y":"x";T[t]+=C[i]*e}))}return T}function Le(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?Lt:l,h=ce(n),d=h?a?kt:kt.filter((function(t){return ce(t)===h})):yt,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]=ke(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[Ut(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const xe={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,_=Ut(g),b=l||(_!==g&&p?function(t){if(Ut(t)===vt)return[];var e=ge(t);return[be(t),e,be(e)]}(g):[ge(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(Ut(i)===vt?Le(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,E=new Map,A=!0,T=v[0],O=0;O=0,D=x?"width":"height",S=ke(e,{placement:C,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),N=x?L?_t:bt:L?gt:mt;y[D]>w[D]&&(N=ge(N));var I=ge(N),P=[];if(o&&P.push(S[k]<=0),a&&P.push(S[N]<=0,S[I]<=0),P.every((function(t){return t}))){T=C,A=!1;break}E.set(C,P)}if(A)for(var j=function(t){var e=v.find((function(e){var i=E.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"!==j(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function De(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 Se(t){return[mt,_t,gt,bt].some((function(e){return t[e]>=0}))}const Ne={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=ke(e,{elementContext:"reference"}),a=ke(e,{altBoundary:!0}),l=De(r,n),c=De(a,s,o),h=Se(l),d=Se(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})}},Ie={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=Lt.reduce((function(t,i){return t[i]=function(t,e,i){var n=Ut(t),s=[bt,mt].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,[bt,_t].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}},Pe={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=Ce({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},je={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=ke(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=Ut(e.placement),b=ce(e.placement),v=!b,y=ee(_),w="x"===y?"y":"x",E=e.modifiersData.popperOffsets,A=e.rects.reference,T=e.rects.popper,O="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,C={x:0,y:0};if(E){if(o||a){var k="y"===y?mt:bt,L="y"===y?gt:_t,x="y"===y?"height":"width",D=E[y],S=E[y]+g[k],N=E[y]-g[L],I=f?-T[x]/2:0,P=b===wt?A[x]:T[x],j=b===wt?-T[x]:-A[x],M=e.elements.arrow,H=f&&M?Kt(M):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},R=B[k],W=B[L],$=oe(0,A[x],H[x]),z=v?A[x]/2-I-$-R-O:P-$-R-O,q=v?-A[x]/2+I+$+W+O:j+$+W+O,F=e.elements.arrow&&te(e.elements.arrow),U=F?"y"===y?F.clientTop||0:F.clientLeft||0:0,V=e.modifiersData.offset?e.modifiersData.offset[e.placement][y]:0,K=E[y]+z-V-U,X=E[y]+q-V;if(o){var Y=oe(f?ne(S,K):S,D,f?ie(N,X):N);E[y]=Y,C[y]=Y-D}if(a){var Q="x"===y?mt:bt,G="x"===y?gt:_t,Z=E[w],J=Z+g[Q],tt=Z-g[G],et=oe(f?ne(J,K):J,Z,f?ie(tt,X):tt);E[w]=et,C[w]=et-Z}}e.modifiersData[n]=C}},requiresIfExists:["offset"]};function Me(t,e,i){void 0===i&&(i=!1);var n=zt(e);zt(e)&&function(t){var e=t.getBoundingClientRect();e.width,t.offsetWidth,e.height,t.offsetHeight}(e);var s,o,r=Gt(e),a=Vt(t),l={scrollLeft:0,scrollTop:0},c={x:0,y:0};return(n||!n&&!i)&&(("body"!==Rt(e)||we(r))&&(l=(s=e)!==Wt(s)&&zt(s)?{scrollLeft:(o=s).scrollLeft,scrollTop:o.scrollTop}:ve(s)),zt(e)?((c=Vt(e)).x+=e.clientLeft,c.y+=e.clientTop):r&&(c.x=ye(r))),{x:a.left+l.scrollLeft-c.x,y:a.top+l.scrollTop-c.y,width:a.width,height:a.height}}function He(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 Be={placement:"bottom",modifiers:[],strategy:"absolute"};function Re(){for(var t=arguments.length,e=new Array(t),i=0;ij.on(t,"mouseover",d))),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(Je),this._element.classList.add(Je),j.trigger(this._element,"shown.bs.dropdown",t)}hide(){if(c(this._element)||!this._isShown(this._menu))return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){j.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._popper&&this._popper.destroy(),this._menu.classList.remove(Je),this._element.classList.remove(Je),this._element.setAttribute("aria-expanded","false"),U.removeDataAttribute(this._menu,"popper"),j.trigger(this._element,"hidden.bs.dropdown",t))}_getConfig(t){if(t={...this.constructor.Default,...U.getDataAttributes(this._element),...t},a(Ue,t,this.constructor.DefaultType),"object"==typeof t.reference&&!o(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${Ue.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(t){if(void 0===Fe)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let e=this._element;"parent"===this._config.reference?e=t:o(this._config.reference)?e=r(this._config.reference):"object"==typeof this._config.reference&&(e=this._config.reference);const i=this._getPopperConfig(),n=i.modifiers.find((t=>"applyStyles"===t.name&&!1===t.enabled));this._popper=qe(e,this._menu,i),n&&U.setDataAttribute(this._menu,"popper","static")}_isShown(t=this._element){return t.classList.contains(Je)}_getMenuElement(){return V.next(this._element,ei)[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains("dropend"))return ri;if(t.classList.contains("dropstart"))return ai;const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?ni:ii:e?oi:si}_detectNavbar(){return null!==this._element.closest(".navbar")}_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}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem({key:t,target:e}){const i=V.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter(l);i.length&&v(i,e,t===Ye,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=hi.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(t&&(2===t.button||"keyup"===t.type&&"Tab"!==t.key))return;const e=V.find(ti);for(let i=0,n=e.length;ie+t)),this._setElementAttributes(di,"paddingRight",(e=>e+t)),this._setElementAttributes(ui,"marginRight",(e=>e-t))}_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)[e];t.style[e]=`${i(Number.parseFloat(s))}px`}))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,"paddingRight"),this._resetElementAttributes(di,"paddingRight"),this._resetElementAttributes(ui,"marginRight")}_saveInitialAttribute(t,e){const i=t.style[e];i&&U.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=U.getDataAttribute(t,e);void 0===i?t.style.removeProperty(e):(U.removeDataAttribute(t,e),t.style[e]=i)}))}_applyManipulationCallback(t,e){o(t)?e(t):V.find(t,this._element).forEach(e)}isOverflowing(){return this.getWidth()>0}}const pi={className:"modal-backdrop",isVisible:!0,isAnimated:!1,rootElement:"body",clickCallback:null},mi={className:"string",isVisible:"boolean",isAnimated:"boolean",rootElement:"(element|string)",clickCallback:"(function|null)"},gi="show",_i="mousedown.bs.backdrop";class bi{constructor(t){this._config=this._getConfig(t),this._isAppended=!1,this._element=null}show(t){this._config.isVisible?(this._append(),this._config.isAnimated&&u(this._getElement()),this._getElement().classList.add(gi),this._emulateAnimation((()=>{_(t)}))):_(t)}hide(t){this._config.isVisible?(this._getElement().classList.remove(gi),this._emulateAnimation((()=>{this.dispose(),_(t)}))):_(t)}_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}_getConfig(t){return(t={...pi,..."object"==typeof t?t:{}}).rootElement=r(t.rootElement),a("backdrop",t,mi),t}_append(){this._isAppended||(this._config.rootElement.append(this._getElement()),j.on(this._getElement(),_i,(()=>{_(this._config.clickCallback)})),this._isAppended=!0)}dispose(){this._isAppended&&(j.off(this._element,_i),this._element.remove(),this._isAppended=!1)}_emulateAnimation(t){b(t,this._getElement(),this._config.isAnimated)}}const vi={trapElement:null,autofocus:!0},yi={trapElement:"element",autofocus:"boolean"},wi=".bs.focustrap",Ei="backward";class Ai{constructor(t){this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}activate(){const{trapElement:t,autofocus:e}=this._config;this._isActive||(e&&t.focus(),j.off(document,wi),j.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),j.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,j.off(document,wi))}_handleFocusin(t){const{target:e}=t,{trapElement:i}=this._config;if(e===document||e===i||i.contains(e))return;const n=V.focusableChildren(i);0===n.length?i.focus():this._lastTabNavDirection===Ei?n[n.length-1].focus():n[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?Ei:"forward")}_getConfig(t){return t={...vi,..."object"==typeof t?t:{}},a("focustrap",t,yi),t}}const Ti="modal",Oi="Escape",Ci={backdrop:!0,keyboard:!0,focus:!0},ki={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean"},Li="hidden.bs.modal",xi="show.bs.modal",Di="resize.bs.modal",Si="click.dismiss.bs.modal",Ni="keydown.dismiss.bs.modal",Ii="mousedown.dismiss.bs.modal",Pi="modal-open",ji="show",Mi="modal-static";class Hi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._dialog=V.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollBar=new fi}static get Default(){return Ci}static get NAME(){return Ti}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||j.trigger(this._element,xi,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isAnimated()&&(this._isTransitioning=!0),this._scrollBar.hide(),document.body.classList.add(Pi),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),j.on(this._dialog,Ii,(()=>{j.one(this._element,"mouseup.dismiss.bs.modal",(t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)}))})),this._showBackdrop((()=>this._showElement(t))))}hide(){if(!this._isShown||this._isTransitioning)return;if(j.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const t=this._isAnimated();t&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),this._focustrap.deactivate(),this._element.classList.remove(ji),j.off(this._element,Si),j.off(this._dialog,Ii),this._queueCallback((()=>this._hideModal()),this._element,t)}dispose(){[window,this._dialog].forEach((t=>j.off(t,".bs.modal"))),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new bi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_getConfig(t){return t={...Ci,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Ti,t,ki),t}_showElement(t){const e=this._isAnimated(),i=V.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||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,i&&(i.scrollTop=0),e&&u(this._element),this._element.classList.add(ji),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,j.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,e)}_setEscapeEvent(){this._isShown?j.on(this._element,Ni,(t=>{this._config.keyboard&&t.key===Oi?(t.preventDefault(),this.hide()):this._config.keyboard||t.key!==Oi||this._triggerBackdropTransition()})):j.off(this._element,Ni)}_setResizeEvent(){this._isShown?j.on(window,Di,(()=>this._adjustDialog())):j.off(window,Di)}_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(Pi),this._resetAdjustments(),this._scrollBar.reset(),j.trigger(this._element,Li)}))}_showBackdrop(t){j.on(this._element,Si,(t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&(!0===this._config.backdrop?this.hide():"static"===this._config.backdrop&&this._triggerBackdropTransition())})),this._backdrop.show(t)}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(j.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const{classList:t,scrollHeight:e,style:i}=this._element,n=e>document.documentElement.clientHeight;!n&&"hidden"===i.overflowY||t.contains(Mi)||(n||(i.overflowY="hidden"),t.add(Mi),this._queueCallback((()=>{t.remove(Mi),n||this._queueCallback((()=>{i.overflowY=""}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;(!i&&t&&!m()||i&&!t&&m())&&(this._element.style.paddingLeft=`${e}px`),(i&&!t&&!m()||!i&&t&&m())&&(this._element.style.paddingRight=`${e}px`)}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}j.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=n(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),j.one(e,xi,(t=>{t.defaultPrevented||j.one(e,Li,(()=>{l(this)&&this.focus()}))}));const i=V.findOne(".modal.show");i&&Hi.getInstance(i).hide(),Hi.getOrCreateInstance(e).toggle(this)})),R(Hi),g(Hi);const Bi="offcanvas",Ri={backdrop:!0,keyboard:!0,scroll:!1},Wi={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"},$i="show",zi=".offcanvas.show",qi="hidden.bs.offcanvas";class Fi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get NAME(){return Bi}static get Default(){return Ri}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||j.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._element.style.visibility="visible",this._backdrop.show(),this._config.scroll||(new fi).hide(),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add($i),this._queueCallback((()=>{this._config.scroll||this._focustrap.activate(),j.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(j.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.remove($i),this._backdrop.hide(),this._queueCallback((()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.scroll||(new fi).reset(),j.trigger(this._element,qi)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_getConfig(t){return t={...Ri,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Bi,t,Wi),t}_initializeBackDrop(){return new bi({className:"offcanvas-backdrop",isVisible:this._config.backdrop,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:()=>this.hide()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_addEventListeners(){j.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{this._config.keyboard&&"Escape"===t.key&&this.hide()}))}static jQueryInterface(t){return this.each((function(){const e=Fi.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)}}))}}j.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=n(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this))return;j.one(e,qi,(()=>{l(this)&&this.focus()}));const i=V.findOne(zi);i&&i!==e&&Fi.getInstance(i).hide(),Fi.getOrCreateInstance(e).toggle(this)})),j.on(window,"load.bs.offcanvas.data-api",(()=>V.find(zi).forEach((t=>Fi.getOrCreateInstance(t).show())))),R(Fi),g(Fi);const Ui=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Vi=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,Ki=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Xi=(t,e)=>{const i=t.nodeName.toLowerCase();if(e.includes(i))return!Ui.has(i)||Boolean(Vi.test(t.nodeValue)||Ki.test(t.nodeValue));const n=e.filter((t=>t instanceof RegExp));for(let t=0,e=n.length;t{Xi(t,r)||i.removeAttribute(t.nodeName)}))}return n.body.innerHTML}const Qi="tooltip",Gi=new Set(["sanitize","allowList","sanitizeFn"]),Zi={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},Ji={AUTO:"auto",TOP:"top",RIGHT:m()?"left":"right",BOTTOM:"bottom",LEFT:m()?"right":"left"},tn={animation:!0,template:'

    ',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["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:[]},popperConfig:null},en={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},nn="fade",sn="show",on="show",rn="out",an=".tooltip-inner",ln=".modal",cn="hide.bs.modal",hn="hover",dn="focus";class un extends B{constructor(t,e){if(void 0===Fe)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this._config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return tn}static get NAME(){return Qi}static get Event(){return en}static get DefaultType(){return Zi}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains(sn))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),j.off(this._element.closest(ln),cn,this._hideModalHandler),this.tip&&this.tip.remove(),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=j.trigger(this._element,this.constructor.Event.SHOW),e=h(this._element),i=null===e?this._element.ownerDocument.documentElement.contains(this._element):e.contains(this._element);if(t.defaultPrevented||!i)return;"tooltip"===this.constructor.NAME&&this.tip&&this.getTitle()!==this.tip.querySelector(an).innerHTML&&(this._disposePopper(),this.tip.remove(),this.tip=null);const n=this.getTipElement(),s=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME);n.setAttribute("id",s),this._element.setAttribute("aria-describedby",s),this._config.animation&&n.classList.add(nn);const o="function"==typeof this._config.placement?this._config.placement.call(this,n,this._element):this._config.placement,r=this._getAttachment(o);this._addAttachmentClass(r);const{container:a}=this._config;H.set(n,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(a.append(n),j.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=qe(this._element,n,this._getPopperConfig(r)),n.classList.add(sn);const l=this._resolvePossibleFunction(this._config.customClass);l&&n.classList.add(...l.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>{j.on(t,"mouseover",d)}));const c=this.tip.classList.contains(nn);this._queueCallback((()=>{const t=this._hoverState;this._hoverState=null,j.trigger(this._element,this.constructor.Event.SHOWN),t===rn&&this._leave(null,this)}),this.tip,c)}hide(){if(!this._popper)return;const t=this.getTipElement();if(j.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented)return;t.classList.remove(sn),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1;const e=this.tip.classList.contains(nn);this._queueCallback((()=>{this._isWithActiveTrigger()||(this._hoverState!==on&&t.remove(),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),j.trigger(this._element,this.constructor.Event.HIDDEN),this._disposePopper())}),this.tip,e),this._hoverState=""}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement("div");t.innerHTML=this._config.template;const e=t.children[0];return this.setContent(e),e.classList.remove(nn,sn),this.tip=e,this.tip}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),an)}_sanitizeAndSetContent(t,e,i){const n=V.findOne(i,t);e||!n?this.setElementContent(n,e):n.remove()}setElementContent(t,e){if(null!==t)return o(e)?(e=r(e),void(this._config.html?e.parentNode!==t&&(t.innerHTML="",t.append(e)):t.textContent=e.textContent)):void(this._config.html?(this._config.sanitize&&(e=Yi(e,this._config.allowList,this._config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){const t=this._element.getAttribute("data-bs-original-title")||this._config.title;return this._resolvePossibleFunction(t)}updateAttachment(t){return"right"===t?"end":"left"===t?"start":t}_initializeOnDelegatedTarget(t,e){return e||this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_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"function"==typeof t?t.call(this._element):t}_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:"onChange",enabled:!0,phase:"afterWrite",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(t)}`)}_getAttachment(t){return Ji[t.toUpperCase()]}_setListeners(){this._config.trigger.split(" ").forEach((t=>{if("click"===t)j.on(this._element,this.constructor.Event.CLICK,this._config.selector,(t=>this.toggle(t)));else if("manual"!==t){const e=t===hn?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,i=t===hn?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;j.on(this._element,e,this._config.selector,(t=>this._enter(t))),j.on(this._element,i,this._config.selector,(t=>this._leave(t)))}})),this._hideModalHandler=()=>{this._element&&this.hide()},j.on(this._element.closest(ln),cn,this._hideModalHandler),this._config.selector?this._config={...this._config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?dn:hn]=!0),e.getTipElement().classList.contains(sn)||e._hoverState===on?e._hoverState=on:(clearTimeout(e._timeout),e._hoverState=on,e._config.delay&&e._config.delay.show?e._timeout=setTimeout((()=>{e._hoverState===on&&e.show()}),e._config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?dn:hn]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=rn,e._config.delay&&e._config.delay.hide?e._timeout=setTimeout((()=>{e._hoverState===rn&&e.hide()}),e._config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=U.getDataAttributes(this._element);return Object.keys(e).forEach((t=>{Gi.has(t)&&delete e[t]})),(t={...this.constructor.Default,...e,..."object"==typeof t&&t?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()),a(Qi,t,this.constructor.DefaultType),t.sanitize&&(t.template=Yi(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`,"g"),i=t.getAttribute("class").match(e);null!==i&&i.length>0&&i.map((t=>t.trim())).forEach((e=>t.classList.remove(e)))}_getBasicClassPrefix(){return"bs-tooltip"}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null)}static jQueryInterface(t){return this.each((function(){const e=un.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(un);const fn={...un.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},pn={...un.DefaultType,content:"(string|element|function)"},mn={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class gn extends un{static get Default(){return fn}static get NAME(){return"popover"}static get Event(){return mn}static get DefaultType(){return pn}isWithContent(){return this.getTitle()||this._getContent()}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),".popover-header"),this._sanitizeAndSetContent(t,this._getContent(),".popover-body")}_getContent(){return this._resolvePossibleFunction(this._config.content)}_getBasicClassPrefix(){return"bs-popover"}static jQueryInterface(t){return this.each((function(){const e=gn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(gn);const _n="scrollspy",bn={offset:10,method:"auto",target:""},vn={offset:"number",method:"string",target:"(string|element)"},yn="active",wn=".nav-link, .list-group-item, .dropdown-item",En="position";class An extends B{constructor(t,e){super(t),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,j.on(this._scrollElement,"scroll.bs.scrollspy",(()=>this._process())),this.refresh(),this._process()}static get Default(){return bn}static get NAME(){return _n}refresh(){const t=this._scrollElement===this._scrollElement.window?"offset":En,e="auto"===this._config.method?t:this._config.method,n=e===En?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),V.find(wn,this._config.target).map((t=>{const s=i(t),o=s?V.findOne(s):null;if(o){const t=o.getBoundingClientRect();if(t.width||t.height)return[U[e](o).top+n,s]}return null})).filter((t=>t)).sort(((t,e)=>t[0]-e[0])).forEach((t=>{this._offsets.push(t[0]),this._targets.push(t[1])}))}dispose(){j.off(this._scrollElement,".bs.scrollspy"),super.dispose()}_getConfig(t){return(t={...bn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}}).target=r(t.target)||document.documentElement,a(_n,t,vn),t}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),i=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=i){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t`${e}[data-bs-target="${t}"],${e}[href="${t}"]`)),i=V.findOne(e.join(","),this._config.target);i.classList.add(yn),i.classList.contains("dropdown-item")?V.findOne(".dropdown-toggle",i.closest(".dropdown")).classList.add(yn):V.parents(i,".nav, .list-group").forEach((t=>{V.prev(t,".nav-link, .list-group-item").forEach((t=>t.classList.add(yn))),V.prev(t,".nav-item").forEach((t=>{V.children(t,".nav-link").forEach((t=>t.classList.add(yn)))}))})),j.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})}_clear(){V.find(wn,this._config.target).filter((t=>t.classList.contains(yn))).forEach((t=>t.classList.remove(yn)))}static jQueryInterface(t){return this.each((function(){const e=An.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(window,"load.bs.scrollspy.data-api",(()=>{V.find('[data-bs-spy="scroll"]').forEach((t=>new An(t)))})),g(An);const Tn="active",On="fade",Cn="show",kn=".active",Ln=":scope > li > .active";class xn extends B{static get NAME(){return"tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains(Tn))return;let t;const e=n(this._element),i=this._element.closest(".nav, .list-group");if(i){const e="UL"===i.nodeName||"OL"===i.nodeName?Ln:kn;t=V.find(e,i),t=t[t.length-1]}const s=t?j.trigger(t,"hide.bs.tab",{relatedTarget:this._element}):null;if(j.trigger(this._element,"show.bs.tab",{relatedTarget:t}).defaultPrevented||null!==s&&s.defaultPrevented)return;this._activate(this._element,i);const o=()=>{j.trigger(t,"hidden.bs.tab",{relatedTarget:this._element}),j.trigger(this._element,"shown.bs.tab",{relatedTarget:t})};e?this._activate(e,e.parentNode,o):o()}_activate(t,e,i){const n=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?V.children(e,kn):V.find(Ln,e))[0],s=i&&n&&n.classList.contains(On),o=()=>this._transitionComplete(t,n,i);n&&s?(n.classList.remove(Cn),this._queueCallback(o,t,!0)):o()}_transitionComplete(t,e,i){if(e){e.classList.remove(Tn);const t=V.findOne(":scope > .dropdown-menu .active",e.parentNode);t&&t.classList.remove(Tn),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add(Tn),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),u(t),t.classList.contains(On)&&t.classList.add(Cn);let n=t.parentNode;if(n&&"LI"===n.nodeName&&(n=n.parentNode),n&&n.classList.contains("dropdown-menu")){const e=t.closest(".dropdown");e&&V.find(".dropdown-toggle",e).forEach((t=>t.classList.add(Tn))),t.setAttribute("aria-expanded",!0)}i&&i()}static jQueryInterface(t){return this.each((function(){const e=xn.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this)||xn.getOrCreateInstance(this).show()})),g(xn);const Dn="toast",Sn="hide",Nn="show",In="showing",Pn={animation:"boolean",autohide:"boolean",delay:"number"},jn={animation:!0,autohide:!0,delay:5e3};class Mn extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get DefaultType(){return Pn}static get Default(){return jn}static get NAME(){return Dn}show(){j.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(Sn),u(this._element),this._element.classList.add(Nn),this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.remove(In),j.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this._element.classList.contains(Nn)&&(j.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.add(Sn),this._element.classList.remove(In),this._element.classList.remove(Nn),j.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this._element.classList.contains(Nn)&&this._element.classList.remove(Nn),super.dispose()}_getConfig(t){return t={...jn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}},a(Dn,t,this.constructor.DefaultType),t}_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(){j.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),j.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=Mn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(Mn),g(Mn),{Alert:W,Button:z,Carousel:st,Collapse:pt,Dropdown:hi,Modal:Hi,Offcanvas:Fi,Popover:gn,ScrollSpy:An,Tab:xn,Toast:Mn,Tooltip:un}})); -//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/docs/_site/site_libs/clipboard/clipboard.min.js b/docs/_site/site_libs/clipboard/clipboard.min.js deleted file mode 100644 index 1103f81..0000000 --- a/docs/_site/site_libs/clipboard/clipboard.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * 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}",u.sheet.cssRules.length),u.sheet.insertRule("[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}",u.sheet.cssRules.length),u.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")}',u.sheet.cssRules.length)),u=document.querySelectorAll("[id]"),t=[].map.call(u,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/site_libs/quarto-html/popper.min.js b/docs/_site/site_libs/quarto-html/popper.min.js deleted file mode 100644 index 2269d66..0000000 --- a/docs/_site/site_libs/quarto-html/popper.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * @popperjs/core v2.11.4 - 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(e,t){void 0===t&&(t=!1);var n=e.getBoundingClientRect(),o=1,i=1;if(r(e)&&t){var a=e.offsetHeight,f=e.offsetWidth;f>0&&(o=s(n.width)/f||1),a>0&&(i=s(n.height)/a||1)}return{width:n.width/o,height:n.height/i,top:n.top/i,right:n.right/o,bottom:n.bottom/i,left:n.left/o,x:n.left/o,y:n.top/i}}function c(e){var n=t(e);return{scrollLeft:n.pageXOffset,scrollTop:n.pageYOffset}}function p(e){return e?(e.nodeName||"").toLowerCase():null}function u(e){return((n(e)?e.ownerDocument:e.document)||window.document).documentElement}function l(e){return f(u(e)).left+c(e).scrollLeft}function d(e){return t(e).getComputedStyle(e)}function h(e){var t=d(e),n=t.overflow,r=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+r)}function m(e,n,o){void 0===o&&(o=!1);var i,a,d=r(n),m=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),v=u(n),g=f(e,m),y={scrollLeft:0,scrollTop:0},b={x:0,y:0};return(d||!d&&!o)&&(("body"!==p(n)||h(v))&&(y=(i=n)!==t(i)&&r(i)?{scrollLeft:(a=i).scrollLeft,scrollTop:a.scrollTop}:c(i)),r(n)?((b=f(n,!0)).x+=n.clientLeft,b.y+=n.clientTop):v&&(b.x=l(v))),{x:g.left+y.scrollLeft-b.x,y:g.top+y.scrollTop-b.y,width:g.width,height:g.height}}function v(e){var t=f(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 g(e){return"html"===p(e)?e:e.assignedSlot||e.parentNode||(o(e)?e.host:null)||u(e)}function y(e){return["html","body","#document"].indexOf(p(e))>=0?e.ownerDocument.body:r(e)&&h(e)?e:y(g(e))}function b(e,n){var r;void 0===n&&(n=[]);var o=y(e),i=o===(null==(r=e.ownerDocument)?void 0:r.body),a=t(o),s=i?[a].concat(a.visualViewport||[],h(o)?o:[]):o,f=n.concat(s);return i?f:f.concat(b(g(s)))}function x(e){return["table","td","th"].indexOf(p(e))>=0}function w(e){return r(e)&&"fixed"!==d(e).position?e.offsetParent:null}function O(e){for(var n=t(e),i=w(e);i&&x(i)&&"static"===d(i).position;)i=w(i);return i&&("html"===p(i)||"body"===p(i)&&"static"===d(i).position)?n:i||function(e){var t=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&r(e)&&"fixed"===d(e).position)return null;var n=g(e);for(o(n)&&(n=n.host);r(n)&&["html","body"].indexOf(p(n))<0;){var i=d(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 j="top",E="bottom",D="right",A="left",L="auto",P=[j,E,D,A],M="start",k="end",W="viewport",B="popper",H=P.reduce((function(e,t){return e.concat([t+"-"+M,t+"-"+k])}),[]),T=[].concat(P,[L]).reduce((function(e,t){return e.concat([t,t+"-"+M,t+"-"+k])}),[]),R=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function S(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 q(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 V(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function N(e,r){return r===W?V(function(e){var n=t(e),r=u(e),o=n.visualViewport,i=r.clientWidth,a=r.clientHeight,s=0,f=0;return o&&(i=o.width,a=o.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(s=o.offsetLeft,f=o.offsetTop)),{width:i,height:a,x:s+l(e),y:f}}(e)):n(r)?function(e){var t=f(e);return t.top=t.top+e.clientTop,t.left=t.left+e.clientLeft,t.bottom=t.top+e.clientHeight,t.right=t.left+e.clientWidth,t.width=e.clientWidth,t.height=e.clientHeight,t.x=t.left,t.y=t.top,t}(r):V(function(e){var t,n=u(e),r=c(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+l(e),p=-r.scrollTop;return"rtl"===d(o||n).direction&&(f+=i(n.clientWidth,o?o.clientWidth:0)-a),{width:a,height:s,x:f,y:p}}(u(e)))}function I(e,t,o){var s="clippingParents"===t?function(e){var t=b(g(e)),o=["absolute","fixed"].indexOf(d(e).position)>=0&&r(e)?O(e):e;return n(o)?t.filter((function(e){return n(e)&&q(e,o)&&"body"!==p(e)})):[]}(e):[].concat(t),f=[].concat(s,[o]),c=f[0],u=f.reduce((function(t,n){var r=N(e,n);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}),N(e,c));return u.width=u.right-u.left,u.height=u.bottom-u.top,u.x=u.left,u.y=u.top,u}function _(e){return e.split("-")[1]}function F(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function U(e){var t,n=e.reference,r=e.element,o=e.placement,i=o?C(o):null,a=o?_(o):null,s=n.x+n.width/2-r.width/2,f=n.y+n.height/2-r.height/2;switch(i){case j:t={x:s,y:n.y-r.height};break;case E:t={x:s,y:n.y+n.height};break;case D:t={x:n.x+n.width,y:f};break;case A:t={x:n.x-r.width,y:f};break;default:t={x:n.x,y:n.y}}var c=i?F(i):null;if(null!=c){var p="y"===c?"height":"width";switch(a){case M:t[c]=t[c]-(n[p]/2-r[p]/2);break;case k:t[c]=t[c]+(n[p]/2-r[p]/2)}}return t}function z(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function X(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function Y(e,t){void 0===t&&(t={});var r=t,o=r.placement,i=void 0===o?e.placement:o,a=r.boundary,s=void 0===a?"clippingParents":a,c=r.rootBoundary,p=void 0===c?W:c,l=r.elementContext,d=void 0===l?B:l,h=r.altBoundary,m=void 0!==h&&h,v=r.padding,g=void 0===v?0:v,y=z("number"!=typeof g?g:X(g,P)),b=d===B?"reference":B,x=e.rects.popper,w=e.elements[m?b:d],O=I(n(w)?w:w.contextElement||u(e.elements.popper),s,p),A=f(e.elements.reference),L=U({reference:A,element:x,strategy:"absolute",placement:i}),M=V(Object.assign({},x,L)),k=d===B?M:A,H={top:O.top-k.top+y.top,bottom:k.bottom-O.bottom+y.bottom,left:O.left-k.left+y.left,right:k.right-O.right+y.right},T=e.modifiersData.offset;if(d===B&&T){var R=T[i];Object.keys(H).forEach((function(e){var t=[D,E].indexOf(e)>=0?1:-1,n=[j,E].indexOf(e)>=0?"y":"x";H[e]+=R[n]*t}))}return H}var G={placement:"bottom",modifiers:[],strategy:"absolute"};function J(){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,[A,D].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}},ie={left:"right",right:"left",bottom:"top",top:"bottom"};function ae(e){return e.replace(/left|right|bottom|top/g,(function(e){return ie[e]}))}var se={start:"end",end:"start"};function fe(e){return e.replace(/start|end/g,(function(e){return se[e]}))}function ce(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?T:f,p=_(r),u=p?s?H:H.filter((function(e){return _(e)===p})):P,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]=Y(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 pe={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,g=C(v),y=f||(g===v||!h?[ae(v)]:function(e){if(C(e)===L)return[];var t=ae(e);return[fe(e),t,fe(t)]}(v)),b=[v].concat(y).reduce((function(e,n){return e.concat(C(n)===L?ce(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,P=!0,k=b[0],W=0;W=0,S=R?"width":"height",q=Y(t,{placement:B,boundary:p,rootBoundary:u,altBoundary:l,padding:c}),V=R?T?D:A:T?E:j;x[S]>w[S]&&(V=ae(V));var N=ae(V),I=[];if(i&&I.push(q[H]<=0),s&&I.push(q[V]<=0,q[N]<=0),I.every((function(e){return e}))){k=B,P=!1;break}O.set(B,I)}if(P)for(var F=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 k=t,"break"},U=h?3:1;U>0;U--){if("break"===F(U))break}t.placement!==k&&(t.modifiersData[r]._skip=!0,t.placement=k,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function ue(e,t,n){return i(e,a(t,n))}var le={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,g=n.tetherOffset,y=void 0===g?0:g,b=Y(t,{boundary:p,rootBoundary:u,padding:d,altBoundary:l}),x=C(t.placement),w=_(t.placement),L=!w,P=F(x),k="x"===P?"y":"x",W=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,q={x:0,y:0};if(W){if(s){var V,N="y"===P?j:A,I="y"===P?E:D,U="y"===P?"height":"width",z=W[P],X=z+b[N],G=z-b[I],J=m?-H[U]/2:0,K=w===M?B[U]:H[U],Q=w===M?-H[U]:-B[U],Z=t.elements.arrow,$=m&&Z?v(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=ue(0,B[U],$[U]),oe=L?B[U]/2-J-re-te-R.mainAxis:K-re-te-R.mainAxis,ie=L?-B[U]/2+J+re+ne+R.mainAxis:Q+re+ne+R.mainAxis,ae=t.elements.arrow&&O(t.elements.arrow),se=ae?"y"===P?ae.clientTop||0:ae.clientLeft||0:0,fe=null!=(V=null==S?void 0:S[P])?V:0,ce=z+ie-fe,pe=ue(m?a(X,z+oe-fe-se):X,z,m?i(G,ce):G);W[P]=pe,q[P]=pe-z}if(c){var le,de="x"===P?j:A,he="x"===P?E:D,me=W[k],ve="y"===k?"height":"width",ge=me+b[de],ye=me-b[he],be=-1!==[j,A].indexOf(x),xe=null!=(le=null==S?void 0:S[k])?le:0,we=be?ge:me-B[ve]-H[ve]-xe+R.altAxis,Oe=be?me+B[ve]+H[ve]-xe-R.altAxis:ye,je=m&&be?function(e,t,n){var r=ue(e,t,n);return r>n?n:r}(we,me,Oe):ue(m?we:ge,me,m?Oe:ye);W[k]=je,q[k]=je-me}t.modifiersData[r]=q}},requiresIfExists:["offset"]};var de={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=F(s),c=[A,D].indexOf(s)>=0?"height":"width";if(i&&a){var p=function(e,t){return z("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:X(e,P))}(o.padding,n),u=v(i),l="y"===f?j:A,d="y"===f?E:D,h=n.rects.reference[c]+n.rects.reference[f]-a[f]-n.rects.popper[c],m=a[f]-n.rects.reference[f],g=O(i),y=g?"y"===f?g.clientHeight||0:g.clientWidth||0:0,b=h/2-m/2,x=p[l],w=y-u[c]-p[d],L=y/2-u[c]/2+b,M=ue(x,L,w),k=f;n.modifiersData[r]=((t={})[k]=M,t.centerOffset=M-L,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)))&&q(t.elements.popper,r)&&(t.elements.arrow=r)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function he(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 me(e){return[j,D,E,A].some((function(t){return e[t]>=0}))}var ve={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=Y(t,{elementContext:"reference"}),s=Y(t,{altBoundary:!0}),f=he(a,r),c=he(s,o,i),p=me(f),u=me(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})}},ge=K({defaultModifiers:[Z,$,ne,re]}),ye=[Z,$,ne,re,oe,pe,le,de,ve],be=K({defaultModifiers:ye});e.applyStyles=re,e.arrow=de,e.computeStyles=ne,e.createPopper=be,e.createPopperLite=ge,e.defaultModifiers=ye,e.detectOverflow=Y,e.eventListeners=Z,e.flip=pe,e.hide=ve,e.offset=oe,e.popperGenerator=K,e.popperOffsets=$,e.preventOverflow=le,Object.defineProperty(e,"__esModule",{value:!0})})); - diff --git a/docs/_site/site_libs/quarto-html/quarto-syntax-highlighting.css b/docs/_site/site_libs/quarto-html/quarto-syntax-highlighting.css deleted file mode 100644 index d9fd98f..0000000 --- a/docs/_site/site_libs/quarto-html/quarto-syntax-highlighting.css +++ /dev/null @@ -1,203 +0,0 @@ -/* 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; -} - -pre > code.sourceCode > span { - color: #003B4F; -} - -code span { - color: #003B4F; -} - -code.sourceCode > span { - color: #003B4F; -} - -div.sourceCode, -div.sourceCode pre.sourceCode { - color: #003B4F; -} - -code span.ot { - color: #003B4F; - font-style: inherit; -} - -code span.at { - color: #657422; - font-style: inherit; -} - -code span.ss { - color: #20794D; - font-style: inherit; -} - -code span.an { - color: #5E5E5E; - font-style: inherit; -} - -code span.fu { - color: #4758AB; - font-style: inherit; -} - -code span.st { - color: #20794D; - font-style: inherit; -} - -code span.cf { - color: #003B4F; - font-style: inherit; -} - -code span.op { - color: #5E5E5E; - font-style: inherit; -} - -code span.er { - color: #AD0000; - font-style: inherit; -} - -code span.bn { - color: #AD0000; - font-style: inherit; -} - -code span.al { - color: #AD0000; - font-style: inherit; -} - -code span.va { - color: #111111; - font-style: inherit; -} - -code span.bu { - font-style: inherit; -} - -code span.ex { - font-style: inherit; -} - -code span.pp { - color: #AD0000; - font-style: inherit; -} - -code span.in { - color: #5E5E5E; - font-style: inherit; -} - -code span.vs { - color: #20794D; - font-style: inherit; -} - -code span.wa { - color: #5E5E5E; - font-style: italic; -} - -code span.do { - color: #5E5E5E; - font-style: italic; -} - -code span.im { - color: #00769E; - font-style: inherit; -} - -code span.ch { - color: #20794D; - font-style: inherit; -} - -code span.dt { - color: #AD0000; - font-style: inherit; -} - -code span.fl { - color: #AD0000; - font-style: inherit; -} - -code span.co { - color: #5E5E5E; - font-style: inherit; -} - -code span.cv { - color: #5E5E5E; - font-style: italic; -} - -code span.cn { - color: #8f5902; - font-style: inherit; -} - -code span.sc { - color: #5E5E5E; - font-style: inherit; -} - -code span.dv { - color: #AD0000; - font-style: inherit; -} - -code span.kw { - color: #003B4F; - font-style: inherit; -} - -.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 > * " - ); - - 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; - console.log({ - childtop: marginChild.getBoundingClientRect().top, - scroll: window.scrollY, - top, - lastBottom, - }); - if (top < lastBottom) { - const margin = lastBottom - top; - marginChild.style.marginTop = `${margin}px`; - } - const styles = window.getComputedStyle(marginChild); - const marginTop = parseFloat(styles["marginTop"]); - - console.log({ - top, - height: marginChild.getBoundingClientRect().height, - marginTop, - total: top + marginChild.getBoundingClientRect().height + 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, 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; - } - }; - - // fire slideEnter for bootstrap tab activations (for htmlwidget resize behavior) - function fireSlideEnter(e) { - 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); - }); - - // fire slideEnter for tabby tab activations (for htmlwidget resize behavior) - document.addEventListener("tabby", fireSlideEnter, 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 - ) { - sectionIndex = 0; - } else { - 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() { - const currentPagePath = offsetAbsoluteUrl(window.location.href); - 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) { - if ( - item === currentPagePath || - item === 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"; - } - - 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.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; - } - - 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 (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) { - 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) { - walk(tocEl, 0); - updateActiveLink(); - } - - // 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 (!isReaderMode()) { - hideOverlappedSidebars(); - } - }, 10) - ); - hideOverlappedSidebars(); - highlightReaderToggle(isReaderMode()); -}); - -// grouped tabsets -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); - } - } -}); - -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/site_libs/quarto-html/tippy.css b/docs/_site/site_libs/quarto-html/tippy.css deleted file mode 100644 index e6ae635..0000000 --- a/docs/_site/site_libs/quarto-html/tippy.css +++ /dev/null @@ -1 +0,0 @@ -.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/site_libs/quarto-html/tippy.umd.min.js b/docs/_site/site_libs/quarto-html/tippy.umd.min.js deleted file mode 100644 index ca292be..0000000 --- a/docs/_site/site_libs/quarto-html/tippy.umd.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!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/site_libs/quarto-nav/headroom.min.js b/docs/_site/site_libs/quarto-nav/headroom.min.js deleted file mode 100644 index b08f1df..0000000 --- a/docs/_site/site_libs/quarto-nav/headroom.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * 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/site_libs/quarto-nav/quarto-nav.js b/docs/_site/site_libs/quarto-nav/quarto-nav.js deleted file mode 100644 index 3b21201..0000000 --- a/docs/_site/site_libs/quarto-nav/quarto-nav.js +++ /dev/null @@ -1,277 +0,0 @@ -const headroomChanged = new CustomEvent("quarto-hrChanged", { - detail: {}, - bubbles: true, - cancelable: false, - composed: false, -}); - -window.document.addEventListener("DOMContentLoaded", function () { - let init = false; - - // 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 updateDocumentOffsetWithoutAnimation() { - updateDocumentOffset(false); - } - - function updateDocumentOffset(animated) { - // set body offset - const topOffset = headerOffset(); - const bodyOffset = topOffset + footerOffset(); - 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( - updateDocumentOffsetWithoutAnimation - ); - 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].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" - ); - 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/site_libs/quarto-search/autocomplete.umd.js b/docs/_site/site_libs/quarto-search/autocomplete.umd.js deleted file mode 100644 index 619c57c..0000000 --- a/docs/_site/site_libs/quarto-search/autocomplete.umd.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! @algolia/autocomplete-js 1.7.3 | 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)return;var r,o,i=[],u=!0,a=!1;try{for(n=n.call(e);!(u=(r=n.next()).done)&&(i.push(r.value),!t||i.length!==t);u=!0);}catch(e){a=!0,o=e}finally{try{u||null==n.return||n.return()}finally{if(a)throw o}}return i}(e,t)||l(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 c(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)||l(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 l(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);n=n?null===r?null:0:o}function S(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 I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function E(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=function(e){for(var t=1;te.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}var ae,ce,le,se=null,pe=(ae=-1,ce=-1,le=void 0,function(e){var t=++ae;return Promise.resolve(e).then((function(e){return le&&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}var ye=["props","refresh","store"],be=["inputElement","formElement","panelElement"],Oe=["inputElement"],_e=["inputElement","maxLength"],Pe=["item","source"];function je(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 we(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 Ee(e){var t=e.props,n=e.refresh,r=e.store,o=Ie(e,ye);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 we({onTouchStart:u,onMouseDown:u,onTouchMove:function(e){!1!==r.getState().isOpen&&n===t.environment.document.activeElement&&e.target!==n&&n.blur()}},Ie(e,be))},getRootProps:function(e){return we({role:"combobox","aria-expanded":r.getState().isOpen,"aria-haspopup":"listbox","aria-owns":r.getState().isOpen?"".concat(t.id,"-list"):void 0,"aria-labelledby":"".concat(t.id,"-label")},e)},getFormProps:function(e){return e.inputElement,we({action:"",noValidate:!0,role:"search",onSubmit:function(i){var u;i.preventDefault(),t.onSubmit(we({event:i,refresh:n,state:r.getState()},o)),r.dispatch("submit",null),null===(u=e.inputElement)||void 0===u||u.blur()},onReset:function(i){var u;i.preventDefault(),t.onReset(we({event:i,refresh:n,state:r.getState()},o)),r.dispatch("reset",null),null===(u=e.inputElement)||void 0===u||u.focus()}},Ie(e,Oe))},getLabelProps:function(e){return we({htmlFor:"".concat(t.id,"-input"),id:"".concat(t.id,"-label")},e)},getInputProps:function(e){var i;function u(e){(t.openOnFocus||Boolean(r.getState().query))&&fe(we({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 c=a.maxLength,l=void 0===c?512:c,s=Ie(a,_e),p=A(r.getState()),f=function(e){return Boolean(e&&e.match(C))}((null===(i=t.environment.navigator)||void 0===i?void 0:i.userAgent)||""),d=null!=p&&p.itemUrl&&!f?"go":"search";return we({"aria-autocomplete":"both","aria-activedescendant":r.getState().isOpen&&null!==r.getState().activeItemId?"".concat(t.id,"-item-").concat(r.getState().activeItemId):void 0,"aria-controls":r.getState().isOpen?"".concat(t.id,"-list"):void 0,"aria-labelledby":"".concat(t.id,"-label"),value:r.getState().completion||r.getState().query,id:"".concat(t.id,"-input"),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",enterKeyHint:d,spellCheck:"false",autoFocus:t.autoFocus,placeholder:t.placeholder,maxLength:l,type:"search",onChange:function(e){fe(we({event:e,props:t,query:e.currentTarget.value.slice(0,l),refresh:n,store:r},o))},onKeyDown:function(e){!function(e){var t=e.event,n=e.props,r=e.refresh,o=e.store,i=ge(e,de);if("ArrowUp"===t.key||"ArrowDown"===t.key){var u=function(){var e=n.environment.document.getElementById("".concat(n.id,"-item-").concat(o.getState().activeItemId));e&&(e.scrollIntoViewIfNeeded?e.scrollIntoViewIfNeeded(!1):e.scrollIntoView(!1))},a=function(){var e=A(o.getState());if(null!==o.getState().activeItemId&&e){var n=e.item,u=e.itemInputValue,a=e.itemUrl,c=e.source;c.onActive(ve({event:t,item:n,itemInputValue:u,itemUrl:a,refresh:r,source:c,state:o.getState()},i))}};t.preventDefault(),!1===o.getState().isOpen&&(n.openOnFocus||Boolean(o.getState().query))?fe(ve({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})))return void(n.debug||o.pendingRequests.cancelAll());t.preventDefault();var c=A(o.getState()),l=c.item,s=c.itemInputValue,p=c.itemUrl,f=c.source;if(t.metaKey||t.ctrlKey)void 0!==p&&(f.onSelect(ve({event:t,item:l,itemInputValue:s,itemUrl:p,refresh:r,source:f,state:o.getState()},i)),n.navigator.navigateNewTab({itemUrl:p,item:l,state:o.getState()}));else if(t.shiftKey)void 0!==p&&(f.onSelect(ve({event:t,item:l,itemInputValue:s,itemUrl:p,refresh:r,source:f,state:o.getState()},i)),n.navigator.navigateNewWindow({itemUrl:p,item:l,state:o.getState()}));else if(t.altKey);else{if(void 0!==p)return f.onSelect(ve({event:t,item:l,itemInputValue:s,itemUrl:p,refresh:r,source:f,state:o.getState()},i)),void n.navigator.navigate({itemUrl:p,item:l,state:o.getState()});fe(ve({event:t,nextState:{isOpen:!1},props:n,query:s,refresh:r,store:o},i)).then((function(){f.onSelect(ve({event:t,item:l,itemInputValue:s,itemUrl:p,refresh:r,source:f,state:o.getState()},i))}))}}}(we({event:e,props:t,refresh:n,store:r},o))},onFocus:u,onBlur:y,onClick:function(n){e.inputElement!==t.environment.document.activeElement||r.getState().isOpen||u(n)}},s)},getPanelProps:function(e){return we({onMouseDown:function(e){e.preventDefault()},onMouseLeave:function(){r.dispatch("mouseleave",null)}},e)},getListProps:function(e){return we({role:"listbox","aria-labelledby":"".concat(t.id,"-label"),id:"".concat(t.id,"-list")},e)},getItemProps:function(e){var i=e.item,u=e.source,a=Ie(e,Pe);return we({id:"".concat(t.id,"-item-").concat(i.__autocomplete_id),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=A(r.getState());if(null!==r.getState().activeItemId&&t){var u=t.item,a=t.itemInputValue,c=t.itemUrl,l=t.source;l.onActive(we({event:e,item:u,itemInputValue:a,itemUrl:c,refresh:n,source:l,state:r.getState()},o))}}},onMouseDown:function(e){e.preventDefault()},onClick:function(e){var a=u.getItemInputValue({item:i,state:r.getState()}),c=u.getItemUrl({item:i,state:r.getState()});(c?Promise.resolve():fe(we({event:e,nextState:{isOpen:!1},props:t,query:a,refresh:n,store:r},o))).then((function(){u.onSelect(we({event:e,item:i,itemInputValue:a,itemUrl:c,refresh:n,source:u,state:r.getState()},o))}))}},a)}}}function Ae(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 Ce(e){for(var t=1;t0},reshape:function(e){return e.sources}},e),{},{id:null!==(n=e.id)&&void 0!==n?n:v(),plugins:o,initialState:H({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(F(o.map((function(e){return e.getSources}))),[e.getSources]).filter(Boolean).map((function(e){return E(e,n)}))).then((function(e){return d(e)})).then((function(e){return e.map((function(e){return H(H({},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)}))}})}))}))},navigator:H({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)})}(e,t),r=R(Te,n,(function(e){var t=e.prevState,r=e.state;n.onStateChange(Be({prevState:t,state:r,refresh:u},o))})),o=function(e){var t=e.store;return{setActiveItemId:function(e){t.dispatch("setActiveItemId",e)},setQuery:function(e){t.dispatch("setQuery",e)},setCollections:function(e){var n=0,r=e.map((function(e){return L(L({},e),{},{items:d(e.items).map((function(e){return L(L({},e),{},{__autocomplete_id:n++})}))})}));t.dispatch("setCollections",r)},setIsOpen:function(e){t.dispatch("setIsOpen",e)},setStatus:function(e){t.dispatch("setStatus",e)},setContext:function(e){t.dispatch("setContext",e)}}}({store:r}),i=Ee(Be({props:n,refresh:u,store:r},o));function u(){return fe(Be({event:new Event("input"),nextState:{isOpen:r.getState().isOpen},props:n,query:r.getState().query,refresh:u,store:r},o))}return n.plugins.forEach((function(e){var n;return null===(n=e.subscribe)||void 0===n?void 0:n.call(e,Be(Be({},o),{},{refresh:u,onSelect:function(e){t.push({onSelect:e})},onActive:function(e){t.push({onActive:e})}}))})),function(e){var t,n,r=e.metadata,o=e.environment;if(null===(t=o.navigator)||void 0===t||null===(n=t.userAgent)||void 0===n?void 0:n.includes("Algolia Crawler")){var i=o.document.createElement("meta"),u=o.document.querySelector("head");i.name="algolia:metadata",setTimeout((function(){i.content=JSON.stringify(r),u.appendChild(i)}),0)}}({metadata:ke({plugins:n.plugins,options:e}),environment:n.environment}),Be(Be({refresh:u},i),o)}var Ue=function(e,t,n,r){var o;t[0]=0;for(var i=1;i=5&&((o||!e&&5===r)&&(u.push(r,0,o,n),r=6),e&&(u.push(r,e,0,n),r=6)),o=""},c=0;c"===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[c][l+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 We=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 Qe(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 $e(){for(var e=arguments.length,t=new Array(e),n=0;n2&&(u.children=arguments.length>3?lt.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 _t(e,u,r,o,null)}function _t(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?++pt:o};return null==o&&null!=st.vnode&&st.vnode(i),i}function Pt(e){return e.children}function jt(e,t){this.props=e,this.context=t}function wt(e,t){if(null==t)return e.__?wt(e.__,e.__.__k.indexOf(e)+1):null;for(var n;t0?_t(d.type,d.props,d.key,null,d.__v):d)){if(d.__=n,d.__b=n.__b+1,null===(f=g[s])||f&&d.key==f.key&&d.type===f.type)g[s]=void 0;else for(p=0;p0&&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(Ht);r.add({value:t[0],isHighlighted:!0}),""!==t[1]&&r.add({value:t[1],isHighlighted:!1})})),r.get()}function Wt(e){return function(e){if(Array.isArray(e))return Qt(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 Qt(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 Qt(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 Qt(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n",""":'"',"'":"'"},Gt=new RegExp(/\w/i),Kt=/&(amp|quot|lt|gt|#39);/g,Jt=RegExp(Kt.source);function Yt(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 Gt.test((o=i.value)&&Jt.test(o)?o.replace(Kt,(function(e){return zt[e]})):o)||a!==u?i.isHighlighted:a}function Xt(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 Zt(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 mn(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);n0;if(!O.value.core.openOnFocus&&!t.query)return n;var r=Boolean(h.current||O.value.renderer.renderNoResults);return!n&&r||n},__autocomplete_metadata:{userAgents:Sn,options:e}}))})),j=p(n({collections:[],completion:null,context:{},isOpen:!1,query:"",activeItemId:null,status:"idle"},O.value.core.initialState)),w={getEnvironmentProps:O.value.renderer.getEnvironmentProps,getFormProps:O.value.renderer.getFormProps,getInputProps:O.value.renderer.getInputProps,getItemProps:O.value.renderer.getItemProps,getLabelProps:O.value.renderer.getLabelProps,getListProps:O.value.renderer.getListProps,getPanelProps:O.value.renderer.getPanelProps,getRootProps:O.value.renderer.getRootProps},S={setActiveItemId:P.value.setActiveItemId,setQuery:P.value.setQuery,setCollections:P.value.setCollections,setIsOpen:P.value.setIsOpen,setStatus:P.value.setStatus,setContext:P.value.setContext,refresh:P.value.refresh},I=d((function(){return Ve.bind(O.value.renderer.renderer.createElement)})),E=d((function(){return ct({autocomplete:P.value,autocompleteScopeApi:S,classNames:O.value.renderer.classNames,environment:O.value.core.environment,isDetached:_.value,placeholder:O.value.core.placeholder,propGetters:w,setIsModalOpen:k,state:j.current,translations:O.value.renderer.translations})}));function A(){tt(E.value.panel,{style:_.value?{}:wn({panelPlacement:O.value.renderer.panelPlacement,container:E.value.root,form:E.value.form,environment:O.value.core.environment})})}function C(e){j.current=e;var t={autocomplete:P.value,autocompleteScopeApi:S,classNames:O.value.renderer.classNames,components:O.value.renderer.components,container:O.value.renderer.container,html:I.value,dom:E.value,panelContainer:_.value?E.value.detachedContainer:O.value.renderer.panelContainer,propGetters:w,state:j.current,renderer:O.value.renderer.renderer},r=!g(e)&&!h.current&&O.value.renderer.renderNoResults||O.value.renderer.render;!function(e){var t=e.autocomplete,r=e.autocompleteScopeApi,o=e.dom,i=e.propGetters,u=e.state;nt(o.root,i.getRootProps(n({state:u,props:t.getRootProps({})},r))),nt(o.input,i.getInputProps(n({state:u,props:t.getInputProps({inputElement:o.input}),inputElement:o.input},r))),tt(o.label,{hidden:"stalled"===u.status}),tt(o.loadingIndicator,{hidden:"stalled"!==u.status}),tt(o.clearButton,{hidden:!u.query})}(t),function(e,t){var r=t.autocomplete,o=t.autocompleteScopeApi,u=t.classNames,a=t.html,c=t.dom,l=t.panelContainer,s=t.propGetters,p=t.state,f=t.components,d=t.renderer;if(p.isOpen){l.contains(c.panel)||"loading"===p.status||l.appendChild(c.panel),c.panel.classList.toggle("aa-Panel--stalled","stalled"===p.status);var m=p.collections.filter((function(e){var t=e.source,n=e.items;return t.templates.noResults||n.length>0})).map((function(e,t){var c=e.source,l=e.items;return d.createElement("section",{key:t,className:u.source,"data-autocomplete-source-id":c.sourceId},c.templates.header&&d.createElement("div",{className:u.sourceHeader},c.templates.header({components:f,createElement:d.createElement,Fragment:d.Fragment,items:l,source:c,state:p,html:a})),c.templates.noResults&&0===l.length?d.createElement("div",{className:u.sourceNoResults},c.templates.noResults({components:f,createElement:d.createElement,Fragment:d.Fragment,source:c,state:p,html:a})):d.createElement("ul",i({className:u.list},s.getListProps(n({state:p,props:r.getListProps({})},o))),l.map((function(e){var t=r.getItemProps({item:e,source:c});return d.createElement("li",i({key:t.id,className:u.item},s.getItemProps(n({state:p,props:t},o))),c.templates.item({components:f,createElement:d.createElement,Fragment:d.Fragment,item:e,state:p,html:a}))}))),c.templates.footer&&d.createElement("div",{className:u.sourceFooter},c.templates.footer({components:f,createElement:d.createElement,Fragment:d.Fragment,items:l,source:c,state:p,html:a})))})),v=d.createElement(d.Fragment,null,d.createElement("div",{className:u.panelLayout},m),d.createElement("div",{className:"aa-GradientBottom"})),h=m.reduce((function(e,t){return e[t.props["data-autocomplete-source-id"]]=t,e}),{});e(n(n({children:v,state:p,sections:m,elements:h},d),{},{components:f,html:a},o),c.panel)}else l.contains(c.panel)&&l.removeChild(c.panel)}(r,t)}function D(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};c();var t=O.value.renderer,n=t.components,r=u(t,In);y.current=Ge(r,O.value.core,{components:Ke(n,(function(e){return!e.value.hasOwnProperty("__autocomplete_componentName")})),initialState:j.current},e),m(),l(),P.value.refresh().then((function(){C(j.current)}))}function k(e){requestAnimationFrame((function(){var t=O.value.core.environment.document.body.contains(E.value.detachedOverlay);e!==t&&(e?(O.value.core.environment.document.body.appendChild(E.value.detachedOverlay),O.value.core.environment.document.body.classList.add("aa-Detached"),E.value.input.focus()):(O.value.core.environment.document.body.removeChild(E.value.detachedOverlay),O.value.core.environment.document.body.classList.remove("aa-Detached"),P.value.setQuery(""),P.value.refresh()))}))}return a((function(){var e=P.value.getEnvironmentProps({formElement:E.value.form,panelElement:E.value.panel,inputElement:E.value.input});return tt(O.value.core.environment,e),function(){tt(O.value.core.environment,Object.keys(e).reduce((function(e,t){return n(n({},e),{},o({},t,void 0))}),{}))}})),a((function(){var e=_.value?O.value.core.environment.document.body:O.value.renderer.panelContainer,t=_.value?E.value.detachedOverlay:E.value.panel;return _.value&&j.current.isOpen&&k(!0),C(j.current),function(){e.contains(t)&&e.removeChild(t)}})),a((function(){var e=O.value.renderer.container;return e.appendChild(E.value.root),function(){e.removeChild(E.value.root)}})),a((function(){var e=f((function(e){C(e.state)}),0);return b.current=function(t){var n=t.state,r=t.prevState;(_.value&&r.isOpen!==n.isOpen&&k(n.isOpen),_.value||!n.isOpen||r.isOpen||A(),n.query!==r.query)&&O.value.core.environment.document.querySelectorAll(".aa-Panel--scrollable").forEach((function(e){0!==e.scrollTop&&(e.scrollTop=0)}));e({state:n})},function(){b.current=void 0}})),a((function(){var e=f((function(){var e=_.value;_.value=O.value.core.environment.matchMedia(O.value.renderer.detachedMediaQuery).matches,e!==_.value?D({}):requestAnimationFrame(A)}),20);return O.value.core.environment.addEventListener("resize",e),function(){O.value.core.environment.removeEventListener("resize",e)}})),a((function(){if(!_.value)return function(){};function e(e){E.value.detachedContainer.classList.toggle("aa-DetachedContainer--modal",e)}function t(t){e(t.matches)}var n=O.value.core.environment.matchMedia(getComputedStyle(O.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(A),function(){}})),n(n({},S),{},{update:D,destroy:function(){c()}})},e.getAlgoliaFacets=function(e){var t=En({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=An,Object.defineProperty(e,"__esModule",{value:!0})})); - diff --git a/docs/_site/site_libs/quarto-search/fuse.min.js b/docs/_site/site_libs/quarto-search/fuse.min.js deleted file mode 100644 index adc2835..0000000 --- a/docs/_site/site_libs/quarto-search/fuse.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * 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/site_libs/quarto-search/quarto-search.js b/docs/_site/site_libs/quarto-search/quarto-search.js deleted file mode 100644 index f5d852d..0000000 --- a/docs/_site/site_libs/quarto-search/quarto-search.js +++ /dev/null @@ -1,1140 +0,0 @@ -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"; - -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 currentUrl = new URL(window.location); - const query = currentUrl.searchParams.get(kQueryArg); - const showSearchResults = currentUrl.searchParams.get(kResultsArg); - const mainEl = window.document.querySelector("main"); - - // highlight matches on the page - if (query !== null && mainEl) { - // perform any highlighting - highlight(escapeRegExp(query), mainEl); - - // fix up the URL to remove the q query param - const replacementUrl = new URL(window.location); - replacementUrl.searchParams.delete(kQueryArg); - window.history.replaceState({}, "", replacementUrl); - } - - // 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 !== null && searchTerm !== query) { - clearHighlight(query, mainEl); - highlighting = false; - } - }; - - // Clear search highlighting when the user scrolls sufficiently - const resetFn = () => { - resetHighlighting(""); - window.removeEventListener("quarto-hrChanged", resetFn); - window.removeEventListener("quarto-sectionChanged", resetFn); - }; - - // Register this event after the initial scrolling and settling of events - // on the page - window.addEventListener("quarto-hrChanged", resetFn); - window.addEventListener("quarto-sectionChanged", resetFn); - - // 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", - }, - 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 }) { - // 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 }) { - return renderItem( - item, - createElement, - state, - setActiveItemId, - setContext, - refresh - ); - }, - }, - }, - ]; - }, - }); - - window.quartoOpenSearch = () => { - setIsOpen(false); - setIsOpen(true); - focusSearchInput(); - }; - - // 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"); - } - } - - // 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 = () => { - setIsOpen(false); - }; - - 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"] - ) { - window.aa("init", { - appId, - apiKey, - useCookie: true, - }); - - const { createAlgoliaInsightsPlugin } = - window["@algolia/autocomplete-plugin-algolia-insights"]; - // Register the insights client - const algoliaInsightsPlugin = createAlgoliaInsightsPlugin({ - insightsClient: window.aa, - onItemsChange({ insights, insightsEvents }) { - const events = insightsEvents.map((event) => { - const maxEvents = event.objectIDs.slice(0, 20); - return { - ...event, - objectIDs: maxEvents, - }; - }); - - insights.viewedObjectIDs(...events); - }, - }); - 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; -async function readSearchData() { - // Initialize the search index on demand - if (fuseIndex === undefined) { - // create fuse index - const options = { - keys: [ - { name: "title", weight: 20 }, - { name: "section", weight: 20 }, - { name: "text", weight: 10 }, - ], - ignoreLocation: true, - threshold: 0.1, - }; - const fuse = new window.Fuse([], options); - - // 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 -) { - switch (item.type) { - case kItemTypeDoc: - return createDocumentCard( - createElement, - "file-richtext", - item.title, - item.section, - item.text, - item.href - ); - 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) { - const iconEl = createElement("i", { - class: `bi bi-${icon} search-result-icon`, - }); - const titleEl = createElement("p", { class: "search-result-title" }, title); - const titleContainerEl = createElement( - "div", - { class: "search-result-title-container" }, - [iconEl, titleEl] - ); - - 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); - } - } - } -} - -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string -} - -// highlight matches -function highlight(term, el) { - const termRegex = new RegExp(term, "ig"); - const childNodes = el.childNodes; - - // walk back to front avoid mutating elements in front of us - for (let i = childNodes.length - 1; i >= 0; i--) { - const node = childNodes[i]; - - if (node.nodeType === Node.TEXT_NODE) { - // Search text nodes for text to highlight - const text = node.nodeValue; - - let startIndex = 0; - let matchIndex = text.search(termRegex); - if (matchIndex > -1) { - const markFragment = document.createDocumentFragment(); - while (matchIndex > -1) { - const prefix = text.slice(startIndex, matchIndex); - markFragment.appendChild(document.createTextNode(prefix)); - - const mark = document.createElement("mark"); - mark.appendChild( - document.createTextNode( - text.slice(matchIndex, matchIndex + term.length) - ) - ); - markFragment.appendChild(mark); - - startIndex = matchIndex + term.length; - matchIndex = text.slice(startIndex).search(new RegExp(term, "ig")); - if (matchIndex > -1) { - matchIndex = startIndex + matchIndex; - } - } - if (startIndex < text.length) { - markFragment.appendChild( - document.createTextNode(text.slice(startIndex, text.length)) - ); - } - - el.replaceChild(markFragment, node); - } - } else if (node.nodeType === Node.ELEMENT_NODE) { - // recurse through elements - highlight(term, node); - } - } -} - -/* 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"].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; - } - }, - }); -} - -function fuseSearch(query, fuse, fuseOptions) { - return fuse.search(query, fuseOptions).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), - }; - }); -} diff --git a/docs/_site/tutorials/index.html b/docs/_site/tutorials/index.html deleted file mode 100644 index 22c0e5b..0000000 --- a/docs/_site/tutorials/index.html +++ /dev/null @@ -1,369 +0,0 @@ - - - - - - - - - -NGLui Documentation – index - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - -
    - - - - -
    - - - -
    -

    Tutorials

    -

    Do one thing, then another.

    - - -
    - -
    - -
    - - - - \ No newline at end of file diff --git a/docs/_site/tutorials/parser.html b/docs/_site/tutorials/parser.html deleted file mode 100644 index 3929d6e..0000000 --- a/docs/_site/tutorials/parser.html +++ /dev/null @@ -1,369 +0,0 @@ - - - - - - - - - -NGLui Documentation – parser - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - -
    - -
    - - - - -
    - - - -
    -

    Parser Tutorial

    -

    Basics of how to use nglui parser.

    - - -
    - -
    - -
    - - - - \ No newline at end of file diff --git a/docs/_site/tutorials/statebuilder.html b/docs/_site/tutorials/statebuilder.html deleted file mode 100644 index 74451a9..0000000 --- a/docs/_site/tutorials/statebuilder.html +++ /dev/null @@ -1,449 +0,0 @@ - - - - - - - - - -NGLui Documentation - StateBuilder Tutorial - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - -
    - -
    - - -
    - - - -
    - -
    -
    -

    StateBuilder Tutorial

    -
    - - - -
    - - - - -
    - - -
    - -

    The StateBuilder module is designed to allow rules-based generation of Neuroglancer states based on DataFrames or numpy arrays.

    -
    -

    Background

    -

    Neuroglancer is a web application for viewing large volumetric imagery and segmentation data, as well as meshes and annotations like points or lines. Data in Neuroglancer is organized into layers, where each layer is configured to show information like images, segmentation, or annotations. Each layer can show one type of data and has different properties associated with it. In addition, Neuroglancer also stores the exact view that the user sees — what location in the data is centered, the orientation and zoom level of the camera, and more. Collectively, the information underlying both layers and the user view is refered to as the “state,” which is stored as a collection of key/value pairs.

    -

    StateBuilder follows this model by defining a set of rules for initializing layers. For layers that contain properties like selected segment ids or annotations, this configuration involves specifying how to map DataFrame columns to selected segmentations or annotations such as synapses. The general pattern is that you build up a collection of configurations for individual layers, assemble them into a StateBuilder object, and then pass a dataframe through this object to render out a state.

    -
    -
    -

    Simple Layers and StateBuilder

    -
    from nglui import statebuilder
    -
    -img = statebuilder.ImageLayerConfig(
    -    source=client.info.image_source(),
    -    contrast_controls=True, # this just puts in the code needed to manually adjust contrast
    -)
    -
    -seg = statebuilder.SegmentationLayerConfig(
    -    source=client.info.segmentation_source(),
    -)
    -
    -
    -

    Data-driven States

    - - -
    - -
    - -
    - - - - \ No newline at end of file diff --git a/docs/about.qmd b/docs/about.qmd deleted file mode 100644 index 07c5e7f..0000000 --- a/docs/about.qmd +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: "About" ---- - -About this site diff --git a/CHANGELOG.md b/docs/changelog.md similarity index 91% rename from CHANGELOG.md rename to docs/changelog.md index f0d899d..c794bd8 100644 --- a/CHANGELOG.md +++ b/docs/changelog.md @@ -2,6 +2,23 @@ This project attempts to follow [Semantic Versioning](https://semver.org) and uses [Keep-a-Changelog formatting](https://keepachangelog.com/en/1.0.0/). But I make mistakes sometimes. +## [3.2.0] - 2024-07-10 + +### Added + +- **SegmentProperties** : A new module has been created to build Segment Properties, which are a method of organizing information about segment IDs in a Neuroglancer segmentation layer. +Segment Properties only work with the newer Google/Spelunker branches, and offer a way to add browsable and searchable metadata to segments that can be viewed in the viewer. +- **StateBuilder** : Various changes were made to support segment properties from both explicit URLs and from data-driven mapping. See documentation for details. + +## Changed + +- **StateBuilder** : Image layers for spelunker now use native contrast controls. + +### Fixed + +- **StateBuilder** : Improvements to the use of `target_site` and `url_prefix` in general when both creating statebuilder and rendering states. In particular, the values in `render_state` should now correctly take precendence over the values in `StateBuilder` when both are set. + + ## [3.1.0] - 2024-05-29 ### Added diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..9ebf076 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,46 @@ +# NGLui + +NGLui is a library for programmatically generating shareable Neuroglancer states in order to explore and visualize large, 3d image datasets. +It is designed to be used in conjunction with the [Neuroglancer](https://github.com/google/neuroglancer) web viewer and the [CAVE analysis ecosystem](https://caveconnectome.github.io/CAVEclient/). +It aims to separate the *rules* you want to use to generate states from the *data* you want to visualize, allowing you make reusable code to generate states from different datasets and analyses. + +## Installation + +NGLui is available on PyPI and can be installed with pip: + +```bash +pip install nglui +``` + +If you want to clone the repository and develop on NGLui, note that it uses [Hatch](https://hatch.pypa.io/latest/) for development and packaging. + +## Quick Usage + +!!! note + + Using the CAVEclient with the MICrons dataset is required for the following examples. + +Here's a quick example of how to use NGLui to generate a Neuroglancer state from the [Microns cortical dataset](https://www.microns-explorer.org). + +```python +import caveclient +from nglui import statebuilder + +client = caveclient.CAVEclient('minnie65_public') + +# Get a root id of a specific neuron +root_id = client.materialize.query_table( + 'nucleus_detection_v0', + filter_equal_dict={'id': 255258} +)['pt_root_id'] + +statebuilder.helpers.make_neuron_neuroglancer_link( + client, + root_id, + show_inputs=True, + show_outputs=True, + ngl_url='https://spelunker.cave-explorer.org', +) +``` + +This code will generate a link to produce a Neuroglancer state showing a neuron and its synapses. \ No newline at end of file diff --git a/docs/index.qmd b/docs/index.qmd deleted file mode 100644 index b5e21cc..0000000 --- a/docs/index.qmd +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: "Docs" ---- - -This is a Quarto website. - -To learn more about Quarto websites visit . diff --git a/docs/objects.json b/docs/objects.json deleted file mode 100644 index 5d7b948..0000000 --- a/docs/objects.json +++ /dev/null @@ -1 +0,0 @@ -{"project": "nglui", "version": "0.0.9999", "count": 44, "items": [{"name": "nglui.statebuilder.ImageLayerConfig", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.ImageLayerConfig.html#nglui.statebuilder.ImageLayerConfig", "dispname": "-"}, {"name": "nglui.statebuilder.layers.ImageLayerConfig", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.ImageLayerConfig.html#nglui.statebuilder.ImageLayerConfig", "dispname": "nglui.statebuilder.ImageLayerConfig"}, {"name": "nglui.statebuilder.SegmentationLayerConfig", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.SegmentationLayerConfig.html#nglui.statebuilder.SegmentationLayerConfig", "dispname": "-"}, {"name": "nglui.statebuilder.layers.SegmentationLayerConfig", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.SegmentationLayerConfig.html#nglui.statebuilder.SegmentationLayerConfig", "dispname": "nglui.statebuilder.SegmentationLayerConfig"}, {"name": "nglui.statebuilder.AnnotationLayerConfig", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.AnnotationLayerConfig.html#nglui.statebuilder.AnnotationLayerConfig", "dispname": "-"}, {"name": "nglui.statebuilder.layers.AnnotationLayerConfig", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.AnnotationLayerConfig.html#nglui.statebuilder.AnnotationLayerConfig", "dispname": "nglui.statebuilder.AnnotationLayerConfig"}, {"name": "nglui.statebuilder.PointMapper", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.PointMapper.html#nglui.statebuilder.PointMapper", "dispname": "-"}, {"name": "nglui.statebuilder.mappers.PointMapper", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.PointMapper.html#nglui.statebuilder.PointMapper", "dispname": "nglui.statebuilder.PointMapper"}, {"name": "nglui.statebuilder.LineMapper", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.LineMapper.html#nglui.statebuilder.LineMapper", "dispname": "-"}, {"name": "nglui.statebuilder.mappers.LineMapper", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.LineMapper.html#nglui.statebuilder.LineMapper", "dispname": "nglui.statebuilder.LineMapper"}, {"name": "nglui.statebuilder.SphereMapper", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.SphereMapper.html#nglui.statebuilder.SphereMapper", "dispname": "-"}, {"name": "nglui.statebuilder.mappers.SphereMapper", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.SphereMapper.html#nglui.statebuilder.SphereMapper", "dispname": "nglui.statebuilder.SphereMapper"}, {"name": "nglui.statebuilder.BoundingBoxMapper", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.BoundingBoxMapper.html#nglui.statebuilder.BoundingBoxMapper", "dispname": "-"}, {"name": "nglui.statebuilder.mappers.BoundingBoxMapper", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.BoundingBoxMapper.html#nglui.statebuilder.BoundingBoxMapper", "dispname": "nglui.statebuilder.BoundingBoxMapper"}, {"name": "nglui.statebuilder.SplitPointMapper", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.SplitPointMapper.html#nglui.statebuilder.SplitPointMapper", "dispname": "-"}, {"name": "nglui.statebuilder.mappers.SplitPointMapper", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.SplitPointMapper.html#nglui.statebuilder.SplitPointMapper", "dispname": "nglui.statebuilder.SplitPointMapper"}, {"name": "nglui.statebuilder.StateBuilder", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.StateBuilder.html#nglui.statebuilder.StateBuilder", "dispname": "-"}, {"name": "nglui.statebuilder.statebuilder.StateBuilder", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.StateBuilder.html#nglui.statebuilder.StateBuilder", "dispname": "nglui.statebuilder.StateBuilder"}, {"name": "nglui.statebuilder.ChainedStateBuilder", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.ChainedStateBuilder.html#nglui.statebuilder.ChainedStateBuilder", "dispname": "-"}, {"name": "nglui.statebuilder.statebuilder.ChainedStateBuilder", "domain": "py", "role": "class", "priority": "1", "uri": "reference/statebuilder.ChainedStateBuilder.html#nglui.statebuilder.ChainedStateBuilder", "dispname": "nglui.statebuilder.ChainedStateBuilder"}, {"name": "nglui.statebuilder.helpers.from_client", "domain": "py", "role": "function", "priority": "1", "uri": "reference/statebuilder.helpers.from_client.html#nglui.statebuilder.helpers.from_client", "dispname": "-"}, {"name": "nglui.statebuilder.helpers.sort_dataframe_by_root_id", "domain": "py", "role": "function", "priority": "1", "uri": "reference/statebuilder.helpers.sort_dataframe_by_root_id.html#nglui.statebuilder.helpers.sort_dataframe_by_root_id", "dispname": "-"}, {"name": "nglui.statebuilder.helpers.make_line_statebuilder", "domain": "py", "role": "function", "priority": "1", "uri": "reference/statebuilder.helpers.make_line_statebuilder.html#nglui.statebuilder.helpers.make_line_statebuilder", "dispname": "-"}, {"name": "nglui.statebuilder.helpers.make_point_statebuilder", "domain": "py", "role": "function", "priority": "1", "uri": "reference/statebuilder.helpers.make_point_statebuilder.html#nglui.statebuilder.helpers.make_point_statebuilder", "dispname": "-"}, {"name": "nglui.statebuilder.helpers.make_pre_post_statebuilder", "domain": "py", "role": "function", "priority": "1", "uri": "reference/statebuilder.helpers.make_pre_post_statebuilder.html#nglui.statebuilder.helpers.make_pre_post_statebuilder", "dispname": "-"}, {"name": "nglui.statebuilder.helpers.make_state_url", "domain": "py", "role": "function", "priority": "1", "uri": "reference/statebuilder.helpers.make_state_url.html#nglui.statebuilder.helpers.make_state_url", "dispname": "-"}, {"name": "nglui.statebuilder.helpers.make_url_robust", "domain": "py", "role": "function", "priority": "1", "uri": "reference/statebuilder.helpers.make_url_robust.html#nglui.statebuilder.helpers.make_url_robust", "dispname": "-"}, {"name": "nglui.statebuilder.helpers.package_state", "domain": "py", "role": "function", "priority": "1", "uri": "reference/statebuilder.helpers.package_state.html#nglui.statebuilder.helpers.package_state", "dispname": "-"}, {"name": "nglui.statebuilder.helpers.make_synapse_neuroglancer_link", "domain": "py", "role": "function", "priority": "1", "uri": "reference/statebuilder.helpers.make_synapse_neuroglancer_link.html#nglui.statebuilder.helpers.make_synapse_neuroglancer_link", "dispname": "-"}, {"name": "nglui.statebuilder.helpers.make_neuron_neuroglancer_link", "domain": "py", "role": "function", "priority": "1", "uri": "reference/statebuilder.helpers.make_neuron_neuroglancer_link.html#nglui.statebuilder.helpers.make_neuron_neuroglancer_link", "dispname": "-"}, {"name": "nglui.parser.base.layer_names", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.layer_names.html#nglui.parser.base.layer_names", "dispname": "-"}, {"name": "nglui.parser.base.image_layers", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.image_layers.html#nglui.parser.base.image_layers", "dispname": "-"}, {"name": "nglui.parser.base.segmentation_layers", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.segmentation_layers.html#nglui.parser.base.segmentation_layers", "dispname": "-"}, {"name": "nglui.parser.base.annotation_layers", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.annotation_layers.html#nglui.parser.base.annotation_layers", "dispname": "-"}, {"name": "nglui.parser.base.tag_dictionary", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.tag_dictionary.html#nglui.parser.base.tag_dictionary", "dispname": "-"}, {"name": "nglui.parser.base.get_layer", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.get_layer.html#nglui.parser.base.get_layer", "dispname": "-"}, {"name": "nglui.parser.base.view_settings", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.view_settings.html#nglui.parser.base.view_settings", "dispname": "-"}, {"name": "nglui.parser.base.get_selected_ids", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.get_selected_ids.html#nglui.parser.base.get_selected_ids", "dispname": "-"}, {"name": "nglui.parser.base.point_annotations", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.point_annotations.html#nglui.parser.base.point_annotations", "dispname": "-"}, {"name": "nglui.parser.base.line_annotations", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.line_annotations.html#nglui.parser.base.line_annotations", "dispname": "-"}, {"name": "nglui.parser.base.sphere_annotations", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.sphere_annotations.html#nglui.parser.base.sphere_annotations", "dispname": "-"}, {"name": "nglui.parser.base.group_annotations", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.group_annotations.html#nglui.parser.base.group_annotations", "dispname": "-"}, {"name": "nglui.parser.base.extract_multicut", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.extract_multicut.html#nglui.parser.base.extract_multicut", "dispname": "-"}, {"name": "nglui.parser.base.annotation_dataframe", "domain": "py", "role": "function", "priority": "1", "uri": "reference/parser.base.annotation_dataframe.html#nglui.parser.base.annotation_dataframe", "dispname": "-"}]} \ No newline at end of file diff --git a/docs/reference/AnnotationLayerConfig.qmd b/docs/reference/AnnotationLayerConfig.qmd deleted file mode 100644 index eb07c64..0000000 --- a/docs/reference/AnnotationLayerConfig.qmd +++ /dev/null @@ -1,17 +0,0 @@ -# AnnotationLayerConfig { #nglui.statebuilder.layers.AnnotationLayerConfig } - -`statebuilder.layers.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)` - -Configuration class for annotation layers - -## Parameters - -| Name | Type | Description | Default | -|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------| -| `name` | str | Layer name. By default, 'annos' | `None` | -| `color` | str | Hex color code with an initial #. By default, None | `None` | -| `linked_segmentation_layer` | str | Name of a linked segmentation layer for selected ids. By default, None | `None` | -| `mapping_rules` | (nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list) | One rule or a list of rules mapping data to annotations. By default, [] | `[]` | -| `array_data` | bool | If True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features. | `False` | -| `tags` | list | List of tags for the layer. | `None` | -| `active` | bool | If True, makes the layer selected. Default is True (unlike for image/segmentation layers). | `True` | \ No newline at end of file diff --git a/docs/reference/ChainedStateBuilder.qmd b/docs/reference/ChainedStateBuilder.qmd deleted file mode 100644 index b9679aa..0000000 --- a/docs/reference/ChainedStateBuilder.qmd +++ /dev/null @@ -1,34 +0,0 @@ -# ChainedStateBuilder { #nglui.statebuilder.statebuilder.ChainedStateBuilder } - -`statebuilder.statebuilder.ChainedStateBuilder(self, statebuilders)` - -Builds a collection of states that sequentially add annotations based on a sequence of dataframes. - -## Parameters - -| Name | Type | Description | Default | -|-----------------|--------|-----------------------------------------------------------------------|------------| -| `statebuilders` | list | List of DataStateBuilders, in same order as dataframes will be passed | _required_ | - -## Methods - -| Name | Description | -| --- | --- | -| [render_state](#nglui.statebuilder.statebuilder.ChainedStateBuilder.render_state) | Generate a single neuroglancer state by addatively applying an ordered collection of | - -### render_state { #nglui.statebuilder.statebuilder.ChainedStateBuilder.render_state } - -`statebuilder.statebuilder.ChainedStateBuilder.render_state(data_list=None, base_state=None, return_as='url', url_prefix=default_neuroglancer_base, link_text='Neuroglancer Link', target_site=None)` - -Generate a single neuroglancer state by addatively applying an ordered collection of -dataframes to an collection of StateBuilder renders. -Parameters - data_list : Collection of DataFrame. The order must match the order of StateBuilders - contained in the class on creation. - base_state : JSON neuroglancer state (optional, default is None). - Used as a base state for adding everything else to. - return_as: ['url', 'viewer', 'html', 'json']. optional, default='url'. - Sets how the state is returned. Note that if a viewer is returned, - the state is not reset to default. - url_prefix: string, optional (default is https://neuromancer-seung-import.appspot.com). - Overrides the default neuroglancer url for url generation. \ No newline at end of file diff --git a/docs/reference/ImageLayerConfig.qmd b/docs/reference/ImageLayerConfig.qmd deleted file mode 100644 index d387a0d..0000000 --- a/docs/reference/ImageLayerConfig.qmd +++ /dev/null @@ -1,18 +0,0 @@ -# ImageLayerConfig { #nglui.statebuilder.layers.ImageLayerConfig } - -`statebuilder.layers.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)` - -Image layer configuration class. - -This provides the rules for setting up an image layer in neuroglancer. - -## Parameters - -| Name | Type | Description | Default | -|---------------------|--------|------------------------------------------------------------------------------------------------|------------| -| `source` | str | Cloudpath to an image source | _required_ | -| `name` | str | Name of the image layer. By default, 'img'. | `None` | -| `active` | bool | If True, makes the layer active in neuroglancer. Default is False. | `False` | -| `contrast_controls` | bool | If True, gives the layer a user-controllable brightness and contrast shader. Default is False. | `False` | -| `black` | float | If contrast_controls is True, sets the default black level. Default is 0.0. | `0.0` | -| `white` | float | If contrast_controls is True, sets the default white level. Default is 1.0. | `1.0` | \ No newline at end of file diff --git a/docs/reference/SegmentationLayerConfig.qmd b/docs/reference/SegmentationLayerConfig.qmd deleted file mode 100644 index edda51b..0000000 --- a/docs/reference/SegmentationLayerConfig.qmd +++ /dev/null @@ -1,44 +0,0 @@ -# SegmentationLayerConfig { #nglui.statebuilder.layers.SegmentationLayerConfig } - -`statebuilder.layers.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)` - -Configuration class for segmentation layers - -## Parameters - -| Name | Type | Description | Default | -|-----------------------|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------| -| `source` | str | Segmentation source | _required_ | -| `name` | (str, optional) | Layer name. | `None` | -| `selected_ids_column` | str or list-like, optional. | Column name (or list of column names) to use for selected ids. | `None` | -| `fixed_ids` | list-like, optional. | List of root ids to select directly. | `None` | -| `fixed_id_colors` | list-like, optional. | List of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values. | `None` | -| `color_column` | str, optional. | # at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a | `None` | -| `active` | bool, optional. | If True, makes the layer selected. Default is False. | `False` | -| `alpha_selected` | | Opacity of selected segmentations in the image layer. Optional, default is 0.3. | `0.3` | -| `alpha_3d` | | Opacity of meshes. Optional, default is 1. | `1` | -| `alpha_unselected` | | Opacity of unselected segments. Optional, default is 0. | `0` | -| `split_point_map` | | If not None, provides an object to map the dataframe input to multicut points. Default is None. | `None` | -| `view_kws` | dict, optional. | Keyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module. | `None` | -| `timestamp` | float or datetime, optional. | Timestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None. | `None` | - -## Methods - -| Name | Description | -| --- | --- | -| [add_selection_map](#nglui.statebuilder.layers.SegmentationLayerConfig.add_selection_map) | Add rules for selecting active segment ids and their colors | - -### add_selection_map { #nglui.statebuilder.layers.SegmentationLayerConfig.add_selection_map } - -`statebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)` - -Add rules for selecting active segment ids and their colors - -#### Parameters - -| Name | Type | Description | Default | -|-----------------------|-------------|----------------------------------------------------------------------------------------------------|-----------| -| `selected_ids_column` | str | Dataframe column to use for adding selected segment ids to the segmentation layer, by default None | `None` | -| `fixed_ids` | int or list | Add one or more segment ids to be active, independent of the data, by default None | `None` | -| `fixed_id_colors` | list | Add a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default None | `None` | -| `color_column` | str | Dataframe column to use for adding selected segment colors, by default None | `None` | \ No newline at end of file diff --git a/docs/reference/_api_index.qmd b/docs/reference/_api_index.qmd deleted file mode 100644 index 0a1d945..0000000 --- a/docs/reference/_api_index.qmd +++ /dev/null @@ -1,74 +0,0 @@ -# {.doc .doc-index} - -## StateBuilder Functions - -### Layers - -Instantiating types of layers - -| | | -| --- | --- | -| [statebuilder.ImageLayerConfig](statebuilder.ImageLayerConfig.qmd#nglui.statebuilder.ImageLayerConfig) | Image layer configuration class. | -| [statebuilder.SegmentationLayerConfig](statebuilder.SegmentationLayerConfig.qmd#nglui.statebuilder.SegmentationLayerConfig) | Configuration class for segmentation layers | -| [statebuilder.AnnotationLayerConfig](statebuilder.AnnotationLayerConfig.qmd#nglui.statebuilder.AnnotationLayerConfig) | Configuration class for annotation layers | - -### Mapping Rules - -Rules for mapping data to annotations - -| | | -| --- | --- | -| [statebuilder.PointMapper](statebuilder.PointMapper.qmd#nglui.statebuilder.PointMapper) | Sets rules to map dataframes to point annotations | -| [statebuilder.LineMapper](statebuilder.LineMapper.qmd#nglui.statebuilder.LineMapper) | Sets rules to map dataframes to line annotations | -| [statebuilder.SphereMapper](statebuilder.SphereMapper.qmd#nglui.statebuilder.SphereMapper) | Sets rules to map dataframes to sphere annotations | -| [statebuilder.BoundingBoxMapper](statebuilder.BoundingBoxMapper.qmd#nglui.statebuilder.BoundingBoxMapper) | Sets rules to map dataframes to bounding box annotations | -| [statebuilder.SplitPointMapper](statebuilder.SplitPointMapper.qmd#nglui.statebuilder.SplitPointMapper) | Mapper to create split points in a segmentation layer. | - -### StateBuilder Classes - -Tools for data-generated neuroglancer state creation - -| | | -| --- | --- | -| [statebuilder.StateBuilder](statebuilder.StateBuilder.qmd#nglui.statebuilder.StateBuilder) | A class for schematic mapping data frames into neuroglancer states. | -| [statebuilder.ChainedStateBuilder](statebuilder.ChainedStateBuilder.qmd#nglui.statebuilder.ChainedStateBuilder) | Builds a collection of states that sequentially add annotations based on a sequence of dataframes. | - -### Helpers - -Tools for common types of states - -| | | -| --- | --- | -| [statebuilder.helpers.from_client](statebuilder.helpers.from_client.qmd#nglui.statebuilder.helpers.from_client) | Generate basic image and segmentation layers from a FrameworkClient | -| [statebuilder.helpers.sort_dataframe_by_root_id](statebuilder.helpers.sort_dataframe_by_root_id.qmd#nglui.statebuilder.helpers.sort_dataframe_by_root_id) | Sort a dataframe so that rows belonging to the same root id are together, ordered by how many times the root id appears. | -| [statebuilder.helpers.make_line_statebuilder](statebuilder.helpers.make_line_statebuilder.qmd#nglui.statebuilder.helpers.make_line_statebuilder) | Generate a state builder that puts points on a single column with a linked segmentaton id | -| [statebuilder.helpers.make_point_statebuilder](statebuilder.helpers.make_point_statebuilder.qmd#nglui.statebuilder.helpers.make_point_statebuilder) | Generate a state builder that puts points on a single column with a linked segmentaton id | -| [statebuilder.helpers.make_pre_post_statebuilder](statebuilder.helpers.make_pre_post_statebuilder.qmd#nglui.statebuilder.helpers.make_pre_post_statebuilder) | Function to generate ChainedStateBuilder with optional pre and post synaptic | -| [statebuilder.helpers.make_state_url](statebuilder.helpers.make_state_url.qmd#nglui.statebuilder.helpers.make_state_url) | Generate a url from a neuroglancer state via a state server. | -| [statebuilder.helpers.make_url_robust](statebuilder.helpers.make_url_robust.qmd#nglui.statebuilder.helpers.make_url_robust) | Generate a url from a neuroglancer state. If too long, return through state server, | -| [statebuilder.helpers.package_state](statebuilder.helpers.package_state.qmd#nglui.statebuilder.helpers.package_state) | Automate creating a state from a statebuilder and | -| [statebuilder.helpers.make_synapse_neuroglancer_link](statebuilder.helpers.make_synapse_neuroglancer_link.qmd#nglui.statebuilder.helpers.make_synapse_neuroglancer_link) | Generate a neuroglancer link from a synapse dataframe as returned from CAVEclient.materialize.synapse_query. | -| [statebuilder.helpers.make_neuron_neuroglancer_link](statebuilder.helpers.make_neuron_neuroglancer_link.qmd#nglui.statebuilder.helpers.make_neuron_neuroglancer_link) | function to create a neuroglancer link view of a neuron, optionally including inputs and outputs | - -## Parser - -### Parser Tools - -Simple tools for parsing neuroglancer states - -| | | -| --- | --- | -| [parser.base.layer_names](parser.base.layer_names.qmd#nglui.parser.base.layer_names) | Get all layer names in the state | -| [parser.base.image_layers](parser.base.image_layers.qmd#nglui.parser.base.image_layers) | Get all image layer names in the state | -| [parser.base.segmentation_layers](parser.base.segmentation_layers.qmd#nglui.parser.base.segmentation_layers) | Get all segmentation layer names in the state | -| [parser.base.annotation_layers](parser.base.annotation_layers.qmd#nglui.parser.base.annotation_layers) | Get all annotation layer names in the state | -| [parser.base.tag_dictionary](parser.base.tag_dictionary.qmd#nglui.parser.base.tag_dictionary) | Get the tag id to string dictionary for a layer | -| [parser.base.get_layer](parser.base.get_layer.qmd#nglui.parser.base.get_layer) | Gets the contents of the layer based on the layer name. | -| [parser.base.view_settings](parser.base.view_settings.qmd#nglui.parser.base.view_settings) | Get all data about the view state in neuroglancer: position, | -| [parser.base.get_selected_ids](parser.base.get_selected_ids.qmd#nglui.parser.base.get_selected_ids) | Get a list of selected ids in a segmentation layer | -| [parser.base.point_annotations](parser.base.point_annotations.qmd#nglui.parser.base.point_annotations) | Get all point annotation points and other info from a layer. | -| [parser.base.line_annotations](parser.base.line_annotations.qmd#nglui.parser.base.line_annotations) | Get all line annotation points and other info from a layer. | -| [parser.base.sphere_annotations](parser.base.sphere_annotations.qmd#nglui.parser.base.sphere_annotations) | Get all sphere annotation points and other info from a layer. | -| [parser.base.group_annotations](parser.base.group_annotations.qmd#nglui.parser.base.group_annotations) | All group annotations and their associated points | -| [parser.base.extract_multicut](parser.base.extract_multicut.qmd#nglui.parser.base.extract_multicut) | Extract information entered into the multicut graph operation | -| [parser.base.annotation_dataframe](parser.base.annotation_dataframe.qmd#nglui.parser.base.annotation_dataframe) | Return all annotations across all annotation layers in the state. | \ No newline at end of file diff --git a/docs/reference/easyviewer.md b/docs/reference/easyviewer.md new file mode 100644 index 0000000..d5728fc --- /dev/null +++ b/docs/reference/easyviewer.md @@ -0,0 +1,19 @@ +--- +title: EasyViewer +--- + +::: src.nglui.easyviewer.ev_base.base + options: + show_source: false + heading_level: 2 + + +::: src.nglui.easyviewer.ev_base.mainline + options: + show_source: false + heading_level: 2 + +::: src.nglui.easyviewer.ev_base.seunglab + options: + show_source: false + heading_level: 2 \ No newline at end of file diff --git a/docs/reference/get_object.qmd b/docs/reference/get_object.qmd deleted file mode 100644 index 63d7643..0000000 --- a/docs/reference/get_object.qmd +++ /dev/null @@ -1,32 +0,0 @@ -# get_object { #quartodoc.get_object } - -`get_object(path, object_name=None, parser='numpy', load_aliases=True, dynamic=False, loader=None)` - -Fetch a griffe object. - -## Parameters - -| Name | Type | Description | Default | -|----------------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|------------| -| `path` | str | An import path to the object. This should have the form `path.to.module:object`. For example, `quartodoc:get_object` or `quartodoc:MdRenderer.render`. | _required_ | -| `object_name` | 'str \| None' | (Deprecated). A function name. | `None` | -| `parser` | str | A docstring parser to use. | `'numpy'` | -| `load_aliases` | | For aliases that were imported from other modules, should we load that module? | `True` | -| `dynamic` | | Whether to dynamically import object. Useful if docstring is not hard-coded, but was set on object by running python code. | `False` | - -## See Also - -preview: print a user-friendly preview of a griffe object. - -## Examples - -```python ->>> get_function("quartodoc", "get_function") -}} \ No newline at end of file diff --git a/docs/reference/layers.AnnotationLayerConfig.qmd b/docs/reference/layers.AnnotationLayerConfig.qmd deleted file mode 100644 index f10fb43..0000000 --- a/docs/reference/layers.AnnotationLayerConfig.qmd +++ /dev/null @@ -1,17 +0,0 @@ -# layers.AnnotationLayerConfig { #nglui.statebuilder.layers.AnnotationLayerConfig } - -`statebuilder.layers.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)` - -Configuration class for annotation layers - -## Parameters - -| Name | Type | Description | Default | -|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------| -| `name` | str | Layer name. By default, 'annos' | `None` | -| `color` | str | Hex color code with an initial #. By default, None | `None` | -| `linked_segmentation_layer` | str | Name of a linked segmentation layer for selected ids. By default, None | `None` | -| `mapping_rules` | (nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list) | One rule or a list of rules mapping data to annotations. By default, [] | `[]` | -| `array_data` | bool | If True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features. | `False` | -| `tags` | list | List of tags for the layer. | `None` | -| `active` | bool | If True, makes the layer selected. Default is True (unlike for image/segmentation layers). | `True` | \ No newline at end of file diff --git a/docs/reference/layers.ImageLayerConfig.qmd b/docs/reference/layers.ImageLayerConfig.qmd deleted file mode 100644 index 837eb8b..0000000 --- a/docs/reference/layers.ImageLayerConfig.qmd +++ /dev/null @@ -1,18 +0,0 @@ -# layers.ImageLayerConfig { #nglui.statebuilder.layers.ImageLayerConfig } - -`statebuilder.layers.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)` - -Image layer configuration class. - -This provides the rules for setting up an image layer in neuroglancer. - -## Parameters - -| Name | Type | Description | Default | -|---------------------|--------|------------------------------------------------------------------------------------------------|------------| -| `source` | str | Cloudpath to an image source | _required_ | -| `name` | str | Name of the image layer. By default, 'img'. | `None` | -| `active` | bool | If True, makes the layer active in neuroglancer. Default is False. | `False` | -| `contrast_controls` | bool | If True, gives the layer a user-controllable brightness and contrast shader. Default is False. | `False` | -| `black` | float | If contrast_controls is True, sets the default black level. Default is 0.0. | `0.0` | -| `white` | float | If contrast_controls is True, sets the default white level. Default is 1.0. | `1.0` | \ No newline at end of file diff --git a/docs/reference/layers.SegmentationLayerConfig.qmd b/docs/reference/layers.SegmentationLayerConfig.qmd deleted file mode 100644 index f5196f4..0000000 --- a/docs/reference/layers.SegmentationLayerConfig.qmd +++ /dev/null @@ -1,44 +0,0 @@ -# layers.SegmentationLayerConfig { #nglui.statebuilder.layers.SegmentationLayerConfig } - -`statebuilder.layers.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)` - -Configuration class for segmentation layers - -## Parameters - -| Name | Type | Description | Default | -|-----------------------|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------| -| `source` | str | Segmentation source | _required_ | -| `name` | (str, optional) | Layer name. | `None` | -| `selected_ids_column` | str or list-like, optional. | Column name (or list of column names) to use for selected ids. | `None` | -| `fixed_ids` | list-like, optional. | List of root ids to select directly. | `None` | -| `fixed_id_colors` | list-like, optional. | List of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values. | `None` | -| `color_column` | str, optional. | # at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a | `None` | -| `active` | bool, optional. | If True, makes the layer selected. Default is False. | `False` | -| `alpha_selected` | | Opacity of selected segmentations in the image layer. Optional, default is 0.3. | `0.3` | -| `alpha_3d` | | Opacity of meshes. Optional, default is 1. | `1` | -| `alpha_unselected` | | Opacity of unselected segments. Optional, default is 0. | `0` | -| `split_point_map` | | If not None, provides an object to map the dataframe input to multicut points. Default is None. | `None` | -| `view_kws` | dict, optional. | Keyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module. | `None` | -| `timestamp` | float or datetime, optional. | Timestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None. | `None` | - -## Methods - -| Name | Description | -| --- | --- | -| [add_selection_map](#nglui.statebuilder.layers.SegmentationLayerConfig.add_selection_map) | Add rules for selecting active segment ids and their colors | - -### add_selection_map { #nglui.statebuilder.layers.SegmentationLayerConfig.add_selection_map } - -`statebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)` - -Add rules for selecting active segment ids and their colors - -#### Parameters - -| Name | Type | Description | Default | -|-----------------------|-------------|----------------------------------------------------------------------------------------------------|-----------| -| `selected_ids_column` | str | Dataframe column to use for adding selected segment ids to the segmentation layer, by default None | `None` | -| `fixed_ids` | int or list | Add one or more segment ids to be active, independent of the data, by default None | `None` | -| `fixed_id_colors` | list | Add a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default None | `None` | -| `color_column` | str | Dataframe column to use for adding selected segment colors, by default None | `None` | \ No newline at end of file diff --git a/docs/reference/layers.qmd b/docs/reference/layers.qmd deleted file mode 100644 index 8e61ef7..0000000 --- a/docs/reference/layers.qmd +++ /dev/null @@ -1,112 +0,0 @@ -# layers { #nglui.statebuilder.layers } - -`statebuilder.layers` - - - -## Classes - -| Name | Description | -| --- | --- | -| [AnnotationLayerConfig](#nglui.statebuilder.layers.AnnotationLayerConfig) | Configuration class for annotation layers | -| [ImageLayerConfig](#nglui.statebuilder.layers.ImageLayerConfig) | Image layer configuration class. | -| [LayerConfigBase](#nglui.statebuilder.layers.LayerConfigBase) | Base class for configuring layers | -| [SegmentationLayerConfig](#nglui.statebuilder.layers.SegmentationLayerConfig) | Configuration class for segmentation layers | - -## AnnotationLayerConfig { #nglui.statebuilder.layers.AnnotationLayerConfig } - -`statebuilder.layers.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)` - -Configuration class for annotation layers - -### Parameters - -| Name | Type | Description | Default | -|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------| -| `name` | str | Layer name. By default, 'annos' | `None` | -| `color` | str | Hex color code with an initial #. By default, None | `None` | -| `linked_segmentation_layer` | str | Name of a linked segmentation layer for selected ids. By default, None | `None` | -| `mapping_rules` | (nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list) | One rule or a list of rules mapping data to annotations. By default, [] | `[]` | -| `array_data` | bool | If True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features. | `False` | -| `tags` | list | List of tags for the layer. | `None` | -| `active` | bool | If True, makes the layer selected. Default is True (unlike for image/segmentation layers). | `True` | - -## ImageLayerConfig { #nglui.statebuilder.layers.ImageLayerConfig } - -`statebuilder.layers.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)` - -Image layer configuration class. - -This provides the rules for setting up an image layer in neuroglancer. - -### Parameters - -| Name | Type | Description | Default | -|---------------------|--------|------------------------------------------------------------------------------------------------|------------| -| `source` | str | Cloudpath to an image source | _required_ | -| `name` | str | Name of the image layer. By default, 'img'. | `None` | -| `active` | bool | If True, makes the layer active in neuroglancer. Default is False. | `False` | -| `contrast_controls` | bool | If True, gives the layer a user-controllable brightness and contrast shader. Default is False. | `False` | -| `black` | float | If contrast_controls is True, sets the default black level. Default is 0.0. | `0.0` | -| `white` | float | If contrast_controls is True, sets the default white level. Default is 1.0. | `1.0` | - -## LayerConfigBase { #nglui.statebuilder.layers.LayerConfigBase } - -`statebuilder.layers.LayerConfigBase(self, name, type, source, color, active)` - -Base class for configuring layers - -### Parameters - -| Name | Type | Description | Default | -|----------|--------|---------------------------------------------|------------| -| `name` | str | Layer name for reference and display | _required_ | -| `type` | str | Layer type. Usually handled by the subclass | _required_ | -| `source` | str | Datasource for the layer | _required_ | -| `color` | str | Hex string (with starting hash). | _required_ | -| `active` | (bool) | If True, becomes a selected layer. | _required_ | - -## SegmentationLayerConfig { #nglui.statebuilder.layers.SegmentationLayerConfig } - -`statebuilder.layers.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)` - -Configuration class for segmentation layers - -### Parameters - -| Name | Type | Description | Default | -|-----------------------|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------| -| `source` | str | Segmentation source | _required_ | -| `name` | (str, optional) | Layer name. | `None` | -| `selected_ids_column` | str or list-like, optional. | Column name (or list of column names) to use for selected ids. | `None` | -| `fixed_ids` | list-like, optional. | List of root ids to select directly. | `None` | -| `fixed_id_colors` | list-like, optional. | List of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values. | `None` | -| `color_column` | str, optional. | # at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a | `None` | -| `active` | bool, optional. | If True, makes the layer selected. Default is False. | `False` | -| `alpha_selected` | | Opacity of selected segmentations in the image layer. Optional, default is 0.3. | `0.3` | -| `alpha_3d` | | Opacity of meshes. Optional, default is 1. | `1` | -| `alpha_unselected` | | Opacity of unselected segments. Optional, default is 0. | `0` | -| `split_point_map` | | If not None, provides an object to map the dataframe input to multicut points. Default is None. | `None` | -| `view_kws` | dict, optional. | Keyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module. | `None` | -| `timestamp` | float or datetime, optional. | Timestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None. | `None` | - -### Methods - -| Name | Description | -| --- | --- | -| [add_selection_map](#nglui.statebuilder.layers.SegmentationLayerConfig.add_selection_map) | Add rules for selecting active segment ids and their colors | - -#### add_selection_map { #nglui.statebuilder.layers.SegmentationLayerConfig.add_selection_map } - -`statebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)` - -Add rules for selecting active segment ids and their colors - -##### Parameters - -| Name | Type | Description | Default | -|-----------------------|-------------|----------------------------------------------------------------------------------------------------|-----------| -| `selected_ids_column` | str | Dataframe column to use for adding selected segment ids to the segmentation layer, by default None | `None` | -| `fixed_ids` | int or list | Add one or more segment ids to be active, independent of the data, by default None | `None` | -| `fixed_id_colors` | list | Add a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default None | `None` | -| `color_column` | str | Dataframe column to use for adding selected segment colors, by default None | `None` | \ No newline at end of file diff --git a/docs/reference/nglui.statebuilder.layers.AnnotationLayerConfig.qmd b/docs/reference/nglui.statebuilder.layers.AnnotationLayerConfig.qmd deleted file mode 100644 index eb07c64..0000000 --- a/docs/reference/nglui.statebuilder.layers.AnnotationLayerConfig.qmd +++ /dev/null @@ -1,17 +0,0 @@ -# AnnotationLayerConfig { #nglui.statebuilder.layers.AnnotationLayerConfig } - -`statebuilder.layers.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)` - -Configuration class for annotation layers - -## Parameters - -| Name | Type | Description | Default | -|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------| -| `name` | str | Layer name. By default, 'annos' | `None` | -| `color` | str | Hex color code with an initial #. By default, None | `None` | -| `linked_segmentation_layer` | str | Name of a linked segmentation layer for selected ids. By default, None | `None` | -| `mapping_rules` | (nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list) | One rule or a list of rules mapping data to annotations. By default, [] | `[]` | -| `array_data` | bool | If True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features. | `False` | -| `tags` | list | List of tags for the layer. | `None` | -| `active` | bool | If True, makes the layer selected. Default is True (unlike for image/segmentation layers). | `True` | \ No newline at end of file diff --git a/docs/reference/nglui.statebuilder.layers.ImageLayerConfig.qmd b/docs/reference/nglui.statebuilder.layers.ImageLayerConfig.qmd deleted file mode 100644 index d387a0d..0000000 --- a/docs/reference/nglui.statebuilder.layers.ImageLayerConfig.qmd +++ /dev/null @@ -1,18 +0,0 @@ -# ImageLayerConfig { #nglui.statebuilder.layers.ImageLayerConfig } - -`statebuilder.layers.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)` - -Image layer configuration class. - -This provides the rules for setting up an image layer in neuroglancer. - -## Parameters - -| Name | Type | Description | Default | -|---------------------|--------|------------------------------------------------------------------------------------------------|------------| -| `source` | str | Cloudpath to an image source | _required_ | -| `name` | str | Name of the image layer. By default, 'img'. | `None` | -| `active` | bool | If True, makes the layer active in neuroglancer. Default is False. | `False` | -| `contrast_controls` | bool | If True, gives the layer a user-controllable brightness and contrast shader. Default is False. | `False` | -| `black` | float | If contrast_controls is True, sets the default black level. Default is 0.0. | `0.0` | -| `white` | float | If contrast_controls is True, sets the default white level. Default is 1.0. | `1.0` | \ No newline at end of file diff --git a/docs/reference/nglui.statebuilder.layers.LayerConfigBase.qmd b/docs/reference/nglui.statebuilder.layers.LayerConfigBase.qmd deleted file mode 100644 index ca2b3ab..0000000 --- a/docs/reference/nglui.statebuilder.layers.LayerConfigBase.qmd +++ /dev/null @@ -1,15 +0,0 @@ -# LayerConfigBase { #nglui.statebuilder.layers.LayerConfigBase } - -`statebuilder.layers.LayerConfigBase(self, name, type, source, color, active)` - -Base class for configuring layers - -## Parameters - -| Name | Type | Description | Default | -|----------|--------|---------------------------------------------|------------| -| `name` | str | Layer name for reference and display | _required_ | -| `type` | str | Layer type. Usually handled by the subclass | _required_ | -| `source` | str | Datasource for the layer | _required_ | -| `color` | str | Hex string (with starting hash). | _required_ | -| `active` | (bool) | If True, becomes a selected layer. | _required_ | \ No newline at end of file diff --git a/docs/reference/nglui.statebuilder.layers.SegmentationLayerConfig.qmd b/docs/reference/nglui.statebuilder.layers.SegmentationLayerConfig.qmd deleted file mode 100644 index edda51b..0000000 --- a/docs/reference/nglui.statebuilder.layers.SegmentationLayerConfig.qmd +++ /dev/null @@ -1,44 +0,0 @@ -# SegmentationLayerConfig { #nglui.statebuilder.layers.SegmentationLayerConfig } - -`statebuilder.layers.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)` - -Configuration class for segmentation layers - -## Parameters - -| Name | Type | Description | Default | -|-----------------------|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------| -| `source` | str | Segmentation source | _required_ | -| `name` | (str, optional) | Layer name. | `None` | -| `selected_ids_column` | str or list-like, optional. | Column name (or list of column names) to use for selected ids. | `None` | -| `fixed_ids` | list-like, optional. | List of root ids to select directly. | `None` | -| `fixed_id_colors` | list-like, optional. | List of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values. | `None` | -| `color_column` | str, optional. | # at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a | `None` | -| `active` | bool, optional. | If True, makes the layer selected. Default is False. | `False` | -| `alpha_selected` | | Opacity of selected segmentations in the image layer. Optional, default is 0.3. | `0.3` | -| `alpha_3d` | | Opacity of meshes. Optional, default is 1. | `1` | -| `alpha_unselected` | | Opacity of unselected segments. Optional, default is 0. | `0` | -| `split_point_map` | | If not None, provides an object to map the dataframe input to multicut points. Default is None. | `None` | -| `view_kws` | dict, optional. | Keyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module. | `None` | -| `timestamp` | float or datetime, optional. | Timestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None. | `None` | - -## Methods - -| Name | Description | -| --- | --- | -| [add_selection_map](#nglui.statebuilder.layers.SegmentationLayerConfig.add_selection_map) | Add rules for selecting active segment ids and their colors | - -### add_selection_map { #nglui.statebuilder.layers.SegmentationLayerConfig.add_selection_map } - -`statebuilder.layers.SegmentationLayerConfig.add_selection_map(selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None)` - -Add rules for selecting active segment ids and their colors - -#### Parameters - -| Name | Type | Description | Default | -|-----------------------|-------------|----------------------------------------------------------------------------------------------------|-----------| -| `selected_ids_column` | str | Dataframe column to use for adding selected segment ids to the segmentation layer, by default None | `None` | -| `fixed_ids` | int or list | Add one or more segment ids to be active, independent of the data, by default None | `None` | -| `fixed_id_colors` | list | Add a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default None | `None` | -| `color_column` | str | Dataframe column to use for adding selected segment colors, by default None | `None` | \ No newline at end of file diff --git a/docs/reference/nglui.statebuilder.statebuilder.StateBuilder.initialize_state.qmd b/docs/reference/nglui.statebuilder.statebuilder.StateBuilder.initialize_state.qmd deleted file mode 100644 index dc5e9e5..0000000 --- a/docs/reference/nglui.statebuilder.statebuilder.StateBuilder.initialize_state.qmd +++ /dev/null @@ -1,11 +0,0 @@ -# initialize_state { #nglui.statebuilder.statebuilder.StateBuilder.initialize_state } - -`statebuilder.statebuilder.StateBuilder.initialize_state(base_state=None, target_site=None)` - -Generate a new Neuroglancer state with layers as needed for the schema. - -## Parameters - -| Name | Type | Description | Default | -|--------------|--------|-----------------------------------------------------------------------------|-----------| -| `base_state` | str | Optional initial state to build on, described by its JSON. By default None. | `None` | \ No newline at end of file diff --git a/docs/reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.qmd b/docs/reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.qmd deleted file mode 100644 index 5863fdb..0000000 --- a/docs/reference/nglui.statebuilder.statebuilder.StateBuilder.render_state.qmd +++ /dev/null @@ -1,21 +0,0 @@ -# render_state { #nglui.statebuilder.statebuilder.StateBuilder.render_state } - -`statebuilder.statebuilder.StateBuilder.render_state(data=None, base_state=None, return_as='url', url_prefix=None, link_text='Neuroglancer Link', target_site=None)` - -Build a Neuroglancer state out of a DataFrame. - -## Parameters - -| Name | Type | Description | Default | -|--------------|----------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------| -| `data` | pandas.pandas.DataFrame | DataFrame to use as a point source. By default None, for which it will return only the base_state and any fixed values. | `None` | -| `base_state` | dict | Initial state to build on, expressed as Neuroglancer JSON. By default None | `None` | -| `return_as` | \[url, nglui.statebuilder.statebuilder.StateBuilder.viewer, html, json, dict, shared\] | Choice of output types. Note that if a viewer is returned, the state is not reset. url : Returns the raw url describing the state viewer : Returns an EasyViewer object holding the state information html : Returns an HTML link to the url, useful for notebooks. json : Returns a JSON string describing the state. dict : Returns a dict version of the JSON state. By default 'url' | `'url'` | -| `url_prefix` | str | Neuroglancer URL prefix to use. By default None, for which it will open with the class default. | `None` | -| `link_text` | str | Text to use for the link when returning as html, by default 'Neuroglancer Link' | `'Neuroglancer Link'` | - -## Returns - -| Type | Description | -|--------------------------------------------|---------------------------------------------------------------------------------------------------------------------| -| string or neuroglancer.neuroglancer.Viewer | A link to or viewer for a Neuroglancer state with layers, annotations, and selected objects determined by the data. | \ No newline at end of file diff --git a/docs/reference/parser.base.annotation_dataframe.qmd b/docs/reference/parser.base.annotation_dataframe.qmd deleted file mode 100644 index 81d684d..0000000 --- a/docs/reference/parser.base.annotation_dataframe.qmd +++ /dev/null @@ -1,17 +0,0 @@ -# parser.base.annotation_dataframe { #nglui.parser.base.annotation_dataframe } - -`parser.base.annotation_dataframe(state)` - -Return all annotations across all annotation layers in the state. - -## Parameters - -| Name | Type | Description | Default | -|---------|--------|-------------------------------|------------| -| `state` | dict | Neuroglancer state dictionary | _required_ | - -## Returns - -| Type | Description | -|-------------------------|--------------------------------------------------------------------------------------------------------------------| -| pandas.pandas.DataFrame | Dataframe with columns layer, anno_type, point, pointB, linked_segmentation, tags, anno_id, group_id, description. | \ No newline at end of file diff --git a/docs/reference/parser.base.annotation_layers.qmd b/docs/reference/parser.base.annotation_layers.qmd deleted file mode 100644 index e8ec0d1..0000000 --- a/docs/reference/parser.base.annotation_layers.qmd +++ /dev/null @@ -1,17 +0,0 @@ -# parser.base.annotation_layers { #nglui.parser.base.annotation_layers } - -`parser.base.annotation_layers(state)` - -Get all annotation layer names in the state - -## Parameters - -| Name | Type | Description | Default | -|---------|--------|-----------------------------------|------------| -| `state` | dict | Neuroglancer state as a JSON dict | _required_ | - -## Returns - -| Type | Description | -|--------|---------------------| -| list | List of layer names | \ No newline at end of file diff --git a/docs/reference/parser.base.extract_multicut.qmd b/docs/reference/parser.base.extract_multicut.qmd deleted file mode 100644 index 46e8db0..0000000 --- a/docs/reference/parser.base.extract_multicut.qmd +++ /dev/null @@ -1,21 +0,0 @@ -# parser.base.extract_multicut { #nglui.parser.base.extract_multicut } - -`parser.base.extract_multicut(state, seg_layer=None)` - -Extract information entered into the multicut graph operation - -## Parameters - -| Name | Type | Description | Default | -|-------------|--------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------| -| `state` | dict | Neuroglancer state | _required_ | -| `seg_layer` | str | Name of a segmentation layer or None. If None, the function will check how many segmentation layers there are and, if only one exits, choose it. If more than one segmentation layer is present, it errors. By default None | `None` | - -## Returns - -| Type | Description | -|-------------------|-----------------------------------------------------------------------------------------------------------------------| -| numpy.numpy.array | Nx3 array of points selected | -| numpy.numpy.array | N array with 'source' or 'sink', depending on which side the point is on. | -| numpy.numpy.array | N array with selected supervoxel. If only points are selected (e.g. via clicking on the mesh), the value will be NaN. | -| int | Root id of the object to split | \ No newline at end of file diff --git a/docs/reference/parser.base.get_layer.qmd b/docs/reference/parser.base.get_layer.qmd deleted file mode 100644 index 1646f20..0000000 --- a/docs/reference/parser.base.get_layer.qmd +++ /dev/null @@ -1,18 +0,0 @@ -# parser.base.get_layer { #nglui.parser.base.get_layer } - -`parser.base.get_layer(state, layer_name)` - -Gets the contents of the layer based on the layer name. - -## Parameters - -| Name | Type | Description | Default | -|--------------|--------|-----------------------------------|------------| -| `state` | dict | Neuroglancer state as a JSON dict | _required_ | -| `layer_name` | str | Name of layer | _required_ | - -## Returns - -| Type | Description | -|--------|---------------------| -| dict | Layer data contents | \ No newline at end of file diff --git a/docs/reference/parser.base.get_selected_ids.qmd b/docs/reference/parser.base.get_selected_ids.qmd deleted file mode 100644 index eb596df..0000000 --- a/docs/reference/parser.base.get_selected_ids.qmd +++ /dev/null @@ -1,18 +0,0 @@ -# parser.base.get_selected_ids { #nglui.parser.base.get_selected_ids } - -`parser.base.get_selected_ids(state, layer=None)` - -Get a list of selected ids in a segmentation layer - -## Parameters - -| Name | Type | Description | Default | -|---------|--------|------------------------------------------------------------------------------------------------------------------------|------------| -| `state` | dict | State dict | _required_ | -| `layer` | str | Segmentation layer name, if needed. If None and only one segmentation layer is present, default to it. By default None | `None` | - -## Returns - -| Type | Description | -|--------|-------------------| -| list | List of root ids. | \ No newline at end of file diff --git a/docs/reference/parser.base.group_annotations.qmd b/docs/reference/parser.base.group_annotations.qmd deleted file mode 100644 index 343e3cb..0000000 --- a/docs/reference/parser.base.group_annotations.qmd +++ /dev/null @@ -1,25 +0,0 @@ -# parser.base.group_annotations { #nglui.parser.base.group_annotations } - -`parser.base.group_annotations(state, layer_name, description=False, linked_segmentations=False, tags=False)` - -All group annotations and their associated points - -## Parameters - -| Name | Type | Description | Default | -|------------------------|--------|----------------------------------------------------------------------|------------| -| `state` | dict | Neuroglancer state as JSON dict | _required_ | -| `layer_name` | str | Annotation layer name | _required_ | -| `description` | bool | If True, also returns descriptions as well. By default False | `False` | -| `linked_segmentations` | bool | If True, also returns list of linked segmentations, by default False | `False` | -| `tags` | bool | If True, also returns list of tags, by default False | `False` | - -## Returns - -| Type | Description | -|--------|----------------------------------------------------------------------------| -| list | List of N 3-element points | -| list | List of N id strings for groups. | -| list | List of N strings (or None), only returned if description=True. | -| list | List of N lists of object ids. Only returned if linked_segmentations=True. | -| list | List of N lists of tag ids. Only returned if tags=True. | \ No newline at end of file diff --git a/docs/reference/parser.base.image_layers.qmd b/docs/reference/parser.base.image_layers.qmd deleted file mode 100644 index 415b3da..0000000 --- a/docs/reference/parser.base.image_layers.qmd +++ /dev/null @@ -1,17 +0,0 @@ -# parser.base.image_layers { #nglui.parser.base.image_layers } - -`parser.base.image_layers(state)` - -Get all image layer names in the state - -## Parameters - -| Name | Type | Description | Default | -|---------|--------|-----------------------------------|------------| -| `state` | dict | Neuroglancer state as a JSON dict | _required_ | - -## Returns - -| Type | Description | -|--------|---------------------| -| list | List of layer names | \ No newline at end of file diff --git a/docs/reference/parser.base.layer_names.qmd b/docs/reference/parser.base.layer_names.qmd deleted file mode 100644 index 946a582..0000000 --- a/docs/reference/parser.base.layer_names.qmd +++ /dev/null @@ -1,17 +0,0 @@ -# parser.base.layer_names { #nglui.parser.base.layer_names } - -`parser.base.layer_names(state)` - -Get all layer names in the state - -## Parameters - -| Name | Type | Description | Default | -|---------|--------|-----------------------------------|------------| -| `state` | dict | Neuroglancer state as a JSON dict | _required_ | - -## Returns - -| Type | Description | -|--------|---------------------| -| list | List of layer names | \ No newline at end of file diff --git a/docs/reference/parser.base.line_annotations.qmd b/docs/reference/parser.base.line_annotations.qmd deleted file mode 100644 index 66ad684..0000000 --- a/docs/reference/parser.base.line_annotations.qmd +++ /dev/null @@ -1,26 +0,0 @@ -# parser.base.line_annotations { #nglui.parser.base.line_annotations } - -`parser.base.line_annotations(state, layer_name, description=False, linked_segmentations=False, tags=False, group=False)` - -Get all line annotation points and other info from a layer. - -## Parameters - -| Name | Type | Description | Default | -|------------------------|--------|----------------------------------------------------------------------|------------| -| `state` | dict | Neuroglancer state as JSON dict | _required_ | -| `layer_name` | str | Layer name | _required_ | -| `description` | bool | If True, also returns descriptions as well. By default False | `False` | -| `linked_segmentations` | bool | If True, also returns list of linked segmentations, by default False | `False` | -| `tags` | bool | If True, also returns list of tags, by default False | `False` | - -## Returns - -| Type | Description | -|--------|------------------------------------------------------------------------------------| -| list | List of N 3-element points (as list) of the first point in each line. | -| list | List of N 3-element points (as list) of the second point in each line. | -| list | List of N strings (or None), only returned if description=True. | -| list | List of N lists of object ids. Only returned if linked_segmentations=True. | -| list | List of N lists of tag ids. Only returned if tags=True. | -| list | List of group ids (as string) or None for annotations. Only returned if group=True | \ No newline at end of file diff --git a/docs/reference/parser.base.point_annotations.qmd b/docs/reference/parser.base.point_annotations.qmd deleted file mode 100644 index 6af753c..0000000 --- a/docs/reference/parser.base.point_annotations.qmd +++ /dev/null @@ -1,25 +0,0 @@ -# parser.base.point_annotations { #nglui.parser.base.point_annotations } - -`parser.base.point_annotations(state, layer_name, description=False, linked_segmentations=False, tags=False, group=False)` - -Get all point annotation points and other info from a layer. - -## Parameters - -| Name | Type | Description | Default | -|------------------------|--------|----------------------------------------------------------------------|------------| -| `state` | dict | Neuroglancer state as JSON dict | _required_ | -| `layer_name` | str | Layer name | _required_ | -| `description` | bool | If True, also returns descriptions as well. By default False | `False` | -| `linked_segmentations` | bool | If True, also returns list of linked segmentations, by default False | `False` | -| `tags` | bool | If True, also returns list of tags, by default False | `False` | - -## Returns - -| Type | Description | -|--------|------------------------------------------------------------------------------------| -| list | List of N 3-element points (as list) | -| list | List of N strings (or None), only returned if description=True. | -| list | List of N lists of object ids. Only returned if linked_segmentations=True. | -| list | List of N lists of tag ids. Only returned if tags=True. | -| list | List of group ids (as string) or None for annotations. Only returned if group=True | \ No newline at end of file diff --git a/docs/reference/parser.base.segmentation_layers.qmd b/docs/reference/parser.base.segmentation_layers.qmd deleted file mode 100644 index 95dddb2..0000000 --- a/docs/reference/parser.base.segmentation_layers.qmd +++ /dev/null @@ -1,17 +0,0 @@ -# parser.base.segmentation_layers { #nglui.parser.base.segmentation_layers } - -`parser.base.segmentation_layers(state)` - -Get all segmentation layer names in the state - -## Parameters - -| Name | Type | Description | Default | -|---------|--------|-----------------------------------|------------| -| `state` | dict | Neuroglancer state as a JSON dict | _required_ | - -## Returns - -| Type | Description | -|--------|---------------------| -| list | List of layer names | \ No newline at end of file diff --git a/docs/reference/parser.base.sphere_annotations.qmd b/docs/reference/parser.base.sphere_annotations.qmd deleted file mode 100644 index 6911373..0000000 --- a/docs/reference/parser.base.sphere_annotations.qmd +++ /dev/null @@ -1,26 +0,0 @@ -# parser.base.sphere_annotations { #nglui.parser.base.sphere_annotations } - -`parser.base.sphere_annotations(state, layer_name, description=False, linked_segmentations=False, tags=False, group=False)` - -Get all sphere annotation points and other info from a layer. - -## Parameters - -| Name | Type | Description | Default | -|------------------------|--------|----------------------------------------------------------------------|------------| -| `state` | dict | Neuroglancer state as JSON dict | _required_ | -| `layer_name` | str | Layer name | _required_ | -| `description` | bool | If True, also returns descriptions as well. By default False | `False` | -| `linked_segmentations` | bool | If True, also returns list of linked segmentations, by default False | `False` | -| `tags` | bool | If True, also returns list of tags, by default False | `False` | - -## Returns - -| Type | Description | -|--------|------------------------------------------------------------------------------------| -| list | List of N 3-element center points (as list) | -| list | List of N 3-element radii for each axis of the ellipsoid. | -| list | List of N strings (or None), only returned if description=True. | -| list | List of N lists of object ids. Only returned if linked_segmentations=True. | -| list | List of N lists of tag ids. Only returned if tags=True. | -| list | List of group ids (as string) or None for annotations. Only returned if group=True | \ No newline at end of file diff --git a/docs/reference/parser.base.tag_dictionary.qmd b/docs/reference/parser.base.tag_dictionary.qmd deleted file mode 100644 index 718d022..0000000 --- a/docs/reference/parser.base.tag_dictionary.qmd +++ /dev/null @@ -1,18 +0,0 @@ -# parser.base.tag_dictionary { #nglui.parser.base.tag_dictionary } - -`parser.base.tag_dictionary(state, layer_name)` - -Get the tag id to string dictionary for a layer - -## Parameters - -| Name | Type | Description | Default | -|--------------|----------|---------------|------------| -| `state` | dict | | _required_ | -| `layer_name` | \[type\] | [description] | _required_ | - -## Returns - -| Type | Description | -|----------|---------------| -| \[type\] | [description] | \ No newline at end of file diff --git a/docs/reference/parser.base.view_settings.qmd b/docs/reference/parser.base.view_settings.qmd deleted file mode 100644 index f005eba..0000000 --- a/docs/reference/parser.base.view_settings.qmd +++ /dev/null @@ -1,18 +0,0 @@ -# parser.base.view_settings { #nglui.parser.base.view_settings } - -`parser.base.view_settings(state)` - -Get all data about the view state in neuroglancer: position, -image zoom, orientation and zoom of the 3d view, and voxel size. - -## Parameters - -| Name | Type | Description | Default | -|---------|--------|---------------------------------|------------| -| `state` | dict | Neuroglancer state as JSON dict | _required_ | - -## Returns - -| Type | Description | -|--------|----------------------------------------------------------------------------------------------------| -| dict | Dictionary with keys: position, zoomFactor, perspectiveOrientation, perspectiveZoom, and voxelSize | \ No newline at end of file diff --git a/docs/reference/parser.md b/docs/reference/parser.md new file mode 100644 index 0000000..81a99b4 --- /dev/null +++ b/docs/reference/parser.md @@ -0,0 +1,8 @@ +--- +title: State Parser +--- + +::: src.nglui.parser + options: + show_source: false + heading_level: 2 \ No newline at end of file diff --git a/docs/reference/preview.qmd b/docs/reference/preview.qmd deleted file mode 100644 index 7f58ab7..0000000 --- a/docs/reference/preview.qmd +++ /dev/null @@ -1,22 +0,0 @@ -# preview { #quartodoc.preview } - -`preview(ast, max_depth=999, compact=False, as_string=False)` - -Print a friendly representation of a griffe object (e.g. function, docstring) - -## Examples - -```python ->>> from quartodoc import get_object ->>> obj = get_object("quartodoc", "get_object") -``` - -```python ->>> preview(obj.docstring.parsed) - ... -``` - -```python ->>> preview(obj) - ... -``` \ No newline at end of file diff --git a/docs/reference/segprops.md b/docs/reference/segprops.md new file mode 100644 index 0000000..fc56920 --- /dev/null +++ b/docs/reference/segprops.md @@ -0,0 +1,13 @@ +--- +title: Segment Properties +--- + +!!! note + + Autogeneration of the function reference does not capture the full range of segment properties. + Please see the documentation for the individual segment types if you want to build segment properties manually. + +::: src.nglui.segmentprops.base + options: + show_source: false + heading_level: 2 diff --git a/docs/reference/statebuilder.AnnotationLayerConfig.qmd b/docs/reference/statebuilder.AnnotationLayerConfig.qmd deleted file mode 100644 index 9bbc8fc..0000000 --- a/docs/reference/statebuilder.AnnotationLayerConfig.qmd +++ /dev/null @@ -1,17 +0,0 @@ -# statebuilder.AnnotationLayerConfig { #nglui.statebuilder.AnnotationLayerConfig } - -`statebuilder.AnnotationLayerConfig(self, name=None, color=None, linked_segmentation_layer=None, mapping_rules=[], array_data=False, tags=None, active=True, filter_by_segmentation=False, brackets_show_segmentation=True, selection_shows_segmentation=True, filter_query=None, data_resolution=None)` - -Configuration class for annotation layers - -## Parameters - -| Name | Type | Description | Default | -|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------| -| `name` | str | Layer name. By default, 'annos' | `None` | -| `color` | str | Hex color code with an initial #. By default, None | `None` | -| `linked_segmentation_layer` | str | Name of a linked segmentation layer for selected ids. By default, None | `None` | -| `mapping_rules` | (nglui.statebuilder.mappers.PointMapper, nglui.statebuilder.mappers.LineMapper, nglui.statebuilder.mappers.SphereMapper or list) | One rule or a list of rules mapping data to annotations. By default, [] | `[]` | -| `array_data` | bool | If True, allows simple mapping where one or more arrays are passed instead of a dataframe. Only allows basic annotation creation, no tags, linked segmentations, or other rich features. | `False` | -| `tags` | list | List of tags for the layer. | `None` | -| `active` | bool | If True, makes the layer selected. Default is True (unlike for image/segmentation layers). | `True` | \ No newline at end of file diff --git a/docs/reference/statebuilder.BoundingBoxMapper.qmd b/docs/reference/statebuilder.BoundingBoxMapper.qmd deleted file mode 100644 index 71df9bb..0000000 --- a/docs/reference/statebuilder.BoundingBoxMapper.qmd +++ /dev/null @@ -1,20 +0,0 @@ -# statebuilder.BoundingBoxMapper { #nglui.statebuilder.BoundingBoxMapper } - -`statebuilder.BoundingBoxMapper(self, point_column_a=None, point_column_b=None, description_column=None, linked_segmentation_column=None, tag_column=None, group_column=None, gather_linked_segmentations=True, share_linked_segmentations=False, set_position=True, multipoint=False, collapse_groups=False, split_positions=False, mapping_set=None)` - -Sets rules to map dataframes to bounding box annotations - -## Parameters - -| Name | Type | Description | Default | -|------------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------| -| `point_column_a` | str | Column name with 3d position data for the first point of the bounding box. Must be set if array_data is False (the default) | `None` | -| `point_column_b` | str | Column name with 3d position data for the second point of the bounding box. Must be set if array_data is False (the default) | `None` | -| `description_column` | str | Column name with string data for annotation descriptions | `None` | -| `linked_segmentation_column` | str | Column name for root ids to link to annotations | `None` | -| `tag_column` | str | Column name for categorical tag data. Tags must match those set in the annotation layer. | `None` | -| `group_column` | str | Column name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation. | `None` | -| `set_position` | bool | If set to True, moves the position to center on the first point in the data (using point_column_a). | `True` | -| `multipoint` | | If True, permits multiple points in a given row, sharing data in other columns. Each point row must have the same number of points. Default is False. | `False` | -| `collapse_groups` | | If True, groups are toggled closed in the annotation view. | `False` | -| `mapping_set` | | If set, assumes data is passed as a dictionary and uses this string to as the key for the data to use. | `None` | \ No newline at end of file diff --git a/docs/reference/statebuilder.ChainedStateBuilder.qmd b/docs/reference/statebuilder.ChainedStateBuilder.qmd deleted file mode 100644 index d9fc296..0000000 --- a/docs/reference/statebuilder.ChainedStateBuilder.qmd +++ /dev/null @@ -1,11 +0,0 @@ -# statebuilder.ChainedStateBuilder { #nglui.statebuilder.ChainedStateBuilder } - -`statebuilder.ChainedStateBuilder(self, statebuilders)` - -Builds a collection of states that sequentially add annotations based on a sequence of dataframes. - -## Parameters - -| Name | Type | Description | Default | -|-----------------|--------|-----------------------------------------------------------------------|------------| -| `statebuilders` | list | List of DataStateBuilders, in same order as dataframes will be passed | _required_ | \ No newline at end of file diff --git a/docs/reference/statebuilder.ImageLayerConfig.qmd b/docs/reference/statebuilder.ImageLayerConfig.qmd deleted file mode 100644 index 399e924..0000000 --- a/docs/reference/statebuilder.ImageLayerConfig.qmd +++ /dev/null @@ -1,18 +0,0 @@ -# statebuilder.ImageLayerConfig { #nglui.statebuilder.ImageLayerConfig } - -`statebuilder.ImageLayerConfig(self, source, name=None, active=False, contrast_controls=False, black=0.0, white=1.0)` - -Image layer configuration class. - -This provides the rules for setting up an image layer in neuroglancer. - -## Parameters - -| Name | Type | Description | Default | -|---------------------|--------|------------------------------------------------------------------------------------------------|------------| -| `source` | str | Cloudpath to an image source | _required_ | -| `name` | str | Name of the image layer. By default, 'img'. | `None` | -| `active` | bool | If True, makes the layer active in neuroglancer. Default is False. | `False` | -| `contrast_controls` | bool | If True, gives the layer a user-controllable brightness and contrast shader. Default is False. | `False` | -| `black` | float | If contrast_controls is True, sets the default black level. Default is 0.0. | `0.0` | -| `white` | float | If contrast_controls is True, sets the default white level. Default is 1.0. | `1.0` | \ No newline at end of file diff --git a/docs/reference/statebuilder.LineMapper.qmd b/docs/reference/statebuilder.LineMapper.qmd deleted file mode 100644 index 7d88e92..0000000 --- a/docs/reference/statebuilder.LineMapper.qmd +++ /dev/null @@ -1,20 +0,0 @@ -# statebuilder.LineMapper { #nglui.statebuilder.LineMapper } - -`statebuilder.LineMapper(self, point_column_a=None, point_column_b=None, description_column=None, linked_segmentation_column=None, tag_column=None, group_column=None, gather_linked_segmentations=True, share_linked_segmentations=False, set_position=True, multipoint=False, collapse_groups=False, split_positions=False, mapping_set=None)` - -Sets rules to map dataframes to line annotations - -## Parameters - -| Name | Type | Description | Default | -|------------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------| -| `point_column_a` | str | Column name with 3d position data for the first point of the line. Must be set if array_data is False (the default) | `None` | -| `point_column_b` | str | Column name with 3d position data for the first point of the line. Must be set if array_data is False (the default) | `None` | -| `description_column` | str | Column name with string data for annotation descriptions | `None` | -| `linked_segmentation_column` | str | Column name for root ids to link to annotations | `None` | -| `tag_column` | str | Column name for categorical tag data. Tags must match those set in the annotation layer. | `None` | -| `group_column` | str | Column name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation. | `None` | -| `set_position` | bool | If set to True, moves the position to center on the first point in the data (using point_column_a). | `True` | -| `multipoint` | | If True, permits multiple points in a given row, sharing data in other columns. Each point row must have the same number of points. Default is False. | `False` | -| `collapse_groups` | | If True, groups are toggled closed in the annotation view. | `False` | -| `mapping_set` | | If set, assumes data is passed as a dictionary and uses this string to as the key for the data to use. | `None` | \ No newline at end of file diff --git a/docs/reference/statebuilder.PointMapper.qmd b/docs/reference/statebuilder.PointMapper.qmd deleted file mode 100644 index 71b1f12..0000000 --- a/docs/reference/statebuilder.PointMapper.qmd +++ /dev/null @@ -1,19 +0,0 @@ -# statebuilder.PointMapper { #nglui.statebuilder.PointMapper } - -`statebuilder.PointMapper(self, point_column=None, description_column=None, linked_segmentation_column=None, tag_column=None, group_column=None, gather_linked_segmentations=True, share_linked_segmentations=False, set_position=True, multipoint=False, collapse_groups=False, split_positions=False, mapping_set=None)` - -Sets rules to map dataframes to point annotations - -## Parameters - -| Name | Type | Description | Default | -|------------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------| -| `point_column` | str | Column name with 3d position data | `None` | -| `description_column` | str | Column name with string data for annotation descriptions | `None` | -| `linked_segmentation_column` | str | Column name for root ids to link to annotations | `None` | -| `tag_column` | str | Column name for categorical tag data. Tags must match those set in the annotation layer. | `None` | -| `group_column` | str | Column name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation. | `None` | -| `set_position` | bool | If set to True, moves the position to center on the first point in the data. | `True` | -| `multipoint` | | If True, permits multiple points in a given row, sharing data in other columns. Default is False. | `False` | -| `collapse_groups` | | If True, groups are toggled closed in the annotation view. | `False` | -| `mapping_set` | | If given, assumes data is passed as a dictionary and uses this string to as the key for the data to use. | `None` | \ No newline at end of file diff --git a/docs/reference/statebuilder.SegmentationLayerConfig.qmd b/docs/reference/statebuilder.SegmentationLayerConfig.qmd deleted file mode 100644 index 2d3ed62..0000000 --- a/docs/reference/statebuilder.SegmentationLayerConfig.qmd +++ /dev/null @@ -1,23 +0,0 @@ -# statebuilder.SegmentationLayerConfig { #nglui.statebuilder.SegmentationLayerConfig } - -`statebuilder.SegmentationLayerConfig(self, source, name=None, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, active=False, alpha_selected=0.3, alpha_3d=1, alpha_unselected=0, split_point_map=None, view_kws=None, timestamp=None, data_resolution=None)` - -Configuration class for segmentation layers - -## Parameters - -| Name | Type | Description | Default | -|-----------------------|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------| -| `source` | str | Segmentation source | _required_ | -| `name` | (str, optional) | Layer name. | `None` | -| `selected_ids_column` | str or list-like, optional. | Column name (or list of column names) to use for selected ids. | `None` | -| `fixed_ids` | list-like, optional. | List of root ids to select directly. | `None` | -| `fixed_id_colors` | list-like, optional. | List of colors for fixed ids. Should be the same length as fixed_ids, although null entries can be padded with None values. | `None` | -| `color_column` | str, optional. | # at the begining. Column to use for color values for selected objects. Values should be RGB hex strings with a | `None` | -| `active` | bool, optional. | If True, makes the layer selected. Default is False. | `False` | -| `alpha_selected` | | Opacity of selected segmentations in the image layer. Optional, default is 0.3. | `0.3` | -| `alpha_3d` | | Opacity of meshes. Optional, default is 1. | `1` | -| `alpha_unselected` | | Opacity of unselected segments. Optional, default is 0. | `0` | -| `split_point_map` | | If not None, provides an object to map the dataframe input to multicut points. Default is None. | `None` | -| `view_kws` | dict, optional. | Keyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module. | `None` | -| `timestamp` | float or datetime, optional. | Timestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None. | `None` | \ No newline at end of file diff --git a/docs/reference/statebuilder.SphereMapper.qmd b/docs/reference/statebuilder.SphereMapper.qmd deleted file mode 100644 index ca11e22..0000000 --- a/docs/reference/statebuilder.SphereMapper.qmd +++ /dev/null @@ -1,20 +0,0 @@ -# statebuilder.SphereMapper { #nglui.statebuilder.SphereMapper } - -`statebuilder.SphereMapper(self, center_column=None, radius_column=None, description_column=None, linked_segmentation_column=None, tag_column=None, group_column=None, gather_linked_segmentations=True, share_linked_segmentations=False, z_multiplier=0.1, set_position=True, multipoint=False, collapse_groups=False, split_positions=False, mapping_set=None)` - -Sets rules to map dataframes to sphere annotations - -## Parameters - -| Name | Type | Description | Default | -|------------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------| -| `center_column` | str | Column name with 3d position data for the center of the sphere | `None` | -| `radius_column` | str | Column name with a radius for the sphere (in nm) | `None` | -| `description_column` | str | Column name with string data for annotation descriptions | `None` | -| `linked_segmentation_column` | str | Column name for root ids to link to annotations | `None` | -| `tag_column` | str | Column name for categorical tag data. Tags must match those set in the annotation layer. | `None` | -| `group_column` | str | Column name for grouping data. Data in this row should be numeric with possible NaNs. Rows with the same non-NaN value will be collected into a grouped annotation. | `None` | -| `set_position` | bool | If set to True, moves the position to center on the first point in the data. | `True` | -| `multipoint` | | If True, permits multiple points in a given row, sharing data in other columns. Each point row must have the same number of points. Default is False. | `False` | -| `collapse_groups` | | If True, groups are toggled closed in the annotation view. | `False` | -| `mapping_set` | | If set, assumes data is passed as a dictionary and uses this string to as the key for the data to use. | `None` | \ No newline at end of file diff --git a/docs/reference/statebuilder.SplitPointMapper.qmd b/docs/reference/statebuilder.SplitPointMapper.qmd deleted file mode 100644 index 84452b4..0000000 --- a/docs/reference/statebuilder.SplitPointMapper.qmd +++ /dev/null @@ -1,22 +0,0 @@ -# statebuilder.SplitPointMapper { #nglui.statebuilder.SplitPointMapper } - -`statebuilder.SplitPointMapper(self, id_column, point_column, team_column, team_names=['red', 'blue'], supervoxel_column=None, focus=True, mapping_set=None)` - -Mapper to create split points in a segmentation layer. - -## Parameters - -| Name | Type | Description | Default | -|---------------------|-------------|------------------------------------------------------------------------------------------------------------------------------------------------|-------------------| -| `id_column` | str | Column name for segment ids. The id column must contain the same id in all rows. | _required_ | -| `point_column` | str | Name of the column containing points in space. | _required_ | -| `team_column` | str | Name of the column describing the team for the points. The contents of the column should have two values, by default "red" and "blue". | _required_ | -| `team_names` | list | List of two values for the team names used in the team column. The first is mapped to red points, the second blue. Default is ["red", "blue"]. | `['red', 'blue']` | -| `supervoxel_column` | str or None | Name of a column providing supervoxel ids. If None (default), the supervoxel must be looked up on the server. | `None` | -| `focus` | bool | If True, sets the focus on the split tool and sets the position to the center of split points. Default is True. | `True` | - -## Returns - -| Type | Description | -|------------------------------------------------------------|---------------| -| SplitPointMapper instance to pass to a segmentation layer. | | \ No newline at end of file diff --git a/docs/reference/statebuilder.StateBuilder.qmd b/docs/reference/statebuilder.StateBuilder.qmd deleted file mode 100644 index 9616dfb..0000000 --- a/docs/reference/statebuilder.StateBuilder.qmd +++ /dev/null @@ -1,17 +0,0 @@ -# statebuilder.StateBuilder { #nglui.statebuilder.StateBuilder } - -`statebuilder.StateBuilder(self, layers=[], base_state=None, url_prefix=None, state_server=None, resolution=None, view_kws={}, client=None, target_site=None)` - -A class for schematic mapping data frames into neuroglancer states. - -## Parameters - -| Name | Type | Description | Default | -|----------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------| -| `layers` | | | `[]` | -| `base_state` | | | `None` | -| `url_prefix` | | Defaults to None, which will use https://neuromancer-seung-import.appspot.com | `None` | -| `state_server` | | | `None` | -| `resolution` | | | `None` | -| `view_kws` | | keys are: show_slices: Boolean sets if slices are shown in the 3d view. Defaults to False. layout: str `xy-3d`/`xz-3d`/`yz-3d` (sections plus 3d pane), `xy`/`yz`/`xz`/`3d` (only one pane), or `4panel` (all panes). Default is `xy-3d`. show_axis_lines: Boolean determines if the axis lines are shown in the middle of each view. show_scale_bar: Boolean toggles showing the scale bar. orthographic : Boolean toggles orthographic view in the 3d pane. position* : 3-element vector determines the centered location. zoom_image : float Zoom level for the imagery in units of nm per voxel. Defaults to 8. zoom_3d : float Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are more zoomed in. background_color : str or list Sets the background color of the 3d view. Arguments can be rgb values, hex colors, or named web colors. Defaults to black. | `{}` | -| `client` | | | `None` | \ No newline at end of file diff --git a/docs/reference/statebuilder.helpers.from_client.qmd b/docs/reference/statebuilder.helpers.from_client.qmd deleted file mode 100644 index 9bdbc7a..0000000 --- a/docs/reference/statebuilder.helpers.from_client.qmd +++ /dev/null @@ -1,21 +0,0 @@ -# statebuilder.helpers.from_client { #nglui.statebuilder.helpers.from_client } - -`statebuilder.helpers.from_client(client, image_name=None, segmentation_name=None, contrast=None)` - -Generate basic image and segmentation layers from a FrameworkClient - -## Parameters - -| Name | Type | Description | Default | -|---------------------|----------------------------------|----------------------------------------------------------------------------------------------------------------------------------|------------| -| `client` | caveclient.caveclient.CAVEclient | A CAVEclient with a specified datastack | _required_ | -| `image_name` | str | Name for the image layer, by default None. | `None` | -| `segmentation_name` | str | Name for the segmentation layer, by default None | `None` | -| `contrast` | list - like | Two elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set. | `None` | - -## Returns - -| Type | Description | -|--------------------------------------------|--------------------------------------------------------| -| nglui.statebuilder.layers.ImageLayerConfig | Image layer with default values from the client | -| nglui.statebuilder.layers.ImageLayerConfig | Segmentation layer with default values from the client | \ No newline at end of file diff --git a/docs/reference/statebuilder.helpers.make_line_statebuilder.qmd b/docs/reference/statebuilder.helpers.make_line_statebuilder.qmd deleted file mode 100644 index 5c61d9e..0000000 --- a/docs/reference/statebuilder.helpers.make_line_statebuilder.qmd +++ /dev/null @@ -1,26 +0,0 @@ -# statebuilder.helpers.make_line_statebuilder { #nglui.statebuilder.helpers.make_line_statebuilder } - -`statebuilder.helpers.make_line_statebuilder(client, point_column_a='pre_pt_position', point_column_b='post_pt_position', linked_seg_column='pt_root_id', description_column=None, tag_column=None, data_resolution=None, group_column=None, contrast=None, view_kws=None, point_layer_name='lines', color=None, split_positions=False)` - -Generate a state builder that puts points on a single column with a linked segmentaton id - -## Parameters - -| Name | Type | Description | Default | -|----------------------|-----------------------|----------------------------------------------------------------------------------------------------------------------------------|----------------------| -| `client` | caveclient.CAVEclient | CAVEclient configured for the datastack desired | _required_ | -| `point_column_a` | str | column in dataframe to pull points from. Defaults to "pre_pt_position". | `'pre_pt_position'` | -| `point_column_b` | str | column in dataframe to pull points from. Defaults to "post_pt_position". | `'post_pt_position'` | -| `linked_seg_column` | str | column to link to segmentation, None for no column. Defaults to "pt_root_id". | `'pt_root_id'` | -| `group_column` | str, or list | column(s) to group annotations by, None for no grouping (default=None) | `None` | -| `tag_column` | str | column to use for tags, None for no tags (default=None) | `None` | -| `description_column` | str | column to use for descriptions, None for no descriptions (default=None) | `None` | -| `contrast` | list | Two elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set. | `None` | -| `view_kws` | dict | dictionary of view keywords to configure neuroglancer view | `None` | -| `split_positions` | bool | whether the position column into x,y,z columns. Defaults to False. | `False` | - -## Returns - -| Type | Description | -|--------|---------------------------------------------------------| -| | A statebuilder to make points with linked segmentations | \ No newline at end of file diff --git a/docs/reference/statebuilder.helpers.make_neuron_neuroglancer_link.qmd b/docs/reference/statebuilder.helpers.make_neuron_neuroglancer_link.qmd deleted file mode 100644 index 2390c8c..0000000 --- a/docs/reference/statebuilder.helpers.make_neuron_neuroglancer_link.qmd +++ /dev/null @@ -1,43 +0,0 @@ -# statebuilder.helpers.make_neuron_neuroglancer_link { #nglui.statebuilder.helpers.make_neuron_neuroglancer_link } - -`statebuilder.helpers.make_neuron_neuroglancer_link(client, root_ids, return_as='html', shorten='always', show_inputs=False, show_outputs=False, sort_inputs=True, sort_outputs=True, sort_ascending=False, input_color=DEFAULT_POSTSYN_COLOR, output_color=DEFAULT_PRESYN_COLOR, contrast=None, timestamp=None, view_kws=None, point_column='ctr_pt_position', pre_pt_root_id_col='pre_pt_root_id', post_pt_root_id_col='post_pt_root_id', input_layer_name='syns_in', output_layer_name='syns_out', ngl_url=None, link_text='Neuroglancer Link', target_site=None)` - -function to create a neuroglancer link view of a neuron, optionally including inputs and outputs - -## Parameters - -| Name | Type | Description | Default | -|-----------------------|----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------| -| `client` | caveclient.CAVEclient | A CAVEclient configured for the datastack to visualize. | _required_ | -| `root_ids` | typing.Iterable\[int\] | The root_ids to build the visualization around. | _required_ | -| `return_as` | str | How to return the URL or state. Valid options are: - 'html': Returns an IPython HTML element. - 'json': Returns a dictionary representing the Neuroglancer state. - 'url': Returns a URL string. Defaults to 'html'. | `'html'` | -| `shorten` | str | Whether to shorten the link. Valid options are: - 'always': Always shorten the link. - 'if_long': Shorten the link if it exceeds MAX_URL_LENGTH. - 'never': Never shorten the link. Defaults to 'if_long'. | `'always'` | -| `show_inputs` | bool | Whether to include input synapses. Defaults to False. | `False` | -| `show_outputs` | bool | Whether to include output synapses. Defaults to False. | `False` | -| `sort_inputs` | bool | Whether to sort input synapses by presynaptic root id, ordered by synapse count. Defaults to True. | `True` | -| `sort_outputs` | bool | Whether to sort output synapses by presynaptic root id, ordered by postsynaptic synapse count. Defaults to True. | `True` | -| `sort_ascending` | bool | If sorting, whether to sort ascending (lowest synapse count to highest). Defaults to False. | `False` | -| `input_color` | list(float) or str | Color of input synapse points as an RGB list [0, 1], hex string, or common name. | `DEFAULT_POSTSYN_COLOR` | -| `output_color` | list(float) or str | Color of output synapse points as an RGB list [0, 1], hex string, or common name. | `DEFAULT_PRESYN_COLOR` | -| `contrast` | list | List of two floats between 0 and 1, specifying the black and white levels. If None, no contrast is set. | `None` | -| `timestamp` | datetime.datetime.datetime | Timestamp to use for the query. Defaults to None, which will use the materialized version. | `None` | -| `view_kws` | dict | Dictionary containing viewer settings for Neuroglancer. See nglui.StateBuilder for options. See the previous docstring for details on available keys. | `None` | -| `point_column` | str | Column to pull synapse positions from. Defaults to "ctr_pt_position". | `'ctr_pt_position'` | -| `pre_pt_root_id_col` | str | Column to pull presynaptic IDs for synapses from. Defaults to "pre_pt_root_id". | `'pre_pt_root_id'` | -| `post_pt_root_id_col` | str | Column to pull postsynaptic IDs for synapses from. Defaults to "post_pt_root_id". | `'post_pt_root_id'` | -| `input_layer_name` | str | Name of the layer for input synapses. Defaults to "syns_in". | `'syns_in'` | -| `output_layer_name` | str | Name of the layer for output synapses. Defaults to "syns_out". | `'syns_out'` | -| `ngl_url` | str | URL of the Neuroglancer instance to use. Defaults to the default viewer set in the datastack. | `None` | -| `link_text` | str | Text to use for the HTML return. Defaults to 'Neuroglancer Link'. | `'Neuroglancer Link'` | - -## Raises - -| Type | Description | -|------------|--------------------------------------------------------------------| -| ValueError | If the specified point column is not present in the synapse table. | - -## Returns - -| Type | Description | -|----------------------------|-----------------------------------------------------------------------------------| -| IPython.HTML, str, or dict | Representation of the Neuroglancer state, depending on the `return_as` parameter. | \ No newline at end of file diff --git a/docs/reference/statebuilder.helpers.make_point_statebuilder.qmd b/docs/reference/statebuilder.helpers.make_point_statebuilder.qmd deleted file mode 100644 index fc4506e..0000000 --- a/docs/reference/statebuilder.helpers.make_point_statebuilder.qmd +++ /dev/null @@ -1,25 +0,0 @@ -# statebuilder.helpers.make_point_statebuilder { #nglui.statebuilder.helpers.make_point_statebuilder } - -`statebuilder.helpers.make_point_statebuilder(client, point_column='pt_position', linked_seg_column='pt_root_id', data_resolution=None, group_column=None, tag_column=None, description_column=None, contrast=None, view_kws=None, point_layer_name='pts', color=None, split_positions=False)` - -Generate a state builder that puts points on a single column with a linked segmentaton id - -## Parameters - -| Name | Type | Description | Default | -|----------------------|-----------------------|----------------------------------------------------------------------------------------------------------------------------------|-----------------| -| `client` | caveclient.CAVEclient | CAVEclient configured for the datastack desired | _required_ | -| `point_column` | str | Column in dataframe to pull points from. Defaults to "pt_position". | `'pt_position'` | -| `linked_seg_column` | str | column to link to segmentation, None for no column. Defaults to "pt_root_id". | `'pt_root_id'` | -| `group_column` | str, or list | column(s) to group annotations by, None for no grouping (default=None) | `None` | -| `tag_column` | str, optional) | column to use for tags, None for no tags (default=None) | `None` | -| `description_column` | str | column to use for descriptions, None for no descriptions (default=None) | `None` | -| `contrast` | list | Two elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set. | `None` | -| `view_kws` | dict | dictionary of view keywords to configure neuroglancer view | `None` | -| `split_positions` | bool | whether the position column into x,y,z columns. Defaults to False. | `False` | - -## Returns - -| Type | Description | -|--------|---------------------------------------------------------| -| | A statebuilder to make points with linked segmentations | \ No newline at end of file diff --git a/docs/reference/statebuilder.helpers.make_pre_post_statebuilder.qmd b/docs/reference/statebuilder.helpers.make_pre_post_statebuilder.qmd deleted file mode 100644 index 744b56a..0000000 --- a/docs/reference/statebuilder.helpers.make_pre_post_statebuilder.qmd +++ /dev/null @@ -1,28 +0,0 @@ -# statebuilder.helpers.make_pre_post_statebuilder { #nglui.statebuilder.helpers.make_pre_post_statebuilder } - -`statebuilder.helpers.make_pre_post_statebuilder(client, show_inputs=False, show_outputs=False, contrast=None, view_kws=None, point_column='ctr_pt_position', pre_pt_root_id_col='pre_pt_root_id', post_pt_root_id_col='post_pt_root_id', dataframe_resolution_pre=None, dataframe_resolution_post=None, input_layer_name='syns_in', output_layer_name='syns_out', input_layer_color=DEFAULT_POSTSYN_COLOR, output_layer_color=DEFAULT_PRESYN_COLOR, split_positions=False)` - -Function to generate ChainedStateBuilder with optional pre and post synaptic -annotation layers - -## Parameters - -| Name | Type | Description | Default | -|-----------------------|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------| -| `client` | caveclient.CAVEclient | a CAVEclient configured for datastack to visualize | _required_ | -| `show_inputs` | bool | whether to show input synapses. Defaults to False. | `False` | -| `show_outputs` | bool | whether to show output synapses.. Defaults to False. | `False` | -| `contrast` | list | Two elements specifying the black level and white level as floats between 0 and 1, by default None. If None, no contrast is set. | `None` | -| `view_kws` | dict | view_kws to configure statebuilder, see nglui.StateBuilder. Defaults to None. keys are: show_slices: Boolean sets if slices are shown in the 3d view. Defaults to False. layout: str `xy-3d`/`xz-3d`/`yz-3d` (sections plus 3d pane), `xy`/`yz`/`xz`/`3d` (only one pane), or `4panel` (all panes). Default is `xy-3d`. show_axis_lines: Boolean determines if the axis lines are shown in the middle of each view. show_scale_bar: Boolean toggles showing the scale bar. orthographic : Boolean toggles orthographic view in the 3d pane. position* : 3-element vector determines the centered location. zoom_image : float Zoom level for the imagery in units of nm per voxel. Defaults to 8. zoom_3d : float Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are more zoomed in. | `None` | -| `point_column` | str | column to pull points for synapses from. Defaults to "ctr_pt_position". | `'ctr_pt_position'` | -| `pre_pt_root_id_col` | str | column to pull pre synaptic ids for synapses from. Defaults to "pre_pt_root_id". | `'pre_pt_root_id'` | -| `post_pt_root_id_col` | str | column to pull post synaptic ids for synapses from. Defaults to "post_pt_root_id". | `'post_pt_root_id'` | -| `input_layer_name` | str | name of layer for inputs. Defaults to "syns_in". | `'syns_in'` | -| `output_layer_name` | str | name of layer for outputs. Defaults to "syns_out". | `'syns_out'` | -| `split_positions` | bool | whether the position column is split into x,y,z columns. Defaults to False. | `False` | - -## Returns - -| Type | Description | -|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| | An instance of a ChainedStateBuilder configured to accept a list starting with None followed by optionally synapse input dataframe followed by optionally synapse output dataframe. | \ No newline at end of file diff --git a/docs/reference/statebuilder.helpers.make_state_url.qmd b/docs/reference/statebuilder.helpers.make_state_url.qmd deleted file mode 100644 index b49771d..0000000 --- a/docs/reference/statebuilder.helpers.make_state_url.qmd +++ /dev/null @@ -1,21 +0,0 @@ -# statebuilder.helpers.make_state_url { #nglui.statebuilder.helpers.make_state_url } - -`statebuilder.helpers.make_state_url(df, sb, client, ngl_url=None, target_site=None)` - -Generate a url from a neuroglancer state via a state server. - -## Parameters - -| Name | Type | Description | Default | -|---------------|------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------| -| `df` | pandas.pandas.DataFrame | Dataframe to pass through statebuilder | _required_ | -| `sb` | nglui.statebuilder.statebuilder.nglui.statebuilder.statebuilder.StateBuilder | Statebuilder to use to render data for link | _required_ | -| `client` | caveclient.CAVEclient | CAVEclient configured with a state server | _required_ | -| `ngl_url` | str | Neuroglancer deployment URL, by default None | `None` | -| `target_site` | str | Type of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use `seunglab` for a Seung-lab branch and either `mainline` or `cave-explorer` for the Cave Explorer or main Google branch. | `None` | - -## Returns - -| Type | Description | -|--------|-----------------------------------------| -| str | Url to the uploaded neuroglancer state. | \ No newline at end of file diff --git a/docs/reference/statebuilder.helpers.make_synapse_neuroglancer_link.qmd b/docs/reference/statebuilder.helpers.make_synapse_neuroglancer_link.qmd deleted file mode 100644 index 768c03f..0000000 --- a/docs/reference/statebuilder.helpers.make_synapse_neuroglancer_link.qmd +++ /dev/null @@ -1,38 +0,0 @@ -# statebuilder.helpers.make_synapse_neuroglancer_link { #nglui.statebuilder.helpers.make_synapse_neuroglancer_link } - -`statebuilder.helpers.make_synapse_neuroglancer_link(synapse_df, client, return_as='html', shorten='always', contrast=None, point_column='ctr_pt_position', dataframe_resolution=None, group_connections=True, link_pre_and_post=True, ngl_url=None, view_kws=None, pre_post_columns=None, neuroglancer_link_text='Neuroglancer Link', color=None, split_positions=False, target_site=None)` - -Generate a neuroglancer link from a synapse dataframe as returned from CAVEclient.materialize.synapse_query. - -## Parameters - -| Name | Type | Description | Default | -|--------------------------|----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------| -| `synapse_df` | pandas.pandas.DataFrame | DataFrame where each row represents a synapse. | _required_ | -| `client` | caveclient.caveclient.CAVEclient | A CAVEclient instance. | _required_ | -| `return_as` | str | How to return the URL. Valid options are: - 'html': Returns an IPython HTML element. - 'url': Returns a URL string. - 'json': Returns a dictionary representing the Neuroglancer state. Defaults to 'html'. | `'html'` | -| `shorten` | str | Whether to shorten the link. Valid options are: - 'always': Always shorten the link. - 'if_long': Shorten the link if it exceeds MAX_URL_LENGTH. - 'never': Never shorten the link. Defaults to 'always'. | `'always'` | -| `contrast` | list | List of two floats between 0 and 1, specifying the black and white levels. If None, no contrast is set. | `None` | -| `point_column` | str | Column in the DataFrame containing synapse positions. Defaults to 'ctr_pt_position'. | `'ctr_pt_position'` | -| `dataframe_resolution` | list | List of length 3, specifying the resolution units of the position column. If None, attempts to get the resolution from DataFrame metadata or client.info.viewer_resolution(). | `None` | -| `group_connections` | bool | Whether to group synapses within the same connection (between the same neurons). Defaults to True. | `True` | -| `link_pre_and_post` | bool | Whether to link the synapse annotations to the pre- and post-synaptic partners. Defaults to True. | `True` | -| `ngl_url` | str | URL of the Neuroglancer instance to use. Defaults to client.info.viewer_site() or DEFAULT_NGL. | `None` | -| `view_kws` | dict | Dictionary containing viewer settings for Neuroglancer. Available keys: - show_slices: Boolean, sets if slices are shown in the 3D view. - layout: str, specifies the viewer layout (e.g., 'xy-3d', '4panel'). - show_axis_lines: Boolean, determines if axis lines are shown. - show_scale_bar: Boolean, toggles the scale bar. - orthographic: Boolean, toggles orthographic view in the 3D pane. - position: 3-element vector, sets the centered location. - zoom_image: float, zoom level for the imagery in nm per voxel. - zoom_3d: float, zoom level for the 3D pane. | `None` | -| `pre_post_columns` | list | List of two strings, specifying the column names for pre- and post-synaptic root_ids. Defaults to ['pre_pt_root_id', 'post_pt_root_id']. | `None` | -| `neuroglancer_link_text` | str | Text to use in the returned HTML link. Defaults to 'Neuroglancer Link'. | `'Neuroglancer Link'` | -| `color` | list(float) or str | Color of synapse points as an RGB list [0, 1], hex string, or common name. | `None` | -| `split_positions` | bool | Whether the position column is split into x, y, and z columns. | `False` | -| `target_site` | str | Type of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use `seunglab` for a Seung-lab branch and either `mainline` or `cave-explorer` for the Cave Explorer or main Google branch. | `None` | - -## Returns - -| Type | Description | -|----------------------------|-----------------------------------------------------------------------------------| -| IPython.HTML, str, or dict | Representation of the Neuroglancer state, depending on the `return_as` parameter. | - -## Raises - -| Type | Description | -|------------|----------------------------------------------------------------| -| ValueError | If the specified `point_column` is not found in the DataFrame. | \ No newline at end of file diff --git a/docs/reference/statebuilder.helpers.make_url_robust.qmd b/docs/reference/statebuilder.helpers.make_url_robust.qmd deleted file mode 100644 index 5f4f7e5..0000000 --- a/docs/reference/statebuilder.helpers.make_url_robust.qmd +++ /dev/null @@ -1,24 +0,0 @@ -# statebuilder.helpers.make_url_robust { #nglui.statebuilder.helpers.make_url_robust } - -`statebuilder.helpers.make_url_robust(df, sb, client, shorten='if_long', ngl_url=None, max_url_length=MAX_URL_LENGTH, target_site=None)` - -Generate a url from a neuroglancer state. If too long, return through state server, -othewise return a url containing the data directly. - -## Parameters - -| Name | Type | Description | Default | -|------------------|------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------| -| `df` | pandas.pandas.DataFrame | Dataframe to pass through statebuilder | _required_ | -| `sb` | nglui.statebuilder.statebuilder.nglui.statebuilder.statebuilder.StateBuilder | Statebuilder to use to render data for link | _required_ | -| `client` | caveclient.CAVEclient | CAVEclient configured with a state server | _required_ | -| `shorten` | str | How to shorten link. one of 'if_long', 'always', 'never'. 'if_long' will use the state server to shorten links longer than nglui.statebuilder.MAX_URL_LENGTH (set to 1,750,000). 'always' will always use the state server to shorten the url 'never' will always return the full url. Defaults to "if_long". | `'if_long'` | -| `ngl_url` | str | Neuroglancer deployment URL, by default None | `None` | -| `max_url_length` | int | Maximum length of url to return directly, by default 1_750_000 | `MAX_URL_LENGTH` | -| `target_site` | str | Type of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use `seunglab` for a Seung-lab branch and either `mainline` or `cave-explorer` for the Cave Explorer or main Google branch. | `None` | - -## Returns - -| Type | Description | -|--------|-------------------------------------------------------| -| str | URL containing the state created by the statebuilder. | \ No newline at end of file diff --git a/docs/reference/statebuilder.helpers.package_state.qmd b/docs/reference/statebuilder.helpers.package_state.qmd deleted file mode 100644 index 413ca0e..0000000 --- a/docs/reference/statebuilder.helpers.package_state.qmd +++ /dev/null @@ -1,27 +0,0 @@ -# statebuilder.helpers.package_state { #nglui.statebuilder.helpers.package_state } - -`statebuilder.helpers.package_state(df, sb, client, shorten='if_long', return_as='url', ngl_url=None, link_text='Neuroglancer Link', target_site=None)` - -Automate creating a state from a statebuilder and -a dataframe, return it in the desired format, shortening if desired. - -# Convert below to numpydoc - -## Parameters - -| Name | Type | Description | Default | -|---------------|------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------| -| `df` | pandas.pandas.DataFrame | Dataframe to pass through statebuilder | _required_ | -| `sb` | nglui.statebuilder.statebuilder.nglui.statebuilder.statebuilder.StateBuilder | Statebuilder to use to render data for link | _required_ | -| `client` | caveclient.CAVEclient | CAVEclient configured with a state server | _required_ | -| `shorten` | str | How to shorten link. one of 'if_long', 'always', 'never'. 'if_long' will use the state server to shorten links longer than nglui.statebuilder.MAX_URL_LENGTH (set to 1,750,000). 'always' will always use the state server to shorten the url 'never' will always return the full url. Defaults to "if_long". | `'if_long'` | -| `return_as` | str | How to return the state. one of 'html', 'url', 'json'. 'html' will return an ipython clickable link 'url' will return a string with the url 'json' will return the state as a dictionary | `'url'` | -| `ngl_url` | str | Neuroglancer deployment URL, by default None | `None` | -| `link_text` | str | Text to use for the link, by default "Neuroglancer Link" | `'Neuroglancer Link'` | -| `target_site` | str | Type of neuroglancer deployment to build link for, by default None. This value overrides automatic checking based on the provided url. Use `seunglab` for a Seung-lab branch and either `mainline` or `cave-explorer` for the Cave Explorer or main Google branch. | `None` | - -## Returns - -| Type | Description | -|-------------------------------------|----------------------------------------| -| (IPython.display.HTML, str or dict) | state in format specified by return_as | \ No newline at end of file diff --git a/docs/reference/statebuilder.helpers.sort_dataframe_by_root_id.qmd b/docs/reference/statebuilder.helpers.sort_dataframe_by_root_id.qmd deleted file mode 100644 index 4ab9139..0000000 --- a/docs/reference/statebuilder.helpers.sort_dataframe_by_root_id.qmd +++ /dev/null @@ -1,21 +0,0 @@ -# statebuilder.helpers.sort_dataframe_by_root_id { #nglui.statebuilder.helpers.sort_dataframe_by_root_id } - -`statebuilder.helpers.sort_dataframe_by_root_id(df, root_id_column, ascending=False, num_column='n_times', drop=False)` - -Sort a dataframe so that rows belonging to the same root id are together, ordered by how many times the root id appears. - -## Parameters - -| Name | Type | Description | Default | -|------------------|-------------------------|------------------------------------------------------------------------------|-------------| -| `df` | pandas.pandas.DataFrame | dataframe to sort | _required_ | -| `root_id_column` | str | Column name to use for sorting root ids | _required_ | -| `ascending` | bool | Whether to sort ascending (lowest count to highest) or not, by default False | `False` | -| `num_column` | str | Temporary column name to use for count information, by default 'n_times' | `'n_times'` | -| `drop` | bool | If True, drop the additional column when returning. | `False` | - -## Returns - -| Type | Description | -|-------------------------|---------------| -| pandas.pandas.DataFrame | | \ No newline at end of file diff --git a/docs/reference/statebuilder.md b/docs/reference/statebuilder.md new file mode 100644 index 0000000..1e5fcc3 --- /dev/null +++ b/docs/reference/statebuilder.md @@ -0,0 +1,23 @@ +--- +title: Statebuilder +--- + +::: src.nglui.statebuilder.statebuilder + options: + show_source: false + heading_level: 2 + +::: src.nglui.statebuilder.layers + options: + show_source: false + heading_level: 2 + +::: src.nglui.statebuilder.mappers + options: + show_source: false + heading_level: 2 + +::: src.nglui.statebuilder.helpers + options: + show_source: false + heading_level: 2 \ No newline at end of file diff --git a/docs/reference/statebuilder.qmd b/docs/reference/statebuilder.qmd deleted file mode 100644 index c3e9364..0000000 --- a/docs/reference/statebuilder.qmd +++ /dev/null @@ -1,58 +0,0 @@ -# StateBuilder { #nglui.statebuilder.statebuilder.StateBuilder } - -`statebuilder.statebuilder.StateBuilder(self, layers=[], base_state=None, url_prefix=None, state_server=None, resolution=None, view_kws={}, client=None, target_site=None)` - -A class for schematic mapping data frames into neuroglancer states. - -## Parameters - -| Name | Type | Description | Default | -|----------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------| -| `layers` | | | `[]` | -| `base_state` | | | `None` | -| `url_prefix` | | Defaults to None, which will use https://neuromancer-seung-import.appspot.com | `None` | -| `state_server` | | | `None` | -| `resolution` | | | `None` | -| `view_kws` | | keys are: show_slices: Boolean sets if slices are shown in the 3d view. Defaults to False. layout: str `xy-3d`/`xz-3d`/`yz-3d` (sections plus 3d pane), `xy`/`yz`/`xz`/`3d` (only one pane), or `4panel` (all panes). Default is `xy-3d`. show_axis_lines: Boolean determines if the axis lines are shown in the middle of each view. show_scale_bar: Boolean toggles showing the scale bar. orthographic : Boolean toggles orthographic view in the 3d pane. position* : 3-element vector determines the centered location. zoom_image : float Zoom level for the imagery in units of nm per voxel. Defaults to 8. zoom_3d : float Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are more zoomed in. background_color : str or list Sets the background color of the 3d view. Arguments can be rgb values, hex colors, or named web colors. Defaults to black. | `{}` | -| `client` | | | `None` | - -## Methods - -| Name | Description | -| --- | --- | -| [initialize_state](#nglui.statebuilder.statebuilder.StateBuilder.initialize_state) | Generate a new Neuroglancer state with layers as needed for the schema. | -| [render_state](#nglui.statebuilder.statebuilder.StateBuilder.render_state) | Build a Neuroglancer state out of a DataFrame. | - -### initialize_state { #nglui.statebuilder.statebuilder.StateBuilder.initialize_state } - -`statebuilder.statebuilder.StateBuilder.initialize_state(base_state=None, target_site=None)` - -Generate a new Neuroglancer state with layers as needed for the schema. - -#### Parameters - -| Name | Type | Description | Default | -|--------------|--------|-----------------------------------------------------------------------------|-----------| -| `base_state` | str | Optional initial state to build on, described by its JSON. By default None. | `None` | - -### render_state { #nglui.statebuilder.statebuilder.StateBuilder.render_state } - -`statebuilder.statebuilder.StateBuilder.render_state(data=None, base_state=None, return_as='url', url_prefix=None, link_text='Neuroglancer Link', target_site=None)` - -Build a Neuroglancer state out of a DataFrame. - -#### Parameters - -| Name | Type | Description | Default | -|--------------|----------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------| -| `data` | pandas.pandas.DataFrame | DataFrame to use as a point source. By default None, for which it will return only the base_state and any fixed values. | `None` | -| `base_state` | dict | Initial state to build on, expressed as Neuroglancer JSON. By default None | `None` | -| `return_as` | \[url, nglui.statebuilder.statebuilder.StateBuilder.viewer, html, json, dict, shared\] | Choice of output types. Note that if a viewer is returned, the state is not reset. url : Returns the raw url describing the state viewer : Returns an EasyViewer object holding the state information html : Returns an HTML link to the url, useful for notebooks. json : Returns a JSON string describing the state. dict : Returns a dict version of the JSON state. By default 'url' | `'url'` | -| `url_prefix` | str | Neuroglancer URL prefix to use. By default None, for which it will open with the class default. | `None` | -| `link_text` | str | Text to use for the link when returning as html, by default 'Neuroglancer Link' | `'Neuroglancer Link'` | - -#### Returns - -| Type | Description | -|--------------------------------------------|---------------------------------------------------------------------------------------------------------------------| -| string or neuroglancer.neuroglancer.Viewer | A link to or viewer for a Neuroglancer state with layers, annotations, and selected objects determined by the data. | \ No newline at end of file diff --git a/docs/styles.css b/docs/styles.css deleted file mode 100644 index 2ddf50c..0000000 --- a/docs/styles.css +++ /dev/null @@ -1 +0,0 @@ -/* css styles */ diff --git a/docs/tutorials/index.qmd b/docs/tutorials/index.qmd deleted file mode 100644 index 1047f3e..0000000 --- a/docs/tutorials/index.qmd +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: Tutorials ---- - -# Tutorials - -Do one thing, then another. \ No newline at end of file diff --git a/docs/tutorials/parser.qmd b/docs/tutorials/parser.qmd deleted file mode 100644 index 99b322c..0000000 --- a/docs/tutorials/parser.qmd +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: Parser Tutorial ---- - -# Parser Tutorial - -Basics of how to use `nglui` parser. \ No newline at end of file diff --git a/docs/tutorials/statebuilder.qmd b/docs/tutorials/statebuilder.qmd deleted file mode 100644 index 48edc9c..0000000 --- a/docs/tutorials/statebuilder.qmd +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: "StateBuilder Tutorial" -toc: true -toc-location: left ---- - -The StateBuilder module is designed to allow rules-based generation of Neuroglancer states based on DataFrames or numpy arrays. - -## Background - -[Neuroglancer](https://github.com/google/neuroglancer) is a web application for viewing large volumetric imagery and segmentation data, as well as meshes and annotations like points or lines. -Data in Neuroglancer is organized into layers, where each layer is configured to show information like images, segmentation, or annotations. -Each layer can show one type of data and has different properties associated with it. -In addition, Neuroglancer also stores the exact view that the user sees — what location in the data is centered, the orientation and zoom level of the camera, and more. -Collectively, the information underlying both layers and the user view is refered to as the "state," which is stored as a collection of key/value pairs. - -StateBuilder follows this model by defining a set of rules for initializing layers. -For layers that contain properties like selected segment ids or annotations, this configuration involves specifying how to map DataFrame columns to selected segmentations or annotations such as synapses. -The general pattern is that you build up a collection of configurations for individual layers, assemble them into a `StateBuilder` object, and then pass a dataframe through this object to render out a state. - -## Simple Layers and StateBuilder - -```python -from nglui import statebuilder - -img = statebuilder.ImageLayerConfig( - source=client.info.image_source(), - contrast_controls=True, # this just puts in the code needed to manually adjust contrast -) - -seg = statebuilder.SegmentationLayerConfig( - source=client.info.segmentation_source(), -) -``` - -## Data-driven States \ No newline at end of file diff --git a/docs/usage/parser.md b/docs/usage/parser.md new file mode 100644 index 0000000..8e96cb5 --- /dev/null +++ b/docs/usage/parser.md @@ -0,0 +1,3 @@ +--- +title: State Parser +--- diff --git a/docs/usage/segprops.md b/docs/usage/segprops.md new file mode 100644 index 0000000..66dda13 --- /dev/null +++ b/docs/usage/segprops.md @@ -0,0 +1,5 @@ +--- +title: Segment Properties +--- + +Segment properties are a method of organizing information about segment IDs in a Neuroglancer segment \ No newline at end of file diff --git a/docs/usage/statebuilder.md b/docs/usage/statebuilder.md new file mode 100644 index 0000000..ef5e29e --- /dev/null +++ b/docs/usage/statebuilder.md @@ -0,0 +1,3 @@ +--- +title: StateBuilder +--- diff --git a/examples/dash_with_statebuilder.py b/examples/dash_with_statebuilder.py index b3bbb74..d581eda 100644 --- a/examples/dash_with_statebuilder.py +++ b/examples/dash_with_statebuilder.py @@ -5,10 +5,10 @@ github at https://github.com/AllenInstitute/DashDataFrame. ''' -import os import dash import pandas as pd from dashdataframe import configure_app + from nglui import statebuilder FLASK_PORT = 8880 diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..c5d2e41 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,87 @@ +site_name: NGLui Documentation +site_url: https://caveconnectome.github.io/nglui/ +repo_url: https://github.com/CAVEconnectome/nglui/ +repo_name: CAVEconnectome/NGLui + +nav: +- About: index.md +- Usage: + - usage/parser.md + - usage/segprops.md + - usage/statebuilder.md +- Function Reference: + - reference/parser.md + - reference/segprops.md + - reference/statebuilder.md + - reference/easyviewer.md +- Changelog: changelog.md + + +theme: + name: material + language: en + palette: + primary: blue grey + accent: deep orange + font: + text: Bitter + code: Inconsolata + icon: + repo: fontawesome/brands/github + features: + - navigation.indexes + - navigation.instant + # - navigation.footer + # - navigation.path + - navigation.prune + # - navigation.sections # toggle to have sections in side nav + - navigation.tabs # toggle to mainly use top nav + - navigation.tabs.sticky + - toc.follow + - toc.integrate # whether to include the toc in the main nav bar to the left + - navigation.top + - search.suggest + - search.highlight + - search.share + - content.code.copy + - header.autohide + +markdown_extensions: + - admonition + +plugins: + - mkdocstrings: + default_handler: python + handlers: + python: + import: + - https://docs.python.org/3/objects.inv + - https://numpy.org/doc/stable/objects.inv + - https://pandas.pydata.org/pandas-docs/stable/objects.inv + paths: [.] + options: + show_source: false + docstring_style: numpy + docstring_section_style: list # list, table, spacy + docstring_options: + ignore_init_summary: false + merge_init_into_class: true + allow_section_blank_line: false + show_root_heading: false + show_root_toc_entry: false + show_object_full_path: false + show_symbol_type_heading: false # whether to show "meth/func/etc" in the page + show_symbol_type_toc: false # whether to show "meth/func/etc" in the toc + signature_crossrefs: true # https://mkdocstrings.github.io/python/usage/configuration/signatures/#signature_crossrefs + members_order: alphabetical # can be source + group_by_category: true # order is attributes, classes, functions, modules + summary: true + show_if_no_docstring: false + show_docstring_attributes: false + annotations_path: brief # https://mkdocstrings.github.io/python/usage/configuration/signatures/#annotations_path + show_signature: true + separate_signature: false + show_signature_annotations: false + unwrap_annotated: false # https://mkdocstrings.github.io/python/usage/configuration/signatures/#unwrap_annotated + heading_level: 2 + inherited_members: true diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..bd42a9a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,53 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "nglui" +dynamic = ["version"] +description = "Framework for data-driven generation of neuroglancer states." +readme = "README.md" +license = "MIT" +authors = [ + { name = "Derrick Brittain", email = "caseysm@gmail.com" }, + { name = "Casey Schneider-Mizell" }, + { name = "Forrest Collman" }, +] +dependencies = [ + "caveclient>=5.14.0", + "ipython", + "neuroglancer", + "numpy>=1.11.0", + "pandas>=1.0.0", + "requests", + "six", + "tables", + "webcolors", +] +classifiers = [ + "License :: OSI Approved :: MIT License", +] + +[project.urls] +Homepage = "https://github.com/seung-lab/NeuroglancerAnnotationUI" + +[tool.hatch.version] +path = "src/nglui/__init__.py" + +[tool.hatch.build.targets.sdist] +include = [ + "/src", +] + +[[tool.hatch.envs.hatch-test.matrix]] +python = ["3.9", "3.10", "3.11", "3.12"] + +[tool.hatch.envs.docs] +dependencies = [ + "mkdocs", + "mkdocs-material", + "mkdocstrings[python]", +] +[tool.hatch.envs.docs.scripts] +build = "mkdocs build --clean --strict" +serve = "mkdocs serve --dev-addr localhost:8000" diff --git a/setup.py b/setup.py index 8b4da53..da4b965 100644 --- a/setup.py +++ b/setup.py @@ -1,8 +1,8 @@ -from setuptools import setup -import re -import os import codecs -from setuptools import find_packages +import os +import re + +from setuptools import find_packages, setup here = os.path.abspath(os.path.dirname(__file__)) @@ -21,10 +21,10 @@ def find_version(*file_paths): raise RuntimeError("Unable to find version string.") -with open('requirements.txt', 'r') as f: +with open('requirements.txt') as f: required = f.read().splitlines() -with open('test_requirements.txt', 'r') as f: +with open('test_requirements.txt') as f: test_required = f.read().splitlines() setup( @@ -38,8 +38,7 @@ def find_version(*file_paths): url="https://github.com/seung-lab/NeuroglancerAnnotationUI", packages=find_packages('src'), package_dir={'': 'src'}, - setup_requires=['pytest-runner'], tests_require=test_required, include_package_data=True, - install_requires=[required], # external packages as dependencies + install_requires=required, # external packages as dependencies ) diff --git a/src/nglui/__init__.py b/src/nglui/__init__.py index 1a21507..67d58ad 100644 --- a/src/nglui/__init__.py +++ b/src/nglui/__init__.py @@ -2,5 +2,6 @@ from . import statebuilder from . import parser +from . import segmentprops -__version__ = "3.1.0" +__version__ = "3.2.0" diff --git a/src/nglui/easyviewer/__init__.py b/src/nglui/easyviewer/__init__.py index 3d45cdd..817da1f 100644 --- a/src/nglui/easyviewer/__init__.py +++ b/src/nglui/easyviewer/__init__.py @@ -1,11 +1,18 @@ -from .ev_base import EasyViewerSeunglab, EasyViewerMainline +from .ev_base import EasyViewerMainline, EasyViewerSeunglab + def EasyViewer( - target_site='seunglab', + target_site="seunglab", ): - if target_site == 'seunglab' or target_site is None: + if target_site == "seunglab" or target_site is None: return EasyViewerSeunglab() - elif target_site == 'mainline' or target_site == 'cave-explorer': + elif ( + target_site == "mainline" + or target_site == "cave-explorer" + or target_site == "spelunker" + ): return EasyViewerMainline() else: - raise ValueError(f'Unknown target: {target_site}. Must be one of "seunglab" or "mainline"/"cave-explorer"') + raise ValueError( + f'Unknown target: {target_site}. Must be one of "seunglab" or "spelunker/mainline"/"cave-explorer"' + ) diff --git a/src/nglui/easyviewer/ev_base/__init__.py b/src/nglui/easyviewer/ev_base/__init__.py index 4bf9211..3d1e81c 100644 --- a/src/nglui/easyviewer/ev_base/__init__.py +++ b/src/nglui/easyviewer/ev_base/__init__.py @@ -1,2 +1,2 @@ from .mainline import EasyViewerMainline -from .seunglab import EasyViewerSeunglab \ No newline at end of file +from .seunglab import EasyViewerSeunglab diff --git a/src/nglui/easyviewer/ev_base/annotation_compatibility.py b/src/nglui/easyviewer/ev_base/annotation_compatibility.py index fcabc2a..d8cc1bc 100644 --- a/src/nglui/easyviewer/ev_base/annotation_compatibility.py +++ b/src/nglui/easyviewer/ev_base/annotation_compatibility.py @@ -1,8 +1,8 @@ from neuroglancer import ( + AxisAlignedBoundingBoxAnnotation, + EllipsoidAnnotation, LineAnnotation, PointAnnotation, - EllipsoidAnnotation, - AxisAlignedBoundingBoxAnnotation, ) diff --git a/src/nglui/easyviewer/ev_base/base.py b/src/nglui/easyviewer/ev_base/base.py index 5796f65..1f198f2 100644 --- a/src/nglui/easyviewer/ev_base/base.py +++ b/src/nglui/easyviewer/ev_base/base.py @@ -1,18 +1,18 @@ -from . import utils -from typing import Union, List, Dict, Tuple, Optional - from abc import ABC, abstractmethod +from typing import Dict, List, Optional, Tuple, Union + +from . import utils SEGMENTATION_LAYER_TYPES = ["segmentation", "segmentation_with_graph"] + class EasyViewerBase(ABC): def __init__(self): self._default_viewer_url = None - pass def __repr__(self): return self.as_url() - + def __repr_html__(self): return f'Viewer' @@ -29,12 +29,12 @@ def add_layers( ) -> None: self.set_resolution(resolution) with self.txn() as s: - for ln, kws in image_layers.items(): - s.layers[ln] = self._ImageLayer(**kws) - for ln, kws in segmentation_layers.items(): - self._SegmentationLayer(s, **kws) - for ln, kws in annotation_layers.items(): - s.layers[ln] = self._AnnotationLayer(**kws) + for ln, kws in image_layers.items(): + s.layers[ln] = self._ImageLayer(**kws) + for ln, kws in segmentation_layers.items(): + self._SegmentationLayer(s, **kws) + for ln, kws in annotation_layers.items(): + s.layers[ln] = self._AnnotationLayer(**kws) @abstractmethod def _ImageLayer(self, source, **kwargs): @@ -56,19 +56,22 @@ def add_segmentation_layer(self, layer_name, source, **kwargs): source (str): source of neuroglancer segment layer """ with self.txn() as s: - s.layers[layer_name] = self._SegmentationLayer( - source=source, **kwargs - ) - - def add_image_layer(self, layer_name, source, **kwargs): + s.layers[layer_name] = self._SegmentationLayer(source=source, **kwargs) + + def add_image_layer(self, layer_name, source, contrast_range=None, **kwargs): """Add segmentation layer to viewer instance. Attributes: layer_name (str): name of layer to be displayed in neuroglancer ui. source (str): source of neuroglancer image layer + contrast_range = (float, float): contrast range for image layer either in 0-1 (floats) or 0-255 (ints). """ with self.txn() as s: s.layers[layer_name] = self._ImageLayer(source=source, **kwargs) + if contrast_range is not None: + self.add_contrast_shader( + layer_name, black=contrast_range[0], white=contrast_range[1] + ) @abstractmethod def set_resolution(self, resolution) -> None: @@ -76,9 +79,9 @@ def set_resolution(self, resolution) -> None: def add_contrast_shader(self, layer_name, black=0.0, white=1.0): shader_text = f"#uicontrol float black slider(min=0, max=1, default={black})\n#uicontrol float white slider(min=0, max=1, default={white})\nfloat rescale(float value) {{\n return (value - black) / (white - black);\n}}\nvoid main() {{\n float val = toNormalized(getDataValue());\n if (val < black) {{\n emitRGB(vec3(0,0,0));\n }} else if (val > white) {{\n emitRGB(vec3(1.0, 1.0, 1.0));\n }} else {{\n emitGrayscale(rescale(val));\n }}\n}}\n" - self._update_layer_shader(layer_name, shader_text) + self.update_shader(layer_name, shader_text) - def _update_layer_shader(self, layer_name, shader_text): + def update_shader(self, layer_name, shader_text): with self.txn() as s: s.layers[layer_name]._json_data["shader"] = shader_text @@ -113,24 +116,24 @@ def clear_annotation_layers(self, layer_names): s.layers[ln].annotations._data = [] def add_annotations( - self, - layer_name: str, - annotations: List, - ): + self, + layer_name: str, + annotations: List, + ): with self.txn() as s: s.layers[layer_name].annotations.extend(annotations) def add_multilayer_annotations( - self, - layer_anno_dict: Dict[str, List], - ): + self, + layer_anno_dict: Dict[str, List], + ): """ layer_anno_dict is a layer_name to annotation list dict. """ with self.txn() as s: for ln, annos in layer_anno_dict.items(): if annos is None: - continue + continue s.layers[ln].annotations.extend(annos) def remove_annotations(self, layer_name, anno_ids): @@ -149,7 +152,6 @@ def remove_annotations(self, layer_name, anno_ids): except: self.update_message("Could not remove annotation") - @abstractmethod def add_annotation_tags(self, layer_name, tags): pass @@ -178,13 +180,13 @@ def select_annotation(self, layer_name, anno_id): @property def layer_names(self): return [l.name for l in self.state.layers] - + def selected_objects(self, segmentation_layer): return list(self.state.layers[segmentation_layer].segments) @abstractmethod def add_selected_objects( - self, + self, segmentation_layer: str, oids: List[int], colors: Optional[Union[List, Dict]] = None, @@ -195,7 +197,7 @@ def add_selected_objects( def set_view_options( self, show_slices: Optional[bool] = None, - layout: Optional[str]=None, + layout: Optional[str] = None, show_axis_lines: Optional[bool] = None, show_scale_bar: Optional[bool] = None, orthographic: Optional[bool] = None, @@ -203,7 +205,7 @@ def set_view_options( zoom_image: Optional[float] = None, zoom_3d: Optional[float] = None, background_color: Optional[Tuple[float]] = None, - )->None: + ) -> None: pass @abstractmethod @@ -211,7 +213,7 @@ def set_segmentation_view_options( self, layer_name: str, alpha_selected: Optional[float] = None, - alpha_3d: Optional[float] =None, + alpha_3d: Optional[float] = None, alpha_unselected: Optional[float] = None, **kwargs, ): @@ -236,7 +238,6 @@ def assign_colors(self, layer_name, seg_colors): seg_colors : dict dict with root ids as keys and colors as values. """ - pass @abstractmethod def set_multicut_points( @@ -250,7 +251,7 @@ def set_multicut_points( focus=True, ): pass - + @staticmethod @abstractmethod def point_annotation( @@ -316,4 +317,3 @@ def group_annotations( children_visible=True, ): pass - diff --git a/src/nglui/easyviewer/ev_base/mainline.py b/src/nglui/easyviewer/ev_base/mainline.py index 37ee24d..17b4d2c 100644 --- a/src/nglui/easyviewer/ev_base/mainline.py +++ b/src/nglui/easyviewer/ev_base/mainline.py @@ -10,12 +10,14 @@ use_ngl = False else: use_ngl = True +from typing import Dict, List, Optional, Tuple, Union +from warnings import warn + +from numpy import integer, issubdtype + from . import utils +from .base import SEGMENTATION_LAYER_TYPES, EasyViewerBase -from warnings import warn -from .base import EasyViewerBase, SEGMENTATION_LAYER_TYPES -from typing import Union, List, Dict, Tuple, Optional -from numpy import issubdtype, integer def nanometer_dimension(resolution): return neuroglancer.CoordinateSpace( @@ -24,14 +26,18 @@ def nanometer_dimension(resolution): units="nm", ) + class UnservedViewer(neuroglancer.viewer_base.UnsynchronizedViewerBase): def __init__(self, **kwargs): super().__init__(**kwargs) - self._default_viewer_url = kwargs.pop('default_viewer_url', utils.default_mainline_neuroglancer_base) + self._default_viewer_url = kwargs.pop( + "default_viewer_url", utils.default_mainline_neuroglancer_base + ) def get_server_url(self): return self._default_viewer_url + class EasyViewerMainline(UnservedViewer, EasyViewerBase): def __init__(self, **kwargs): super(UnservedViewer, self).__init__(**kwargs) @@ -44,11 +50,14 @@ def load_url(self, url) -> None: def _ImageLayer(self, source, **kwargs): return neuroglancer.viewer_state.ImageLayer(source=source, **kwargs) - + def _SegmentationLayer(self, source, **kwargs): - source = utils.parse_graphene_header(source, target='mainline') + if isinstance(source, str): + source = utils.parse_graphene_header(source, target="mainline") + elif isinstance(source, list): + source = [utils.parse_graphene_header(s, target="mainline") for s in source] return neuroglancer.viewer_state.SegmentationLayer(source=source, **kwargs) - + def _AnnotationLayer(self, *args, **kwargs): return neuroglancer.viewer_state.LocalAnnotationLayer(*args, **kwargs) @@ -57,8 +66,7 @@ def set_resolution(self, resolution) -> None: s.dimensions = nanometer_dimension(resolution) def set_state_server(self, state_server) -> None: - Warning('State server is set by neuroglancer deployment for this viewer type.') - pass + Warning("State server is set by neuroglancer deployment for this viewer type.") def add_annotation_layer( self, @@ -71,17 +79,17 @@ def add_annotation_layer( tags=None, ) -> None: if layer_name is None: - layer_name = 'annos' + layer_name = "annos" if layer_name in [l.name for l in self.state.layers]: - raise ValueError("Layer name already exists") + raise ValueError("Layer name already exists") if filter_by_segmentation: - filter_by_segmentation = ['segments'] + filter_by_segmentation = ["segments"] else: filter_by_segmentation = [] if linked_segmentation_layer is not None: - linked_segmentation_layer = {'segments': linked_segmentation_layer} + linked_segmentation_layer = {"segments": linked_segmentation_layer} else: linked_segmentation_layer = {} @@ -96,10 +104,10 @@ def add_annotation_layer( s.layers[layer_name].annotationColor = utils.parse_color(color) if tags is not None: - warn('Tags are not supported by this viewer type.') - + warn("Tags are not supported by this viewer type.") + def add_annotation_tags(self, layer_name, tags): - warn('Annotation tags are not supported by this viewer type.') + warn("Annotation tags are not supported by this viewer type.") def as_url( self, @@ -111,32 +119,47 @@ def as_url( prefix = utils.default_mainline_neuroglancer_base ngl_url = neuroglancer.to_url(self.state, prefix=prefix) if as_html: - return '{}'.format(ngl_url, link_text) + return f'{link_text}' else: return ngl_url def set_selected_layer(self, layer_name): with self.txn() as s: - s.selected_layer = neuroglancer.SelectedLayerState({'visible': True, 'layer': layer_name}) + s.selected_layer = neuroglancer.SelectedLayerState( + {"visible": True, "layer": layer_name} + ) + + def add_contrast_shader(self, layer_name, black=0, white=255): + if isinstance(black, float) and black < 1: + black = int(black * 255) + if isinstance(white, float) and white < 1: + white = int(white * 255) + with self.txn() as s: + s.layers[ + layer_name + ].shader_controls = neuroglancer.viewer_state.ShaderControls( + {"normalized": {"range": [black, white]}} + ) def select_annotation(self, layer_name, annotation_id): # self.set_selected_layer(layer_name) - raise Warning('Annotation selection is not supported by this viewer type.') + raise Warning("Annotation selection is not supported by this viewer type.") def assign_colors(self, layer_name, seg_colors): with self.txn() as s: s.layers[layer_name].segmentColors = seg_colors def add_selected_objects( - self, - segmentation_layer: str, - oids: List[int], - colors: Optional[Union[List, Dict]] = None - ) -> None: + self, + segmentation_layer: str, + oids: List[int], + colors: Optional[Union[List, Dict]] = None, + ) -> None: if issubdtype(type(oids), integer): oids = [oids] with self.txn() as s: - s.layers[segmentation_layer].segments.update(oids) + for oid in oids: + s.layers[segmentation_layer].segments.add(oid) if colors is not None: if isinstance(colors, dict): self.assign_colors(segmentation_layer, colors) @@ -144,10 +167,38 @@ def add_selected_objects( seg_colors = {oid: clr for oid, clr in zip(oids, colors)} self.assign_colors(segmentation_layer, seg_colors) + def add_segmentation_layer(self, layer_name, source, **kwargs): + """Add segmentation layer to viewer instance. + + Attributes: + layer_name (str): name of layer to be displayed in neuroglancer ui. + source (str): source of neuroglancer segment layer + """ + with self.txn() as s: + s.layers[layer_name] = self._SegmentationLayer(source=source, **kwargs) + + def append_source_to_segmentation_layer(self, layer_name, source): + """Append source or sources to an existing segmentation layer. + + Parameters + ---------- + layer_name : str + Name of an existing layer + source : str or list of str + Source or sources to add to the layer + """ + if isinstance(source, str): + source = [source] + source = [utils.parse_graphene_header(s, target="mainline") for s in source] + + with self.txn() as s: + for src in source: + s.layers[layer_name].source.append({"url": src}) + def set_view_options( self, show_slices: Optional[bool] = None, - layout: Optional[str]=None, + layout: Optional[str] = None, show_axis_lines: Optional[bool] = None, show_scale_bar: Optional[bool] = None, orthographic: Optional[bool] = None, @@ -155,7 +206,7 @@ def set_view_options( zoom_image: Optional[float] = None, zoom_3d: Optional[float] = None, background_color: Optional[Tuple[float]] = None, - )->None: + ) -> None: with self.txn() as s: if show_slices is not None: s.showSlices = show_slices @@ -164,9 +215,9 @@ def set_view_options( if show_axis_lines is not None: s.showAxisLines = show_axis_lines if show_scale_bar is not None: - s.showScaleBar = show_scale_bar + s.showScaleBar = show_scale_bar if orthographic is not None: - s.layout.orthographic_projection = orthographic + s.layout.orthographic_projection = orthographic if position is not None: s.position = position if zoom_image is not None: @@ -176,12 +227,11 @@ def set_view_options( if background_color is not None: s.perspectiveViewBackgroundColor = utils.parse_color(background_color) - def set_segmentation_view_options( self, layer_name: str, alpha_selected: Optional[float] = None, - alpha_3d: Optional[float] =None, + alpha_3d: Optional[float] = None, alpha_unselected: Optional[float] = None, silhouette_value: Optional[float] = None, **kwargs, @@ -198,7 +248,6 @@ def set_segmentation_view_options( l.notSelectedAlpha = alpha_unselected if silhouette_value is not None: l.meshSilhouetteRendering = silhouette_value - def set_timestamp( self, @@ -207,7 +256,6 @@ def set_timestamp( ): if timestamp is not None: warn("Timestamp setting is not yet enabled for this viewer type.") - pass def set_multicut_points( self, @@ -219,7 +267,7 @@ def set_multicut_points( supervoxels_blue=None, focus=True, ): - Warning('Setting multicut is not yet enabled for this viewer type') + Warning("Setting multicut is not yet enabled for this viewer type") @staticmethod def point_annotation( @@ -238,7 +286,7 @@ def point_annotation( description=description, segments=[[int(x) for x in segments]], ) - + @staticmethod def line_annotation( pointA, @@ -278,7 +326,7 @@ def ellipsoid_annotation( description=description, segments=[[int(x) for x in segments]], ) - + @staticmethod def bounding_box_annotation( pointA, @@ -310,7 +358,4 @@ def group_annotations( children_visible=True, **kwargs, ): - Warning( - 'Annotation groups are not yet supported by this viewer type.' - ) - pass \ No newline at end of file + Warning("Annotation groups are not yet supported by this viewer type.") diff --git a/src/nglui/easyviewer/ev_base/nglite/__init__.py b/src/nglui/easyviewer/ev_base/nglite/__init__.py index e775346..f4ba20d 100644 --- a/src/nglui/easyviewer/ev_base/nglite/__init__.py +++ b/src/nglui/easyviewer/ev_base/nglite/__init__.py @@ -19,4 +19,4 @@ from .equivalence_map import EquivalenceMap from .url_state import to_url, parse_url from . import skeleton -from .annotation import * \ No newline at end of file +from .annotation import * diff --git a/src/nglui/easyviewer/ev_base/nglite/equivalence_map.py b/src/nglui/easyviewer/ev_base/nglite/equivalence_map.py index 4420014..2bef24f 100644 --- a/src/nglui/easyviewer/ev_base/nglite/equivalence_map.py +++ b/src/nglui/easyviewer/ev_base/nglite/equivalence_map.py @@ -12,14 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -from __future__ import absolute_import import copy import six -class EquivalenceMap(object): +class EquivalenceMap: """Union-find data structure""" supports_readonly = True diff --git a/src/nglui/easyviewer/ev_base/nglite/json_utils.py b/src/nglui/easyviewer/ev_base/nglite/json_utils.py index 3d0b068..3f64713 100644 --- a/src/nglui/easyviewer/ev_base/nglite/json_utils.py +++ b/src/nglui/easyviewer/ev_base/nglite/json_utils.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from __future__ import absolute_import import collections import json @@ -34,9 +33,7 @@ def json_encoder_default(obj): return str(obj) elif isinstance(obj, np.floating): return float(obj) - elif isinstance(obj, np.ndarray): - return list(obj) - elif isinstance(obj, (set, frozenset)): + elif isinstance(obj, (frozenset, np.ndarray, set)): return list(obj) raise TypeError diff --git a/src/nglui/easyviewer/ev_base/nglite/json_wrappers.py b/src/nglui/easyviewer/ev_base/nglite/json_wrappers.py index bad4340..f1cd28b 100644 --- a/src/nglui/easyviewer/ev_base/nglite/json_wrappers.py +++ b/src/nglui/easyviewer/ev_base/nglite/json_wrappers.py @@ -13,7 +13,6 @@ # limitations under the License. """Facilities for converting JSON <-> Python objects""" -from __future__ import absolute_import import collections import copy @@ -24,8 +23,6 @@ import numpy as np import six -from six.moves import range - from .json_utils import encode_json_for_repr @@ -39,7 +36,7 @@ def to_json(value): return method() -class JsonObjectWrapper(object): +class JsonObjectWrapper: supports_readonly = True __slots__ = ("_json_data", "_cached_wrappers", "_lock", "_readonly") @@ -75,7 +72,7 @@ def __deepcopy__(self, memo): return type(self)(copy.deepcopy(self.to_json(), memo)) def __repr__(self): - return u"%s(%s)" % (type(self).__name__, encode_json_for_repr(self.to_json())) + return "%s(%s)" % (type(self).__name__, encode_json_for_repr(self.to_json())) def _get_wrapped(self, key, wrapped_type): with self._lock: @@ -167,7 +164,7 @@ def modified_wrapper(value, **kwargs): return modified_wrapper -class MapBase(object): +class MapBase: pass @@ -257,7 +254,7 @@ def wrapper(x, _readonly=False): def typed_list(wrapped_type, validator=None): validator = _normalize_validator(wrapped_type, validator) - class TypedList(object): + class TypedList: supports_readonly = True supports_validation = True diff --git a/src/nglui/easyviewer/ev_base/nglite/skeleton.py b/src/nglui/easyviewer/ev_base/nglite/skeleton.py index 8d15b37..2284656 100644 --- a/src/nglui/easyviewer/ev_base/nglite/skeleton.py +++ b/src/nglui/easyviewer/ev_base/nglite/skeleton.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from __future__ import absolute_import import collections import io @@ -22,7 +21,7 @@ import six -class Skeleton(object): +class Skeleton: def __init__(self, vertex_positions, edges, vertex_attributes=None): self.vertex_positions = np.array(vertex_positions, dtype=" None: with self.txn() as s: s._json_data["jsonStateServer"] = state_server + def add_segmentation_layer(self, layer_name, source, **kwargs): + """Add segmentation layer to viewer instance. + + Attributes: + layer_name (str): name of layer to be displayed in neuroglancer ui. + source (str): source of neuroglancer segment layer + """ + if type(source) is not str: + source = source[0] + warn("Only using first source in list for seung-lab segmentation layer") + super().add_segmentation_layer(layer_name, source, **kwargs) + def add_annotation_layer( self, layer_name=None, @@ -100,7 +115,7 @@ def as_url( ) # 'seunglab' hard-coded because of file. ngl_url = neuroglancer.to_url(self.state, prefix=prefix) if as_html: - return '{}'.format(ngl_url, link_text) + return f'{link_text}' else: return ngl_url diff --git a/src/nglui/easyviewer/ev_base/utils.py b/src/nglui/easyviewer/ev_base/utils.py index 096e4a1..ace1e71 100644 --- a/src/nglui/easyviewer/ev_base/utils.py +++ b/src/nglui/easyviewer/ev_base/utils.py @@ -1,12 +1,15 @@ +import numbers +import re +from urllib.parse import urlparse + import numpy as np import pandas as pd import webcolors -import re -import numbers -from urllib.parse import urlparse default_seunglab_neuroglancer_base = "https://neuromancer-seung-import.appspot.com/" default_mainline_neuroglancer_base = "https://ngl.cave-explorer.org/" +MAINLINE_NAMES = ["mainline", "cave-explorer", "spelunker"] + def omit_nones(seg_list): if seg_list is None or np.all(pd.isna(seg_list)): @@ -18,6 +21,7 @@ def omit_nones(seg_list): else: return seg_list + def parse_color(clr): if clr is None: return None @@ -34,36 +38,42 @@ def parse_color(clr): else: return webcolors.rgb_to_hex([int(255 * x) for x in clr]) + def parse_graphene_header(source, target): qry = urlparse(source) - if qry.scheme=='graphene': - if target == 'seunglab': + if qry.scheme == "graphene": + if target == "seunglab": return _parse_to_seunglab(qry) - elif target == 'mainline' or target == 'cave-explorer': + elif target == "mainline" or target == "cave-explorer": return _parse_to_mainline(qry) else: return source + def _parse_to_seunglab(qry): return f"{qry.scheme}://https:{qry.path}" + def _parse_to_mainline(qry): - if 'https' in qry.netloc: + if "https" in qry.netloc: return f"{qry.scheme}://middleauth+https:{qry.path}" else: return f"{qry.scheme}://middleauth+http:{qry.path}" - + + def neuroglancer_url(url, target_site): """ Check neuroglancer info to determine which kind of site a neuroglancer URL is. """ if url is not None: return url - elif target_site == 'seunglab': + elif target_site is None: + return None + elif target_site == "seunglab": return default_seunglab_neuroglancer_base - elif target_site == 'mainline' or target_site == 'cave-explorer': + elif target_site in MAINLINE_NAMES: return default_mainline_neuroglancer_base else: - raise ValueError("Must specify either a URL or a target site (one of 'seunglab' or 'mainline'/'cave-explorer')") - - \ No newline at end of file + raise ValueError( + f"Must specify either a URL or a target site (either 'seunglab' or one of {MAINLINE_NAMES})" + ) diff --git a/src/nglui/parser/base.py b/src/nglui/parser/base.py index d3a4d65..57499f0 100644 --- a/src/nglui/parser/base.py +++ b/src/nglui/parser/base.py @@ -1,6 +1,6 @@ + import numpy as np import pandas as pd -from itertools import chain from ..easyviewer.ev_base.base import SEGMENTATION_LAYER_TYPES diff --git a/src/nglui/parser/info.py b/src/nglui/parser/info.py index 1619ef8..e4eeaa6 100644 --- a/src/nglui/parser/info.py +++ b/src/nglui/parser/info.py @@ -13,4 +13,4 @@ def get_ngl_info(ngl_url): return r.json() except Exception as e: print(f"Error getting neuroglancer version: {e}") - return None \ No newline at end of file + return None diff --git a/src/nglui/segmentprops/__init__.py b/src/nglui/segmentprops/__init__.py new file mode 100644 index 0000000..7094649 --- /dev/null +++ b/src/nglui/segmentprops/__init__.py @@ -0,0 +1,7 @@ +from .base import ( + LabelProperty, + NumberProperty, + SegmentProperties, + StringProperty, + TagProperty, +) diff --git a/src/nglui/segmentprops/base.py b/src/nglui/segmentprops/base.py new file mode 100644 index 0000000..b6b521b --- /dev/null +++ b/src/nglui/segmentprops/base.py @@ -0,0 +1,432 @@ +from functools import partial +from itertools import chain +from typing import Optional, Union + +import attrs +import numpy as np +import pandas as pd + +""" +Options and validation for neuroglancer segment properties based on the segment properties spec: +https://github.com/google/neuroglancer/blob/master/src/datasource/precomputed/segment_properties.md +""" + + +class SegmentPropertyBase: + pass + + +ALLOWED_NUMBER_DATA_TYPES = [ + "uint8", + "int8", + "uint16", + "int16", + "uint32", + "int32", + "float32", +] +NONE_ATTR_FILTERS = ["tag_descriptions", "description"] + + +def list_of_strings(x: list) -> list: + return [str(v) for v in x] + + +def space_to_underscore(x: list) -> list: + return [str(y).replace(" ", "_") for y in x] + + +def sort_tag_arrays(x: list) -> list: + return [sorted(y) for y in x] + + +@attrs.define +class InlineProperties: + ids = attrs.field(type=list[int], converter=list_of_strings, kw_only=True) + properties = attrs.field(type=list[SegmentPropertyBase], default=[], kw_only=True) + + def __len__(self): + return len(self.ids) + + def __attrs_post_init__(self): + if len(self.properties) > 0: + _validate_properties(self.ids, self.properties) + + +@attrs.define +class LabelProperty(SegmentPropertyBase): + id = attrs.field(default="label", type=str, kw_only=True) + type = attrs.field(init=False, default="label", type=str) + values = attrs.field(type=list, converter=list_of_strings, kw_only=True) + description = attrs.field(type=Optional[str], default=None, kw_only=True) + + def __len__(self): + return len(self.values) + + +@attrs.define +class DescriptionProperty(SegmentPropertyBase): + id = attrs.field(default="description", type=str, kw_only=True) + type = attrs.field(init=False, default="description", type=str) + values = attrs.field(type=list, converter=list_of_strings, kw_only=True) + description = attrs.field(type=Optional[str], default=None, kw_only=True) + + def __len__(self): + return len(self.values) + + +@attrs.define +class StringProperty(SegmentPropertyBase): + id = attrs.field(type=str, kw_only=True) + type = attrs.field(init=False, default="string", type=str) + values = attrs.field(type=list, converter=list_of_strings, kw_only=True) + description = attrs.field(type=Optional[str], default=None, kw_only=True) + + def __len__(self): + return len(self.values) + + +@attrs.define +class NumberProperty(SegmentPropertyBase): + id = attrs.field(type=str, kw_only=True) + type = attrs.field(init=False, default="number", type=str) + values = attrs.field(type=list, kw_only=True) + description = attrs.field(type=Optional[str], default=None, kw_only=True) + data_type = attrs.field( + type=str, + kw_only=True, + validator=attrs.validators.in_(ALLOWED_NUMBER_DATA_TYPES), + ) + + def __attrs_post_init__(self): + prop_dtype = np.dtype(self.data_type) + self.values = ( + np.array(self.values).astype(prop_dtype, casting="same_kind").tolist() + ) + + def __len__(self): + return len(self.values) + + +@attrs.define +class TagProperty(SegmentPropertyBase): + id = attrs.field(type=str, kw_only=True, default="tags") + type = attrs.field(init=False, type=str, default="tags") + tags = attrs.field( + type=list[str], + converter=space_to_underscore, + validator=attrs.validators.not_(attrs.validators.matches_re(r"^\#")), + kw_only=True, + ) + tag_descriptions = attrs.field( + type=list[str], + default=None, + kw_only=True, + ) + values = attrs.field( + type=list[list[int]], + converter=sort_tag_arrays, + kw_only=True, + ) + + def __len__(self): + return len(self.values) + + +def prop_filter(attr, value): + "Filters out None for optional attributes for use in 'attrs.asdict' conversion" + return value is not None or attr.name not in NONE_ATTR_FILTERS + + +prop_to_dict = partial(attrs.asdict, filter=prop_filter) + + +def _validate_properties( + ids, + properties, +): + n_ids = len(ids) + for prop in properties: + if len(prop) != n_ids: + msg = f"Property {prop} does not have the same number of entries as the id list." + raise ValueError(msg) + + +def build_segment_properties( + ids: list[int], + properties: list, +): + return { + "@type": "neuroglancer_segment_properties", + "inline": prop_to_dict(InlineProperties(ids=ids, properties=properties)), + } + + +def _find_column_dtype(column): + "Get data type string from a dataframe column" + if column.dtype in ALLOWED_NUMBER_DATA_TYPES: + return str(column.dtype) + elif column.dtype == "int64": + return "int32" + elif column.dtype == "float64": + return "float32" + elif column.dtype == "object": + try: + column.astype("float32") + except Exception: + raise ValueError( + f"Column {column} has an unsupported data type {column.dtype}" + ) + else: + raise ValueError(f"Column {column} has an unsupported data type {column.dtype}") + + +def _tag_descriptions(tags, tag_descriptions): + if tag_descriptions is None: + return None + else: + return [tag_descriptions.get(tag, tag) for tag in tags] + + +def _make_tag_property(df, value_columns, bool_columns, tag_descriptions, name="tags"): + if value_columns is None: + value_columns = [] + if bool_columns is None: + bool_columns = [] + tags = [] + for col in value_columns: + unique_tags = df[col].unique() + # df.unique works differently for categorical dtype columns and does not return an ndarray so we have to check + if isinstance(unique_tags, np.ndarray): + unique_tags = sorted([x for x in unique_tags.tolist() if x is not None]) + else: + unique_tags = unique_tags.sort_values().tolist() + if np.any(np.isin(tags, unique_tags)): + raise ValueError("Tags across columns are not unique") + tags.extend(unique_tags) + tags.extend(bool_columns) + tag_map = {tag: i for i, tag in enumerate(tags) if tag is not None} + tag_values = [] + for _, row in df.iterrows(): + tag_values.append( + [tag_map[tag] for tag in row[value_columns] if tag is not None] + ) + for tv in bool_columns: + for loc in np.flatnonzero(df[tv]): + tag_values[loc].append(tag_map[tv]) + return TagProperty( + id=name, + tags=tags, + values=tag_values, + tag_descriptions=_tag_descriptions(tags, tag_descriptions), + ) + + +class SegmentProperties: + def __init__( + self, + ids: list[int], + label_property: Optional[LabelProperty] = None, + description_property: Optional[DescriptionProperty] = None, + tag_properties: Optional[TagProperty] = None, + string_properties: Optional[Union[StringProperty, list[StringProperty]]] = None, + number_properties: Optional[Union[NumberProperty, list[NumberProperty]]] = None, + ): + self.ids = ids + self.label_property = label_property + self.description_property = description_property + self.tag_properties = tag_properties + + if isinstance(string_properties, StringProperty): + string_properties = [string_properties] + self.string_properties = string_properties + + if isinstance(number_properties, NumberProperty): + number_properties = [number_properties] + self.number_properties = number_properties + + def __len__(self): + return len(self.ids) + + def _property_list(self): + single_prop_list = [ + prop + for prop in [ + self.label_property, + self.description_property, + self.tag_properties, + ] + if prop is not None + ] + multi_prop_list = list( + chain.from_iterable( + [ + prop + for prop in [ + self.string_properties, + self.number_properties, + ] + if prop is not None + ] + ) + ) + return single_prop_list + multi_prop_list + + def __repr__(self): + return f"SegmentProperties ({len(self.ids)} segments, {len(self._property_list())} properties)" + + def __str__(self): + return self.__repr__() + + def property_description(self): + return [(prop.id, prop.type, len(prop)) for prop in self._property_list()] + + def to_dict(self): + "Converts the segment properties to a dictionary for use in neuroglancer" + return build_segment_properties( + self.ids, + self._property_list(), + ) + + @classmethod + def from_dataframe( + cls, + df: pd.DataFrame, + id_col: str = "pt_root_id", + label_col: Optional[str] = None, + description_col: Optional[str] = None, + string_cols: Optional[Union[str, list[str]]] = None, + number_cols: Optional[Union[str, list[str]]] = None, + tag_value_cols: Optional[Union[str, list[str]]] = None, + tag_bool_cols: Optional[list[str]] = None, + tag_descriptions: Optional[dict] = None, + ): + """Generate a segment property object from a pandas dataframe based on column + + Parameters + ---------- + df : pd.DataFrame + Dataframe containing propeties + id_col : str, optional + Name of the column with object ids, by default "pt_root_id" + label_col : Optional[str], optional + Name of column to use for producing labels, by default None + description_col : Optional[str], optional + Name of column to use for producing descriptions, by default None + string_cols : Optional[Union[str, list[str]]], optional + Column (or list of columns) to use for string properties, by default None. + WARNING: Neuroglancer does not currently display these properties. + number_cols : Optional[Union[str, list[str]]], optional + Column (or list of columns) to use for numeric properties, by default None. + tag_value_cols : Optional[list[str]], optional + Column (or list of columns) to generate tags based on unique values. + Each column produces one tag per row based on the value, by default None + tag_bool_cols : Optional[list[str]], optional + List of columns to generate tags based on boolean values where each column is a tag, and each id gets the tag if it has a True in its row. + By default None. + tag_descriptions : Optional[dict], optional + Dictionary of tag values to long-form tag descriptions, by default None. + Tags without a key/value are passed through directly. + + Returns + ------- + SegmentProperties + Segment properties object + """ + ids = df[id_col].tolist() + properties = {} + if label_col: + properties["label_property"] = LabelProperty(values=df[label_col].tolist()) + if description_col: + properties["description_property"] = DescriptionProperty( + values=df[description_col].tolist() + ) + if string_cols: + if isinstance(string_cols, str): + string_cols = [string_cols] + properties["string_properties"] = [ + StringProperty(id=col, values=df[col].tolist()) for col in string_cols + ] + if number_cols: + if isinstance(number_cols, str): + number_cols = [number_cols] + properties["number_properties"] = [ + NumberProperty( + id=col, + values=df[col].tolist(), + data_type=_find_column_dtype(df[col]), + ) + for col in number_cols + ] + if tag_value_cols or tag_bool_cols: + if isinstance(tag_value_cols, str): + tag_value_cols = [tag_value_cols] + if isinstance(tag_bool_cols, str): + tag_bool_cols = [tag_bool_cols] + properties["tag_properties"] = _make_tag_property( + df, + tag_value_cols, + tag_bool_cols, + tag_descriptions, + ) + return cls(ids, **properties) + + @classmethod + def from_dict( + cls, + seg_prop_dict: dict, + ): + """Generate a segment property object from a segment property dictionary + + Parameters + ---------- + seg_prop_dict : dict + Segment property dictionary, as imported from the json. + + Returns + ------- + SegmentProperties + Segment properties object + """ + ids = seg_prop_dict["inline"]["ids"] + props = seg_prop_dict["inline"]["properties"] + prop_classes = {} + for prop in props: + if prop["type"] == "label": + prop_classes["label_property"] = LabelProperty( + values=prop["values"], + description=prop.get("description"), + ) + elif prop["type"] == "description": + prop_classes["description_property"] = DescriptionProperty( + values=prop["values"], + description=prop.get("description"), + ) + elif prop["type"] == "string": + if "string_properties" not in prop_classes: + prop_classes["string_properties"] = [] + prop_classes["string_properties"].append( + StringProperty( + id=prop["id"], + values=prop["values"], + description=prop.get("description"), + ) + ) + elif prop["type"] == "number": + if "number_properties" not in prop_classes: + prop_classes["number_properties"] = [] + prop_classes["number_properties"].append( + NumberProperty( + id=prop["id"], + values=prop["values"], + data_type=prop["data_type"], + description=prop.get("description"), + ) + ) + elif prop["type"] == "tags": + prop_classes["tag_properties"] = TagProperty( + tags=prop["tags"], + values=prop["values"], + tag_descriptions=prop.get("tag_descriptions"), + ) + return cls(ids, **prop_classes) diff --git a/src/nglui/statebuilder/helpers.py b/src/nglui/statebuilder/helpers.py index 51edc9f..85651fe 100644 --- a/src/nglui/statebuilder/helpers.py +++ b/src/nglui/statebuilder/helpers.py @@ -1,16 +1,17 @@ from typing import Iterable + +import pandas as pd +from caveclient import CAVEclient +from caveclient.endpoints import fallback_ngl_endpoint +from IPython.display import HTML + from .layers import ( + AnnotationLayerConfig, ImageLayerConfig, SegmentationLayerConfig, - AnnotationLayerConfig, - PointMapper, - LineMapper, ) +from .mappers import LineMapper, PointMapper from .statebuilder import ChainedStateBuilder, StateBuilder -from caveclient import CAVEclient -from caveclient.endpoints import fallback_ngl_endpoint -import pandas as pd -from IPython.display import HTML DEFAULT_POSTSYN_COLOR = (0.25098039, 0.87843137, 0.81568627) # CSS3 color turquise DEFAULT_PRESYN_COLOR = (1.0, 0.38823529, 0.27843137) # CSS3 color tomato @@ -20,7 +21,12 @@ "contrast_controls": True, "black": 0.35, "white": 0.70, - } + }, + "minnie65_public": { + "contrast_controls": True, + "black": 0.35, + "white": 0.70, + }, } MAX_URL_LENGTH = 1_750_000 DEFAULT_NGL = fallback_ngl_endpoint @@ -106,7 +112,10 @@ def make_line_statebuilder( dictionary of view keywords to configure neuroglancer view split_positions : bool, optional whether the position column into x,y,z columns. Defaults to False. - + ngl_url : str, optional + URL of the Neuroglancer instance to use. Defaults to client.info.viewer_site() or DEFAULT_NGL. + target_site : str, optional + Category of Neuroglancer deployment to build link for. Defaults to None. Returns ------- StateBuilder: @@ -284,8 +293,8 @@ def make_pre_post_statebuilder( if view_kws is None: view_kws = {} - sb1 = StateBuilder(layers=[img_layer, seg_layer], client=client, view_kws=view_kws) + sb1 = StateBuilder(layers=[img_layer, seg_layer], client=client, view_kws=view_kws) state_builders = [sb1] if show_inputs: # First state builder @@ -350,7 +359,9 @@ def make_state_url(df, sb, client, ngl_url=None, target_site=None): ngl_url = client.info.viewer_site() if ngl_url is None: ngl_url = DEFAULT_NGL - url = client.state.build_neuroglancer_url(state_id, ngl_url=ngl_url) + url = client.state.build_neuroglancer_url( + state_id, ngl_url=ngl_url, target_site=target_site + ) return url @@ -404,7 +415,7 @@ def make_url_robust( df, sb, client, ngl_url=ngl_url, target_site=target_site ) elif shorten == "always": - url = make_state_url(df, sb, client, target_site=target_site) + url = make_state_url(df, sb, client, ngl_url=ngl_url, target_site=target_site) elif shorten == "never": url = sb.render_state( df, return_as="url", url_prefix=ngl_url, target_site=target_site @@ -476,7 +487,9 @@ def package_state( else: return url elif return_as == "json": - return sb.render_state(df, return_as=return_as, target_site=target_site) + return sb.render_state( + df, return_as=return_as, ngl_url=ngl_url, target_site=target_site + ) else: raise ( ValueError( @@ -756,16 +769,17 @@ def make_neuron_neuroglancer_link( dataframe_resolution_post=data_resolution_post, split_positions=True, ) - return package_state( - dataframes, - sb, - client, - shorten, - return_as, - ngl_url, - link_text, - target_site=target_site, - ) + return sb, dataframes + # return package_state( + # dataframes, + # sb, + # client, + # shorten, + # return_as, + # ngl_url, + # link_text, + # target_site=target_site, + # ) def from_client(client, image_name=None, segmentation_name=None, contrast=None): @@ -797,8 +811,16 @@ def from_client(client, image_name=None, segmentation_name=None, contrast=None): ) else: config = {"contrast_controls": True, "black": contrast[0], "white": contrast[1]} - img_layer = ImageLayerConfig(client.info.image_source(), name=image_name, **config) - seg_layer = SegmentationLayerConfig( - client.info.segmentation_source(), name=segmentation_name - ) + if image_name is not False: + img_layer = ImageLayerConfig( + client.info.image_source(), name=image_name, **config + ) + else: + img_layer = None + if segmentation_name is not False: + seg_layer = SegmentationLayerConfig( + client.info.segmentation_source(), name=segmentation_name + ) + else: + seg_layer = None return img_layer, seg_layer diff --git a/src/nglui/statebuilder/layers.py b/src/nglui/statebuilder/layers.py index de4fd88..c61f639 100644 --- a/src/nglui/statebuilder/layers.py +++ b/src/nglui/statebuilder/layers.py @@ -1,14 +1,16 @@ +import numbers +from datetime import datetime +from typing import Optional, Union +from warnings import warn + +import numpy as np + +from ..easyviewer import EasyViewerMainline +from ..segmentprops.base import SegmentProperties from .mappers import ( - SelectionMapper, AnnotationMapperBase, - PointMapper, - LineMapper, - SphereMapper, - BoundingBoxMapper, + SelectionMapper, ) -from datetime import datetime -import numpy as np -import numbers DEFAULT_IMAGE_LAYER = "img" DEFAULT_SEG_LAYER = "seg" @@ -21,7 +23,7 @@ } -class LayerConfigBase(object): +class LayerConfigBase: """Base class for configuring layers Parameters @@ -91,7 +93,7 @@ def active(self, val): self._config["active"] = val def _render_layer( - self, viewer, data, viewer_resolution=None, return_annos=False + self, viewer, data, viewer_resolution=None, return_annos=False, client=None ): """Applies rendering rules""" annos = self._specific_rendering( @@ -99,6 +101,7 @@ def _render_layer( data, viewer_resolution=viewer_resolution, return_annos=return_annos, + client=client, ) if self.active: viewer.set_selected_layer(self.name) @@ -107,21 +110,21 @@ def _render_layer( else: pass - def _add_layer( - self, viewer - ): + def _add_layer(self, viewer): "Subclass implements layer addition rules" - pass def _set_view_options(self, *args, **kwargs): "Subclass implements own rules" - pass def _specific_rendering( - self, viewer, data, viewer_resolution=None, return_annos=False, + self, + viewer, + data, + viewer_resolution=None, + return_annos=False, + client=None, ): """Subclasses implement specific rendering rules""" - pass class ImageLayerConfig(LayerConfigBase): @@ -167,7 +170,12 @@ def _add_layer(self, viewer): viewer.add_image_layer(self.name, self.source) def _specific_rendering( - self, viewer, data, viewer_resolution=None, return_annos=False, + self, + viewer, + data, + viewer_resolution=None, + return_annos=False, + client=None, ): if self._contrast_controls: viewer.add_contrast_shader(self.name, black=self._black, white=self._white) @@ -205,6 +213,10 @@ class SegmentationLayerConfig(LayerConfigBase): Keyword arguments for viewer.set_segmentation_view_options. Sets selected (and unselected) segmetation alpha values. Defaults to values in DEFAULT_SEGMENTATION_VIEW_KWS dict specified in this module. timestamp : float or datetime, optional. Timestamp at which to fix the chunkedgraph in either unix epoch or datetime format. Optional, default is None. + mapping_set : str, optional. + Name of the mapping set, the key in the data dictionary for statebuilder. Optional, default is None. + segment_properties: str, optional + Location of a segment properties file. Optional, default is None. """ def __init__( @@ -223,6 +235,8 @@ def __init__( view_kws=None, timestamp=None, data_resolution=None, + mapping_set=None, + segment_properties=None, ): if name is None: name = DEFAULT_SEG_LAYER @@ -231,6 +245,7 @@ def __init__( name=name, type="segmentation", source=source, color=None, active=active ) self._config["data_resolution"] = data_resolution + self._config["segment_properties"] = segment_properties if selected_ids_column is not None or fixed_ids is not None: self._selection_map = SelectionMapper( @@ -238,6 +253,7 @@ def __init__( fixed_ids=fixed_ids, fixed_id_colors=fixed_id_colors, color_column=color_column, + mapping_set=mapping_set, ) else: self._selection_map = None @@ -257,17 +273,114 @@ def __init__( } base_seg_kws.update(view_kws) self._view_kws = view_kws + self._segment_property_map = None @property def data_resolution(self): return self._config.get("data_resolution", None) + @property + def segment_properties(self): + if isinstance(self._config.get("segment_properties"), str): + return [self._config.get("segment_properties")] + else: + return self._config.get("segment_properties", []) + + @property + def source(self): + if self.segment_properties: + seg_prop_url = self.segment_properties + else: + seg_prop_url = [] + if self._config.get("source"): + if isinstance(self._config.get("source"), str): + source = [self._config.get("source")] + else: + source = self._config.get("source") + else: + source = [] + out = source + seg_prop_url + if len(out) == 1: + return out[0] + else: + return out + + def add_segment_propeties( + self, + segment_property: str, + ): + self._config["segment_properties"] = segment_property + + def add_segment_properties_map( + self, + id_col: str = "pt_root_id", + label_col: Optional[str] = None, + description_col: Optional[str] = None, + string_cols: Optional[Union[str, list[str]]] = None, + number_cols: Optional[Union[str, list[str]]] = None, + tag_value_cols: Optional[Union[str, list[str]]] = None, + tag_bool_cols: Optional[list[str]] = None, + tag_descriptions: Optional[dict] = None, + mapping_set: Optional[str] = None, + ): + segment_property_map = { + "id_col": id_col, + "label_col": label_col, + "description_col": description_col, + "string_cols": string_cols, + "number_cols": number_cols, + "tag_value_cols": tag_value_cols, + "tag_bool_cols": tag_bool_cols, + "tag_descriptions": tag_descriptions, + } + if mapping_set: + if not isinstance(self._segment_property_map, dict): + self._segment_property_map = {} + self._segment_property_map[mapping_set] = segment_property_map + else: + self._segment_property_map = segment_property_map + + def _render_single_segment_prop(self, data, seg_prop_map, client): + props = SegmentProperties.from_dataframe(data, **seg_prop_map) + pid = client.state.upload_property_json(props.to_dict()) + return client.state.build_neuroglancer_url( + pid, + target_site="cave-explorer", + format_propeties=True, + ) + + def _render_segment_property_map(self, data, client, target_site=None): + if target_site == "seunglab": + warn("Cannot render segment properties for seunglab") + return None + if client is None: + raise ValueError( + "Client must be provided to dynamically render segment properties" + ) + seg_prop_urls = [] + if isinstance(data, dict): + for k, v in data.items(): + if k in self._segment_property_map: + seg_prop_urls.append( + self._render_single_segment_prop( + v, self._segment_property_map.get(k), client + ) + ) + else: + seg_prop_urls.append( + self._render_single_segment_prop( + data, self._segment_property_map, client + ) + ) + return seg_prop_urls + def add_selection_map( self, selected_ids_column=None, fixed_ids=None, fixed_id_colors=None, color_column=None, + mapping_set=None, ): """Add rules for selecting active segment ids and their colors @@ -281,6 +394,8 @@ def add_selection_map( Add a list of colors (hex, rgb, or CSS3 string) to assign to the fixed ids, by default None color_column : str, optional Dataframe column to use for adding selected segment colors, by default None + mapping_set : str, optional + Name of the mapping set, the key in the data dictionary for statebuilder, by default None """ if self._selection_map is not None: if isinstance(selected_ids_column, str): @@ -327,19 +442,34 @@ def add_selection_map( fixed_ids=new_fixed_ids, fixed_id_colors=new_fixed_id_colors, color_column=color_column, + mapping_set=mapping_set, ) def _add_layer(self, viewer): viewer.add_segmentation_layer(self.name, self.source) def _specific_rendering( - self, viewer, data, viewer_resolution=None, return_annos=False, + self, + viewer, + data, + viewer_resolution=None, + return_annos=False, + client=None, ): if self._selection_map is not None: selected_ids = self._selection_map.selected_ids(data) colors = self._selection_map.seg_colors(data) viewer.add_selected_objects(self.name, selected_ids, colors) + if self._segment_property_map is not None: + if isinstance(viewer, EasyViewerMainline): + target_site = "cave-explorer" + else: + target_site = "seunglab" + seg_prop_urls = self._render_segment_property_map(data, client, target_site) + for seg_prop_url in seg_prop_urls: + viewer.append_source_to_segmentation_layer(self.name, seg_prop_url) + if self._split_point_map is not None: ( seg_id, @@ -365,7 +495,6 @@ def _specific_rendering( viewer.set_timestamp(self.name, self.timestamp) viewer.set_segmentation_view_options(self.name, **self._view_kws) - pass class AnnotationLayerConfig(LayerConfigBase): @@ -471,19 +600,22 @@ def _set_view_options(self, viewer, data, viewer_resolution=None): data = data.query(self.filter_query) for rule in self._annotation_map_rules: pos = rule._get_position( - data, - data_resolution=self.data_resolution, - viewer_resolution=viewer_resolution, - ) - viewer.set_view_options( - position=pos + data, + data_resolution=self.data_resolution, + viewer_resolution=viewer_resolution, ) + viewer.set_view_options(position=pos) if pos is not None: break return pos def _specific_rendering( - self, viewer, data, viewer_resolution=None, return_annos=False, + self, + viewer, + data, + viewer_resolution=None, + return_annos=False, + client=None, ): annos = [] for rule in self._annotation_map_rules: @@ -504,4 +636,3 @@ def _specific_rendering( return annos else: viewer.add_annotations(self.name, annos) - pass diff --git a/src/nglui/statebuilder/mappers.py b/src/nglui/statebuilder/mappers.py index fd5e141..d321881 100644 --- a/src/nglui/statebuilder/mappers.py +++ b/src/nglui/statebuilder/mappers.py @@ -1,9 +1,12 @@ -import numpy as np -import pandas as pd from collections.abc import Collection from itertools import chain + +import numpy as np +import pandas as pd + from .utils import is_split_position, split_position_columns + def _multipoint_transform(row, pt_columns, squeeze_cols): """Reshape dataframe to accomodate multiple points in a single row""" pts = {pcol: np.atleast_2d(row[pcol]) for pcol in pt_columns} @@ -22,12 +25,13 @@ def _multipoint_transform(row, pt_columns, squeeze_cols): r[col] = row[col] return rows + def _multipoint_transform_split(df, multi_columns=[]): col_data = {} for col in df.columns: col_data[col] = [] for _, row in df.iterrows(): - if len(multi_columns)>0: + if len(multi_columns) > 0: n_pts = len(row[multi_columns[0]]) else: n_pts = 1 @@ -35,7 +39,7 @@ def _multipoint_transform_split(df, multi_columns=[]): if col in multi_columns: col_data[col].extend(row[col]) else: - col_data[col].extend(n_pts*[row[col]]) + col_data[col].extend(n_pts * [row[col]]) return pd.DataFrame(col_data) @@ -47,7 +51,7 @@ def _data_scaler(data_resolution, viewer_resolution): return (np.array(data_resolution) / np.array(viewer_resolution)).reshape((1, 3)) -class SelectionMapper(object): +class SelectionMapper: """Class for configuring object selections based on root id Parameters @@ -67,7 +71,12 @@ class SelectionMapper(object): """ def __init__( - self, data_columns=None, fixed_ids=None, fixed_id_colors=None, color_column=None, mapping_set=None, + self, + data_columns=None, + fixed_ids=None, + fixed_id_colors=None, + color_column=None, + mapping_set=None, ): if isinstance(data_columns, str): data_columns = [data_columns] @@ -114,7 +123,6 @@ def color_column(self): def mapping_set(self): return self._config.get("mapping_set", None) - def selected_ids(self, data): """Uses the rules to generate a list of ids from a dataframe.""" if self.mapping_set is not None: @@ -129,6 +137,9 @@ def selected_ids(self, data): return np.concatenate(selected_ids) def seg_colors(self, data): + if self.mapping_set is not None: + data = data.get(self.mapping_set) + colors = {} if len(self.fixed_id_colors) == len(self.fixed_ids): for ii, oid in enumerate(self.fixed_ids): @@ -143,7 +154,7 @@ def seg_colors(self, data): return colors -class AnnotationMapperBase(object): +class AnnotationMapperBase: def __init__( self, type, @@ -160,7 +171,6 @@ def __init__( split_positions=None, mapping_set=None, ): - self._config = dict( type=type, data_columns=data_columns, @@ -226,28 +236,27 @@ def collapse_groups(self): def multipoint_reshape(self, data, pt_columns, squeeze_cols=[]): if data is None or len(data) == 0: return data + elif not self.split_positions: + rows = data.apply( + lambda x: _multipoint_transform( + x, pt_columns=pt_columns, squeeze_cols=squeeze_cols + ), + axis=1, + ).tolist() + return pd.DataFrame.from_records([r for r in chain.from_iterable(rows)]) else: - if not self.split_positions: - rows = data.apply( - lambda x: _multipoint_transform( - x, pt_columns=pt_columns, squeeze_cols=squeeze_cols - ), - axis=1, - ).tolist() - return pd.DataFrame.from_records([r for r in chain.from_iterable(rows)]) - else: - split_cols = [] - for pt_col in pt_columns: - split_cols.extend(split_position_columns(pt_col)) - return _multipoint_transform_split(data, split_cols) + split_cols = [] + for pt_col in pt_columns: + split_cols.extend(split_position_columns(pt_col)) + return _multipoint_transform_split(data, split_cols) @property def split_positions(self): - return self._config.get('split_positions') + return self._config.get("split_positions") @property def mapping_set(self): - return self._config.get('mapping_set', None) + return self._config.get("mapping_set", None) @property def tag_map(self): @@ -292,25 +301,28 @@ def _assign_tags(self, data): anno_tags = [[None] for x in range(len(data))] return anno_tags - def _parse_data(self, data, first=False): if self.mapping_set is not None: if not isinstance(data, dict): - raise ValueError('If mapping sets are used, dataframes must be provided as values in a dictionary') + raise ValueError( + "If mapping sets are used, dataframes must be provided as values in a dictionary" + ) data = data.get(self.mapping_set) if first and data is not None: if len(data) > 0: if isinstance(data, pd.DataFrame): data = data.iloc[[0]] else: - data = np.array(data)[0].reshape(1,-1) + data = np.array(data)[0].reshape(1, -1) return data def _process_columns(self, data, skip_columns=[]): if self.split_positions is not None: split_positions = self.split_positions else: - is_split = np.bool([is_split_position(col, data) for col in self.data_columns]) + is_split = np.bool( + [is_split_position(col, data) for col in self.data_columns] + ) if np.all(~is_split): split_positions = False if np.any(is_split): @@ -319,13 +331,13 @@ def _process_columns(self, data, skip_columns=[]): for col, spl in zip(self.data_columns, is_split): if spl: skip_columns.append(col) - + if split_positions and not self.array_data: data = data.copy() for col in self.data_columns: if col in skip_columns: continue - split_cols = [f'{col}_{suf}' for suf in ["x", "y", "z"]] + split_cols = [f"{col}_{suf}" for suf in ["x", "y", "z"]] data[col] = np.vstack(data[split_cols].values).tolist() return data else: @@ -391,10 +403,11 @@ def _add_groups(self, data, annos, viewer): annos.extend([g for g in group_annos if g is not None]) return annos - def _get_position(self, data, data_resolution=None, viewer_resolution=None): # Parse data because get_position is called by the layer, not the render_annotation function. - data = self._preprocess_data(data, skip_columns=self.data_columns[1:], first=True) + data = self._preprocess_data( + data, skip_columns=self.data_columns[1:], first=True + ) if data is None: return None @@ -434,6 +447,7 @@ class PointMapper(AnnotationMapperBase): mapping_set: str, optional If given, assumes data is passed as a dictionary and uses this string to as the key for the data to use. """ + def __init__( self, point_column=None, @@ -530,6 +544,7 @@ class LineMapper(AnnotationMapperBase): mapping_set: str, optional If set, assumes data is passed as a dictionary and uses this string to as the key for the data to use. """ + def __init__( self, point_column_a=None, @@ -675,7 +690,7 @@ def _render_data(self, data, data_resolution, viewer_resolution, viewer): "Transforms data to neuroglancer annotations" col_ctr, col_rad = self.data_columns - data = self._preprocess_data(data, skip_columns=['rad'], squeeze_cols=[col_rad]) + data = self._preprocess_data(data, skip_columns=["rad"], squeeze_cols=[col_rad]) if data is None: return [] @@ -741,6 +756,7 @@ class BoundingBoxMapper(AnnotationMapperBase): mapping_set: str, optional If set, assumes data is passed as a dictionary and uses this string to as the key for the data to use. """ + def __init__( self, point_column_a=None, @@ -782,7 +798,7 @@ def _process_array_data(self, data): data={"pt_a": data[0].tolist(), "pt_b": data[1].tolist()} ) return data - + def _render_data(self, data, data_resolution, viewer_resolution, viewer): "Transforms data to neuroglancer annotations" data = self._preprocess_data(data) @@ -812,7 +828,7 @@ def _render_data(self, data, data_resolution, viewer_resolution, viewer): return annos -class SplitPointMapper(object): +class SplitPointMapper: """Mapper to create split points in a segmentation layer. Parameters diff --git a/src/nglui/statebuilder/statebuilder.py b/src/nglui/statebuilder/statebuilder.py index be85223..95a0b4b 100644 --- a/src/nglui/statebuilder/statebuilder.py +++ b/src/nglui/statebuilder/statebuilder.py @@ -1,10 +1,18 @@ +from warnings import warn + +from IPython.display import HTML + from nglui.easyviewer import EasyViewer -from ..easyviewer.ev_base.utils import neuroglancer_url, default_seunglab_neuroglancer_base from nglui.easyviewer.ev_base.nglite.json_utils import encode_json -from IPython.display import HTML + +from ..easyviewer.ev_base.utils import ( + default_seunglab_neuroglancer_base, + neuroglancer_url, +) from .utils import check_target_site -DEFAULT_TARGET_SITE = 'seunglab' +DEFAULT_TARGET_SITE = "seunglab" +DEFAULT_URL = default_seunglab_neuroglancer_base DEFAULT_VIEW_KWS = { "layout": "xy-3d", @@ -13,39 +21,57 @@ "zoom_3d": 2000, } + class StateBuilder: """A class for schematic mapping data frames into neuroglancer states. Parameters ---------- - layers (list, optional): list of nglui.statebuilder.layers.LayerConfigBase to add. Defaults to []. - base_state (dict, optional): json state to add to. Defaults to None. - url_prefix (str, optional): http(s) path to neuroglancer deployment to use. - Defaults to None, which will use https://neuromancer-seung-import.appspot.com - state_server (str, optional): state server to post links to. Defaults to None. - resolution (list, optional): 3 element vector controlling the viewer resolution. Defaults to None. If None and a client is set, uses the client viewer resolution. - view_kws (dict, optional): dictionary controlling view parameters. Defaults to {}. - keys are: - show_slices: Boolean - sets if slices are shown in the 3d view. Defaults to False. - layout: str - `xy-3d`/`xz-3d`/`yz-3d` (sections plus 3d pane), `xy`/`yz`/`xz`/`3d` (only one pane), or `4panel` (all panes). Default is `xy-3d`. - show_axis_lines: Boolean - determines if the axis lines are shown in the middle of each view. - show_scale_bar: Boolean - toggles showing the scale bar. - orthographic : Boolean - toggles orthographic view in the 3d pane. - position* : 3-element vector - determines the centered location. - zoom_image : float - Zoom level for the imagery in units of nm per voxel. Defaults to 8. - zoom_3d : float - Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are more zoomed in. - background_color : str or list - Sets the background color of the 3d view. Arguments can be rgb values, hex colors, or named web colors. Defaults to black. - client (caveclient.CAVEclient, optional): a caveclient to get defaults from. Defaults to None. + layers : list of nglui.statebuilder.layers.LayerConfigBase, optional + List of layers to add. Defaults to []. + base_state : dict, optional + JSON state to add to. Defaults to None. + url_prefix : str, optional + http(s) path to Neuroglancer deployment to use. Defaults to None, + which will use https://neuromancer-seung-import.appspot.com + state_server : str, optional + State server to post links to. Defaults to None. + resolution : list of float, optional + 3-element vector controlling the viewer resolution. Defaults to None. + If None and a client is set, uses the client viewer resolution. + view_kws : dict, optional + Dictionary controlling view parameters. Defaults to {}. + + Keys are: + show_slices : bool, optional + Sets if slices are shown in the 3d view. Defaults to False. + layout : str, optional + `xy-3d`/`xz-3d`/`yz-3d` (sections plus 3d pane), + `xy`/`yz`/`xz`/`3d` (only one pane), or `4panel` (all panes). + Default is `xy-3d`. + show_axis_lines : bool, optional + Determines if the axis lines are shown in the middle of each view. + show_scale_bar : bool, optional + Toggles showing the scale bar. + orthographic : bool, optional + Toggles orthographic view in the 3d pane. + position : list of float, optional (length-3) + Determines the centered location. + zoom_image : float, optional + Zoom level for the imagery in units of nm per voxel. Defaults to 8. + zoom_3d : float, optional + Zoom level for the 3d pane. Defaults to 2000. Smaller numbers are + more zoomed in. + background_color : str or list of float, optional + Sets the background color of the 3d view. Arguments can be rgb + values, hex colors, or named web colors. Defaults to black. + client : caveclient.CAVEclient, optional + A caveclient to get defaults from. Defaults to None. + target_site : str, optional + Target Neuroglancer category: either "seunglab" or "mainline"/"cave-explorer"/"spelunker". Defaults to None. + Will be looked up automatically based on ngl_url, if used. """ + def __init__( self, layers=[], @@ -66,8 +92,7 @@ def __init__( resolution = client.info.viewer_resolution().tolist() if target_site is None: target_site = check_target_site(url_prefix, client) - if url_prefix is None and target_site is None: - target_site = DEFAULT_TARGET_SITE + self._client = client url_prefix = neuroglancer_url(url_prefix, target_site) self._base_state = base_state @@ -112,10 +137,11 @@ def initialize_state(self, base_state=None, target_site=None): def handle_positions(self, data): for l in self._layers[::-1]: - pos = l._set_view_options(self._temp_viewer, data, viewer_resolution=self._resolution) + pos = l._set_view_options( + self._temp_viewer, data, viewer_resolution=self._resolution + ) if pos is not None: break - pass def render_state( self, @@ -156,19 +182,26 @@ class default. if base_state is None: base_state = self._base_state if target_site is None: - if self._target_site is not None: - target_site = self._target_site + target_site = self._target_site + if url_prefix is None: + url_prefix = self._url_prefix + if target_site is None and url_prefix is not None: + if self._client is not None: + target_site = check_target_site(url_prefix, self._client) + elif target_site is None and url_prefix is None: + target_site = DEFAULT_TARGET_SITE + url_prefix = DEFAULT_URL + warn( + 'Deprecation warning: No target site or url prefix set, using default "seunglab" site. This will switch to "spelunker" in the future.' + ) - self.initialize_state( - base_state=base_state, target_site=target_site - ) + self.initialize_state(base_state=base_state, target_site=target_site) self.handle_positions(data) self._render_layers( data, ) - if url_prefix is None: url_prefix = self._url_prefix @@ -176,27 +209,26 @@ class default. return self.viewer elif return_as == "url": url = self._temp_viewer.as_url(prefix=url_prefix) - self.initialize_state() return url elif return_as == "html": out = self._temp_viewer.as_url( prefix=url_prefix, as_html=True, link_text=link_text ) out = HTML(out) - self.initialize_state() return out elif return_as == "dict": out = self._temp_viewer.state.to_json() - self.initialize_state() return out elif return_as == "json": out = self._temp_viewer.state.to_json() - self.initialize_state() return encode_json(out) else: raise ValueError("No appropriate return type selected") - def _render_layers(self, data,): + def _render_layers( + self, + data, + ): # Inactivate all layers except last. found_active = False for l in self._layers[::-1]: @@ -211,6 +243,7 @@ def _render_layers(self, data,): data, viewer_resolution=self._resolution, return_annos=True, + client=self._client, ) self._temp_viewer.add_multilayer_annotations(anno_dict) @@ -227,6 +260,7 @@ class ChainedStateBuilder: statebuilders : list List of DataStateBuilders, in same order as dataframes will be passed """ + def __init__(self, statebuilders): self._statebuilders = statebuilders if len(self._statebuilders) == 0: @@ -267,7 +301,8 @@ def render_state( data=data, base_state=temp_state, return_as="dict", - target_site=target_site + url_prefix=url_prefix, + target_site=target_site, ) last_builder = self._statebuilders[-1] return last_builder.render_state( diff --git a/src/nglui/statebuilder/utils.py b/src/nglui/statebuilder/utils.py index 8bbe428..8a66c6c 100644 --- a/src/nglui/statebuilder/utils.py +++ b/src/nglui/statebuilder/utils.py @@ -1,7 +1,7 @@ +import re from collections.abc import Iterable -from dataclasses import dataclass + import numpy as np -import re FALLBACK_SEUNGLAB_NGL_URL = "https://neuroglancer.neuvue.io" FALLBACK_MAINLINE_NGL_URL = "https://ngl.cave-explorer.org" @@ -29,16 +29,14 @@ def bucket_of_values(col, data, item_is_array=False, array_width=3): return np.vstack(dataseries.values) else: return dataseries.values[0].reshape(1, -1) + elif len(data) > 1: + return np.vstack(dataseries.map(np.vstack)).reshape(-1, array_width) else: - if len(data) > 1: - return np.vstack(dataseries.map(np.vstack)).reshape(-1, array_width) - else: - return np.vstack(dataseries).reshape(1, -1) + return np.vstack(dataseries).reshape(1, -1) + elif isinstance(dataseries.iloc[0], Iterable): + return np.concatenate(dataseries.values) else: - if isinstance(dataseries.iloc[0], Iterable): - return np.concatenate(dataseries.values) - else: - return dataseries.values + return dataseries.values def is_split_position(pt_col, df, suffixes=SPLIT_SUFFIXES): @@ -59,7 +57,7 @@ def is_split_split_position(pt_col, df, suffixes=SPLIT_SUFFIXES): expected_name = '_'.join(split_name[:-1]) + f'_{suf}_{split_name[-1]}' is_split_split.append(expected_name in df.columns) return np.all(is_split_split) - + def assemble_split_points(pt_col, df, suffixes=SPLIT_SUFFIXES): cols = split_position_columns(pt_col, suffixes) return np.vstack(df[cols].values) @@ -79,4 +77,3 @@ def check_target_site(ngl_url, client): return 'seunglab' else: return "cave-explorer" - \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index 54eddc1..93f9f86 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,17 +1,21 @@ +import json + +import numpy as np +import pandas as pd import pytest + from nglui import EasyViewer -import pandas as pd -import numpy as np -import json @pytest.fixture(scope="session") def viewer(): - return EasyViewer(target_site='seunglab') + return EasyViewer(target_site="seunglab") + @pytest.fixture(scope="session") def viewer_cave_explorer(): - return EasyViewer(target_site='mainline') + return EasyViewer(target_site="mainline") + @pytest.fixture(scope="session") def img_path(): @@ -42,7 +46,7 @@ def soma_df(): def soma_df_Int64(): df = pd.read_hdf("tests/testdata/test_data.h5", "soma").head(5) df["pt_root_id"] = df["pt_root_id"].astype("Int64") - df["pt_root_id"].iloc[0] = np.nan + df.loc[0, "pt_root_id"] = np.nan return df.head() @@ -58,7 +62,7 @@ def post_syn_df(): @pytest.fixture(scope="session") def test_state(): - with open("tests/testdata/test_state.json", "r") as f: + with open("tests/testdata/test_state.json") as f: state = json.load(f) return state @@ -87,4 +91,4 @@ def split_point_df(): } ) - return pd.concat((red_df, blue_df)) \ No newline at end of file + return pd.concat((red_df, blue_df)) diff --git a/tests/test_parser.py b/tests/test_parser.py index 22f7ad4..595699c 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -1,6 +1,6 @@ -import pytest import numpy as np import pandas as pd + from nglui import parser diff --git a/tests/test_segment_props.py b/tests/test_segment_props.py new file mode 100644 index 0000000..9b2c3e9 --- /dev/null +++ b/tests/test_segment_props.py @@ -0,0 +1,40 @@ +import numpy as np +import pandas as pd +import pytest + +from nglui.segmentprops import SegmentProperties + + +@pytest.fixture +def test_df(): + return pd.DataFrame( + { + "seg_id": np.arange(0, 100), + "cell_type": 30 * ["ct_a"] + 30 * ["ct_b"] + 40 * ["ct_c"], + "category": 50 * ["cat_1"] + 40 * ["cat_2"] + 10 * [None], + "number_int": np.arange(300, 400), + "number_float": np.arange(300, 400) + 0.1, + "tag_a": 90 * [False] + 10 * [True], + "tag_b": 95 * [True] + 5 * [False], + } + ) + + +def test_segment_props(test_df): + props = SegmentProperties.from_dataframe( + test_df, + id_col="seg_id", + label_col="seg_id", + number_cols=["number_int", "number_float"], + tag_value_cols="cell_type", + tag_bool_cols=["tag_a", "tag_b"], + tag_descriptions={"tag_a": "The first tag", "tag_b": "The second tag"}, + ) + + assert len(props) == 100 + assert len(props.property_description()) == 4 + p_dict = props.to_dict() + assert p_dict["inline"]["properties"][2]["data_type"] == "int32" + + rh_props = SegmentProperties.from_dict(p_dict) + assert len(rh_props) == 100 diff --git a/tests/test_statebuilder.py b/tests/test_statebuilder.py index 4ab1a49..b9d0945 100644 --- a/tests/test_statebuilder.py +++ b/tests/test_statebuilder.py @@ -1,16 +1,18 @@ -import pytest -import numpy as np from collections import OrderedDict + +import numpy as np +import pytest + from nglui.statebuilder import ( - ImageLayerConfig, - SegmentationLayerConfig, AnnotationLayerConfig, - StateBuilder, - PointMapper, + ChainedStateBuilder, + ImageLayerConfig, LineMapper, + PointMapper, + SegmentationLayerConfig, SphereMapper, SplitPointMapper, - ChainedStateBuilder, + StateBuilder, ) @@ -68,7 +70,7 @@ def test_basic_cave_explorer(image_layer, seg_layer_basic, anno_layer_basic): assert state.data == f'Neuroglancer Link' state = sb.render_state(return_as="dict") - assert isinstance(state, OrderedDict) + assert isinstance(state, (OrderedDict, dict)) # Cave-explorer uses dict state = sb.render_state(return_as="json") assert type(state) is str @@ -89,8 +91,15 @@ def test_segmentation_layer(soma_df, seg_path_precomputed, target_site): sb = StateBuilder(layers=[seg_layer], target_site=target_site) state = sb.render_state(soma_df, return_as="dict") print(state["layers"]) - assert 648518346349538466 in state["layers"][0]["segments"] - assert 1000 in state["layers"][0]["segments"] + assert ( + 648518346349538466 in state["layers"][0]["segments"] + or "648518346349538466" + in state["layers"][0]["segments"] # Cave-explorer uses strings for ids + ) + assert ( + 1000 in state["layers"][0]["segments"] + or "1000" in state["layers"][0]["segments"] + ) @pytest.mark.parametrize("target_site", [None, "seunglab", "cave-explorer"]) @@ -188,6 +197,7 @@ def test_annotations_linked(soma_df, soma_df_Int64, seg_path_precomputed, target ) state = sb.render_state(soma_df_Int64, return_as="dict") + print("TYPE IS", state["layers"][1]["annotations"][0]["segments"]) assert len(np.squeeze(state["layers"][1]["annotations"][0]["segments"])) == 0 diff --git a/tests/test_viewer.py b/tests/test_viewer.py index 4b63268..4b1781f 100644 --- a/tests/test_viewer.py +++ b/tests/test_viewer.py @@ -1,4 +1,3 @@ -import pytest # from nglui import annotation import numpy as np
    - -