diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 00000000..cfb796c6 --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: a19e2f5da275cb21aa168c8d2b30f908 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.doctrees/api/gimie.doctree b/.doctrees/api/gimie.doctree new file mode 100644 index 00000000..64046f80 Binary files /dev/null and b/.doctrees/api/gimie.doctree differ diff --git a/.doctrees/api/gimie.extractors.doctree b/.doctrees/api/gimie.extractors.doctree new file mode 100644 index 00000000..e66d255b Binary files /dev/null and b/.doctrees/api/gimie.extractors.doctree differ diff --git a/.doctrees/api/gimie.graph.doctree b/.doctrees/api/gimie.graph.doctree new file mode 100644 index 00000000..172b668c Binary files /dev/null and b/.doctrees/api/gimie.graph.doctree differ diff --git a/.doctrees/api/gimie.parsers.doctree b/.doctrees/api/gimie.parsers.doctree new file mode 100644 index 00000000..8b336637 Binary files /dev/null and b/.doctrees/api/gimie.parsers.doctree differ diff --git a/.doctrees/api/gimie.parsers.license.doctree b/.doctrees/api/gimie.parsers.license.doctree new file mode 100644 index 00000000..e3312fde Binary files /dev/null and b/.doctrees/api/gimie.parsers.license.doctree differ diff --git a/.doctrees/api/modules.doctree b/.doctrees/api/modules.doctree new file mode 100644 index 00000000..8584bb05 Binary files /dev/null and b/.doctrees/api/modules.doctree differ diff --git a/.doctrees/changelog_link.doctree b/.doctrees/changelog_link.doctree new file mode 100644 index 00000000..bef6a894 Binary files /dev/null and b/.doctrees/changelog_link.doctree differ diff --git a/.doctrees/cli.doctree b/.doctrees/cli.doctree new file mode 100644 index 00000000..3ea58400 Binary files /dev/null and b/.doctrees/cli.doctree differ diff --git a/.doctrees/environment.pickle b/.doctrees/environment.pickle new file mode 100644 index 00000000..63d006fc Binary files /dev/null and b/.doctrees/environment.pickle differ diff --git a/.doctrees/index.doctree b/.doctrees/index.doctree new file mode 100644 index 00000000..cef3819e Binary files /dev/null and b/.doctrees/index.doctree differ diff --git a/.doctrees/intro/git.doctree b/.doctrees/intro/git.doctree new file mode 100644 index 00000000..4d3e6a1d Binary files /dev/null and b/.doctrees/intro/git.doctree differ diff --git a/.doctrees/intro/linked_data.doctree b/.doctrees/intro/linked_data.doctree new file mode 100644 index 00000000..eed43b44 Binary files /dev/null and b/.doctrees/intro/linked_data.doctree differ diff --git a/.doctrees/intro/quickstart.doctree b/.doctrees/intro/quickstart.doctree new file mode 100644 index 00000000..82badd84 Binary files /dev/null and b/.doctrees/intro/quickstart.doctree differ diff --git a/.doctrees/intro/tokens.doctree b/.doctrees/intro/tokens.doctree new file mode 100644 index 00000000..d2a8c29d Binary files /dev/null and b/.doctrees/intro/tokens.doctree differ diff --git a/.doctrees/intro/usage_python.doctree b/.doctrees/intro/usage_python.doctree new file mode 100644 index 00000000..21d38d3f Binary files /dev/null and b/.doctrees/intro/usage_python.doctree differ diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/_images/logo.svg b/_images/logo.svg new file mode 100644 index 00000000..8de61204 --- /dev/null +++ b/_images/logo.svg @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + gimie + + diff --git a/_modules/gimie/cli.html b/_modules/gimie/cli.html new file mode 100644 index 00000000..6d5b121a --- /dev/null +++ b/_modules/gimie/cli.html @@ -0,0 +1,339 @@ + + + + + + + + + gimie.cli | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Source code for gimie.cli

+# Gimie
+# Copyright 2022 - Swiss Data Science Center (SDSC)
+# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
+# Eidgenössische Technische Hochschule Zürich (ETHZ).
+#
+# 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.
+"""Command line interface to the gimie package."""
+from enum import Enum
+from typing import List, Optional
+
+import click
+import typer
+
+from gimie import __version__
+from gimie.parsers import get_parser, list_default_parsers, list_parsers
+from gimie.project import Project
+
+app = typer.Typer(add_completion=False)
+
+
+# Used to autogenerate docs with sphinx-click
+@click.group()
+def cli():
+    """Command line group"""
+    pass
+
+
+
[docs]class RDFFormatChoice(str, Enum): + ttl = "ttl" + jsonld = "json-ld" + nt = "nt"
+ + +
[docs]def version_callback(value: bool): + if value: + print(f"gimie {__version__}") + # Exits successfully + raise typer.Exit()
+ + +
[docs]@app.command() +def data( + url: str, + format: RDFFormatChoice = typer.Option( + RDFFormatChoice.ttl, + "--format", + show_choices=True, + help="Output serialization format for the RDF graph.", + ), + base_url: Optional[str] = typer.Option( + None, + "--base-url", + help="Specify the base URL of the git provider. Inferred by default.", + ), + include_parser: Optional[List[str]] = typer.Option( + None, + "--include-parser", + "-I", + help="Only include selected parser. Use 'gimie parsers' to list parsers.", + ), + exclude_parser: Optional[List[str]] = typer.Option( + None, + "--exclude-parser", + "-X", + help="Exclude selected parser.", + ), + version: Optional[bool] = typer.Option( + None, + "--version", + help="Display version and exit", + callback=version_callback, + ), +): + """Extract linked metadata from a Git repository at the target URL. + + The output is sent to stdout, and turtle is used as the default serialization format. + """ + parser_names = list_default_parsers() + if exclude_parser: + parser_names -= set([parser for parser in exclude_parser]) + if include_parser: + parser_names = set([parser for parser in include_parser]) + proj = Project(url, base_url=base_url, parser_names=parser_names) + repo_meta = proj.extract() + print(repo_meta.serialize(format=format.value))
+ + +
[docs]@app.command() +def advice(url: str): + """Show a metadata completion report for a Git repository + at the target URL. + + NOTE: Not implemented yet""" + ... + raise typer.Exit()
+ + +
[docs]@app.command() +def parsers( + verbose: bool = typer.Option( + False, "--verbose", help="Show parser description." + ) +): + """List available parsers, specifying which are default. + If --verbose is used, show parser description.""" + message = "" + parsers = list_parsers() + default_parsers = list_default_parsers() + + for name in parsers: + # Each parser gets their name in bold green + title = typer.style(name, fg=typer.colors.GREEN, bold=True) + default = " (default)" if name in default_parsers else "" + description = f" - {get_parser(name).__doc__}" if verbose else "" + + parser_line = f"{title}{default}{description}" + message += f"{parser_line}\n" + + typer.echo(message)
+ + +typer_cli = typer.main.get_command(app) +cli.add_command(typer_cli, "cli") + + +# This callback is triggered when gimie is called without subcommand +
[docs]@app.callback() +def callback( + version: Optional[bool] = typer.Option( + None, "--version", callback=version_callback + ) +): + """gimie digs Git repositories for metadata."""
+ + +if __name__ == "__main__": + app() +
+ +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_modules/gimie/extractors.html b/_modules/gimie/extractors.html new file mode 100644 index 00000000..7f140de3 --- /dev/null +++ b/_modules/gimie/extractors.html @@ -0,0 +1,287 @@ + + + + + + + + + gimie.extractors | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Source code for gimie.extractors

+# Gimie
+# Copyright 2022 - Swiss Data Science Center (SDSC)
+# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
+# Eidgenössische Technische Hochschule Zürich (ETHZ).
+#
+# 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.
+
+"""Git providers from which metadata can be extracted by gimie."""
+from typing import Dict, Optional, Type
+from gimie.extractors.abstract import Extractor
+from gimie.extractors.github import GithubExtractor
+from gimie.extractors.gitlab import GitlabExtractor
+from gimie.extractors.git import GitExtractor
+from gimie.utils.uri import validate_url
+
+GIT_PROVIDERS: Dict[str, Type[Extractor]] = {
+    "git": GitExtractor,
+    "github": GithubExtractor,
+    "gitlab": GitlabExtractor,
+}
+
+
+
[docs]def get_extractor( + url: str, + source: str, + base_url: Optional[str] = None, + local_path: Optional[str] = None, +) -> Extractor: + """Instantiate the correct extractor for a given source. + + Parameters + ----------- + URL + Where the repository metadata is extracted from. + source + The source of the repository (git, gitlab, github, ...). + base_url + The base URL of the git remote. + local_path + If applicable, the path to the directory where the + repository is located. + + Examples + -------- + >>> extractor = get_extractor( + ... "https://github.com/SDSC-ORD/gimie", + ... "github" + ... ) + """ + try: + return GIT_PROVIDERS[source]( + url, base_url=base_url, local_path=local_path + ) + except KeyError as err: + raise ValueError( + f"Unknown git provider: {source}.\n" + f"Supported sources: {', '.join(GIT_PROVIDERS)}" + ) from err
+ + +
[docs]def infer_git_provider(url: str) -> str: + """Given a git repository URL, return the corresponding git provider. + Local path or unsupported git providers will return "git". + + Examples + -------- + >>> infer_git_provider("https://gitlab.com/foo/bar") + 'gitlab' + >>> infer_git_provider("/foo/bar") + 'git' + >>> infer_git_provider("https://codeberg.org/dnkl/foot") + 'git' + """ + # Fall back to git if local path + if not validate_url(url): + return "git" + + # NOTE: We just check if the provider name is in the URL. + # We may want to use a more robust check. + for name in GIT_PROVIDERS.keys(): + if name in url and name != "git": + return name + + # Fall back to git for unsupported providers + return "git"
+
+ +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_modules/gimie/extractors/abstract.html b/_modules/gimie/extractors/abstract.html new file mode 100644 index 00000000..f4e480c7 --- /dev/null +++ b/_modules/gimie/extractors/abstract.html @@ -0,0 +1,261 @@ + + + + + + + + + gimie.extractors.abstract | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Source code for gimie.extractors.abstract

+# Gimie
+# Copyright 2022 - Swiss Data Science Center (SDSC)
+# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
+# Eidgenössische Technische Hochschule Zürich (ETHZ).
+#
+# 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.
+"""Abstract for Git repository extractors."""
+from abc import ABC, abstractmethod
+from typing import List, Optional
+
+from urllib.parse import urlparse
+
+from gimie.io import Resource
+from gimie.models import Repository
+
+
+
[docs]class Extractor(ABC): + """Extractor is an Abstract Base Class. It is only meant + to define a standard interface for all git repository extractors. + + Subclasses for different git providers must implement + extract() and list_files() methods. + """ + + def __init__( + self, + url: str, + base_url: Optional[str] = None, + local_path: Optional[str] = None, + ): + self.url = url + self.base_url = base_url + self.local_path = local_path + +
[docs] @abstractmethod + def extract(self) -> Repository: + """Extract metadata from the git provider into a Repository object.""" + ...
+ +
[docs] @abstractmethod + def list_files(self) -> List[Resource]: + """List all files in the repository HEAD.""" + ...
+ + @property + def path(self) -> str: + """Path to the repository without the base URL.""" + if self.base_url is None: + return urlparse(self.url).path.strip("/") + return self.url.removeprefix(self.base_url).strip("/") + + @property + def base(self) -> str: + """Base URL of the remote.""" + if self.base_url is None: + url = urlparse(self.url) + return f"{url.scheme}://{url.netloc}" + return self.base_url
+
+ +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_modules/gimie/extractors/git.html b/_modules/gimie/extractors/git.html new file mode 100644 index 00000000..eac65de0 --- /dev/null +++ b/_modules/gimie/extractors/git.html @@ -0,0 +1,354 @@ + + + + + + + + + gimie.extractors.git | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Source code for gimie.extractors.git

+# Gimie
+# Copyright 2022 - Swiss Data Science Center (SDSC)
+# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
+# Eidgenössische Technische Hochschule Zürich (ETHZ).
+#
+# 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.
+"""Extractor which uses a locally available (usually cloned) repository."""
+from dataclasses import dataclass
+from datetime import datetime
+from functools import cached_property
+import os
+import shutil
+import tempfile
+from typing import List, Optional
+import uuid
+
+import git
+import pydriller
+
+from gimie.io import LocalResource
+from gimie.models import Person, Repository
+from gimie.extractors.abstract import Extractor
+from pathlib import Path
+
+
+
[docs]@dataclass +class GitExtractor(Extractor): + """ + This class is responsible for extracting metadata from a git repository. + + Parameters + ---------- + url: str + The url of the git repository. + base_url: Optional[str] + The base url of the git remote. + local_path: Optional[str] + The local path where the cloned git repository is located. + + Attributes + ---------- + uri: Optional[str] + The URI to assign the repository in RDF. + repository: Repository + The repository we are extracting metadata from. + """ + + url: str + base_url: Optional[str] = None + local_path: Optional[str] = None + _cloned: bool = False + +
[docs] def extract(self) -> Repository: + # Assuming author is the first person to commit + self.repository = self._repo_data + + repo_meta = dict( + authors=[self._get_creator()], + contributors=self._get_contributors(), + date_created=self._get_creation_date(), + date_modified=self._get_modification_date(), + name=self.path, + url=self.url, + ) + + return Repository(**repo_meta) # type: ignore
+ +
[docs] def list_files(self) -> List[LocalResource]: + self.repository = self._repo_data + file_list = [] + + for path in Path(self.local_path).rglob("*"): # type: ignore + if (path.parts[0] == ".git") or not path.is_file(): + continue + file_list.append(LocalResource(path)) + + return file_list
+ + def __del__(self): + """Cleanup the cloned repo if it was cloned and is located in tempdir.""" + try: + # Can't be too careful with temp files + tempdir = tempfile.gettempdir() + if ( + self.local_path + and self._cloned + and self.local_path.startswith(tempdir) + and tempdir != os.getcwd() + ): + shutil.rmtree(self.local_path) + except AttributeError: + pass + + @cached_property + def _repo_data(self) -> pydriller.Repository: + """Get the repository data by accessing local data or cloning.""" + if self.local_path is None: + self._cloned = True + self.local_path = tempfile.TemporaryDirectory().name + git.Repo.clone_from(self.url, self.local_path) # type: ignore + return pydriller.Repository(self.local_path) + + def _get_contributors(self) -> List[Person]: + """Get the authors of the repository.""" + authors = set() + for commit in self.repository.traverse_commits(): + if commit.author is not None: + authors.add((commit.author.name, commit.author.email)) + return [self._dev_to_person(name, email) for name, email in authors] + + def _get_creation_date(self) -> Optional[datetime]: + """Get the creation date of the repository.""" + try: + return next(self.repository.traverse_commits()).author_date + except StopIteration: + return None + + def _get_modification_date(self) -> Optional[datetime]: + """Get the last modification date of the repository.""" + commit = None + try: + for commit in self.repository.traverse_commits(): + pass + except (StopIteration, NameError): + pass + finally: + return commit.author_date if commit else None + + def _get_creator(self) -> Optional[Person]: + """Get the creator of the repository.""" + try: + creator = next(self.repository.traverse_commits()).author + return self._dev_to_person(creator.name, creator.email) + except StopIteration: + return None + + def _dev_to_person( + self, name: Optional[str], email: Optional[str] + ) -> Person: + """Convert a Developer object to a Person object.""" + if name is None: + uid = str(uuid.uuid4()) + else: + uid = name.replace(" ", "_").lower() + dev_id = f"{self.url}/{uid}" + return Person( + _id=dev_id, + identifier=uid, + name=name, + email=email, + )
+
+ +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_modules/gimie/extractors/github.html b/_modules/gimie/extractors/github.html new file mode 100644 index 00000000..a25e41a3 --- /dev/null +++ b/_modules/gimie/extractors/github.html @@ -0,0 +1,499 @@ + + + + + + + + + gimie.extractors.github | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Source code for gimie.extractors.github

+# Gimie
+# Copyright 2022 - Swiss Data Science Center (SDSC)
+# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
+# Eidgenössische Technische Hochschule Zürich (ETHZ).
+#
+# 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.
+from __future__ import annotations
+
+from dataclasses import dataclass
+from dateutil.parser import isoparse
+from functools import cached_property
+import os
+import requests
+from typing import Any, Dict, List, Optional, Union
+from urllib.parse import urlparse
+from dotenv import load_dotenv
+
+from gimie.extractors.abstract import Extractor
+from gimie.models import (
+    Organization,
+    Person,
+    Repository,
+)
+
+from gimie.io import RemoteResource
+from gimie.extractors.common.queries import (
+    send_rest_query,
+    send_graphql_query,
+)
+
+GH_API = "https://api.github.com"
+load_dotenv()
+
+
+
[docs]def query_contributors( + url: str, headers: Dict[str, str] +) -> List[Dict[str, Any]]: + """Queries the list of contributors of target repository + using GitHub's REST and GraphQL APIs. Returns a list of GraphQL User nodes. + NOTE: This is a workaround for the lack of a contributors field in the GraphQL API. + """ + owner, name = urlparse(url).path.strip("/").split("/") + # Get contributors (available in the REST API but not GraphQL) + data = f"repos/{owner}/{name}/contributors" + contributors = send_rest_query(GH_API, data, headers=headers) + ids = [contributor["node_id"] for contributor in contributors] + # Get all contributors' metadata in 1 GraphQL query + users_query = """ + query users($ids: [ID!]!) { + nodes(ids: $ids) { + ... on User { + avatarUrl + company + login + name + organizations(first: 100) { + nodes { + avatarUrl + description + login + name + url + } + } + url + } + } + }""" + + contributors = send_graphql_query( + GH_API, users_query, data={"ids": ids}, headers=headers + ) + # Drop empty users (e.g. dependabot) + return [user for user in contributors["data"]["nodes"] if user]
+ + +
[docs]@dataclass +class GithubExtractor(Extractor): + """Extractor for GitHub repositories. Uses the GitHub GraphQL API to + extract metadata into linked data. + url: str + The url of the git repository. + base_url: Optional[str] + The base url of the git remote. + """ + + url: str + base_url: Optional[str] = None + local_path: Optional[str] = None + + token: Optional[str] = None + +
[docs] def list_files(self) -> List[RemoteResource]: + """takes the root repository folder and returns the list of files present""" + file_list = [] + file_dict = self._repo_data["object"]["entries"] + repo_url = self._repo_data["url"] + defaultbranchref = self._repo_data["defaultBranchRef"]["name"] + + for item in file_dict: + file = RemoteResource( + path=item["name"], + url=f'{repo_url}/raw/{defaultbranchref}/{item["path"]}', + headers=self._set_auth(), + ) + file_list.append(file) + return file_list
+ +
[docs] def extract(self) -> Repository: + """Extract metadata from target GitHub repository.""" + data = self._repo_data + + repo_meta = dict( + authors=[self._get_author(data["owner"])], + contributors=self._fetch_contributors(), + date_created=isoparse(data["createdAt"][:-1]), + date_modified=isoparse(data["updatedAt"][:-1]), + description=data["description"], + name=self.path, + keywords=self._get_keywords(*data["repositoryTopics"]["nodes"]), + url=self.url, + ) + if data["parent"]: + repo_meta["parent_repository"] = data["parent"]["url"] + + if data["latestRelease"]: + repo_meta["date_published"] = isoparse( + data["latestRelease"]["publishedAt"] + ) + + if data["primaryLanguage"] is not None: + repo_meta["prog_langs"] = [data["primaryLanguage"]["name"]] + + if data["latestRelease"]: + version = data["latestRelease"]["name"] + download_url = f"{self.url}/archive/refs/tags/{version}.tar.gz" + repo_meta["download_url"] = download_url + repo_meta["version"] = version + + return Repository(**repo_meta) # type: ignore
+ + @cached_property + def _repo_data(self) -> Dict[str, Any]: + """Repository metadata fetched from GraphQL endpoint.""" + owner, name = self.path.split("/") + data = {"owner": owner, "name": name} + repo_query = """ + query repo($owner: String!, $name: String!) { + repository(name: $name, owner: $owner) { + url + parent {url} + createdAt + description + latestRelease { + publishedAt + name + } + defaultBranchRef { + name + } + object(expression: "HEAD:") { + ... on Tree { + + entries { + name + path + } + } + } + mentionableUsers(first: 100) { + nodes { + login + name + avatarUrl + company + organizations(first: 100) { + nodes { + avatarUrl + description + login + name + url + } + } + url + } + } + name + owner { + avatarUrl + login + url + ... on User { + company + name + organizations(first: 100) { + nodes { + avatarUrl + description + login + name + url + } + } + } + ... on Organization { + name + description + } + } + primaryLanguage { + name + } + repositoryTopics(first: 10) { + nodes { + topic { + name + } + } + } + updatedAt + url + } + } + """ + response = send_graphql_query( + GH_API, repo_query, data, self._set_auth() + ) + + if "errors" in response: + raise ValueError(response["errors"]) + + return response["data"]["repository"] + + def _fetch_contributors(self) -> List[Person]: + """Queries the GitHub GraphQL API to extract contributors through the commit list. + NOTE: This is a workaround for the lack of a contributors field in the GraphQL API. + """ + headers = self._set_auth() + contributors = [] + resp = query_contributors(self.url, headers) + for user in resp: + contributors.append(self._get_user(user)) + return list(contributors) + + def _set_auth(self) -> Any: + """Set authentication headers for GitHub API requests.""" + try: + if not self.token: + self.token = os.environ.get("GITHUB_TOKEN") + assert self.token + headers = {"Authorization": f"token {self.token}"} + + login = requests.get(f"{GH_API}/user", headers=headers) + assert login.json().get("login") + except AssertionError: + return {} + else: + return headers + + def _get_keywords(self, *nodes: Dict[str, Any]) -> List[str]: + """Extract names from GraphQL topic nodes.""" + return [node["topic"]["name"] for node in nodes] + + def _get_organization(self, node: Dict[str, Any]) -> Organization: + """Extract details from a GraphQL organization node.""" + return Organization( + _id=node["url"], + name=node["login"], + description=node["description"], + legal_name=node["name"], + logo=node["avatarUrl"], + ) + + def _get_author(self, node: Dict[str, Any]) -> Union[Organization, Person]: + """Given the GraphQL node for a repository owner, + return the author as a Person or Organization object.""" + + if "organizations" in node: + return self._get_user(node) + + return self._get_organization(node) + + def _get_user(self, node: Dict[str, Any]) -> Person: + """Extract details from a GraphQL user node.""" + # Get user's affiliations + orgs = [ + self._get_organization(org) + for org in node["organizations"]["nodes"] + ] + return Person( + _id=node["url"], + identifier=node["login"], + name=node["name"], + affiliations=orgs, + )
+
+ +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_modules/gimie/extractors/gitlab.html b/_modules/gimie/extractors/gitlab.html new file mode 100644 index 00000000..c1a920f9 --- /dev/null +++ b/_modules/gimie/extractors/gitlab.html @@ -0,0 +1,493 @@ + + + + + + + + + gimie.extractors.gitlab | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Source code for gimie.extractors.gitlab

+# Gimie
+# Copyright 2022 - Swiss Data Science Center (SDSC)
+# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
+# Eidgenössische Technische Hochschule Zürich (ETHZ).
+#
+# 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.
+from __future__ import annotations
+from dataclasses import dataclass
+import os
+import requests
+from datetime import datetime
+from dateutil.parser import isoparse
+from functools import cached_property
+from typing import Any, Dict, List, Optional, Union
+from urllib.parse import urlparse
+from dotenv import load_dotenv
+from gimie.io import RemoteResource
+from gimie.models import (
+    Organization,
+    Person,
+    Repository,
+)
+from gimie.extractors.abstract import Extractor
+from gimie.extractors.common.queries import send_graphql_query, send_rest_query
+
+load_dotenv()
+
+
+
[docs]@dataclass +class GitlabExtractor(Extractor): + """Extractor for Gitlab repositories. Uses the Gitlab GraphQL API to + extract metadata into linked data. + url: str + The url of the git repository. + base_url: Optional[str] + The base url of the git remote. + + """ + + url: str + base_url: Optional[str] = None + local_path: Optional[str] = None + + token: Optional[str] = None + +
[docs] def list_files(self) -> List[RemoteResource]: + """takes the root repository folder and returns the list of files present""" + file_list = [] + file_dict = self._repo_data["repository"]["tree"]["blobs"]["nodes"] + defaultbranchref = self._repo_data["repository"]["rootRef"] + for item in file_dict: + file = RemoteResource( + path=item["name"], + url=f'{self.url}/-/raw/{defaultbranchref}/{item["name"]}', + headers=self._set_auth(), + ) + file_list.append(file) + return file_list
+ +
[docs] def extract(self) -> Repository: + """Extract metadata from target Gitlab repository.""" + + # fetch metadata + data = self._repo_data + + # NOTE(identifier): Each Gitlab project has a unique identifier (integer) + # NOTE(author): Fetches only the group directly related to the project + # the group takes the form: parent/subgroup + + # NOTE(contributors): contributors = project members + # who are not owners + those that have written merge requests + # owners are either multiple individuals or a group. If no user + # is marked as owner, contributors are project members or merge + # request authors + repo_meta = dict( + authors=self._safe_extract_author(data), + contributors=self._safe_extract_contributors(data), + date_created=isoparse(data["createdAt"][:-1]), + date_modified=isoparse(data["lastActivityAt"][:-1]), + description=data["description"], + identifier=urlparse(data["id"]).path.split("/")[2], + keywords=data["topics"], + name=self.path, + prog_langs=[lang["name"] for lang in data["languages"]], + url=self.url, + ) + + if data["releases"]["edges"]: + repo_meta["date_published"] = isoparse( + data["releases"]["edges"][0]["node"]["releasedAt"] + ) + + if data["releases"] and (len(data["releases"]["edges"]) > 0): + # go into releases and take the name from the first node (most recent) + version = data["releases"]["edges"][0]["node"]["name"] + repo_meta["version"] = version + repo_meta[ + "download_url" + ] = f"{self.url}/-/archive/{version}/{self.path.split('/')[-1]}-{version}.tar.gz" + return Repository(**repo_meta) # type: ignore
+ + def _safe_extract_author( + self, repo: Dict[str, Any] + ) -> List[Union[Person, Organization]]: + """Extract the author from a GraphQL repository node. + projectMembers is used if available, otherwise the author + is inferred from the project url.""" + members = repo["projectMembers"]["edges"] + if len(members) > 0: + owners = filter( + lambda m: m["node"]["accessLevel"]["stringValue"] == "OWNER", + members, + ) + return [ + self._get_author(owner["node"]["user"]) for owner in owners + ] + + if repo["group"] is not None: + return [self._get_author(repo["group"])] + + # If the author is absent from the GraphQL response (permission bug), + # fallback to the REST API + return [self._user_from_rest(self.path.split("/")[0])] + + def _safe_extract_contributors( + self, repo: dict[str, Any] + ) -> List[Person] | None: + members = [ + user["node"]["user"] + for user in repo["projectMembers"]["edges"] + if user["node"]["accessLevel"]["stringValue"] != "OWNER" + ] + merge_request_authors = [ + author["node"]["author"] + for author in repo["mergeRequests"]["edges"] + ] + contributors = members + merge_request_authors + # Drop duplicate (unhashable) dicts by "id" key + uniq_contrib = list({c["id"]: c for c in contributors}.values()) + return [self._get_user(contrib) for contrib in uniq_contrib] + + @cached_property + def _repo_data(self) -> Dict[str, Any]: + """Fetch repository metadata from GraphQL endpoint.""" + data = {"path": self.path} + project_query = """ + query project_query($path: ID!) { + project(fullPath: $path) { + name + id + description + createdAt + lastActivityAt + group { + id + name + description + avatarUrl + webUrl + } + languages { + name + share + } + topics + projectMembers { + edges { + node { + id + accessLevel { + stringValue + } + user { + id + name + username + publicEmail + webUrl + } + } + } + } + mergeRequests{ + edges { + node { + author { + id + name + username + publicEmail + webUrl + } + } + } + } + repository { + rootRef + tree{ + blobs{ + nodes { + name + webUrl + } + } + } + } + releases { + edges { + node { + name + releasedAt + } + } + } + } + } + """ + response = send_graphql_query( + self.graphql_endpoint, project_query, data, self._set_auth() + ) + if "errors" in response: + raise ValueError(response["errors"]) + + return response["data"]["project"] + + def _set_auth(self) -> Any: + """Set authentication headers for Gitlab API requests.""" + try: + if not self.token: + self.token = os.environ.get("GITLAB_TOKEN") + assert self.token + headers = {"Authorization": f"token {self.token}"} + + login = requests.get(f"{self.rest_endpoint}/user", headers=headers) + assert login.json().get("login") + except AssertionError: + return {} + else: + return headers + + def _get_author(self, node: Dict[str, Any]) -> Union[Organization, Person]: + """Given the GraphQL node for a repository owner, + return the author as a Person or Organization object.""" + # Is this the best test? + if "username" in node: + return self._get_user(node) + return self._get_organization(node) + + def _get_organization(self, node: Dict[str, Any]) -> Organization: + """Extract details from a GraphQL organization node.""" + return Organization( + _id=node["webUrl"], + name=node["name"], + description=node.get("description"), + logo=node.get("avatarUrl"), + ) + + def _get_user(self, node: Dict[str, Any]) -> Person: + """Extract details from a GraphQL user node.""" + return Person( + _id=node["webUrl"], + identifier=node["username"], + name=node.get("name"), + email=node.get("publicEmail"), + ) + + def _user_from_rest(self, username: str) -> Person: + """Given a username, use the REST API to retrieve the Person object.""" + + author = send_rest_query( + self.rest_endpoint, + f"/users?username={username}", + self._set_auth(), + ) + if isinstance(author, list): + author = author[0] + + return Person( + _id=author["web_url"], + identifier=author["username"], + name=author.get("name"), + ) + + @property + def rest_endpoint(self) -> str: + return f"{self.base}/api/v4/" + + @property + def graphql_endpoint(self) -> str: + return f"{self.base}/api"
+
+ +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_modules/gimie/graph/operations.html b/_modules/gimie/graph/operations.html new file mode 100644 index 00000000..e92b999a --- /dev/null +++ b/_modules/gimie/graph/operations.html @@ -0,0 +1,231 @@ + + + + + + + + + gimie.graph.operations | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Source code for gimie.graph.operations

+# Gimie
+# Copyright 2022 - Swiss Data Science Center (SDSC)
+# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
+# Eidgenössische Technische Hochschule Zürich (ETHZ).
+#
+# 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.
+"""Operations on graphs."""
+from functools import reduce
+from typing import Set
+
+from rdflib import Graph
+from rdflib.term import URIRef
+
+from gimie.graph import Property
+
+
+
[docs]def combine_graphs(*graphs: Graph) -> Graph: + """Combines an arbitrary number of input graphs + into a single graph.""" + return reduce(lambda g1, g2: g1 | g2, graphs)
+ + +
[docs]def properties_to_graph(uri: URIRef, properties: Set[Property]) -> Graph: + """Attaches a set of predicate-object tuples to input + URI to produce an RDF graph.""" + g = Graph() + for pred, obj in properties: + g.add((uri, pred, obj)) + return g
+
+ +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_modules/gimie/io.html b/_modules/gimie/io.html new file mode 100644 index 00000000..dfc93e76 --- /dev/null +++ b/_modules/gimie/io.html @@ -0,0 +1,313 @@ + + + + + + + + + gimie.io | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Source code for gimie.io

+# Gimie
+# Copyright 2022 - Swiss Data Science Center (SDSC)
+# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
+# Eidgenössische Technische Hochschule Zürich (ETHZ).
+#
+# 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.
+"""Standard input interfaces to local or remote resources for gimie."""
+
+import io
+import os
+from pathlib import Path
+import requests
+from typing import Iterator, Optional, Union
+
+
+
[docs]class Resource: + """Abstract class for read-only access to local or remote resources via + a file-like interface. + + Parameters + ---------- + path: + The local relative path to the resource. + """ + + path: Path + +
[docs] def open(self) -> io.RawIOBase: + raise NotImplementedError
+ + +
[docs]class LocalResource(Resource): + """Providing read-only access to local data via a file-like interface. + + Examples + -------- + >>> resource = LocalResource("README.md") + """ + + def __init__(self, path: Union[str, os.PathLike]): + self.path: Path = Path(path) + +
[docs] def open(self) -> io.RawIOBase: + return io.FileIO(self.path, mode="r")
+ + +
[docs]class RemoteResource(Resource): + """Provides read-only access to remote data via a file-like interface. + + Parameters + ---------- + url: + The URL where the resource. can be downladed from. + headers: + Optional headers to pass to the request. + + Examples + -------- + >>> url = "https://raw.githubusercontent.com/SDSC-ORD/gimie/main/README.md" + >>> content = RemoteResource("README.md", url).open().read() + >>> assert isinstance(content, bytes) + """ + + def __init__(self, path: str, url: str, headers: Optional[dict] = None): + self.path = Path(path) + self.url = url + self.headers = headers or {} + +
[docs] def open(self) -> io.RawIOBase: + resp = requests.get( + self.url, headers=self.headers, stream=True + ).iter_content(chunk_size=128) + return IterStream(resp)
+ + +
[docs]class IterStream(io.RawIOBase): + """Wraps an iterator under a like a file-like interface. + Empty elements in the iterator are ignored. + + Parameters + ---------- + iterator: + An iterator yielding bytes. + + Examples + -------- + >>> stream = IterStream(iter([b"Hello ", b"", b"World"])) + >>> stream.read() + b'Hello World' + """ + + def __init__(self, iterator: Iterator[bytes]): + self.leftover = b"" + self.iterator = iterator + +
[docs] def readable(self): + return True
+ +
[docs] def readinto(self, b): + try: + l = len(b) # We're supposed to return at most this much + while True: + chunk = self.leftover or next(self.iterator) + # skip empty elements + if not chunk: + continue + output, self.leftover = chunk[:l], chunk[l:] + b[: len(output)] = output + return len(output) + except StopIteration: + return 0 # indicate EOF
+
+ +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_modules/gimie/models.html b/_modules/gimie/models.html new file mode 100644 index 00000000..0a969669 --- /dev/null +++ b/_modules/gimie/models.html @@ -0,0 +1,372 @@ + + + + + + + + + gimie.models | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Source code for gimie.models

+# Gimie
+# Copyright 2022 - Swiss Data Science Center (SDSC)
+# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
+# Eidgenössische Technische Hochschule Zürich (ETHZ).
+#
+# 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.
+"""Data models to represent nodes in the graph generated by gimie."""
+from __future__ import annotations
+from dataclasses import dataclass, field
+from datetime import datetime
+import datetime
+from typing import List, Optional, Union
+
+from calamus.schema import JsonLDSchema
+from calamus import fields
+from rdflib import Graph
+
+from gimie.graph.namespaces import SDO
+
+
+
[docs]@dataclass(order=True) +class Release: + """ + This class represents a release of a repository. + + Parameters + ---------- + tag: str + The tag of the release. + date: datetime.datetime + The date of the release. + commit_hash: str + The commit hash of the release. + """ + + tag: str = field(compare=False) + date: datetime = field(compare=True) + commit_hash: str = field(compare=False)
+ + +
[docs]@dataclass +class Organization: + """See http//schema.org/Organization""" + + _id: str + name: str + legal_name: Optional[str] = None + email: Optional[List[str]] = None + description: Optional[str] = None + logo: Optional[str] = None
+ + +
[docs]class OrganizationSchema(JsonLDSchema): + _id = fields.Id() + name = fields.String(SDO.name) + legal_name = fields.String(SDO.legalName) + email = fields.String(SDO.email) + description = fields.String(SDO.description) + logo = fields.IRI(SDO.logo) + +
[docs] class Meta: + rdf_type = SDO.Organization + model = Organization
+ + +
[docs]@dataclass +class Person: + """See http//schema.org/Person""" + + _id: str + identifier: str + name: Optional[str] = None + email: Optional[str] = None + affiliations: Optional[List[Organization]] = None + + def __str__(self): + name = f"({self.name}) " if self.name else "" + email = f"<{self.email}> " if self.email else "" + orgs = ( + f"[{', '.join([org.name for org in self.affiliations])}]" + if self.affiliations + else "" + ) + return f"{self.identifier} {name}{email}{orgs}".strip(" ")
+ + +
[docs]class PersonSchema(JsonLDSchema): + _id = fields.Id() + identifier = fields.String(SDO.identifier) + name = fields.String(SDO.name) + affiliations = fields.Nested( + SDO.affiliation, OrganizationSchema, many=True + ) + +
[docs] class Meta: + rdf_type = SDO.Person + model = Person
+ + +
[docs]@dataclass +class Repository: + """This class represents a git repository. + It does not contain any information about the content of the repository. + See https://schema.org/SoftwareSourceCode + """ + + url: str + name: str + + authors: Optional[List[Union[Organization, Person]]] = None + contributors: Optional[List[Person]] = None + date_created: Optional[datetime] = None + date_modified: Optional[datetime] = None + date_published: Optional[datetime] = None + description: Optional[str] = None + download_url: Optional[str] = None + identifier: Optional[str] = None + keywords: Optional[List[str]] = None + licenses: Optional[List[str]] = None + parent_repository: Optional[str] = None + prog_langs: Optional[List[str]] = None + version: Optional[str] = None + + @property + def _id(self) -> str: + """Unique identifier for the repository.""" + return self.url + +
[docs] def to_graph(self) -> Graph: + """Convert repository to RDF graph.""" + jd = RepositorySchema().dumps(self) + g: Graph = Graph().parse(format="json-ld", data=str(jd)) + g.bind("schema", SDO) + return g
+ +
[docs] def serialize(self, format: str = "ttl", **kwargs) -> str: + """Serialize the RDF graph representing the instance.""" + return self.to_graph().serialize(format=format, **kwargs) # type: ignore
+ +
[docs] def jsonld(self) -> str: + """Alias for jsonld serialization.""" + return self.serialize(format="json-ld")
+ + +
[docs]class RepositorySchema(JsonLDSchema): + """This defines the schema used for json-ld serialization.""" + + _id = fields.Id() + authors = fields.Nested( + SDO.author, [PersonSchema, OrganizationSchema], many=True + ) + contributors = fields.Nested(SDO.contributor, PersonSchema, many=True) + date_created = fields.Date(SDO.dateCreated) + date_modified = fields.Date(SDO.dateModified) + date_published = fields.Date(SDO.datePublished) + description = fields.String(SDO.description) + download_url = fields.IRI(SDO.downloadUrl) + identifier = fields.String(SDO.identifier) + keywords = fields.List(SDO.keywords, fields.String) + licenses = fields.List(SDO.license, fields.IRI) + name = fields.String(SDO.name) + parent_repository = fields.IRI(SDO.isBasedOn) + prog_langs = fields.List(SDO.programmingLanguage, fields.String) + url = fields.IRI(SDO.codeRepository) + version = fields.String(SDO.version) + +
[docs] class Meta: + rdf_type = SDO.SoftwareSourceCode + model = Repository + add_value_types = False
+
+ +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_modules/gimie/parsers.html b/_modules/gimie/parsers.html new file mode 100644 index 00000000..0422118c --- /dev/null +++ b/_modules/gimie/parsers.html @@ -0,0 +1,297 @@ + + + + + + + + + gimie.parsers | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Source code for gimie.parsers

+# Gimie
+# Copyright 2022 - Swiss Data Science Center (SDSC)
+# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
+# Eidgenössische Technische Hochschule Zürich (ETHZ).
+#
+# 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.
+"""Files which can be parsed by gimie."""
+from pathlib import Path
+from typing import Iterable, NamedTuple, Optional, Set, Type
+
+from gimie.graph import Property
+from gimie.io import Resource
+from gimie.parsers.abstract import Parser
+from gimie.parsers.license import LicenseParser, is_license_filename
+
+
+
[docs]class ParserInfo(NamedTuple): + default: bool + type: Type[Parser]
+ + +PARSERS = { + "license": ParserInfo(default=True, type=LicenseParser), +} + + +
[docs]def get_parser(name: str) -> Type[Parser]: + """Get a parser by name.""" + parser = PARSERS.get(name, None) + if parser is None: + raise ValueError( + f"Unknown parser: {name}.\n" + f"Supported parsers: {', '.join(PARSERS)}" + ) + return parser.type
+ + +
[docs]def list_default_parsers() -> Set[str]: + """List the names of all default parsers.""" + return {k for k, v in PARSERS.items() if v.default}
+ + +
[docs]def list_parsers() -> Set[str]: + """List the names of all parsers.""" + return set(PARSERS.keys())
+ + +
[docs]def select_parser( + path: Path, + parsers: Optional[Set[str]] = None, +) -> Optional[Type[Parser]]: + """Select the appropriate parser from a collection based on a file path. + If no parser is found, return None. + + Parameters + ---------- + path: + The path of the file to parse. + parsers: + A set of parser names. If None, use the default collection. + """ + # Only parse licenses in the root directory + if is_license_filename(path.name) and len(path.parts) == 1: + name = "license" + else: + return None + + if name not in (parsers or list_parsers()): + return None + return get_parser(name)
+ + +
[docs]def parse_files( + files: Iterable[Resource], + parsers: Optional[Set[str]] = None, +) -> Set[Property]: + """For each input file, select appropriate parser among a collection and + parse its contents. Return the union of all parsed properties. If no parser + is found for a given file, skip it. + + Parameters + ---------- + files: + A collection of file-like objects. + parsers: + A set of parser names. If None, use the default collection. + """ + properties: Set[Property] = set() + for file in files: + parser = select_parser(file.path, parsers) + if not parser: + continue + data = file.open().read() + properties |= parser().parse(data or b"") + return properties
+
+ +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_modules/gimie/parsers/abstract.html b/_modules/gimie/parsers/abstract.html new file mode 100644 index 00000000..0db84da8 --- /dev/null +++ b/_modules/gimie/parsers/abstract.html @@ -0,0 +1,237 @@ + + + + + + + + + gimie.parsers.abstract | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Source code for gimie.parsers.abstract

+# Gimie
+# Copyright 2022 - Swiss Data Science Center (SDSC)
+# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
+# Eidgenössische Technische Hochschule Zürich (ETHZ).
+#
+# 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.
+from abc import ABC, abstractmethod
+from functools import reduce
+from typing import Iterable, Set
+
+from gimie.graph import Property
+
+
+
[docs]class Parser(ABC): + """Parser is an Abstract Base Class. It is only meant + to define a standard interface for all parsers. + + All subclasses must implement parse(). A parser parses + bytes data into a set of predicate-object tuples. + """ + + def __init__(self): + pass + +
[docs] @abstractmethod + def parse(self, data: bytes) -> Set[Property]: + """Extract predicate-object tuples from a source.""" + ...
+ +
[docs] def parse_all(self, docs: Iterable[bytes]) -> Set[Property]: + """Parse multiple sources and return the union of + predicate-object tuples.""" + properties = map(self.parse, docs) + return reduce(lambda p1, p2: p1 | p2, properties)
+
+ +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_modules/gimie/parsers/license.html b/_modules/gimie/parsers/license.html new file mode 100644 index 00000000..982bb528 --- /dev/null +++ b/_modules/gimie/parsers/license.html @@ -0,0 +1,325 @@ + + + + + + + + + gimie.parsers.license | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Source code for gimie.parsers.license

+# Gimie
+# Copyright 2022 - Swiss Data Science Center (SDSC)
+# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
+# Eidgenössische Technische Hochschule Zürich (ETHZ).
+#
+# 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.
+import csv
+from io import BytesIO
+import pkgutil
+import re
+from typing import List, Optional, Set
+
+import numpy as np
+import scipy.sparse as sp
+from rdflib.term import URIRef
+
+from gimie.graph.namespaces import SDO
+from gimie.parsers.abstract import Parser, Property
+from gimie.utils.text_processing import TfidfVectorizer
+
+
+
[docs]class LicenseParser(Parser): + """Parse LICENSE body into schema:license <spdx-url>. + Uses tf-idf-based matching.""" + + def __init__(self): + super().__init__() + +
[docs] def parse(self, data: bytes) -> Set[Property]: + """Extracts an spdx URL from a license file and returns a + set with a single tuple <schema:license> <spdx_url>. + If no matching URL is found, an empty set is returned. + """ + props = set() + license_url = match_license(data) + + if license_url: + props.add((SDO.license, URIRef(license_url))) + return props
+ + +
[docs]def match_license(data: bytes, min_similarity: float = 0.9) -> Optional[str]: + """Given a license file, returns the url of the most similar spdx license. + This is done using TF-IDF on the license text and getting the + closest match in the SPDX license corpus based on cosine similarity. + + Parameters + ---------- + data: + The license body as bytes. + + Examples + -------- + >>> match_license(open('LICENSE', 'rb').read()) + 'https://spdx.org/licenses/Apache-2.0.html' + """ + # Compute tfidf vector for input license + vectorizer = load_tfidf_vectorizer() + input_vec = vectorizer.transform([str(data)]) + + # Load ids and tfidf vectors for spdx licenses + spdx_licenses = load_spdx_ids() + spdx_vecs = load_tfidf_matrix() + # Compute cosine similarity between input_vec and spdx vectors + sim: np.ndarray = (input_vec * spdx_vecs.T).todense() + # Pick the most similar spdx vector + closest_idx = np.argmax(sim) + # If similarity is below threshold, return None + if sim[0, closest_idx] < min_similarity: + return None + closest_id = spdx_licenses[closest_idx] + return f"https://spdx.org/licenses/{closest_id}.html"
+ + +
[docs]def load_tfidf_vectorizer() -> TfidfVectorizer: + """Load tfidf matrix and vectorizer from disk.""" + + data = pkgutil.get_data(__name__, "data/tfidf_vectorizer.json") + if data is None: + raise FileNotFoundError("Could not find tfidf_vectorizer.json") + return TfidfVectorizer.model_validate_json(data)
+ + +
[docs]def load_spdx_ids() -> List[str]: + """Load spdx licenses from disk.""" + data = pkgutil.get_data(__name__, "data/spdx_licenses.csv") + if data is None: + raise FileNotFoundError("Could not find spdx_licenses.csv") + reader = csv.reader(data.decode().split("\n")) + return [l[0] for l in reader if l]
+ + +
[docs]def load_tfidf_matrix() -> sp.csr_matrix: + """Load pre-computed tfidf matrix of spdx licenses from disk. + Matrix has dimensions (n_licenses, n_features).""" + data = pkgutil.get_data(__name__, "data/tfidf_matrix.npz") + if data is None: + raise FileNotFoundError("Could not find tfidf_matrix.npz") + return sp.load_npz(BytesIO(data))
+ + +
[docs]def is_license_filename(filename: str) -> bool: + """Given an input filename, returns a boolean indicating whether the filename path looks like a license. + + Parameters + ---------- + filename: + A filename to check. + + Examples + -------- + >>> is_license_filename('LICENSE-APACHE') + True + >>> is_license_filename('README.md') + False + """ + if filename.startswith("."): + return False + pattern = r".*(license(s)?.*|lizenz|reus(e|ing).*|copy(ing)?.*)(\.(txt|md|rst))?$" + if re.match(pattern, filename, flags=re.IGNORECASE): + return True + return False
+
+ +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_modules/gimie/project.html b/_modules/gimie/project.html new file mode 100644 index 00000000..8dcbcc81 --- /dev/null +++ b/_modules/gimie/project.html @@ -0,0 +1,301 @@ + + + + + + + + + gimie.project | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Source code for gimie.project

+# Gimie
+# Copyright 2022 - Swiss Data Science Center (SDSC)
+# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
+# Eidgenössische Technische Hochschule Zürich (ETHZ).
+#
+# 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.
+"""Orchestration of multiple extractors for a given project.
+This is the main entry point for end-to-end analysis."""
+from typing import Iterable, Optional, Tuple
+
+from rdflib import Graph
+from rdflib.term import URIRef
+from urllib.parse import urlparse
+
+from gimie.extractors import get_extractor, infer_git_provider
+from gimie.graph.operations import properties_to_graph
+from gimie.parsers import parse_files
+from gimie.utils.uri import validate_url
+
+
+
[docs]class Project: + """A class to represent a project's git repository. + + + Parameters + ---------- + path: + The full path (URL) of the repository. + base_url: + The base URL of the git remote. Can be used to + specify delimitation between base URL and project name. + git_provider: + The name of the git provider to extract metadata from. + ('git', 'github', 'gitlab') + parser_names: + Names of file parsers to use. ('license'). + If None, default parsers are used (see gimie.parsers.PARSERS). + + Examples + -------- + >>> proj = Project("https://github.com/SDSC-ORD/gimie") + >>> assert isinstance(proj.extract(), Graph) + """ + + def __init__( + self, + path: str, + base_url: Optional[str] = None, + git_provider: Optional[str] = None, + parser_names: Optional[Iterable[str]] = None, + ): + if not git_provider: + git_provider = infer_git_provider(path) + + self.base_url = base_url + self.project_dir = None + self._cloned = False + if validate_url(path): + self.url = path + else: + self.project_dir = path + + self.extractor = get_extractor( + self.url, + git_provider, + base_url=self.base_url, + local_path=self.project_dir, + ) + if parser_names: + self.parsers = set(parser_names) + else: + self.parsers = None + +
[docs] def extract(self) -> Graph: + """Extract repository metadata from git provider to RDF graph and enrich with + metadata parsed from file contents.""" + + repo = self.extractor.extract() + repo_graph = repo.to_graph() + + files = self.extractor.list_files() + properties = parse_files(files, self.parsers) + + parsed_graph = properties_to_graph(URIRef(self.url), properties) + repo_graph += parsed_graph + return repo_graph
+ + +
[docs]def split_git_url(url: str) -> Tuple[str, str]: + """Split a git URL into base URL and project path. + + Examples + -------- + >>> split_git_url("https://gitlab.com/foo/bar") + ('https://gitlab.com', 'foo/bar') + """ + base_url = urlparse(url).scheme + "://" + urlparse(url).netloc + project = urlparse(url).path.strip("/") + return base_url, project
+
+ +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_modules/index.html b/_modules/index.html new file mode 100644 index 00000000..8dd59cc7 --- /dev/null +++ b/_modules/index.html @@ -0,0 +1,204 @@ + + + + + + + + + Overview: module code | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ + + +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/_sources/api/gimie.extractors.rst.txt b/_sources/api/gimie.extractors.rst.txt new file mode 100644 index 00000000..716a6d1f --- /dev/null +++ b/_sources/api/gimie.extractors.rst.txt @@ -0,0 +1,45 @@ +gimie.extractors package +======================== + +Submodules +---------- + +gimie.extractors.abstract module +-------------------------------- + +.. automodule:: gimie.extractors.abstract + :members: + :undoc-members: + :show-inheritance: + +gimie.extractors.git module +--------------------------- + +.. automodule:: gimie.extractors.git + :members: + :undoc-members: + :show-inheritance: + +gimie.extractors.github module +------------------------------ + +.. automodule:: gimie.extractors.github + :members: + :undoc-members: + :show-inheritance: + +gimie.extractors.gitlab module +------------------------------ + +.. automodule:: gimie.extractors.gitlab + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: gimie.extractors + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/gimie.graph.rst.txt b/_sources/api/gimie.graph.rst.txt new file mode 100644 index 00000000..9c0c488b --- /dev/null +++ b/_sources/api/gimie.graph.rst.txt @@ -0,0 +1,29 @@ +gimie.graph package +=================== + +Submodules +---------- + +gimie.graph.namespaces module +----------------------------- + +.. automodule:: gimie.graph.namespaces + :members: + :undoc-members: + :show-inheritance: + +gimie.graph.operations module +----------------------------- + +.. automodule:: gimie.graph.operations + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: gimie.graph + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/gimie.parsers.license.rst.txt b/_sources/api/gimie.parsers.license.rst.txt new file mode 100644 index 00000000..5f33d330 --- /dev/null +++ b/_sources/api/gimie.parsers.license.rst.txt @@ -0,0 +1,10 @@ +gimie.parsers.license package +============================= + +Module contents +--------------- + +.. automodule:: gimie.parsers.license + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/gimie.parsers.rst.txt b/_sources/api/gimie.parsers.rst.txt new file mode 100644 index 00000000..35eff8d8 --- /dev/null +++ b/_sources/api/gimie.parsers.rst.txt @@ -0,0 +1,29 @@ +gimie.parsers package +===================== + +Subpackages +----------- + +.. toctree:: + :maxdepth: 3 + + gimie.parsers.license + +Submodules +---------- + +gimie.parsers.abstract module +----------------------------- + +.. automodule:: gimie.parsers.abstract + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: gimie.parsers + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/gimie.rst.txt b/_sources/api/gimie.rst.txt new file mode 100644 index 00000000..5ba354a8 --- /dev/null +++ b/_sources/api/gimie.rst.txt @@ -0,0 +1,55 @@ +gimie package +============= + +Subpackages +----------- + +.. toctree:: + :maxdepth: 3 + + gimie.extractors + gimie.graph + gimie.parsers + +Submodules +---------- + +gimie.cli module +---------------- + +.. automodule:: gimie.cli + :members: + :undoc-members: + :show-inheritance: + +gimie.io module +--------------- + +.. automodule:: gimie.io + :members: + :undoc-members: + :show-inheritance: + +gimie.models module +------------------- + +.. automodule:: gimie.models + :members: + :undoc-members: + :show-inheritance: + +gimie.project module +-------------------- + +.. automodule:: gimie.project + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: gimie + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/api/modules.rst.txt b/_sources/api/modules.rst.txt new file mode 100644 index 00000000..4bfbc8c4 --- /dev/null +++ b/_sources/api/modules.rst.txt @@ -0,0 +1,7 @@ +gimie +===== + +.. toctree:: + :maxdepth: 3 + + gimie diff --git a/_sources/changelog_link.md.txt b/_sources/changelog_link.md.txt new file mode 100644 index 00000000..66efc0fe --- /dev/null +++ b/_sources/changelog_link.md.txt @@ -0,0 +1,2 @@ +```{include} ../CHANGELOG.md +``` diff --git a/_sources/cli.rst.txt b/_sources/cli.rst.txt new file mode 100644 index 00000000..362b9d74 --- /dev/null +++ b/_sources/cli.rst.txt @@ -0,0 +1,6 @@ +Command Line Interface +********************** + +.. click:: gimie.cli:cli + :prog: gimie + :nested: full diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 00000000..86b44442 --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,39 @@ +.. gimie documentation master file, created by + sphinx-quickstart on Tue Jun 6 16:50:55 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +.. image:: logo.svg + :width: 200 + :alt: gimie logo + + +Welcome to gimie's documentation! +================================= +gimie (Git Meta Information Extractor) is a python library and command line tool to extract structured metadata from git repositories. + +.. card:: :octicon:`mark-github;2em` `GitHub repository `_ + + Visit gimie's GitHub repository to follow the latest developments! + + +.. toctree:: + :maxdepth: 1 + :caption: Background + + Linked data - What is it and why do we use it? + Git repositories - Where code lives + Access tokens - Authenticate gimie on your behalf + +.. toctree:: + :maxdepth: 1 + :caption: Documentation + + intro/quickstart + intro/usage_python + API Documentation + CLI Documentation + +.. toctree:: changelog_link + :maxdepth: 1 + :caption: Changelog diff --git a/_sources/intro/git.rst.txt b/_sources/intro/git.rst.txt new file mode 100644 index 00000000..00ef1288 --- /dev/null +++ b/_sources/intro/git.rst.txt @@ -0,0 +1,8 @@ +Git repositories +**************** + +Software projects are usually version-controlled and hosted on a server. Git is by far the most popular version control system, and is commonly used for scientific software and data science projects. + +Git natively stores some metadata about the project authors and contributions in a local index, but git providers (servers) such has Github and GitLab store and expose more advanced information about the project and contributors. These information are served in provider-dependent format with specific APIs. + +Gimie aims to provide provider-agnostic metadata in an interoperable format. It will request data from the provider API if available, or from git by cloning the repository into a temporary folder otherwise. This metadata is then converted to the widely used schema.org standard so that it can readily be integrated with other tools and services. diff --git a/_sources/intro/linked_data.rst.txt b/_sources/intro/linked_data.rst.txt new file mode 100644 index 00000000..a709aaf1 --- /dev/null +++ b/_sources/intro/linked_data.rst.txt @@ -0,0 +1,6 @@ +Linked data +*********** + +The aim of gimie is to extract project metadata in an interoperable format. This is achieved by generating `linked data `_ following the widely used `schema.org `_ ontology. The resulting metadata can readily be augmented or integrated with other data sources. + +Gimie's output follows recommendations provided by the `codemeta project `_ , but also provides additional properties. diff --git a/_sources/intro/quickstart.rst.txt b/_sources/intro/quickstart.rst.txt new file mode 100644 index 00000000..94683cd7 --- /dev/null +++ b/_sources/intro/quickstart.rst.txt @@ -0,0 +1,55 @@ +Quick start +*********** + +The easiest way to use gimie is to run it as a command line tool. Here's how to get started: + +Install using pip or docker: + +.. tab-set:: + + .. tab-item:: pip + :sync: pip + :selected: + + .. code-block:: console + + pip install gimie + + .. tab-item:: docker + :sync: docker + + .. code-block:: console + + docker pull ghcr.io/sdsc-ord/gimie:latest + + +.. warning:: + + Before running gimie, you will need to obtain a personal access token for the GitHub and/or GitLab and export it as an environment variable. See :ref:`Token management` for more information. + + +Gimie can then be used as follows to extract repository metadata: + +.. tab-set:: + + .. tab-item:: pip + :sync: pip + :selected: + + .. code-block:: console + :emphasize-text: + + gimie data > output.ttl + + .. tab-item:: docker + :sync: docker + + .. code-block:: console + :emphasize-text: + + docker run -e GITHUB_TOKEN=${GITHUB_TOKEN} ghcr.io/sdsc-ord/gimie:latest data > output.ttl + + +.. note:: + + When running gimie in a container, you need to pass your github or gitlab token as an environment variable inside the container: diff --git a/_sources/intro/tokens.rst.txt b/_sources/intro/tokens.rst.txt new file mode 100644 index 00000000..181c0cd9 --- /dev/null +++ b/_sources/intro/tokens.rst.txt @@ -0,0 +1,84 @@ +Token management +**************** + +Gimie requests data from third party APIs (Gitlab, Github) which require authentication to work. This authentication usually works with Personal Authentication Tokens (PATs). PATs are secret codes that can be used as passwords to perform actions on your behalf, but whose permissions can be limited to specific actions. Since Gimie only consumes data, it will normally work with tokens that have read-only permission. + +Generating tokens can usually be done via the web interface of the service provider, and they must then be provided to Gimie. There are 2 ways to pass your token to Gimie: + +1. Set the corresponding Environment variable. The token will only be accessible for the current session: + + +.. tab-set:: + + .. tab-item:: Linux/Mac/BSD + :selected: + + .. code-block:: console + :emphasize-text: + + export GITLAB_TOKEN= + export GITHUB_TOKEN= + + .. tab-item:: Windows + + .. code-block:: console + :emphasize-text: + + # You may need to restart windows after this + setx GITLAB_TOKEN + setx GITHUB_TOKEN + + +2. Use a ``.env`` file in the current directory. Gimie will look for a file named ``.env`` and source it. The file contents should be as follows: + +.. code-block:: + :emphasize-text: + :caption: File: .env + + GITLAB_TOKEN= + GITHUB_TOKEN= + + +While the latter approach can be convenient to persist your token locally, it is generally not recommended to store your tokens in plain text as they are sensitive information. Hence the first approach should be preferred in most cases. + +Encrypting tokens +================= + +If you are serious about security, you should use a tool like `sops `_ or `pass `_ to encrypt your secrets. + +Below is a quick guide on how to use ``sops`` to store encrypted tokens, and decrypt them on the fly when using gimie. + +.. dropdown:: Generating PGP key + + PGP is a public key encryption system. If you don't already have one, you will need to generate a key pair to encrypt your secrets. + You can use the following command to generate a key pair. You will be prompted for a passphrase, but you may leave it empty if you wish. + + .. code-block:: bash + + gpg --gen-key + +.. dropdown:: Set up SOPS + + SOPS needs to be configured to use your PGP key. You can do so by running the following command: + Replace ```` with the fingerprint of your PGP key (it looks like ``69AB B75E ...``). You can find it by running ``gpg --fingerprint`` + Upon running the command below, `sops` will open a `vim` buffer where you can enter the desired content of your .env file. + Upon saving the file (``:wq``), ``sops`` will encrypt the file and save it as ``.enc.env``. + + .. code-block:: bash + + sops --pgp "${FINGERPRINT}" .enc.env + +.. dropdown:: Source tokens + + Whenever you want to run gimie, you can decrypt secrets on the fly and pass them to gimie using the following command: + + .. code-block:: bash + :emphasize-text: + + sops exec-env .enc.env 'gimie data ' + + Or if you just want to inspect the decrypted file: + + .. code-block:: bash + + sops --decrypt .enc.env diff --git a/_sources/intro/usage_python.rst.txt b/_sources/intro/usage_python.rst.txt new file mode 100644 index 00000000..b6b77287 --- /dev/null +++ b/_sources/intro/usage_python.rst.txt @@ -0,0 +1,36 @@ +Python Usage +************ + +Gimie can be used as a python library. Either to run the end-to-end extraction process on an input URL, or only a specific extractor. + +The end-to-end extraction is performed by ``gimie.Project`` and will automatically detect the git-provider: + +.. code-block:: python + + from gimie.project import Project + url = 'https://github.com/foo/bar' + proj = Project(url) + + +A specific extractor can also be used, for example to use with GitLab projects: + +.. code-block:: python + + from gimie.sources.gitlab import GitlabExtractor + url = "https://gitlab.com/foo/bar" + extractor = GitlabExtractor(url) + extractor.extract() + + +Once a project's metadata has been extracted, it can be stored as an rdflib graph, or serialized to RDF triples: + +.. code-block:: python + + import rdflib + graph: rdflib.Graph = proj.to_graph() + + # serialize project directly as an RDF file + proj.serialize(format='json-ld', destination='foobar.json') + + +Extractors also support the ``to_graph()`` and ``serialize()`` methods. diff --git a/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000..eb19f698 --- /dev/null +++ b/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/_sphinx_design_static/design-tabs.js b/_sphinx_design_static/design-tabs.js new file mode 100644 index 00000000..36b38cf0 --- /dev/null +++ b/_sphinx_design_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/_static/09be83022f2ac2ce16b0.woff b/_static/09be83022f2ac2ce16b0.woff new file mode 100644 index 00000000..13b53d03 Binary files /dev/null and b/_static/09be83022f2ac2ce16b0.woff differ diff --git a/_static/0ffeb7a552b36437b54c.woff b/_static/0ffeb7a552b36437b54c.woff new file mode 100644 index 00000000..21e3bdaa Binary files /dev/null and b/_static/0ffeb7a552b36437b54c.woff differ diff --git a/_static/31f64b9c465158bd6066.woff2 b/_static/31f64b9c465158bd6066.woff2 new file mode 100644 index 00000000..8611135b Binary files /dev/null and b/_static/31f64b9c465158bd6066.woff2 differ diff --git a/_static/3a43b67e5bbdfb3ab0a6.woff2 b/_static/3a43b67e5bbdfb3ab0a6.woff2 new file mode 100644 index 00000000..ae1933f3 Binary files /dev/null and b/_static/3a43b67e5bbdfb3ab0a6.woff2 differ diff --git a/_static/44fd0da18fe361a5cc7f.woff b/_static/44fd0da18fe361a5cc7f.woff new file mode 100644 index 00000000..78af4538 Binary files /dev/null and b/_static/44fd0da18fe361a5cc7f.woff differ diff --git a/_static/46830c334f8112fa510a.woff b/_static/46830c334f8112fa510a.woff new file mode 100644 index 00000000..4abc644d Binary files /dev/null and b/_static/46830c334f8112fa510a.woff differ diff --git a/_static/48af7707fe9e6494d6a5.woff b/_static/48af7707fe9e6494d6a5.woff new file mode 100644 index 00000000..d39bb52a Binary files /dev/null and b/_static/48af7707fe9e6494d6a5.woff differ diff --git a/_static/6f04107ce68d524ebe69.woff b/_static/6f04107ce68d524ebe69.woff new file mode 100644 index 00000000..f80359f7 Binary files /dev/null and b/_static/6f04107ce68d524ebe69.woff differ diff --git a/_static/9ac5da2442b734abc516.woff b/_static/9ac5da2442b734abc516.woff new file mode 100644 index 00000000..b6ad1c5b Binary files /dev/null and b/_static/9ac5da2442b734abc516.woff differ diff --git a/_static/ad463ea60cc8b68792f4.woff b/_static/ad463ea60cc8b68792f4.woff new file mode 100644 index 00000000..5e4069b3 Binary files /dev/null and b/_static/ad463ea60cc8b68792f4.woff differ diff --git a/_static/awesome-sphinx-design.31d6cfe0d16ae931b73c.js b/_static/awesome-sphinx-design.31d6cfe0d16ae931b73c.js new file mode 100644 index 00000000..e69de29b diff --git a/_static/awesome-sphinx-design.4ff695238f641b0a2852.css b/_static/awesome-sphinx-design.4ff695238f641b0a2852.css new file mode 100644 index 00000000..681655f5 --- /dev/null +++ b/_static/awesome-sphinx-design.4ff695238f641b0a2852.css @@ -0,0 +1 @@ +:root{--sd-color-tabs-label-active:var(--color-gray-dark);--sd-color-tabs-underline-active:var(--color-brand);--sd-color-tabs-label-hover:var(--color-brand)}.sd-card-title,.sd-summary-title{font-weight:500!important;letter-spacing:.025em}.sd-tab-set>label{font-weight:500;letter-spacing:.05em}details.sd-dropdown summary:focus{outline-style:solid}.sd-cards-carousel{overflow-x:auto}.sd-shadow-sm{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1)!important;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)!important;box-shadow:0 0 transparent,0 0 transparent,0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1)!important;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important} diff --git a/_static/b009a76ad6afe4ebd301.woff2 b/_static/b009a76ad6afe4ebd301.woff2 new file mode 100644 index 00000000..020729ef Binary files /dev/null and b/_static/b009a76ad6afe4ebd301.woff2 differ diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 00000000..7577acb1 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,903 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/c3b5f43fe4c8f3f1fa21.woff2 b/_static/c3b5f43fe4c8f3f1fa21.woff2 new file mode 100644 index 00000000..bb34907b Binary files /dev/null and b/_static/c3b5f43fe4c8f3f1fa21.woff2 differ diff --git a/_static/cfdd43ce3499ca7f900a.woff2 b/_static/cfdd43ce3499ca7f900a.woff2 new file mode 100644 index 00000000..5737b146 Binary files /dev/null and b/_static/cfdd43ce3499ca7f900a.woff2 differ diff --git a/_static/check-solid.svg b/_static/check-solid.svg new file mode 100644 index 00000000..92fad4b5 --- /dev/null +++ b/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/_static/clipboard.min.js b/_static/clipboard.min.js new file mode 100644 index 00000000..54b3c463 --- /dev/null +++ b/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * 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 o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/_static/copybutton.css b/_static/copybutton.css new file mode 100644 index 00000000..f1916ec7 --- /dev/null +++ b/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/_static/copybutton.js b/_static/copybutton.js new file mode 100644 index 00000000..2ea7ff3e --- /dev/null +++ b/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/_static/copybutton_funcs.js b/_static/copybutton_funcs.js new file mode 100644 index 00000000..dbe1aaad --- /dev/null +++ b/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/_static/d037cb4792991826de7d.woff b/_static/d037cb4792991826de7d.woff new file mode 100644 index 00000000..ebee16b9 Binary files /dev/null and b/_static/d037cb4792991826de7d.woff differ diff --git a/_static/d0b41bd1d599bc0a52b7.woff2 b/_static/d0b41bd1d599bc0a52b7.woff2 new file mode 100644 index 00000000..de8b746b Binary files /dev/null and b/_static/d0b41bd1d599bc0a52b7.woff2 differ diff --git a/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000..eb19f698 --- /dev/null +++ b/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/_static/design-tabs.js b/_static/design-tabs.js new file mode 100644 index 00000000..36b38cf0 --- /dev/null +++ b/_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/_static/docsearch.f1a1a5835ed7a6ab0c85.js b/_static/docsearch.f1a1a5835ed7a6ab0c85.js new file mode 100644 index 00000000..02367755 --- /dev/null +++ b/_static/docsearch.f1a1a5835ed7a6ab0c85.js @@ -0,0 +1,2 @@ +/*! For license information please see docsearch.f1a1a5835ed7a6ab0c85.js.LICENSE.txt */ +!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);n3)for(n=[n],c=3;c0?g(m.type,m.props,m.key,null,m.__v):m)){if(m.__=n,m.__b=n.__b+1,null===(p=b[s])||p&&m.key==p.key&&m.type===p.type)b[s]=void 0;else for(f=0;f3)for(n=[n],c=3;c=n.__.length&&n.__.push({}),n.__[e]}function te(e){return J=1,ne(fe,e)}function ne(e,t,n){var r=ee(W++,2);return r.t=e,r.__c||(r.__=[n?n(t):fe(void 0,t),function(e){var t=r.t(r.__[0],e);r.__[0]!==t&&(r.__=[t,r.__[1]],r.__c.setState({}))}],r.__c=K),r.__}function re(e,t){var n=ee(W++,3);!l.__s&&se(n.__H,t)&&(n.__=e,n.__H=t,K.__H.__h.push(n))}function oe(e,t){var n=ee(W++,4);!l.__s&&se(n.__H,t)&&(n.__=e,n.__H=t,K.__h.push(n))}function ce(e,t){var n=ee(W++,7);return se(n.__H,t)&&(n.__=e(),n.__H=t,n.__h=e),n.__}function ae(){$.forEach((function(e){if(e.__P)try{e.__H.__h.forEach(ue),e.__H.__h.forEach(le),e.__H.__h=[]}catch(t){e.__H.__h=[],l.__e(t,e.__v)}})),$=[]}l.__b=function(e){K=null,Q&&Q(e)},l.__r=function(e){Z&&Z(e),W=0;var t=(K=e.__c).__H;t&&(t.__h.forEach(ue),t.__h.forEach(le),t.__h=[])},l.diffed=function(e){Y&&Y(e);var t=e.__c;t&&t.__H&&t.__H.__h.length&&(1!==$.push(t)&&z===l.requestAnimationFrame||((z=l.requestAnimationFrame)||function(e){var t,n=function(){clearTimeout(r),ie&&cancelAnimationFrame(t),setTimeout(e)},r=setTimeout(n,100);ie&&(t=requestAnimationFrame(n))})(ae)),K=void 0},l.__c=function(e,t){t.some((function(e){try{e.__h.forEach(ue),e.__h=e.__h.filter((function(e){return!e.__||le(e)}))}catch(n){t.some((function(e){e.__h&&(e.__h=[])})),t=[],l.__e(n,e.__v)}})),G&&G(e,t)},l.unmount=function(e){X&&X(e);var t=e.__c;if(t&&t.__H)try{t.__H.__.forEach(ue)}catch(e){l.__e(e,t.__v)}};var ie="function"==typeof requestAnimationFrame;function ue(e){var t=K;"function"==typeof e.__c&&e.__c(),K=t}function le(e){var t=K;e.__c=e.__(),K=t}function se(e,t){return!e||e.length!==t.length||t.some((function(t,n){return t!==e[n]}))}function fe(e,t){return"function"==typeof t?t(e):t}function pe(e,t){for(var n in t)e[n]=t[n];return e}function me(e,t){for(var n in e)if("__source"!==n&&!(n in t))return!0;for(var r in t)if("__source"!==r&&e[r]!==t[r])return!0;return!1}function de(e){this.props=e}(de.prototype=new S).isPureReactComponent=!0,de.prototype.shouldComponentUpdate=function(e,t){return me(this.props,e)||me(this.state,t)};var he=l.__b;l.__b=function(e){e.type&&e.type.__f&&e.ref&&(e.props.ref=e.ref,e.ref=null),he&&he(e)};var ve="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.forward_ref")||3911,ye=function(e,t){return null==e?null:D(D(e).map(t))},_e={map:ye,forEach:ye,count:function(e){return e?D(e).length:0},only:function(e){var t=D(e);if(1!==t.length)throw"Children.only";return t[0]},toArray:D},be=l.__e;function ge(){this.__u=0,this.t=null,this.__b=null}function Oe(e){var t=e.__.__c;return t&&t.__e&&t.__e(e)}function Se(){this.u=null,this.o=null}l.__e=function(e,t,n){if(e.then)for(var r,o=t;o=o.__;)if((r=o.__c)&&r.__c)return null==t.__e&&(t.__e=n.__e,t.__k=n.__k),r.__c(e,t);be(e,t,n)},(ge.prototype=new S).__c=function(e,t){var n=t.__c,r=this;null==r.t&&(r.t=[]),r.t.push(n);var o=Oe(r.__v),c=!1,a=function(){c||(c=!0,n.componentWillUnmount=n.__c,o?o(i):i())};n.__c=n.componentWillUnmount,n.componentWillUnmount=function(){a(),n.__c&&n.__c()};var i=function(){if(!--r.__u){if(r.state.__e){var e=r.state.__e;r.__v.__k[0]=function e(t,n,r){return t&&(t.__v=null,t.__k=t.__k&&t.__k.map((function(t){return e(t,n,r)})),t.__c&&t.__c.__P===n&&(t.__e&&r.insertBefore(t.__e,t.__d),t.__c.__e=!0,t.__c.__P=r)),t}(e,e.__c.__P,e.__c.__O)}var t;for(r.setState({__e:r.__b=null});t=r.t.pop();)t.forceUpdate()}},u=!0===t.__h;r.__u++||u||r.setState({__e:r.__b=r.__v.__k[0]}),e.then(a,a)},ge.prototype.componentWillUnmount=function(){this.t=[]},ge.prototype.render=function(e,t){if(this.__b){if(this.__v.__k){var n=document.createElement("div"),r=this.__v.__k[0].__c;this.__v.__k[0]=function e(t,n,r){return t&&(t.__c&&t.__c.__H&&(t.__c.__H.__.forEach((function(e){"function"==typeof e.__c&&e.__c()})),t.__c.__H=null),null!=(t=pe({},t)).__c&&(t.__c.__P===r&&(t.__c.__P=n),t.__c=null),t.__k=t.__k&&t.__k.map((function(t){return e(t,n,r)}))),t}(this.__b,n,r.__O=r.__P)}this.__b=null}var o=t.__e&&b(O,null,e.fallback);return o&&(o.__h=null),[b(O,null,t.__e?null:e.children),o]};var Ee=function(e,t,n){if(++n[1]===n[0]&&e.o.delete(t),e.props.revealOrder&&("t"!==e.props.revealOrder[0]||!e.o.size))for(n=e.u;n;){for(;n.length>3;)n.pop()();if(n[1]>>1,1),t.i.removeChild(e)}}),F(b(we,{context:t.context},e.__v),t.l)):t.l&&t.componentWillUnmount()}function Pe(e,t){return b(je,{__v:e,i:t})}(Se.prototype=new S).__e=function(e){var t=this,n=Oe(t.__v),r=t.o.get(e);return r[0]++,function(o){var c=function(){t.props.revealOrder?(r.push(o),Ee(t,e,r)):o()};n?n(c):c()}},Se.prototype.render=function(e){this.u=null,this.o=new Map;var t=D(e.children);e.revealOrder&&"b"===e.revealOrder[0]&&t.reverse();for(var n=t.length;n--;)this.o.set(t[n],this.u=[1,0,this.u]);return e.children},Se.prototype.componentDidUpdate=Se.prototype.componentDidMount=function(){var e=this;this.o.forEach((function(t,n){Ee(e,n,t)}))};var Ie="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,ke=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|fill|flood|font|glyph(?!R)|horiz|marker(?!H|W|U)|overline|paint|stop|strikethrough|stroke|text(?!L)|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,De=function(e){return("undefined"!=typeof Symbol&&"symbol"==n(Symbol())?/fil|che|rad/i:/fil|che|ra/i).test(e)};function Ce(e,t,n){return null==t.__k&&(t.textContent=""),F(e,t),"function"==typeof n&&n(),e?e.__c:null}S.prototype.isReactComponent={},["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach((function(e){Object.defineProperty(S.prototype,e,{configurable:!0,get:function(){return this["UNSAFE_"+e]},set:function(t){Object.defineProperty(this,e,{configurable:!0,writable:!0,value:t})}})}));var xe=l.event;function Ae(){}function Ne(){return this.cancelBubble}function Re(){return this.defaultPrevented}l.event=function(e){return xe&&(e=xe(e)),e.persist=Ae,e.isPropagationStopped=Ne,e.isDefaultPrevented=Re,e.nativeEvent=e};var Te,Le={configurable:!0,get:function(){return this.class}},qe=l.vnode;l.vnode=function(e){var t=e.type,n=e.props,r=n;if("string"==typeof t){for(var o in r={},n){var c=n[o];"value"===o&&"defaultValue"in n&&null==c||("defaultValue"===o&&"value"in n&&null==n.value?o="value":"download"===o&&!0===c?c="":/ondoubleclick/i.test(o)?o="ondblclick":/^onchange(textarea|input)/i.test(o+t)&&!De(n.type)?o="oninput":/^on(Ani|Tra|Tou|BeforeInp)/.test(o)?o=o.toLowerCase():ke.test(o)?o=o.replace(/[A-Z0-9]/,"-$&").toLowerCase():null===c&&(c=void 0),r[o]=c)}"select"==t&&r.multiple&&Array.isArray(r.value)&&(r.value=D(n.children).forEach((function(e){e.props.selected=-1!=r.value.indexOf(e.props.value)}))),"select"==t&&null!=r.defaultValue&&(r.value=D(n.children).forEach((function(e){e.props.selected=r.multiple?-1!=r.defaultValue.indexOf(e.props.value):r.defaultValue==e.props.value}))),e.props=r}t&&n.class!=n.className&&(Le.enumerable="className"in n,null!=n.className&&(r.class=n.className),Object.defineProperty(r,"className",Le)),e.$$typeof=Ie,qe&&qe(e)};var Me=l.__r;l.__r=function(e){Me&&Me(e),Te=e.__c};var He={ReactCurrentDispatcher:{current:{readContext:function(e){return Te.__n[e.__c].props.value}}}};function Ue(e){return!!e&&e.$$typeof===Ie}"object"==("undefined"==typeof performance?"undefined":n(performance))&&"function"==typeof performance.now&&performance.now.bind(performance);var Fe={useState:te,useReducer:ne,useEffect:re,useLayoutEffect:oe,useRef:function(e){return J=5,ce((function(){return{current:e}}),[])},useImperativeHandle:function(e,t,n){J=6,oe((function(){"function"==typeof e?e(t()):e&&(e.current=t())}),null==n?n:n.concat(e))},useMemo:ce,useCallback:function(e,t){return J=8,ce((function(){return e}),t)},useContext:function(e){var t=K.context[e.__c],n=ee(W++,9);return n.__c=e,t?(null==n.__&&(n.__=!0,t.sub(K)),t.props.value):e.__},useDebugValue:function(e,t){l.useDebugValue&&l.useDebugValue(t?t(e):e)},version:"16.8.0",Children:_e,render:Ce,hydrate:function(e,t,n){return B(e,t),"function"==typeof n&&n(),e?e.__c:null},unmountComponentAtNode:function(e){return!!e.__k&&(F(null,e),!0)},createPortal:Pe,createElement:b,createContext:function(e,t){var n={__c:t="__cC"+m++,__:e,Consumer:function(e,t){return e.children(t)},Provider:function(e){var n,r;return this.getChildContext||(n=[],(r={})[t]=this,this.getChildContext=function(){return r},this.shouldComponentUpdate=function(e){this.props.value!==e.value&&n.some(j)},this.sub=function(e){n.push(e);var t=e.componentWillUnmount;e.componentWillUnmount=function(){n.splice(n.indexOf(e),1),t&&t.call(e)}}),e.children}};return n.Provider.__=n.Consumer.contextType=n},createFactory:function(e){return b.bind(null,e)},cloneElement:function(e){return Ue(e)?V.apply(null,arguments):e},createRef:function(){return{current:null}},Fragment:O,isValidElement:Ue,findDOMNode:function(e){return e&&(e.base||1===e.nodeType&&e)||null},Component:S,PureComponent:de,memo:function(e,t){function n(e){var n=this.props.ref,r=n==e.ref;return!r&&n&&(n.call?n(null):n.current=null),t?!t(this.props,e)||!r:me(this.props,e)}function r(t){return this.shouldComponentUpdate=n,b(e,t)}return r.displayName="Memo("+(e.displayName||e.name)+")",r.prototype.isReactComponent=!0,r.__f=!0,r},forwardRef:function(e){function t(t,r){var o=pe({},t);return delete o.ref,e(o,(r=t.ref||r)&&("object"!=n(r)||"current"in r)?r:null)}return t.$$typeof=ve,t.render=t,t.prototype.isReactComponent=t.__f=!0,t.displayName="ForwardRef("+(e.displayName||e.name)+")",t},unstable_batchedUpdates:function(e,t){return e(t)},StrictMode:O,Suspense:ge,SuspenseList:Se,lazy:function(e){var t,n,r;function o(o){if(t||(t=e()).then((function(e){n=e.default||e}),(function(e){r=e})),r)throw r;if(!n)throw t;return b(n,o)}return o.displayName="Lazy",o.__f=!0,o},__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:He};function Be(){return Fe.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},Fe.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}function Ve(){return Fe.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},Fe.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}var We=["translations"];function Ke(){return Ke=Object.assign||function(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 c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,We),c=r.buttonText,a=void 0===c?"Search":c,i=r.buttonAriaLabel,u=void 0===i?"Search":i,l=function(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,c=[],a=!0,i=!1;try{for(n=n.call(e);!(a=(r=n.next()).done)&&(c.push(r.value),2!==c.length);a=!0);}catch(e){i=!0,o=e}finally{try{a||null==n.return||n.return()}finally{if(i)throw o}}return c}}(e)||function(e,t){if(e){if("string"==typeof e)return ze(e,2);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)?ze(e,2):void 0}}(e)||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.")}()}(te(null)),s=l[0],f=l[1];return re((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?f("⌘"):f("Ctrl"))}),[]),Fe.createElement("button",Ke({type:"button",className:"DocSearch DocSearch-Button","aria-label":u},o,{ref:t}),Fe.createElement("span",{className:"DocSearch-Button-Container"},Fe.createElement(Ve,null),Fe.createElement("span",{className:"DocSearch-Button-Placeholder"},a)),Fe.createElement("span",{className:"DocSearch-Button-Keys"},null!==s&&Fe.createElement(Fe.Fragment,null,Fe.createElement("kbd",{className:"DocSearch-Button-Key"},"Ctrl"===s?Fe.createElement(Be,null):s),Fe.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))}));function $e(e){return e.reduce((function(e,t){return e.concat(t)}),[])}var Qe=0;function Ze(e){return 0===e.collections.length?0:e.collections.reduce((function(e,t){return e+t.items.length}),0)}var Ye=function(){},Ge=[{segment:"autocomplete-core",version:"1.8.2"}];function Xe(e,t){var n=t;return{then:function(t,r){return Xe(e.then(tt(t,n,e),tt(r,n,e)),n)},catch:function(t){return Xe(e.catch(tt(t,n,e)),n)},finally:function(t){return t&&n.onCancelList.push(t),Xe(e.finally(tt(t&&function(){return n.onCancelList=[],t()},n,e)),n)},cancel:function(){n.isCanceled=!0;var e=n.onCancelList;n.onCancelList=[],e.forEach((function(e){e()}))},isCanceled:function(){return!0===n.isCanceled}}}function et(e){return Xe(e,{isCanceled:!1,onCancelList:[]})}function tt(e,t,n){return e?function(n){return t.isCanceled?n:e(n)}:n}function nt(e,t,n,r){if(!n)return null;if(e<0&&(null===t||null!==r&&0===t))return n+e;var o=(null===t?-1:t)+e;return o<=-1||o>=n?null===r?null:0:o}function rt(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 ot(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 c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,Ct);qt&&o.environment.clearTimeout(qt);var l=u.setCollections,s=u.setIsOpen,f=u.setQuery,p=u.setActiveItemId,m=u.setStatus;if(f(c),p(o.defaultActiveItemId),!c&&!1===o.openOnFocus){var d,h=i.getState().collections.map((function(e){return At(At({},e),{},{items:[]})}));m("idle"),l(h),s(null!==(d=r.isOpen)&&void 0!==d?d:o.shouldPanelOpen({state:i.getState()}));var v=et(Mt(h).then((function(){return Promise.resolve()})));return i.pendingRequests.add(v)}m("loading"),qt=o.environment.setTimeout((function(){m("stalled")}),o.stallThreshold);var y=et(Mt(o.getSources(At({query:c,refresh:a,state:i.getState()},u)).then((function(e){return Promise.all(e.map((function(e){return Promise.resolve(e.getItems(At({query:c,refresh:a,state:i.getState()},u))).then((function(t){return function(e,t,n){if(o=e,Boolean(null==o?void 0:o.execute)){var r="algolia"===e.requesterId?Object.assign.apply(Object,[{}].concat(Pt(Object.keys(n.context).map((function(e){var t;return null===(t=n.context[e])||void 0===t?void 0:t.__algoliaSearchParameters}))))):{};return wt(wt({},e),{},{requests:e.queries.map((function(n){return{query:"algolia"===e.requesterId?wt(wt({},n),{},{params:wt(wt({},r),n.params)}):n,sourceId:t,transformResponse:e.transformResponse}}))})}var o;return{items:e,sourceId:t}}(t,e.sourceId,i.getState())}))}))).then(Dt).then((function(t){return function(e,t,n){return t.map((function(t){var r=e.filter((function(e){return e.sourceId===t.sourceId})),o=r.map((function(e){return e.items})),c=r[0].transformResponse,a=c?c(function(e){var t=e.map((function(e){var t;return lt(lt({},e),{},{hits:null===(t=e.hits)||void 0===t?void 0:t.map((function(t){return lt(lt({},t),{},{__autocomplete_indexName:e.index,__autocomplete_queryID:e.queryID})}))})}));return{results:t,hits:t.map((function(e){return e.hits})).filter(Boolean),facetHits:t.map((function(e){var t;return null===(t=e.facetHits)||void 0===t?void 0:t.map((function(e){return{label:e.value,count:e.count,_highlightResult:{label:{value:e.highlighted}}}}))})).filter(Boolean)}}(o)):o;return t.onResolve({source:t,results:o,items:a,state:n.getState()}),Array.isArray(a),a.every(Boolean),'The `getItems` function from source "'.concat(t.sourceId,'" must return an array of items but returned ').concat(JSON.stringify(void 0),".\n\nDid you forget to return items?\n\nSee: https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/sources/#param-getitems"),{source:t,items:a}}))}(t,e,i)})).then((function(e){return function(e){var t=e.props,n=e.state,r=e.collections.reduce((function(e,t){return Ot(Ot({},e),{},St({},t.source.sourceId,Ot(Ot({},t.source),{},{getItems:function(){return $e(t.items)}})))}),{}),o=t.plugins.reduce((function(e,t){return t.reshape?t.reshape(e):e}),{sourcesBySourceId:r,state:n}).sourcesBySourceId;return $e(t.reshape({sourcesBySourceId:o,sources:Object.values(o),state:n})).filter(Boolean).map((function(e){return{source:e,items:e.getItems()}}))}({collections:e,props:o,state:i.getState()})}))})))).then((function(e){var n;m("idle"),l(e);var f=o.shouldPanelOpen({state:i.getState()});s(null!==(n=r.isOpen)&&void 0!==n?n:o.openOnFocus&&!c&&f||f);var p=at(i.getState());if(null!==i.getState().activeItemId&&p){var d=p.item,h=p.itemInputValue,v=p.itemUrl,y=p.source;y.onActive(At({event:t,item:d,itemInputValue:h,itemUrl:v,refresh:a,source:y,state:i.getState()},u))}})).finally((function(){m("idle"),qt&&o.environment.clearTimeout(qt)}));return i.pendingRequests.add(y)}var Ut=["event","props","refresh","store"];function Ft(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 Bt(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function tn(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 nn(e){for(var t=1;t0},reshape:function(e){return e.sources}},e),{},{id:null!==(n=e.id)&&void 0!==n?n:"autocomplete-".concat(Qe++),plugins:o,initialState:_t({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(function(e){return function(e){if(Array.isArray(e))return vt(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){if("string"==typeof e)return vt(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)?vt(e,t):void 0}}(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.")}()}(o.map((function(e){return e.getSources}))),[e.getSources]).filter(Boolean).map((function(e){return function(e,t){var n=[];return Promise.resolve(e(t)).then((function(e){return Array.isArray(e),Promise.all(e.filter((function(e){return Boolean(e)})).map((function(e){if(e.sourceId,n.includes(e.sourceId))throw new Error("[Autocomplete] The `sourceId` ".concat(JSON.stringify(e.sourceId)," is not unique."));n.push(e.sourceId);var t={getItemInputValue:function(e){return e.state.query},getItemUrl:function(){},onSelect:function(e){(0,e.setIsOpen)(!1)},onActive:Ye,onResolve:Ye};Object.keys(t).forEach((function(e){t[e].__default=!0}));var r=ot(ot({},t),e);return Promise.resolve(r)})))}))}(e,n)}))).then((function(e){return $e(e)})).then((function(e){return e.map((function(e){return _t(_t({},e),{},{onSelect:function(n){e.onSelect(n),t.forEach((function(e){var t;return null===(t=e.onSelect)||void 0===t?void 0:t.call(e,n)}))},onActive:function(n){e.onActive(n),t.forEach((function(e){var t;return null===(t=e.onActive)||void 0===t?void 0:t.call(e,n)}))},onResolve:function(n){e.onResolve(n),t.forEach((function(e){var t;return null===(t=e.onResolve)||void 0===t?void 0:t.call(e,n)}))}})}))}))},navigator:_t({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=function(e,t,n){var r,o=t.initialState;return{getState:function(){return o},dispatch:function(r,c){var a=function(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,Ut);if("ArrowUp"===t.key||"ArrowDown"===t.key){var a=function(){var e=n.environment.document.getElementById("".concat(n.id,"-item-").concat(o.getState().activeItemId));e&&(e.scrollIntoViewIfNeeded?e.scrollIntoViewIfNeeded(!1):e.scrollIntoView(!1))},i=function(){var e=at(o.getState());if(null!==o.getState().activeItemId&&e){var n=e.item,a=e.itemInputValue,i=e.itemUrl,u=e.source;u.onActive(Bt({event:t,item:n,itemInputValue:a,itemUrl:i,refresh:r,source:u,state:o.getState()},c))}};t.preventDefault(),!1===o.getState().isOpen&&(n.openOnFocus||Boolean(o.getState().query))?Ht(Bt({event:t,props:n,query:o.getState().query,refresh:r,store:o},c)).then((function(){o.dispatch(t.key,{nextActiveItemId:n.defaultActiveItemId}),i(),setTimeout(a,0)})):(o.dispatch(t.key,{}),i(),a())}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 u=at(o.getState()),l=u.item,s=u.itemInputValue,f=u.itemUrl,p=u.source;if(t.metaKey||t.ctrlKey)void 0!==f&&(p.onSelect(Bt({event:t,item:l,itemInputValue:s,itemUrl:f,refresh:r,source:p,state:o.getState()},c)),n.navigator.navigateNewTab({itemUrl:f,item:l,state:o.getState()}));else if(t.shiftKey)void 0!==f&&(p.onSelect(Bt({event:t,item:l,itemInputValue:s,itemUrl:f,refresh:r,source:p,state:o.getState()},c)),n.navigator.navigateNewWindow({itemUrl:f,item:l,state:o.getState()}));else if(t.altKey);else{if(void 0!==f)return p.onSelect(Bt({event:t,item:l,itemInputValue:s,itemUrl:f,refresh:r,source:p,state:o.getState()},c)),void n.navigator.navigate({itemUrl:f,item:l,state:o.getState()});Ht(Bt({event:t,nextState:{isOpen:!1},props:n,query:s,refresh:r,store:o},c)).then((function(){p.onSelect(Bt({event:t,item:l,itemInputValue:s,itemUrl:f,refresh:r,source:p,state:o.getState()},c))}))}}}(Gt({event:e,props:t,refresh:n,store:r},o))},onFocus:a,onBlur:Ye,onClick:function(n){e.inputElement!==t.environment.document.activeElement||r.getState().isOpen||a(n)}},s)},getPanelProps:function(e){return Gt({onMouseDown:function(e){e.preventDefault()},onMouseLeave:function(){r.dispatch("mouseleave",null)}},e)},getListProps:function(e){var n=e||{},r=n.sourceIndex,o=en(n,Qt);return Gt({role:"listbox","aria-labelledby":"".concat(c(t.id,r),"-label"),id:"".concat(c(t.id,r),"-list")},o)},getItemProps:function(e){var a=e.item,i=e.source,u=e.sourceIndex,l=en(e,Zt);return Gt({id:"".concat(c(t.id,u),"-item-").concat(a.__autocomplete_id),role:"option","aria-selected":r.getState().activeItemId===a.__autocomplete_id,onMouseMove:function(e){if(a.__autocomplete_id!==r.getState().activeItemId){r.dispatch("mousemove",a.__autocomplete_id);var t=at(r.getState());if(null!==r.getState().activeItemId&&t){var c=t.item,i=t.itemInputValue,u=t.itemUrl,l=t.source;l.onActive(Gt({event:e,item:c,itemInputValue:i,itemUrl:u,refresh:n,source:l,state:r.getState()},o))}}},onMouseDown:function(e){e.preventDefault()},onClick:function(e){var c=i.getItemInputValue({item:a,state:r.getState()}),u=i.getItemUrl({item:a,state:r.getState()});(u?Promise.resolve():Ht(Gt({event:e,nextState:{isOpen:!1},props:t,query:c,refresh:n,store:r},o))).then((function(){i.onSelect(Gt({event:e,item:a,itemInputValue:c,itemUrl:u,refresh:n,source:i,state:r.getState()},o))}))}},l)}}}(pn({props:n,refresh:a,store:r,navigator:n.navigator},o));function a(){return Ht(pn({event:new Event("input"),nextState:{isOpen:r.getState().isOpen},props:n,navigator:n.navigator,query:r.getState().query,refresh:a,store:r},o))}return n.plugins.forEach((function(e){var r;return null===(r=e.subscribe)||void 0===r?void 0:r.call(e,pn(pn({},o),{},{navigator:n.navigator,refresh:a,onSelect:function(e){t.push({onSelect:e})},onActive:function(e){t.push({onActive:e})},onResolve:function(e){t.push({onResolve: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 c=o.document.createElement("meta"),a=o.document.querySelector("head");c.name="algolia:metadata",setTimeout((function(){c.content=JSON.stringify(r),a.appendChild(c)}),0)}}({metadata:on({plugins:n.plugins,options:e}),environment:n.environment}),pn(pn({refresh:a,navigator:n.navigator},c),o)}function hn(e){var t=e.translations,n=(void 0===t?{}:t).searchByText,r=void 0===n?"Search by":n;return Fe.createElement("a",{href:"https://www.algolia.com/ref/docsearch/?utm_source=".concat(window.location.hostname,"&utm_medium=referral&utm_content=powered_by&utm_campaign=docsearch"),target:"_blank",rel:"noopener noreferrer"},Fe.createElement("span",{className:"DocSearch-Label"},r),Fe.createElement("svg",{width:"77",height:"19","aria-label":"Algolia",role:"img",id:"Layer_1",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 2196.2 500"},Fe.createElement("defs",null,Fe.createElement("style",null,".cls-1,.cls-2{fill:#003dff;}.cls-2{fill-rule:evenodd;}")),Fe.createElement("path",{className:"cls-2",d:"M1070.38,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"}),Fe.createElement("rect",{className:"cls-1",x:"1845.88",y:"104.73",width:"62.58",height:"277.9",rx:"5.9",ry:"5.9"}),Fe.createElement("path",{className:"cls-2",d:"M1851.78,71.38h50.77c3.26,0,5.9-2.64,5.9-5.9V5.9c0-3.62-3.24-6.39-6.82-5.83l-50.77,7.95c-2.87,.45-4.99,2.92-4.99,5.83v51.62c0,3.26,2.64,5.9,5.9,5.9Z"}),Fe.createElement("path",{className:"cls-2",d:"M1764.03,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"}),Fe.createElement("path",{className:"cls-2",d:"M1631.95,142.72c-11.14-12.25-24.83-21.65-40.78-28.31-15.92-6.53-33.26-9.85-52.07-9.85-18.78,0-36.15,3.17-51.92,9.85-15.59,6.66-29.29,16.05-40.76,28.31-11.47,12.23-20.38,26.87-26.76,44.03-6.38,17.17-9.24,37.37-9.24,58.36,0,20.99,3.19,36.87,9.55,54.21,6.38,17.32,15.14,32.11,26.45,44.36,11.29,12.23,24.83,21.62,40.6,28.46,15.77,6.83,40.12,10.33,52.4,10.48,12.25,0,36.78-3.82,52.7-10.48,15.92-6.68,29.46-16.23,40.78-28.46,11.29-12.25,20.05-27.04,26.25-44.36,6.22-17.34,9.24-33.22,9.24-54.21,0-20.99-3.34-41.19-10.03-58.36-6.38-17.17-15.14-31.8-26.43-44.03Zm-44.43,163.75c-11.47,15.75-27.56,23.7-48.09,23.7-20.55,0-36.63-7.8-48.1-23.7-11.47-15.75-17.21-34.01-17.21-61.2,0-26.89,5.59-49.14,17.06-64.87,11.45-15.75,27.54-23.52,48.07-23.52,20.55,0,36.63,7.78,48.09,23.52,11.47,15.57,17.36,37.98,17.36,64.87,0,27.19-5.72,45.3-17.19,61.2Z"}),Fe.createElement("path",{className:"cls-2",d:"M894.42,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"}),Fe.createElement("path",{className:"cls-2",d:"M2133.97,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"}),Fe.createElement("path",{className:"cls-2",d:"M1314.05,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-11.79,18.34-19.6,39.64-22.11,62.59-.58,5.3-.88,10.68-.88,16.14s.31,11.15,.93,16.59c4.28,38.09,23.14,71.61,50.66,94.52,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47h0c17.99,0,34.61-5.93,48.16-15.97,16.29-11.58,28.88-28.54,34.48-47.75v50.26h-.11v11.08c0,21.84-5.71,38.27-17.34,49.36-11.61,11.08-31.04,16.63-58.25,16.63-11.12,0-28.79-.59-46.6-2.41-2.83-.29-5.46,1.5-6.27,4.22l-12.78,43.11c-1.02,3.46,1.27,7.02,4.83,7.53,21.52,3.08,42.52,4.68,54.65,4.68,48.91,0,85.16-10.75,108.89-32.21,21.48-19.41,33.15-48.89,35.2-88.52V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,64.1s.65,139.13,0,143.36c-12.08,9.77-27.11,13.59-43.49,14.7-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-1.32,0-2.63-.03-3.94-.1-40.41-2.11-74.52-37.26-74.52-79.38,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33Z"}),Fe.createElement("path",{className:"cls-1",d:"M249.83,0C113.3,0,2,110.09,.03,246.16c-2,138.19,110.12,252.7,248.33,253.5,42.68,.25,83.79-10.19,120.3-30.03,3.56-1.93,4.11-6.83,1.08-9.51l-23.38-20.72c-4.75-4.21-11.51-5.4-17.36-2.92-25.48,10.84-53.17,16.38-81.71,16.03-111.68-1.37-201.91-94.29-200.13-205.96,1.76-110.26,92-199.41,202.67-199.41h202.69V407.41l-115-102.18c-3.72-3.31-9.42-2.66-12.42,1.31-18.46,24.44-48.53,39.64-81.93,37.34-46.33-3.2-83.87-40.5-87.34-86.81-4.15-55.24,39.63-101.52,94-101.52,49.18,0,89.68,37.85,93.91,85.95,.38,4.28,2.31,8.27,5.52,11.12l29.95,26.55c3.4,3.01,8.79,1.17,9.63-3.3,2.16-11.55,2.92-23.58,2.07-35.92-4.82-70.34-61.8-126.93-132.17-131.26-80.68-4.97-148.13,58.14-150.27,137.25-2.09,77.1,61.08,143.56,138.19,145.26,32.19,.71,62.03-9.41,86.14-26.95l150.26,133.2c6.44,5.71,16.61,1.14,16.61-7.47V9.48C499.66,4.25,495.42,0,490.18,0H249.83Z"})))}function vn(e){return Fe.createElement("svg",{width:"15",height:"15","aria-label":e.ariaLabel,role:"img"},Fe.createElement("g",{fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"1.2"},e.children))}function yn(e){var t=e.translations,n=void 0===t?{}:t,r=n.selectText,o=void 0===r?"to select":r,c=n.selectKeyAriaLabel,a=void 0===c?"Enter key":c,i=n.navigateText,u=void 0===i?"to navigate":i,l=n.navigateUpKeyAriaLabel,s=void 0===l?"Arrow up":l,f=n.navigateDownKeyAriaLabel,p=void 0===f?"Arrow down":f,m=n.closeText,d=void 0===m?"to close":m,h=n.closeKeyAriaLabel,v=void 0===h?"Escape key":h,y=n.searchByText,_=void 0===y?"Search by":y;return Fe.createElement(Fe.Fragment,null,Fe.createElement("div",{className:"DocSearch-Logo"},Fe.createElement(hn,{translations:{searchByText:_}})),Fe.createElement("ul",{className:"DocSearch-Commands"},Fe.createElement("li",null,Fe.createElement("kbd",{className:"DocSearch-Commands-Key"},Fe.createElement(vn,{ariaLabel:a},Fe.createElement("path",{d:"M12 3.53088v3c0 1-1 2-2 2H4M7 11.53088l-3-3 3-3"}))),Fe.createElement("span",{className:"DocSearch-Label"},o)),Fe.createElement("li",null,Fe.createElement("kbd",{className:"DocSearch-Commands-Key"},Fe.createElement(vn,{ariaLabel:p},Fe.createElement("path",{d:"M7.5 3.5v8M10.5 8.5l-3 3-3-3"}))),Fe.createElement("kbd",{className:"DocSearch-Commands-Key"},Fe.createElement(vn,{ariaLabel:s},Fe.createElement("path",{d:"M7.5 11.5v-8M10.5 6.5l-3-3-3 3"}))),Fe.createElement("span",{className:"DocSearch-Label"},u)),Fe.createElement("li",null,Fe.createElement("kbd",{className:"DocSearch-Commands-Key"},Fe.createElement(vn,{ariaLabel:v},Fe.createElement("path",{d:"M13.6167 8.936c-.1065.3583-.6883.962-1.4875.962-.7993 0-1.653-.9165-1.653-2.1258v-.5678c0-1.2548.7896-2.1016 1.653-2.1016.8634 0 1.3601.4778 1.4875 1.0724M9 6c-.1352-.4735-.7506-.9219-1.46-.8972-.7092.0246-1.344.57-1.344 1.2166s.4198.8812 1.3445.9805C8.465 7.3992 8.968 7.9337 9 8.5c.032.5663-.454 1.398-1.4595 1.398C6.6593 9.898 6 9 5.963 8.4851m-1.4748.5368c-.2635.5941-.8099.876-1.5443.876s-1.7073-.6248-1.7073-2.204v-.4603c0-1.0416.721-2.131 1.7073-2.131.9864 0 1.6425 1.031 1.5443 2.2492h-2.956"}))),Fe.createElement("span",{className:"DocSearch-Label"},d))))}function _n(e){var t=e.hit,n=e.children;return Fe.createElement("a",{href:t.url},n)}function bn(){return Fe.createElement("svg",{viewBox:"0 0 38 38",stroke:"currentColor",strokeOpacity:".5"},Fe.createElement("g",{fill:"none",fillRule:"evenodd"},Fe.createElement("g",{transform:"translate(1 1)",strokeWidth:"2"},Fe.createElement("circle",{strokeOpacity:".3",cx:"18",cy:"18",r:"18"}),Fe.createElement("path",{d:"M36 18c0-9.94-8.06-18-18-18"},Fe.createElement("animateTransform",{attributeName:"transform",type:"rotate",from:"0 18 18",to:"360 18 18",dur:"1s",repeatCount:"indefinite"})))))}function gn(){return Fe.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},Fe.createElement("g",{stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"},Fe.createElement("path",{d:"M3.18 6.6a8.23 8.23 0 1112.93 9.94h0a8.23 8.23 0 01-11.63 0"}),Fe.createElement("path",{d:"M6.44 7.25H2.55V3.36M10.45 6v5.6M10.45 11.6L13 13"})))}function On(){return Fe.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},Fe.createElement("path",{d:"M10 10l5.09-5.09L10 10l5.09 5.09L10 10zm0 0L4.91 4.91 10 10l-5.09 5.09L10 10z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}function Sn(){return Fe.createElement("svg",{className:"DocSearch-Hit-Select-Icon",width:"20",height:"20",viewBox:"0 0 20 20"},Fe.createElement("g",{stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"},Fe.createElement("path",{d:"M18 3v4c0 2-2 4-4 4H2"}),Fe.createElement("path",{d:"M8 17l-6-6 6-6"})))}var En=function(){return Fe.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},Fe.createElement("path",{d:"M17 6v12c0 .52-.2 1-1 1H4c-.7 0-1-.33-1-1V2c0-.55.42-1 1-1h8l5 5zM14 8h-3.13c-.51 0-.87-.34-.87-.87V4",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinejoin:"round"}))};function wn(e){switch(e.type){case"lvl1":return Fe.createElement(En,null);case"content":return Fe.createElement(Pn,null);default:return Fe.createElement(jn,null)}}function jn(){return Fe.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},Fe.createElement("path",{d:"M13 13h4-4V8H7v5h6v4-4H7V8H3h4V3v5h6V3v5h4-4v5zm-6 0v4-4H3h4z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}function Pn(){return Fe.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},Fe.createElement("path",{d:"M17 5H3h14zm0 5H3h14zm0 5H3h14z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinejoin:"round"}))}function In(){return Fe.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},Fe.createElement("path",{d:"M10 14.2L5 17l1-5.6-4-4 5.5-.7 2.5-5 2.5 5 5.6.8-4 4 .9 5.5z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinejoin:"round"}))}function kn(){return Fe.createElement("svg",{width:"40",height:"40",viewBox:"0 0 20 20",fill:"none",fillRule:"evenodd",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"},Fe.createElement("path",{d:"M19 4.8a16 16 0 00-2-1.2m-3.3-1.2A16 16 0 001.1 4.7M16.7 8a12 12 0 00-2.8-1.4M10 6a12 12 0 00-6.7 2M12.3 14.7a4 4 0 00-4.5 0M14.5 11.4A8 8 0 0010 10M3 16L18 2M10 18h0"}))}function Dn(){return Fe.createElement("svg",{width:"40",height:"40",viewBox:"0 0 20 20",fill:"none",fillRule:"evenodd",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"},Fe.createElement("path",{d:"M15.5 4.8c2 3 1.7 7-1 9.7h0l4.3 4.3-4.3-4.3a7.8 7.8 0 01-9.8 1m-2.2-2.2A7.8 7.8 0 0113.2 2.4M2 18L18 2"}))}function Cn(e){var t=e.translations,n=void 0===t?{}:t,r=n.titleText,o=void 0===r?"Unable to fetch results":r,c=n.helpText,a=void 0===c?"You might want to check your network connection.":c;return Fe.createElement("div",{className:"DocSearch-ErrorScreen"},Fe.createElement("div",{className:"DocSearch-Screen-Icon"},Fe.createElement(kn,null)),Fe.createElement("p",{className:"DocSearch-Title"},o),Fe.createElement("p",{className:"DocSearch-Help"},a))}var xn=["translations"];function An(e,t){(null==t||t>e.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 c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,xn),o=n.noResultsText,c=void 0===o?"No results for":o,a=n.suggestedQueryText,i=void 0===a?"Try searching for":a,u=n.reportMissingResultsText,l=void 0===u?"Believe this query should return results?":u,s=n.reportMissingResultsLinkText,f=void 0===s?"Let us know.":s,p=r.state.context.searchSuggestions;return Fe.createElement("div",{className:"DocSearch-NoResults"},Fe.createElement("div",{className:"DocSearch-Screen-Icon"},Fe.createElement(Dn,null)),Fe.createElement("p",{className:"DocSearch-Title"},c,' "',Fe.createElement("strong",null,r.state.query),'"'),p&&p.length>0&&Fe.createElement("div",{className:"DocSearch-NoResults-Prefill-List"},Fe.createElement("p",{className:"DocSearch-Help"},i,":"),Fe.createElement("ul",null,p.slice(0,3).reduce((function(e,t){return[].concat(function(e){return function(e){if(Array.isArray(e))return An(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){if("string"==typeof e)return An(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)?An(e,t):void 0}}(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.")}()}(e),[Fe.createElement("li",{key:t},Fe.createElement("button",{className:"DocSearch-Prefill",key:t,type:"button",onClick:function(){r.setQuery(t.toLowerCase()+" "),r.refresh(),r.inputRef.current.focus()}},t))])}),[]))),r.getMissingResultsUrl&&Fe.createElement("p",{className:"DocSearch-Help"},"".concat(l," "),Fe.createElement("a",{href:r.getMissingResultsUrl({query:r.state.query}),target:"_blank",rel:"noopener noreferrer"},f)))}var Rn=["hit","attribute","tagName"];function Tn(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 Ln(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,Rn)),{},{dangerouslySetInnerHTML:{__html:Mn(t,"_snippetResult.".concat(n,".value"))||Mn(t,n)}}))}function Un(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,c=[],a=!0,i=!1;try{for(n=n.call(e);!(a=(r=n.next()).done)&&(c.push(r.value),!t||c.length!==t);a=!0);}catch(e){i=!0,o=e}finally{try{a||null==n.return||n.return()}finally{if(i)throw o}}return c}}(e,t)||function(e,t){if(e){if("string"==typeof e)return Fn(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)?Fn(e,t):void 0}}(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 Fn(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n|<\/mark>)/g,Zn=RegExp(Qn.source);function Yn(e){var t,n,r,o,c,a=e;if(!a.__docsearch_parent&&!e._highlightResult)return e.hierarchy.lvl0;var i=((a.__docsearch_parent?null===(t=a.__docsearch_parent)||void 0===t||null===(n=t._highlightResult)||void 0===n||null===(r=n.hierarchy)||void 0===r?void 0:r.lvl0:null===(o=e._highlightResult)||void 0===o||null===(c=o.hierarchy)||void 0===c?void 0:c.lvl0)||{}).value;return i&&Zn.test(i)?i.replace(Qn,""):i}function Gn(){return Gn=Object.assign||function(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,er),o=n.recentSearchesTitle,c=void 0===o?"Recent":o,a=n.noRecentSearchesText,i=void 0===a?"No recent searches":a,u=n.saveRecentSearchButtonTitle,l=void 0===u?"Save this search":u,s=n.removeRecentSearchButtonTitle,f=void 0===s?"Remove this search from history":s,p=n.favoriteSearchesTitle,m=void 0===p?"Favorite":p,d=n.removeFavoriteSearchButtonTitle,h=void 0===d?"Remove this search from favorites":d;return"idle"===r.state.status&&!1===r.hasCollections?r.disableUserPersonalization?null:Fe.createElement("div",{className:"DocSearch-StartScreen"},Fe.createElement("p",{className:"DocSearch-Help"},i)):!1===r.hasCollections?null:Fe.createElement("div",{className:"DocSearch-Dropdown-Container"},Fe.createElement(Vn,tr({},r,{title:c,collection:r.state.collections[0],renderIcon:function(){return Fe.createElement("div",{className:"DocSearch-Hit-icon"},Fe.createElement(gn,null))},renderAction:function(e){var t=e.item,n=e.runFavoriteTransition,o=e.runDeleteTransition;return Fe.createElement(Fe.Fragment,null,Fe.createElement("div",{className:"DocSearch-Hit-action"},Fe.createElement("button",{className:"DocSearch-Hit-action-button",title:l,type:"submit",onClick:function(e){e.preventDefault(),e.stopPropagation(),n((function(){r.favoriteSearches.add(t),r.recentSearches.remove(t),r.refresh()}))}},Fe.createElement(In,null))),Fe.createElement("div",{className:"DocSearch-Hit-action"},Fe.createElement("button",{className:"DocSearch-Hit-action-button",title:f,type:"submit",onClick:function(e){e.preventDefault(),e.stopPropagation(),o((function(){r.recentSearches.remove(t),r.refresh()}))}},Fe.createElement(On,null))))}})),Fe.createElement(Vn,tr({},r,{title:m,collection:r.state.collections[1],renderIcon:function(){return Fe.createElement("div",{className:"DocSearch-Hit-icon"},Fe.createElement(In,null))},renderAction:function(e){var t=e.item,n=e.runDeleteTransition;return Fe.createElement("div",{className:"DocSearch-Hit-action"},Fe.createElement("button",{className:"DocSearch-Hit-action-button",title:h,type:"submit",onClick:function(e){e.preventDefault(),e.stopPropagation(),n((function(){r.favoriteSearches.remove(t),r.refresh()}))}},Fe.createElement(On,null)))}})))}var rr=["translations"];function or(){return or=Object.assign||function(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,rr);if("error"===r.state.status)return Fe.createElement(Cn,{translations:null==n?void 0:n.errorScreen});var o=r.state.collections.some((function(e){return e.items.length>0}));return r.state.query?!1===o?Fe.createElement(Nn,or({},r,{translations:null==n?void 0:n.noResultsScreen})):Fe.createElement(Xn,r):Fe.createElement(nr,or({},r,{hasCollections:o,translations:null==n?void 0:n.startScreen}))}),(function(e,t){return"loading"===t.state.status||"stalled"===t.state.status})),ar=["translations"];function ir(){return ir=Object.assign||function(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,ar),o=n.resetButtonTitle,c=void 0===o?"Clear the query":o,a=n.resetButtonAriaLabel,i=void 0===a?"Clear the query":a,u=n.cancelButtonText,l=void 0===u?"Cancel":u,s=n.cancelButtonAriaLabel,f=void 0===s?"Cancel":s,p=r.getFormProps({inputElement:r.inputRef.current}).onReset;return Fe.useEffect((function(){r.autoFocus&&r.inputRef.current&&r.inputRef.current.focus()}),[r.autoFocus,r.inputRef]),Fe.useEffect((function(){r.isFromSelection&&r.inputRef.current&&r.inputRef.current.select()}),[r.isFromSelection,r.inputRef]),Fe.createElement(Fe.Fragment,null,Fe.createElement("form",{className:"DocSearch-Form",onSubmit:function(e){e.preventDefault()},onReset:p},Fe.createElement("label",ir({className:"DocSearch-MagnifierLabel"},r.getLabelProps()),Fe.createElement(Ve,null)),Fe.createElement("div",{className:"DocSearch-LoadingIndicator"},Fe.createElement(bn,null)),Fe.createElement("input",ir({className:"DocSearch-Input",ref:r.inputRef},r.getInputProps({inputElement:r.inputRef.current,autoFocus:r.autoFocus,maxLength:64}))),Fe.createElement("button",{type:"reset",title:c,className:"DocSearch-Reset","aria-label":i,hidden:!r.state.query},Fe.createElement(On,null))),Fe.createElement("button",{className:"DocSearch-Cancel",type:"reset","aria-label":f,onClick:r.onClose},l))}var lr=["_highlightResult","_snippetResult"];function sr(e){var t=e.key,n=e.limit,r=void 0===n?5:n,o=function(e){return!1===function(){var e="__TEST_KEY__";try{return localStorage.setItem(e,""),localStorage.removeItem(e),!0}catch(e){return!1}}()?{setItem:function(){},getItem:function(){return[]}}:{setItem:function(t){return window.localStorage.setItem(e,JSON.stringify(t))},getItem:function(){var t=window.localStorage.getItem(e);return t?JSON.parse(t):[]}}}(t),c=o.getItem().slice(0,r);return{add:function(e){var t=e,n=(t._highlightResult,t._snippetResult,function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},c=Object.keys(e);for(r=0;r=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(t,lr)),a=c.findIndex((function(e){return e.objectID===n.objectID}));a>-1&&c.splice(a,1),c.unshift(n),c=c.slice(0,r),o.setItem(c)},remove:function(e){c=c.filter((function(t){return t.objectID!==e.objectID})),o.setItem(c)},getAll:function(){return c}}}var fr=["facetName","facetQuery"];function pr(e){var t,n="algoliasearch-client-js-".concat(e.key),r=function(){return void 0===t&&(t=e.localStorage||window.localStorage),t},o=function(){return JSON.parse(r().getItem(n)||"{}")};return{get:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return Promise.resolve().then((function(){var n=JSON.stringify(e),r=o()[n];return Promise.all([r||t(),void 0!==r])})).then((function(e){var t=c(e,2),r=t[0],o=t[1];return Promise.all([r,o||n.miss(r)])})).then((function(e){return c(e,1)[0]}))},set:function(e,t){return Promise.resolve().then((function(){var c=o();return c[JSON.stringify(e)]=t,r().setItem(n,JSON.stringify(c)),t}))},delete:function(e){return Promise.resolve().then((function(){var t=o();delete t[JSON.stringify(e)],r().setItem(n,JSON.stringify(t))}))},clear:function(){return Promise.resolve().then((function(){r().removeItem(n)}))}}}function mr(e){var t=a(e.caches),n=t.shift();return void 0===n?{get:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return t().then((function(e){return Promise.all([e,n.miss(e)])})).then((function(e){return c(e,1)[0]}))},set:function(e,t){return Promise.resolve(t)},delete:function(e){return Promise.resolve()},clear:function(){return Promise.resolve()}}:{get:function(e,r){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return n.get(e,r,o).catch((function(){return mr({caches:t}).get(e,r,o)}))},set:function(e,r){return n.set(e,r).catch((function(){return mr({caches:t}).set(e,r)}))},delete:function(e){return n.delete(e).catch((function(){return mr({caches:t}).delete(e)}))},clear:function(){return n.clear().catch((function(){return mr({caches:t}).clear()}))}}}function dr(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{serializable:!0},t={};return{get:function(n,r){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}},c=JSON.stringify(n);if(c in t)return Promise.resolve(e.serializable?JSON.parse(t[c]):t[c]);var a=r(),i=o&&o.miss||function(){return Promise.resolve()};return a.then((function(e){return i(e)})).then((function(){return a}))},set:function(n,r){return t[JSON.stringify(n)]=e.serializable?JSON.stringify(r):r,Promise.resolve(r)},delete:function(e){return delete t[JSON.stringify(e)],Promise.resolve()},clear:function(){return t={},Promise.resolve()}}}function hr(e){for(var t=e.length-1;t>0;t--){var n=Math.floor(Math.random()*(t+1)),r=e[t];e[t]=e[n],e[n]=r}return e}function vr(e,t){return t?(Object.keys(t).forEach((function(n){e[n]=t[n](e)})),e):e}function yr(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r0?r:void 0,timeout:n.timeout||t,headers:n.headers||{},queryParameters:n.queryParameters||{},cacheable:n.cacheable}}var gr={Read:1,Write:2,Any:3},Or=1;function Sr(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Or;return t(t({},e),{},{status:n,lastUpdate:Date.now()})}function Er(e){return"string"==typeof e?{protocol:"https",url:e,accept:gr.Any}:{protocol:e.protocol||"https",url:e.url,accept:e.accept||gr.Any}}var wr="POST";function jr(e,n,r,o){var c=[],i=function(e,n){if("GET"!==e.method&&(void 0!==e.data||void 0!==n.data)){var r=Array.isArray(e.data)?e.data:t(t({},e.data),n.data);return JSON.stringify(r)}}(r,o),u=function(e,n){var r=t(t({},e.headers),n.headers),o={};return Object.keys(r).forEach((function(e){var t=r[e];o[e.toLowerCase()]=t})),o}(e,o),l=r.method,s="GET"!==r.method?{}:t(t({},r.data),o.data),f=t(t(t({"x-algolia-agent":e.userAgent.value},e.queryParameters),s),o.queryParameters),p=0,m=function t(n,a){var s=n.pop();if(void 0===s)throw{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:Dr(c)};var m={data:i,headers:u,method:l,url:Ir(s,r.path,f),connectTimeout:a(p,e.timeouts.connect),responseTimeout:a(p,o.timeout)},d=function(e){var t={request:m,response:e,host:s,triesLeft:n.length};return c.push(t),t},h={onSucess:function(e){return function(e){try{return JSON.parse(e.content)}catch(t){throw function(e,t){return{name:"DeserializationError",message:e,response:t}}(t.message,e)}}(e)},onRetry:function(r){var o=d(r);return r.isTimedOut&&p++,Promise.all([e.logger.info("Retryable failure",Cr(o)),e.hostsCache.set(s,Sr(s,r.isTimedOut?3:2))]).then((function(){return t(n,a)}))},onFail:function(e){throw d(e),function(e,t){var n=e.content,r=e.status,o=n;try{o=JSON.parse(n).message}catch(e){}return function(e,t,n){return{name:"ApiError",message:e,status:t,transporterStackTrace:n}}(o,r,t)}(e,Dr(c))}};return e.requester.send(m).then((function(e){return function(e,t){return function(e){var t=e.status;return e.isTimedOut||function(e){var t=e.isTimedOut,n=e.status;return!t&&0==~~n}(e)||2!=~~(t/100)&&4!=~~(t/100)}(e)?t.onRetry(e):2==~~(e.status/100)?t.onSucess(e):t.onFail(e)}(e,h)}))};return function(e,t){return Promise.all(t.map((function(t){return e.get(t,(function(){return Promise.resolve(Sr(t))}))}))).then((function(e){var n=e.filter((function(e){return function(e){return e.status===Or||Date.now()-e.lastUpdate>12e4}(e)})),r=e.filter((function(e){return function(e){return 3===e.status&&Date.now()-e.lastUpdate<=12e4}(e)})),o=[].concat(a(n),a(r));return{getTimeout:function(e,t){return(0===r.length&&0===e?1:r.length+3+e)*t},statelessHosts:o.length>0?o.map((function(e){return Er(e)})):t}}))}(e.hostsCache,n).then((function(e){return m(a(e.statelessHosts).reverse(),e.getTimeout)}))}function Pr(e){var t={value:"Algolia for JavaScript (".concat(e,")"),add:function(e){var n="; ".concat(e.segment).concat(void 0!==e.version?" (".concat(e.version,")"):"");return-1===t.value.indexOf(n)&&(t.value="".concat(t.value).concat(n)),t}};return t}function Ir(e,t,n){var r=kr(n),o="".concat(e.protocol,"://").concat(e.url,"/").concat("/"===t.charAt(0)?t.substr(1):t);return r.length&&(o+="?".concat(r)),o}function kr(e){return Object.keys(e).map((function(t){return yr("%s=%s",t,(n=e[t],"[object Object]"===Object.prototype.toString.call(n)||"[object Array]"===Object.prototype.toString.call(n)?JSON.stringify(e[t]):e[t]));var n})).join("&")}function Dr(e){return e.map((function(e){return Cr(e)}))}function Cr(e){var n=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return t(t({},e),{},{request:t(t({},e.request),{},{headers:t(t({},e.request.headers),n)})})}var xr=function(e){var n=e.appId,r=function(e,t,n){var r={"x-algolia-api-key":n,"x-algolia-application-id":t};return{headers:function(){return e===_r.WithinHeaders?r:{}},queryParameters:function(){return e===_r.WithinQueryParameters?r:{}}}}(void 0!==e.authMode?e.authMode:_r.WithinHeaders,n,e.apiKey),o=function(e){var t=e.hostsCache,n=e.logger,r=e.requester,o=e.requestsCache,a=e.responsesCache,i=e.timeouts,u=e.userAgent,l=e.hosts,s=e.queryParameters,f={hostsCache:t,logger:n,requester:r,requestsCache:o,responsesCache:a,timeouts:i,userAgent:u,headers:e.headers,queryParameters:s,hosts:l.map((function(e){return Er(e)})),read:function(e,t){var n=br(t,f.timeouts.read),r=function(){return jr(f,f.hosts.filter((function(e){return 0!=(e.accept&gr.Read)})),e,n)};if(!0!==(void 0!==n.cacheable?n.cacheable:e.cacheable))return r();var o={request:e,mappedRequestOptions:n,transporter:{queryParameters:f.queryParameters,headers:f.headers}};return f.responsesCache.get(o,(function(){return f.requestsCache.get(o,(function(){return f.requestsCache.set(o,r()).then((function(e){return Promise.all([f.requestsCache.delete(o),e])}),(function(e){return Promise.all([f.requestsCache.delete(o),Promise.reject(e)])})).then((function(e){var t=c(e,2);return t[0],t[1]}))}))}),{miss:function(e){return f.responsesCache.set(o,e)}})},write:function(e,t){return jr(f,f.hosts.filter((function(e){return 0!=(e.accept&gr.Write)})),e,br(t,f.timeouts.write))}};return f}(t(t({hosts:[{url:"".concat(n,"-dsn.algolia.net"),accept:gr.Read},{url:"".concat(n,".algolia.net"),accept:gr.Write}].concat(hr([{url:"".concat(n,"-1.algolianet.com")},{url:"".concat(n,"-2.algolianet.com")},{url:"".concat(n,"-3.algolianet.com")}]))},e),{},{headers:t(t(t({},r.headers()),{"content-type":"application/x-www-form-urlencoded"}),e.headers),queryParameters:t(t({},r.queryParameters()),e.queryParameters)})),a={transporter:o,appId:n,addAlgoliaAgent:function(e,t){o.userAgent.add({segment:e,version:t})},clearCache:function(){return Promise.all([o.requestsCache.clear(),o.responsesCache.clear()]).then((function(){}))}};return vr(a,e.methods)},Ar=function(e){return function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return vr({transporter:e.transporter,appId:e.appId,indexName:t},n.methods)}},Nr=function(e){return function(n,r){var o=n.map((function(e){return t(t({},e),{},{params:kr(e.params||{})})}));return e.transporter.read({method:wr,path:"1/indexes/*/queries",data:{requests:o},cacheable:!0},r)}},Rr=function(e){return function(n,r){return Promise.all(n.map((function(n){var o=n.params,c=o.facetName,a=o.facetQuery,i=function(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},c=Object.keys(e);for(r=0;r=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(o,fr);return Ar(e)(n.indexName,{methods:{searchForFacetValues:qr}}).searchForFacetValues(c,a,t(t({},r),i))})))}},Tr=function(e){return function(t,n,r){return e.transporter.read({method:wr,path:yr("1/answers/%s/prediction",e.indexName),data:{query:t,queryLanguages:n},cacheable:!0},r)}},Lr=function(e){return function(t,n){return e.transporter.read({method:wr,path:yr("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},n)}},qr=function(e){return function(t,n,r){return e.transporter.read({method:wr,path:yr("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:n},cacheable:!0},r)}},Mr=1,Hr=2,Ur=3;function Fr(e,n,r){var o,c={appId:e,apiKey:n,timeouts:{connect:1,read:2,write:30},requester:{send:function(e){return new Promise((function(t){var n=new XMLHttpRequest;n.open(e.method,e.url,!0),Object.keys(e.headers).forEach((function(t){return n.setRequestHeader(t,e.headers[t])}));var r,o=function(e,r){return setTimeout((function(){n.abort(),t({status:0,content:r,isTimedOut:!0})}),1e3*e)},c=o(e.connectTimeout,"Connection timeout");n.onreadystatechange=function(){n.readyState>n.OPENED&&void 0===r&&(clearTimeout(c),r=o(e.responseTimeout,"Socket timeout"))},n.onerror=function(){0===n.status&&(clearTimeout(c),clearTimeout(r),t({content:n.responseText||"Network request failed",status:n.status,isTimedOut:!1}))},n.onload=function(){clearTimeout(c),clearTimeout(r),t({content:n.responseText,status:n.status,isTimedOut:!1})},n.send(e.data)}))}},logger:(o=Ur,{debug:function(e,t){return Mr>=o&&console.debug(e,t),Promise.resolve()},info:function(e,t){return Hr>=o&&console.info(e,t),Promise.resolve()},error:function(e,t){return console.error(e,t),Promise.resolve()}}),responsesCache:dr(),requestsCache:dr({serializable:!1}),hostsCache:mr({caches:[pr({key:"".concat("4.8.5","-").concat(e)}),dr()]}),userAgent:Pr("4.8.5").add({segment:"Browser",version:"lite"}),authMode:_r.WithinQueryParameters};return xr(t(t(t({},c),r),{},{methods:{search:Nr,searchForFacetValues:Rr,multipleQueries:Nr,multipleSearchForFacetValues:Rr,initIndex:function(e){return function(t){return Ar(e)(t,{methods:{search:Lr,searchForFacetValues:qr,findAnswers:Tr}})}}}}))}Fr.version="4.8.5";var Br=["footer","searchBox"];function Vr(){return Vr=Object.assign||function(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 c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(j,Br),C=function(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,c=[],a=!0,i=!1;try{for(n=n.call(e);!(a=(r=n.next()).done)&&(c.push(r.value),2!==c.length);a=!0);}catch(e){i=!0,o=e}finally{try{a||null==n.return||n.return()}finally{if(i)throw o}}return c}}(e)||function(e,t){if(e){if("string"==typeof e)return Jr(e,2);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)?Jr(e,2):void 0}}(e)||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.")}()}(Fe.useState({query:"",collections:[],completion:null,context:{},isOpen:!1,activeItemId:null,status:"idle"})),x=C[0],A=C[1],N=Fe.useRef(null),R=Fe.useRef(null),T=Fe.useRef(null),L=Fe.useRef(null),q=Fe.useRef(null),M=Fe.useRef(10),H=Fe.useRef("undefined"!=typeof window?window.getSelection().toString().slice(0,64):"").current,U=Fe.useRef(E||H).current,F=function(e,t,n){return Fe.useMemo((function(){var r=Fr(e,t);return r.addAlgoliaAgent("docsearch","3.3.4"),!1===/docsearch.js \(.*\)/.test(r.transporter.userAgent.value)&&r.addAlgoliaAgent("docsearch-react","3.3.4"),n(r)}),[e,t,n])}(t,n,b),B=Fe.useRef(sr({key:"__DOCSEARCH_FAVORITE_SEARCHES__".concat(r),limit:10})).current,V=Fe.useRef(sr({key:"__DOCSEARCH_RECENT_SEARCHES__".concat(r),limit:0===B.getAll().length?7:4})).current,W=Fe.useCallback((function(e){if(!O){var t="content"===e.type?e.__docsearch_parent:e;t&&-1===B.getAll().findIndex((function(e){return e.objectID===t.objectID}))&&V.add(t)}}),[B,V,O]),K=Fe.useMemo((function(){return dn({id:"docsearch",defaultActiveItemId:0,placeholder:c,openOnFocus:!0,initialState:{query:U,context:{searchSuggestions:[]}},navigator:h,onStateChange:function(e){A(e.state)},getSources:function(e){var t=e.query,n=e.state,o=e.setContext,c=e.setStatus;return t?F.search([{query:t,indexName:r,params:Kr({attributesToRetrieve:["hierarchy.lvl0","hierarchy.lvl1","hierarchy.lvl2","hierarchy.lvl3","hierarchy.lvl4","hierarchy.lvl5","hierarchy.lvl6","content","type","url"],attributesToSnippet:["hierarchy.lvl1:".concat(M.current),"hierarchy.lvl2:".concat(M.current),"hierarchy.lvl3:".concat(M.current),"hierarchy.lvl4:".concat(M.current),"hierarchy.lvl5:".concat(M.current),"hierarchy.lvl6:".concat(M.current),"content:".concat(M.current)],snippetEllipsisText:"…",highlightPreTag:"",highlightPostTag:"",hitsPerPage:20},a)}]).catch((function(e){throw"RetryError"===e.name&&c("error"),e})).then((function(e){var t=e.results[0],r=t.hits,c=t.nbHits,a=Kn(r,(function(e){return Yn(e)}));return n.context.searchSuggestions.length0&&($(),q.current&&q.current.focus())}),[U,$]),Fe.useEffect((function(){function e(){if(R.current){var e=.01*window.innerHeight;R.current.style.setProperty("--docsearch-vh","".concat(e,"px"))}}return e(),window.addEventListener("resize",e),function(){window.removeEventListener("resize",e)}}),[]),Fe.createElement("div",Vr({ref:N},J({"aria-expanded":!0}),{className:["DocSearch","DocSearch-Container","stalled"===x.status&&"DocSearch-Container--Stalled","error"===x.status&&"DocSearch-Container--Errored"].filter(Boolean).join(" "),role:"button",tabIndex:0,onMouseDown:function(e){e.target===e.currentTarget&&u()}}),Fe.createElement("div",{className:"DocSearch-Modal",ref:R},Fe.createElement("header",{className:"DocSearch-SearchBar",ref:T},Fe.createElement(ur,Vr({},K,{state:x,autoFocus:0===U.length,inputRef:q,isFromSelection:Boolean(U)&&U===H,translations:k,onClose:u}))),Fe.createElement("div",{className:"DocSearch-Dropdown",ref:L},Fe.createElement(cr,Vr({},K,{indexName:r,state:x,hitComponent:p,resultsFooterComponent:d,disableUserPersonalization:O,recentSearches:V,favoriteSearches:B,inputRef:q,translations:D,getMissingResultsUrl:P,onItemClick:function(e,t){W(e),Jn(t)||u()}}))),Fe.createElement("footer",{className:"DocSearch-Footer"},Fe.createElement(yn,{translations:I}))))}function Qr(){return Qr=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n1&&void 0!==arguments[1]?arguments[1]:window;return"string"==typeof e?t.document.querySelector(e):e}(e.container,e.environment))}}(); \ No newline at end of file diff --git a/_static/docsearch.f1a1a5835ed7a6ab0c85.js.LICENSE.txt b/_static/docsearch.f1a1a5835ed7a6ab0c85.js.LICENSE.txt new file mode 100644 index 00000000..7baa600d --- /dev/null +++ b/_static/docsearch.f1a1a5835ed7a6ab0c85.js.LICENSE.txt @@ -0,0 +1 @@ +/*! @docsearch/js 3.3.4 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */ diff --git a/_static/docsearch.f30f8b0589fd2b6fd39c.css b/_static/docsearch.f30f8b0589fd2b6fd39c.css new file mode 100644 index 00000000..39a047ff --- /dev/null +++ b/_static/docsearch.f30f8b0589fd2b6fd39c.css @@ -0,0 +1,2 @@ +/*! @docsearch/css 3.3.4 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */:root{--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:rgba(101,108,133,.8);--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12)}html[data-theme=dark]{--docsearch-text-color:#f5f6f7;--docsearch-container-background:rgba(9,10,17,.8);--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3,4,9,.3);--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73,76,106,.5),0 -4px 8px 0 rgba(0,0,0,.2);--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}.DocSearch-Button{align-items:center;background:#ebedf0;background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:#969faf;color:var(--docsearch-muted-color);cursor:pointer;display:flex;font-weight:500;height:36px;justify-content:space-between;margin:0 0 0 16px;padding:0 8px;-webkit-user-select:none;-moz-user-select:none;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:#fff;background:var(--docsearch-searchbox-focus-background);box-shadow:inset 0 0 0 2px #5468ff;box-shadow:var(--docsearch-searchbox-shadow);color:#1c1e21;color:var(--docsearch-text-color);outline:none}.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Button .DocSearch-Search-Icon{color:#1c1e21;color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:linear-gradient(-225deg,#d5dbe4,#f8f8f8);background:var(--docsearch-key-gradient);border:0;border-radius:3px;box-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);box-shadow:var(--docsearch-key-shadow);color:#969faf;color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 2px;position:relative;top:-1px;width:20px}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder{display:none}}.DocSearch--active{overflow:hidden!important}.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}.DocSearch-Container{background-color:rgba(101,108,133,.8);background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{-webkit-text-decoration:none;text-decoration:none}.DocSearch-Link{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:#5468ff;color:var(--docsearch-highlight-color);cursor:pointer;font:inherit;margin:0;padding:0}.DocSearch-Modal{background:#f5f6f7;background:var(--docsearch-modal-background);border-radius:6px;box-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:560px;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:12px 12px 0;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:#fff;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:inset 0 0 0 2px #5468ff;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:56px;height:var(--docsearch-searchbox-height);margin:0;padding:0 12px;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;color:#1c1e21;color:var(--docsearch-text-color);flex:1;font:inherit;font-size:1.2em;height:100%;outline:none;padding:0 0 0 8px;width:80%}.DocSearch-Input::-moz-placeholder{color:#969faf;color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::placeholder{color:#969faf;color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:#5468ff;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator{display:none}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator{align-items:center;color:#5468ff;color:var(--docsearch-highlight-color);display:flex;justify-content:center}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{stroke-width:1.4;stroke-width:var(--docsearch-icon-stroke-width);animation:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0}}.DocSearch-Reset{stroke-width:1.4;stroke-width:var(--docsearch-icon-stroke-width);animation:fade-in .1s ease-in forwards;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;padding:2px;right:0}.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset:hover{color:#5468ff;color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Cancel{display:none}.DocSearch-Dropdown{max-height:488px;max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:12px;min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 12px;padding:0 var(--docsearch-spacing);scrollbar-color:#969faf #f5f6f7;scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:transparent}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:#969faf;background-color:var(--docsearch-muted-color);border:3px solid #f5f6f7;border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help,.DocSearch-Label{color:#969faf;color:var(--docsearch-muted-color)}.DocSearch-Help{font-size:.9em;margin:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:#5468ff;color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:#5468ff;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{color:#969faf;color:var(--docsearch-muted-color);display:flex;font-size:.85em;justify-content:center;margin-bottom:12px;margin-bottom:var(--docsearch-spacing);padding:12px;padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--deleting{transition:none}}.DocSearch-Hit--deleting{opacity:0;transition:all .25s linear}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--favoriting{transition:none}}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:all .25s linear;transition-delay:.25s}.DocSearch-Hit a{background:#fff;background:var(--docsearch-hit-background);border-radius:4px;box-shadow:0 1px 3px 0 #d4d9e1;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:12px;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:#f5f6f7;background:var(--docsearch-modal-background);color:#5468ff;color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{stroke-width:1.4;stroke-width:var(--docsearch-icon-stroke-width);color:#969faf;color:var(--docsearch-muted-color);height:56px;height:var(--docsearch-hit-height);opacity:.5;width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:#5468ff;background-color:var(--docsearch-highlight-color)}.DocSearch-Hit[aria-selected=true] mark{-webkit-text-decoration:underline;text-decoration:underline}.DocSearch-Hit-Container{align-items:center;color:#444950;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:56px;height:var(--docsearch-hit-height);padding:0 12px 0 0;padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{stroke-width:1.4;stroke-width:var(--docsearch-icon-stroke-width);color:#969faf;color:var(--docsearch-muted-color)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:inherit;cursor:pointer;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:rgba(0,0,0,.2);transition:background-color .1s ease-in}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{transition:none}}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:#969faf;color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] mark{color:#fff!important;color:var(--docsearch-hit-active-color)!important}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:rgba(0,0,0,.2);transition:none}}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:#969faf;color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:1em;color:#5468ff;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:none;-webkit-text-decoration:underline;text-decoration:underline}.DocSearch-Footer{align-items:center;background:#fff;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12);box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:44px;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 12px;padding:0 var(--docsearch-spacing);position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%;z-index:300}.DocSearch-Commands{color:#969faf;color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li{align-items:center;display:flex}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{align-items:center;background:linear-gradient(-225deg,#d5dbe4,#f8f8f8);background:var(--docsearch-key-gradient);border:0;border-radius:2px;box-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);box-shadow:var(--docsearch-key-shadow);color:#969faf;color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;width:20px}@media (max-width:768px){:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%}.DocSearch-Container{height:-webkit-fill-available;height:100vh;height:calc(var(--docsearch-vh, 1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:-webkit-fill-available;height:100vh;height:calc(var(--docsearch-vh, 1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Dropdown{max-height:calc(100vh - 112px);max-height:calc(var(--docsearch-vh, 1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Cancel{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:#5468ff;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:12px;margin-left:var(--docsearch-spacing);outline:none;overflow:hidden;padding:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}}@keyframes fade-in{0%{opacity:0}to{opacity:1}} +:root{--docsearch-searchbox-background:transparent;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--color-brand);--docsearch-key-gradient:transparent;--docsearch-primary-color:var(--color-brand);--docsearch-modal-width:960px;--docsearch-modal-background:#fff}.DocSearch-Button{border-radius:0;height:3.5rem;line-height:3.5rem;padding-right:1rem}.DocSearch-Button-Key{font-family:Roboto,sans-serif;font-size:.875rem;height:1.25rem;padding:1rem}.DocSearch-Button:hover .DocSearch-Button-Key{border-color:var(--color-gray-dark);color:var(--color-gray-dark)}.DocSearch-Button .DocSearch-Search-Icon{--tw-text-opacity:1;stroke-width:2.5;color:#f3f4f6;color:rgb(243 244 246/var(--tw-text-opacity))}.DocSearch-Button:hover .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{padding-left:.75rem}.DocSearch-Hit-source{color:var(--color-gray-dark)}.DocSearch-Hit a{--tw-border-opacity:1;--tw-shadow:0 0 transparent;--tw-shadow-colored:0 0 transparent;border-color:#f3f4f6;border-color:rgb(243 244 246/var(--tw-border-opacity));border-radius:.125rem;border-width:1px;box-shadow:0 0 transparent,0 0 transparent,0 0 transparent;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.DocSearch-Modal{border-radius:.125rem} diff --git a/_static/docsearch_config.js b/_static/docsearch_config.js new file mode 100644 index 00000000..e69de29b diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 00000000..d06a71d7 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 00000000..0b7bb050 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,14 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '0.6.1', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/e10742dbb1d4a0864ba8.woff2 b/_static/e10742dbb1d4a0864ba8.woff2 new file mode 100644 index 00000000..e1b7a79f Binary files /dev/null and b/_static/e10742dbb1d4a0864ba8.woff2 differ diff --git a/_static/ec416b97881f4a422686.woff2 b/_static/ec416b97881f4a422686.woff2 new file mode 100644 index 00000000..45f55237 Binary files /dev/null and b/_static/ec416b97881f4a422686.woff2 differ diff --git a/_static/f1e2a76794cb86b2aa8e.woff b/_static/f1e2a76794cb86b2aa8e.woff new file mode 100644 index 00000000..9eaa94f9 Binary files /dev/null and b/_static/f1e2a76794cb86b2aa8e.woff differ diff --git a/_static/f25d774ecfe0996f8eb5.woff2 b/_static/f25d774ecfe0996f8eb5.woff2 new file mode 100644 index 00000000..29342a8d Binary files /dev/null and b/_static/f25d774ecfe0996f8eb5.woff2 differ diff --git a/_static/favicon.ico b/_static/favicon.ico new file mode 100644 index 00000000..33d26857 Binary files /dev/null and b/_static/favicon.ico differ diff --git a/_static/ff058b7e238adc5cba09.woff2 b/_static/ff058b7e238adc5cba09.woff2 new file mode 100644 index 00000000..0424cf8f Binary files /dev/null and b/_static/ff058b7e238adc5cba09.woff2 differ diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/_static/file.png differ diff --git a/_static/language_data.js b/_static/language_data.js new file mode 100644 index 00000000..250f5665 --- /dev/null +++ b/_static/language_data.js @@ -0,0 +1,199 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, is available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/logo_notext.svg b/_static/logo_notext.svg new file mode 100644 index 00000000..658cc974 --- /dev/null +++ b/_static/logo_notext.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + diff --git a/_static/manifest.json b/_static/manifest.json new file mode 100644 index 00000000..fdf951f0 --- /dev/null +++ b/_static/manifest.json @@ -0,0 +1,29 @@ +{ + "_static/theme.css": "_static/theme.c973b470ab69573097f3.css", + "_static/theme.js": "_static/theme.c8991bd7bb6e57cbeea8.js", + "_static/docsearch.css": "_static/docsearch.f30f8b0589fd2b6fd39c.css", + "_static/docsearch.js": "_static/docsearch.f1a1a5835ed7a6ab0c85.js", + "_static/awesome-sphinx-design.css": "_static/awesome-sphinx-design.4ff695238f641b0a2852.css", + "_static/awesome-sphinx-design.js": "_static/awesome-sphinx-design.31d6cfe0d16ae931b73c.js", + "_static/jetbrains-mono-latin-500-italic.woff": "_static/09be83022f2ac2ce16b0.woff", + "_static/jetbrains-mono-latin-700-italic.woff": "_static/0ffeb7a552b36437b54c.woff", + "_static/jetbrains-mono-latin-400-italic.woff": "_static/ad463ea60cc8b68792f4.woff", + "_static/jetbrains-mono-latin-700-normal.woff": "_static/44fd0da18fe361a5cc7f.woff", + "_static/jetbrains-mono-latin-500-normal.woff": "_static/46830c334f8112fa510a.woff", + "_static/jetbrains-mono-latin-400-normal.woff": "_static/6f04107ce68d524ebe69.woff", + "_static/jetbrains-mono-latin-700-italic.woff2": "_static/c3b5f43fe4c8f3f1fa21.woff2", + "_static/jetbrains-mono-latin-500-italic.woff2": "_static/31f64b9c465158bd6066.woff2", + "_static/roboto-latin-500-italic.woff": "_static/9ac5da2442b734abc516.woff", + "_static/roboto-latin-400-italic.woff": "_static/d037cb4792991826de7d.woff", + "_static/jetbrains-mono-latin-400-italic.woff2": "_static/ff058b7e238adc5cba09.woff2", + "_static/jetbrains-mono-latin-700-normal.woff2": "_static/cfdd43ce3499ca7f900a.woff2", + "_static/jetbrains-mono-latin-500-normal.woff2": "_static/ec416b97881f4a422686.woff2", + "_static/roboto-latin-500-normal.woff": "_static/48af7707fe9e6494d6a5.woff", + "_static/jetbrains-mono-latin-400-normal.woff2": "_static/d0b41bd1d599bc0a52b7.woff2", + "_static/roboto-latin-400-normal.woff": "_static/f1e2a76794cb86b2aa8e.woff", + "_static/roboto-latin-400-italic.woff2": "_static/e10742dbb1d4a0864ba8.woff2", + "_static/roboto-latin-500-italic.woff2": "_static/3a43b67e5bbdfb3ab0a6.woff2", + "_static/roboto-latin-500-normal.woff2": "_static/f25d774ecfe0996f8eb5.woff2", + "_static/roboto-latin-400-normal.woff2": "_static/b009a76ad6afe4ebd301.woff2", + "_static/docsearch_config.js_t": "_static/docsearch_config.js_t" +} \ No newline at end of file diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 00000000..d96755fd Binary files /dev/null and b/_static/minus.png differ diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 00000000..7107cec9 Binary files /dev/null and b/_static/plus.png differ diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 00000000..de6b2fbd --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,68 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #ffffff; } +.highlight .c { color: #177500 } /* Comment */ +.highlight .err { color: #000000 } /* Error */ +.highlight .k { color: #A90D91 } /* Keyword */ +.highlight .l { color: #1C01CE } /* Literal */ +.highlight .n { color: #000000 } /* Name */ +.highlight .o { color: #000000 } /* Operator */ +.highlight .ch { color: #177500 } /* Comment.Hashbang */ +.highlight .cm { color: #177500 } /* Comment.Multiline */ +.highlight .cp { color: #633820 } /* Comment.Preproc */ +.highlight .cpf { color: #177500 } /* Comment.PreprocFile */ +.highlight .c1 { color: #177500 } /* Comment.Single */ +.highlight .cs { color: #177500 } /* Comment.Special */ +.highlight .kc { color: #A90D91 } /* Keyword.Constant */ +.highlight .kd { color: #A90D91 } /* Keyword.Declaration */ +.highlight .kn { color: #A90D91 } /* Keyword.Namespace */ +.highlight .kp { color: #A90D91 } /* Keyword.Pseudo */ +.highlight .kr { color: #A90D91 } /* Keyword.Reserved */ +.highlight .kt { color: #A90D91 } /* Keyword.Type */ +.highlight .ld { color: #1C01CE } /* Literal.Date */ +.highlight .m { color: #1C01CE } /* Literal.Number */ +.highlight .s { color: #C41A16 } /* Literal.String */ +.highlight .na { color: #836C28 } /* Name.Attribute */ +.highlight .nb { color: #A90D91 } /* Name.Builtin */ +.highlight .nc { color: #3F6E75 } /* Name.Class */ +.highlight .no { color: #000000 } /* Name.Constant */ +.highlight .nd { color: #000000 } /* Name.Decorator */ +.highlight .ni { color: #000000 } /* Name.Entity */ +.highlight .ne { color: #000000 } /* Name.Exception */ +.highlight .nf { color: #000000 } /* Name.Function */ +.highlight .nl { color: #000000 } /* Name.Label */ +.highlight .nn { color: #000000 } /* Name.Namespace */ +.highlight .nx { color: #000000 } /* Name.Other */ +.highlight .py { color: #000000 } /* Name.Property */ +.highlight .nt { color: #000000 } /* Name.Tag */ +.highlight .nv { color: #000000 } /* Name.Variable */ +.highlight .ow { color: #000000 } /* Operator.Word */ +.highlight .mb { color: #1C01CE } /* Literal.Number.Bin */ +.highlight .mf { color: #1C01CE } /* Literal.Number.Float */ +.highlight .mh { color: #1C01CE } /* Literal.Number.Hex */ +.highlight .mi { color: #1C01CE } /* Literal.Number.Integer */ +.highlight .mo { color: #1C01CE } /* Literal.Number.Oct */ +.highlight .sa { color: #C41A16 } /* Literal.String.Affix */ +.highlight .sb { color: #C41A16 } /* Literal.String.Backtick */ +.highlight .sc { color: #2300CE } /* Literal.String.Char */ +.highlight .dl { color: #C41A16 } /* Literal.String.Delimiter */ +.highlight .sd { color: #C41A16 } /* Literal.String.Doc */ +.highlight .s2 { color: #C41A16 } /* Literal.String.Double */ +.highlight .se { color: #C41A16 } /* Literal.String.Escape */ +.highlight .sh { color: #C41A16 } /* Literal.String.Heredoc */ +.highlight .si { color: #C41A16 } /* Literal.String.Interpol */ +.highlight .sx { color: #C41A16 } /* Literal.String.Other */ +.highlight .sr { color: #C41A16 } /* Literal.String.Regex */ +.highlight .s1 { color: #C41A16 } /* Literal.String.Single */ +.highlight .ss { color: #C41A16 } /* Literal.String.Symbol */ +.highlight .bp { color: #5B269A } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #000000 } /* Name.Function.Magic */ +.highlight .vc { color: #000000 } /* Name.Variable.Class */ +.highlight .vg { color: #000000 } /* Name.Variable.Global */ +.highlight .vi { color: #000000 } /* Name.Variable.Instance */ +.highlight .vm { color: #000000 } /* Name.Variable.Magic */ +.highlight .il { color: #1C01CE } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 00000000..97d56a74 --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,566 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = docUrlRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = docUrlRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms) + ); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + `Search finished, found ${resultCount} page(s) matching the search query.` + ); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent !== undefined) return docContent.textContent; + console.warn( + "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + /** + * execute search (requires search index to be loaded) + */ + query: (query) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + // array of [docname, title, anchor, descr, score, filename] + let results = []; + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + let score = Math.round(100 * queryLower.length / title.length) + results.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id] of foundEntries) { + let score = Math.round(100 * queryLower.length / entry.length) + results.push([ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // lookup as object + objectTerms.forEach((term) => + results.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); + + // now sort the results by score (in opposite order of appearance, since the + // display function below uses pop() to retrieve items) and then + // alphabetically + results.sort((a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; + }); + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + results = results.reverse(); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord) && !terms[word]) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord) && !titleTerms[word]) + arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); + }); + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) + fileMap.get(file).push(word); + else fileMap.set(file, [word]); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords) => { + const text = Search.htmlToText(htmlText); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 00000000..aae669d7 --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,144 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + parent.insertBefore( + span, + parent.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(SphinxHighlight.highlightSearchWords); +_ready(SphinxHighlight.initEscapeListener); diff --git a/_static/theme.c8991bd7bb6e57cbeea8.js b/_static/theme.c8991bd7bb6e57cbeea8.js new file mode 100644 index 00000000..1d8b2bb8 --- /dev/null +++ b/_static/theme.c8991bd7bb6e57cbeea8.js @@ -0,0 +1,2 @@ +/*! For license information please see theme.c8991bd7bb6e57cbeea8.js.LICENSE.txt */ +!function(){var e={798:function(e,t,r){var n={"./clipboard-controller.js":890,"./code-controller.js":606,"./collapsible-controller.js":635,"./scroll-controller.js":850,"./scroll-to-top-controller.js":625,"./search-controller.js":935,"./sidebar-controller.js":214};function s(e){var t=i(e);return r(t)}function i(e){if(!r.o(n,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return n[e]}s.keys=function(){return Object.keys(n)},s.resolve=i,e.exports=s,s.id=798},599:function(e,t,r){"use strict";r.d(t,{Mx:function(){return z},Qr:function(){return G}});class n{constructor(e,t,r){this.eventTarget=e,this.eventName=t,this.eventOptions=r,this.unorderedBindings=new Set}connect(){this.eventTarget.addEventListener(this.eventName,this,this.eventOptions)}disconnect(){this.eventTarget.removeEventListener(this.eventName,this,this.eventOptions)}bindingConnected(e){this.unorderedBindings.add(e)}bindingDisconnected(e){this.unorderedBindings.delete(e)}handleEvent(e){const t=function(e){if("immediatePropagationStopped"in e)return e;{const{stopImmediatePropagation:t}=e;return Object.assign(e,{immediatePropagationStopped:!1,stopImmediatePropagation(){this.immediatePropagationStopped=!0,t.call(this)}})}}(e);for(const e of this.bindings){if(t.immediatePropagationStopped)break;e.handleEvent(t)}}hasBindings(){return this.unorderedBindings.size>0}get bindings(){return Array.from(this.unorderedBindings).sort(((e,t)=>{const r=e.index,n=t.index;return rn?1:0}))}}class s{constructor(e){this.application=e,this.eventListenerMaps=new Map,this.started=!1}start(){this.started||(this.started=!0,this.eventListeners.forEach((e=>e.connect())))}stop(){this.started&&(this.started=!1,this.eventListeners.forEach((e=>e.disconnect())))}get eventListeners(){return Array.from(this.eventListenerMaps.values()).reduce(((e,t)=>e.concat(Array.from(t.values()))),[])}bindingConnected(e){this.fetchEventListenerForBinding(e).bindingConnected(e)}bindingDisconnected(e,t=!1){this.fetchEventListenerForBinding(e).bindingDisconnected(e),t&&this.clearEventListenersForBinding(e)}handleError(e,t,r={}){this.application.handleError(e,`Error ${t}`,r)}clearEventListenersForBinding(e){const t=this.fetchEventListenerForBinding(e);t.hasBindings()||(t.disconnect(),this.removeMappedEventListenerFor(e))}removeMappedEventListenerFor(e){const{eventTarget:t,eventName:r,eventOptions:n}=e,s=this.fetchEventListenerMapForEventTarget(t),i=this.cacheKey(r,n);s.delete(i),0==s.size&&this.eventListenerMaps.delete(t)}fetchEventListenerForBinding(e){const{eventTarget:t,eventName:r,eventOptions:n}=e;return this.fetchEventListener(t,r,n)}fetchEventListener(e,t,r){const n=this.fetchEventListenerMapForEventTarget(e),s=this.cacheKey(t,r);let i=n.get(s);return i||(i=this.createEventListener(e,t,r),n.set(s,i)),i}createEventListener(e,t,r){const s=new n(e,t,r);return this.started&&s.connect(),s}fetchEventListenerMapForEventTarget(e){let t=this.eventListenerMaps.get(e);return t||(t=new Map,this.eventListenerMaps.set(e,t)),t}cacheKey(e,t){const r=[e];return Object.keys(t).sort().forEach((e=>{r.push(`${t[e]?"":"!"}${e}`)})),r.join(":")}}const i={stop({event:e,value:t}){return t&&e.stopPropagation(),!0},prevent({event:e,value:t}){return t&&e.preventDefault(),!0},self({event:e,value:t,element:r}){return!t||r===e.target}},o=/^(?:(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;function a(e){return e.replace(/(?:[_-])([a-z0-9])/g,((e,t)=>t.toUpperCase()))}function c(e){return a(e.replace(/--/g,"-").replace(/__/g,"_"))}function l(e){return e.charAt(0).toUpperCase()+e.slice(1)}function h(e){return e.replace(/([A-Z])/g,((e,t)=>`-${t.toLowerCase()}`))}class u{constructor(e,t,r,n){this.element=e,this.index=t,this.eventTarget=r.eventTarget||e,this.eventName=r.eventName||function(e){const t=e.tagName.toLowerCase();if(t in d)return d[t](e)}(e)||m("missing event name"),this.eventOptions=r.eventOptions||{},this.identifier=r.identifier||m("missing identifier"),this.methodName=r.methodName||m("missing method name"),this.keyFilter=r.keyFilter||"",this.schema=n}static forToken(e,t){return new this(e.element,e.index,function(e){const t=e.trim().match(o)||[];let r=t[1],n=t[2];return n&&!["keydown","keyup","keypress"].includes(r)&&(r+=`.${n}`,n=""),{eventTarget:(s=t[3],"window"==s?window:"document"==s?document:void 0),eventName:r,eventOptions:t[6]?(i=t[6],i.split(":").reduce(((e,t)=>Object.assign(e,{[t.replace(/^!/,"")]:!/^!/.test(t)})),{})):{},identifier:t[4],methodName:t[5],keyFilter:n};var s,i}(e.content),t)}toString(){const e=this.keyFilter?`.${this.keyFilter}`:"",t=this.eventTargetName?`@${this.eventTargetName}`:"";return`${this.eventName}${e}${t}->${this.identifier}#${this.methodName}`}isFilterTarget(e){if(!this.keyFilter)return!1;const t=this.keyFilter.split("+"),r=["meta","ctrl","alt","shift"],[n,s,i,o]=r.map((e=>t.includes(e)));if(e.metaKey!==n||e.ctrlKey!==s||e.altKey!==i||e.shiftKey!==o)return!0;const a=t.filter((e=>!r.includes(e)))[0];return!!a&&(Object.prototype.hasOwnProperty.call(this.keyMappings,a)||m(`contains unknown key filter: ${this.keyFilter}`),this.keyMappings[a].toLowerCase()!==e.key.toLowerCase())}get params(){const e={},t=new RegExp(`^data-${this.identifier}-(.+)-param$`,"i");for(const{name:r,value:n}of Array.from(this.element.attributes)){const s=r.match(t),i=s&&s[1];i&&(e[a(i)]=p(n))}return e}get eventTargetName(){return(e=this.eventTarget)==window?"window":e==document?"document":void 0;var e}get keyMappings(){return this.schema.keyMappings}}const d={a:()=>"click",button:()=>"click",form:()=>"submit",details:()=>"toggle",input:e=>"submit"==e.getAttribute("type")?"click":"input",select:()=>"change",textarea:()=>"input"};function m(e){throw new Error(e)}function p(e){try{return JSON.parse(e)}catch(t){return e}}class g{constructor(e,t){this.context=e,this.action=t}get index(){return this.action.index}get eventTarget(){return this.action.eventTarget}get eventOptions(){return this.action.eventOptions}get identifier(){return this.context.identifier}handleEvent(e){this.willBeInvokedByEvent(e)&&this.applyEventModifiers(e)&&this.invokeWithEvent(e)}get eventName(){return this.action.eventName}get method(){const e=this.controller[this.methodName];if("function"==typeof e)return e;throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`)}applyEventModifiers(e){const{element:t}=this.action,{actionDescriptorFilters:r}=this.context.application;let n=!0;for(const[s,i]of Object.entries(this.eventOptions))if(s in r){const o=r[s];n=n&&o({name:s,value:i,event:e,element:t})}return n}invokeWithEvent(e){const{target:t,currentTarget:r}=e;try{const{params:n}=this.action,s=Object.assign(e,{params:n});this.method.call(this.controller,s),this.context.logDebugActivity(this.methodName,{event:e,target:t,currentTarget:r,action:this.methodName})}catch(t){const{identifier:r,controller:n,element:s,index:i}=this,o={identifier:r,controller:n,element:s,index:i,event:e};this.context.handleError(t,`invoking action "${this.action}"`,o)}}willBeInvokedByEvent(e){const t=e.target;return!(e instanceof KeyboardEvent&&this.action.isFilterTarget(e))&&(this.element===t||(t instanceof Element&&this.element.contains(t)?this.scope.containsElement(t):this.scope.containsElement(this.action.element)))}get controller(){return this.context.controller}get methodName(){return this.action.methodName}get element(){return this.scope.element}get scope(){return this.context.scope}}class f{constructor(e,t){this.mutationObserverInit={attributes:!0,childList:!0,subtree:!0},this.element=e,this.started=!1,this.delegate=t,this.elements=new Set,this.mutationObserver=new MutationObserver((e=>this.processMutations(e)))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,this.mutationObserverInit),this.refresh())}pause(e){this.started&&(this.mutationObserver.disconnect(),this.started=!1),e(),this.started||(this.mutationObserver.observe(this.element,this.mutationObserverInit),this.started=!0)}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started){const e=new Set(this.matchElementsInTree());for(const t of Array.from(this.elements))e.has(t)||this.removeElement(t);for(const t of Array.from(e))this.addElement(t)}}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){"attributes"==e.type?this.processAttributeChange(e.target,e.attributeName):"childList"==e.type&&(this.processRemovedNodes(e.removedNodes),this.processAddedNodes(e.addedNodes))}processAttributeChange(e,t){const r=e;this.elements.has(r)?this.delegate.elementAttributeChanged&&this.matchElement(r)?this.delegate.elementAttributeChanged(r,t):this.removeElement(r):this.matchElement(r)&&this.addElement(r)}processRemovedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.processTree(e,this.removeElement)}}processAddedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.elementIsActive(e)&&this.processTree(e,this.addElement)}}matchElement(e){return this.delegate.matchElement(e)}matchElementsInTree(e=this.element){return this.delegate.matchElementsInTree(e)}processTree(e,t){for(const r of this.matchElementsInTree(e))t.call(this,r)}elementFromNode(e){if(e.nodeType==Node.ELEMENT_NODE)return e}elementIsActive(e){return e.isConnected==this.element.isConnected&&this.element.contains(e)}addElement(e){this.elements.has(e)||this.elementIsActive(e)&&(this.elements.add(e),this.delegate.elementMatched&&this.delegate.elementMatched(e))}removeElement(e){this.elements.has(e)&&(this.elements.delete(e),this.delegate.elementUnmatched&&this.delegate.elementUnmatched(e))}}class v{constructor(e,t,r){this.attributeName=t,this.delegate=r,this.elementObserver=new f(e,this)}get element(){return this.elementObserver.element}get selector(){return`[${this.attributeName}]`}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get started(){return this.elementObserver.started}matchElement(e){return e.hasAttribute(this.attributeName)}matchElementsInTree(e){const t=this.matchElement(e)?[e]:[],r=Array.from(e.querySelectorAll(this.selector));return t.concat(r)}elementMatched(e){this.delegate.elementMatchedAttribute&&this.delegate.elementMatchedAttribute(e,this.attributeName)}elementUnmatched(e){this.delegate.elementUnmatchedAttribute&&this.delegate.elementUnmatchedAttribute(e,this.attributeName)}elementAttributeChanged(e,t){this.delegate.elementAttributeValueChanged&&this.attributeName==t&&this.delegate.elementAttributeValueChanged(e,t)}}function y(e,t){let r=e.get(t);return r||(r=new Set,e.set(t,r)),r}class b{constructor(){this.valuesByKey=new Map}get keys(){return Array.from(this.valuesByKey.keys())}get values(){return Array.from(this.valuesByKey.values()).reduce(((e,t)=>e.concat(Array.from(t))),[])}get size(){return Array.from(this.valuesByKey.values()).reduce(((e,t)=>e+t.size),0)}add(e,t){!function(e,t,r){y(e,t).add(r)}(this.valuesByKey,e,t)}delete(e,t){!function(e,t,r){y(e,t).delete(r),function(e,t){const r=e.get(t);null!=r&&0==r.size&&e.delete(t)}(e,t)}(this.valuesByKey,e,t)}has(e,t){const r=this.valuesByKey.get(e);return null!=r&&r.has(t)}hasKey(e){return this.valuesByKey.has(e)}hasValue(e){return Array.from(this.valuesByKey.values()).some((t=>t.has(e)))}getValuesForKey(e){const t=this.valuesByKey.get(e);return t?Array.from(t):[]}getKeysForValue(e){return Array.from(this.valuesByKey).filter((([t,r])=>r.has(e))).map((([e,t])=>e))}}class E{constructor(e,t,r,n={}){this.selector=t,this.details=n,this.elementObserver=new f(e,this),this.delegate=r,this.matchesByElement=new b}get started(){return this.elementObserver.started}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get element(){return this.elementObserver.element}matchElement(e){const t=e.matches(this.selector);return this.delegate.selectorMatchElement?t&&this.delegate.selectorMatchElement(e,this.details):t}matchElementsInTree(e){const t=this.matchElement(e)?[e]:[],r=Array.from(e.querySelectorAll(this.selector)).filter((e=>this.matchElement(e)));return t.concat(r)}elementMatched(e){this.selectorMatched(e)}elementUnmatched(e){this.selectorUnmatched(e)}elementAttributeChanged(e,t){const r=this.matchElement(e),n=this.matchesByElement.has(this.selector,e);!r&&n&&this.selectorUnmatched(e)}selectorMatched(e){this.delegate.selectorMatched&&(this.delegate.selectorMatched(e,this.selector,this.details),this.matchesByElement.add(this.selector,e))}selectorUnmatched(e){this.delegate.selectorUnmatched(e,this.selector,this.details),this.matchesByElement.delete(this.selector,e)}}class w{constructor(e,t){this.element=e,this.delegate=t,this.started=!1,this.stringMap=new Map,this.mutationObserver=new MutationObserver((e=>this.processMutations(e)))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,{attributes:!0,attributeOldValue:!0}),this.refresh())}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started)for(const e of this.knownAttributeNames)this.refreshAttribute(e,null)}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){const t=e.attributeName;t&&this.refreshAttribute(t,e.oldValue)}refreshAttribute(e,t){const r=this.delegate.getStringMapKeyForAttribute(e);if(null!=r){this.stringMap.has(e)||this.stringMapKeyAdded(r,e);const n=this.element.getAttribute(e);if(this.stringMap.get(e)!=n&&this.stringMapValueChanged(n,r,t),null==n){const t=this.stringMap.get(e);this.stringMap.delete(e),t&&this.stringMapKeyRemoved(r,e,t)}else this.stringMap.set(e,n)}}stringMapKeyAdded(e,t){this.delegate.stringMapKeyAdded&&this.delegate.stringMapKeyAdded(e,t)}stringMapValueChanged(e,t,r){this.delegate.stringMapValueChanged&&this.delegate.stringMapValueChanged(e,t,r)}stringMapKeyRemoved(e,t,r){this.delegate.stringMapKeyRemoved&&this.delegate.stringMapKeyRemoved(e,t,r)}get knownAttributeNames(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}get currentAttributeNames(){return Array.from(this.element.attributes).map((e=>e.name))}get recordedAttributeNames(){return Array.from(this.stringMap.keys())}}class A{constructor(e,t,r){this.attributeObserver=new v(e,t,this),this.delegate=r,this.tokensByElement=new b}get started(){return this.attributeObserver.started}start(){this.attributeObserver.start()}pause(e){this.attributeObserver.pause(e)}stop(){this.attributeObserver.stop()}refresh(){this.attributeObserver.refresh()}get element(){return this.attributeObserver.element}get attributeName(){return this.attributeObserver.attributeName}elementMatchedAttribute(e){this.tokensMatched(this.readTokensForElement(e))}elementAttributeValueChanged(e){const[t,r]=this.refreshTokensForElement(e);this.tokensUnmatched(t),this.tokensMatched(r)}elementUnmatchedAttribute(e){this.tokensUnmatched(this.tokensByElement.getValuesForKey(e))}tokensMatched(e){e.forEach((e=>this.tokenMatched(e)))}tokensUnmatched(e){e.forEach((e=>this.tokenUnmatched(e)))}tokenMatched(e){this.delegate.tokenMatched(e),this.tokensByElement.add(e.element,e)}tokenUnmatched(e){this.delegate.tokenUnmatched(e),this.tokensByElement.delete(e.element,e)}refreshTokensForElement(e){const t=this.tokensByElement.getValuesForKey(e),r=this.readTokensForElement(e),n=function(e,t){const r=Math.max(e.length,t.length);return Array.from({length:r},((r,n)=>[e[n],t[n]]))}(t,r).findIndex((([e,t])=>{return n=t,!((r=e)&&n&&r.index==n.index&&r.content==n.content);var r,n}));return-1==n?[[],[]]:[t.slice(n),r.slice(n)]}readTokensForElement(e){const t=this.attributeName;return function(e,t,r){return e.trim().split(/\s+/).filter((e=>e.length)).map(((e,n)=>({element:t,attributeName:r,content:e,index:n})))}(e.getAttribute(t)||"",e,t)}}class O{constructor(e,t,r){this.tokenListObserver=new A(e,t,this),this.delegate=r,this.parseResultsByToken=new WeakMap,this.valuesByTokenByElement=new WeakMap}get started(){return this.tokenListObserver.started}start(){this.tokenListObserver.start()}stop(){this.tokenListObserver.stop()}refresh(){this.tokenListObserver.refresh()}get element(){return this.tokenListObserver.element}get attributeName(){return this.tokenListObserver.attributeName}tokenMatched(e){const{element:t}=e,{value:r}=this.fetchParseResultForToken(e);r&&(this.fetchValuesByTokenForElement(t).set(e,r),this.delegate.elementMatchedValue(t,r))}tokenUnmatched(e){const{element:t}=e,{value:r}=this.fetchParseResultForToken(e);r&&(this.fetchValuesByTokenForElement(t).delete(e),this.delegate.elementUnmatchedValue(t,r))}fetchParseResultForToken(e){let t=this.parseResultsByToken.get(e);return t||(t=this.parseToken(e),this.parseResultsByToken.set(e,t)),t}fetchValuesByTokenForElement(e){let t=this.valuesByTokenByElement.get(e);return t||(t=new Map,this.valuesByTokenByElement.set(e,t)),t}parseToken(e){try{return{value:this.delegate.parseValueForToken(e)}}catch(e){return{error:e}}}}class k{constructor(e,t){this.context=e,this.delegate=t,this.bindingsByAction=new Map}start(){this.valueListObserver||(this.valueListObserver=new O(this.element,this.actionAttribute,this),this.valueListObserver.start())}stop(){this.valueListObserver&&(this.valueListObserver.stop(),delete this.valueListObserver,this.disconnectAllActions())}get element(){return this.context.element}get identifier(){return this.context.identifier}get actionAttribute(){return this.schema.actionAttribute}get schema(){return this.context.schema}get bindings(){return Array.from(this.bindingsByAction.values())}connectAction(e){const t=new g(this.context,e);this.bindingsByAction.set(e,t),this.delegate.bindingConnected(t)}disconnectAction(e){const t=this.bindingsByAction.get(e);t&&(this.bindingsByAction.delete(e),this.delegate.bindingDisconnected(t))}disconnectAllActions(){this.bindings.forEach((e=>this.delegate.bindingDisconnected(e,!0))),this.bindingsByAction.clear()}parseValueForToken(e){const t=u.forToken(e,this.schema);if(t.identifier==this.identifier)return t}elementMatchedValue(e,t){this.connectAction(t)}elementUnmatchedValue(e,t){this.disconnectAction(t)}}class T{constructor(e,t){this.context=e,this.receiver=t,this.stringMapObserver=new w(this.element,this),this.valueDescriptorMap=this.controller.valueDescriptorMap}start(){this.stringMapObserver.start(),this.invokeChangedCallbacksForDefaultValues()}stop(){this.stringMapObserver.stop()}get element(){return this.context.element}get controller(){return this.context.controller}getStringMapKeyForAttribute(e){if(e in this.valueDescriptorMap)return this.valueDescriptorMap[e].name}stringMapKeyAdded(e,t){const r=this.valueDescriptorMap[t];this.hasValue(e)||this.invokeChangedCallback(e,r.writer(this.receiver[e]),r.writer(r.defaultValue))}stringMapValueChanged(e,t,r){const n=this.valueDescriptorNameMap[t];null!==e&&(null===r&&(r=n.writer(n.defaultValue)),this.invokeChangedCallback(t,e,r))}stringMapKeyRemoved(e,t,r){const n=this.valueDescriptorNameMap[e];this.hasValue(e)?this.invokeChangedCallback(e,n.writer(this.receiver[e]),r):this.invokeChangedCallback(e,n.writer(n.defaultValue),r)}invokeChangedCallbacksForDefaultValues(){for(const{key:e,name:t,defaultValue:r,writer:n}of this.valueDescriptors)null==r||this.controller.data.has(e)||this.invokeChangedCallback(t,n(r),void 0)}invokeChangedCallback(e,t,r){const n=`${e}Changed`,s=this.receiver[n];if("function"==typeof s){const n=this.valueDescriptorNameMap[e];try{const e=n.reader(t);let i=r;r&&(i=n.reader(r)),s.call(this.receiver,e,i)}catch(e){throw e instanceof TypeError&&(e.message=`Stimulus Value "${this.context.identifier}.${n.name}" - ${e.message}`),e}}}get valueDescriptors(){const{valueDescriptorMap:e}=this;return Object.keys(e).map((t=>e[t]))}get valueDescriptorNameMap(){const e={};return Object.keys(this.valueDescriptorMap).forEach((t=>{const r=this.valueDescriptorMap[t];e[r.name]=r})),e}hasValue(e){const t=`has${l(this.valueDescriptorNameMap[e].name)}`;return this.receiver[t]}}class M{constructor(e,t){this.context=e,this.delegate=t,this.targetsByName=new b}start(){this.tokenListObserver||(this.tokenListObserver=new A(this.element,this.attributeName,this),this.tokenListObserver.start())}stop(){this.tokenListObserver&&(this.disconnectAllTargets(),this.tokenListObserver.stop(),delete this.tokenListObserver)}tokenMatched({element:e,content:t}){this.scope.containsElement(e)&&this.connectTarget(e,t)}tokenUnmatched({element:e,content:t}){this.disconnectTarget(e,t)}connectTarget(e,t){var r;this.targetsByName.has(t,e)||(this.targetsByName.add(t,e),null===(r=this.tokenListObserver)||void 0===r||r.pause((()=>this.delegate.targetConnected(e,t))))}disconnectTarget(e,t){var r;this.targetsByName.has(t,e)&&(this.targetsByName.delete(t,e),null===(r=this.tokenListObserver)||void 0===r||r.pause((()=>this.delegate.targetDisconnected(e,t))))}disconnectAllTargets(){for(const e of this.targetsByName.keys)for(const t of this.targetsByName.getValuesForKey(e))this.disconnectTarget(t,e)}get attributeName(){return`data-${this.context.identifier}-target`}get element(){return this.context.element}get scope(){return this.context.scope}}function x(e,t){const r=S(e);return Array.from(r.reduce(((e,r)=>(function(e,t){const r=e[t];return Array.isArray(r)?r:[]}(r,t).forEach((t=>e.add(t))),e)),new Set))}function S(e){const t=[];for(;e;)t.push(e),e=Object.getPrototypeOf(e);return t.reverse()}class N{constructor(e,t){this.context=e,this.delegate=t,this.outletsByName=new b,this.outletElementsByName=new b,this.selectorObserverMap=new Map}start(){0===this.selectorObserverMap.size&&(this.outletDefinitions.forEach((e=>{const t=this.selector(e),r={outletName:e};t&&this.selectorObserverMap.set(e,new E(document.body,t,this,r))})),this.selectorObserverMap.forEach((e=>e.start()))),this.dependentContexts.forEach((e=>e.refresh()))}stop(){this.selectorObserverMap.size>0&&(this.disconnectAllOutlets(),this.selectorObserverMap.forEach((e=>e.stop())),this.selectorObserverMap.clear())}refresh(){this.selectorObserverMap.forEach((e=>e.refresh()))}selectorMatched(e,t,{outletName:r}){const n=this.getOutlet(e,r);n&&this.connectOutlet(n,e,r)}selectorUnmatched(e,t,{outletName:r}){const n=this.getOutletFromMap(e,r);n&&this.disconnectOutlet(n,e,r)}selectorMatchElement(e,{outletName:t}){return this.hasOutlet(e,t)&&e.matches(`[${this.context.application.schema.controllerAttribute}~=${t}]`)}connectOutlet(e,t,r){var n;this.outletElementsByName.has(r,t)||(this.outletsByName.add(r,e),this.outletElementsByName.add(r,t),null===(n=this.selectorObserverMap.get(r))||void 0===n||n.pause((()=>this.delegate.outletConnected(e,t,r))))}disconnectOutlet(e,t,r){var n;this.outletElementsByName.has(r,t)&&(this.outletsByName.delete(r,e),this.outletElementsByName.delete(r,t),null===(n=this.selectorObserverMap.get(r))||void 0===n||n.pause((()=>this.delegate.outletDisconnected(e,t,r))))}disconnectAllOutlets(){for(const e of this.outletElementsByName.keys)for(const t of this.outletElementsByName.getValuesForKey(e))for(const r of this.outletsByName.getValuesForKey(e))this.disconnectOutlet(r,t,e)}selector(e){return this.scope.outlets.getSelectorForOutletName(e)}get outletDependencies(){const e=new b;return this.router.modules.forEach((t=>{x(t.definition.controllerConstructor,"outlets").forEach((r=>e.add(r,t.identifier)))})),e}get outletDefinitions(){return this.outletDependencies.getKeysForValue(this.identifier)}get dependentControllerIdentifiers(){return this.outletDependencies.getValuesForKey(this.identifier)}get dependentContexts(){const e=this.dependentControllerIdentifiers;return this.router.contexts.filter((t=>e.includes(t.identifier)))}hasOutlet(e,t){return!!this.getOutlet(e,t)||!!this.getOutletFromMap(e,t)}getOutlet(e,t){return this.application.getControllerForElementAndIdentifier(e,t)}getOutletFromMap(e,t){return this.outletsByName.getValuesForKey(t).find((t=>t.element===e))}get scope(){return this.context.scope}get identifier(){return this.context.identifier}get application(){return this.context.application}get router(){return this.application.router}}class C{constructor(e,t){this.logDebugActivity=(e,t={})=>{const{identifier:r,controller:n,element:s}=this;t=Object.assign({identifier:r,controller:n,element:s},t),this.application.logDebugActivity(this.identifier,e,t)},this.module=e,this.scope=t,this.controller=new e.controllerConstructor(this),this.bindingObserver=new k(this,this.dispatcher),this.valueObserver=new T(this,this.controller),this.targetObserver=new M(this,this),this.outletObserver=new N(this,this);try{this.controller.initialize(),this.logDebugActivity("initialize")}catch(e){this.handleError(e,"initializing controller")}}connect(){this.bindingObserver.start(),this.valueObserver.start(),this.targetObserver.start(),this.outletObserver.start();try{this.controller.connect(),this.logDebugActivity("connect")}catch(e){this.handleError(e,"connecting controller")}}refresh(){this.outletObserver.refresh()}disconnect(){try{this.controller.disconnect(),this.logDebugActivity("disconnect")}catch(e){this.handleError(e,"disconnecting controller")}this.outletObserver.stop(),this.targetObserver.stop(),this.valueObserver.stop(),this.bindingObserver.stop()}get application(){return this.module.application}get identifier(){return this.module.identifier}get schema(){return this.application.schema}get dispatcher(){return this.application.dispatcher}get element(){return this.scope.element}get parentElement(){return this.element.parentElement}handleError(e,t,r={}){const{identifier:n,controller:s,element:i}=this;r=Object.assign({identifier:n,controller:s,element:i},r),this.application.handleError(e,`Error ${t}`,r)}targetConnected(e,t){this.invokeControllerMethod(`${t}TargetConnected`,e)}targetDisconnected(e,t){this.invokeControllerMethod(`${t}TargetDisconnected`,e)}outletConnected(e,t,r){this.invokeControllerMethod(`${c(r)}OutletConnected`,e,t)}outletDisconnected(e,t,r){this.invokeControllerMethod(`${c(r)}OutletDisconnected`,e,t)}invokeControllerMethod(e,...t){const r=this.controller;"function"==typeof r[e]&&r[e](...t)}}const F="function"==typeof Object.getOwnPropertySymbols?e=>[...Object.getOwnPropertyNames(e),...Object.getOwnPropertySymbols(e)]:Object.getOwnPropertyNames,L=(()=>{function e(e){function t(){return Reflect.construct(e,arguments,new.target)}return t.prototype=Object.create(e.prototype,{constructor:{value:t}}),Reflect.setPrototypeOf(t,e),t}try{return function(){const t=e((function(){this.a.call(this)}));t.prototype.a=function(){},new t}(),e}catch(e){return e=>class extends e{}}})();class B{constructor(e,t){this.application=e,this.definition=function(e){return{identifier:e.identifier,controllerConstructor:(t=e.controllerConstructor,function(e,t){const r=L(e),n=function(e,t){return F(t).reduce(((r,n)=>{const s=function(e,t,r){const n=Object.getOwnPropertyDescriptor(e,r);if(!n||!("value"in n)){const e=Object.getOwnPropertyDescriptor(t,r).value;return n&&(e.get=n.get||e.get,e.set=n.set||e.set),e}}(e,t,n);return s&&Object.assign(r,{[n]:s}),r}),{})}(e.prototype,t);return Object.defineProperties(r.prototype,n),r}(t,function(e){return x(e,"blessings").reduce(((t,r)=>{const n=r(e);for(const e in n){const r=t[e]||{};t[e]=Object.assign(r,n[e])}return t}),{})}(t)))};var t}(t),this.contextsByScope=new WeakMap,this.connectedContexts=new Set}get identifier(){return this.definition.identifier}get controllerConstructor(){return this.definition.controllerConstructor}get contexts(){return Array.from(this.connectedContexts)}connectContextForScope(e){const t=this.fetchContextForScope(e);this.connectedContexts.add(t),t.connect()}disconnectContextForScope(e){const t=this.contextsByScope.get(e);t&&(this.connectedContexts.delete(t),t.disconnect())}fetchContextForScope(e){let t=this.contextsByScope.get(e);return t||(t=new C(this,e),this.contextsByScope.set(e,t)),t}}class ${constructor(e){this.scope=e}has(e){return this.data.has(this.getDataKey(e))}get(e){return this.getAll(e)[0]}getAll(e){return(this.data.get(this.getDataKey(e))||"").match(/[^\s]+/g)||[]}getAttributeName(e){return this.data.getAttributeNameForKey(this.getDataKey(e))}getDataKey(e){return`${e}-class`}get data(){return this.scope.data}}class j{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get(e){const t=this.getAttributeNameForKey(e);return this.element.getAttribute(t)}set(e,t){const r=this.getAttributeNameForKey(e);return this.element.setAttribute(r,t),this.get(e)}has(e){const t=this.getAttributeNameForKey(e);return this.element.hasAttribute(t)}delete(e){if(this.has(e)){const t=this.getAttributeNameForKey(e);return this.element.removeAttribute(t),!0}return!1}getAttributeNameForKey(e){return`data-${this.identifier}-${h(e)}`}}class D{constructor(e){this.warnedKeysByObject=new WeakMap,this.logger=e}warn(e,t,r){let n=this.warnedKeysByObject.get(e);n||(n=new Set,this.warnedKeysByObject.set(e,n)),n.has(t)||(n.add(t),this.logger.warn(r,e))}}function I(e,t){return`[${e}~="${t}"]`}class K{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce(((e,t)=>e||this.findTarget(t)||this.findLegacyTarget(t)),void 0)}findAll(...e){return e.reduce(((e,t)=>[...e,...this.findAllTargets(t),...this.findAllLegacyTargets(t)]),[])}findTarget(e){const t=this.getSelectorForTargetName(e);return this.scope.findElement(t)}findAllTargets(e){const t=this.getSelectorForTargetName(e);return this.scope.findAllElements(t)}getSelectorForTargetName(e){return I(this.schema.targetAttributeForScope(this.identifier),e)}findLegacyTarget(e){const t=this.getLegacySelectorForTargetName(e);return this.deprecate(this.scope.findElement(t),e)}findAllLegacyTargets(e){const t=this.getLegacySelectorForTargetName(e);return this.scope.findAllElements(t).map((t=>this.deprecate(t,e)))}getLegacySelectorForTargetName(e){const t=`${this.identifier}.${e}`;return I(this.schema.targetAttribute,t)}deprecate(e,t){if(e){const{identifier:r}=this,n=this.schema.targetAttribute,s=this.schema.targetAttributeForScope(r);this.guide.warn(e,`target:${t}`,`Please replace ${n}="${r}.${t}" with ${s}="${t}". The ${n} attribute is deprecated and will be removed in a future version of Stimulus.`)}return e}get guide(){return this.scope.guide}}class V{constructor(e,t){this.scope=e,this.controllerElement=t}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce(((e,t)=>e||this.findOutlet(t)),void 0)}findAll(...e){return e.reduce(((e,t)=>[...e,...this.findAllOutlets(t)]),[])}getSelectorForOutletName(e){const t=this.schema.outletAttributeForScope(this.identifier,e);return this.controllerElement.getAttribute(t)}findOutlet(e){const t=this.getSelectorForOutletName(e);if(t)return this.findElement(t,e)}findAllOutlets(e){const t=this.getSelectorForOutletName(e);return t?this.findAllElements(t,e):[]}findElement(e,t){return this.scope.queryElements(e).filter((r=>this.matchesElement(r,e,t)))[0]}findAllElements(e,t){return this.scope.queryElements(e).filter((r=>this.matchesElement(r,e,t)))}matchesElement(e,t,r){const n=e.getAttribute(this.scope.schema.controllerAttribute)||"";return e.matches(t)&&n.split(" ").includes(r)}}class P{constructor(e,t,r,n){this.targets=new K(this),this.classes=new $(this),this.data=new j(this),this.containsElement=e=>e.closest(this.controllerSelector)===this.element,this.schema=e,this.element=t,this.identifier=r,this.guide=new D(n),this.outlets=new V(this.documentScope,t)}findElement(e){return this.element.matches(e)?this.element:this.queryElements(e).find(this.containsElement)}findAllElements(e){return[...this.element.matches(e)?[this.element]:[],...this.queryElements(e).filter(this.containsElement)]}queryElements(e){return Array.from(this.element.querySelectorAll(e))}get controllerSelector(){return I(this.schema.controllerAttribute,this.identifier)}get isDocumentScope(){return this.element===document.documentElement}get documentScope(){return this.isDocumentScope?this:new P(this.schema,document.documentElement,this.identifier,this.guide.logger)}}class R{constructor(e,t,r){this.element=e,this.schema=t,this.delegate=r,this.valueListObserver=new O(this.element,this.controllerAttribute,this),this.scopesByIdentifierByElement=new WeakMap,this.scopeReferenceCounts=new WeakMap}start(){this.valueListObserver.start()}stop(){this.valueListObserver.stop()}get controllerAttribute(){return this.schema.controllerAttribute}parseValueForToken(e){const{element:t,content:r}=e,n=this.fetchScopesByIdentifierForElement(t);let s=n.get(r);return s||(s=this.delegate.createScopeForElementAndIdentifier(t,r),n.set(r,s)),s}elementMatchedValue(e,t){const r=(this.scopeReferenceCounts.get(t)||0)+1;this.scopeReferenceCounts.set(t,r),1==r&&this.delegate.scopeConnected(t)}elementUnmatchedValue(e,t){const r=this.scopeReferenceCounts.get(t);r&&(this.scopeReferenceCounts.set(t,r-1),1==r&&this.delegate.scopeDisconnected(t))}fetchScopesByIdentifierForElement(e){let t=this.scopesByIdentifierByElement.get(e);return t||(t=new Map,this.scopesByIdentifierByElement.set(e,t)),t}}class U{constructor(e){this.application=e,this.scopeObserver=new R(this.element,this.schema,this),this.scopesByIdentifier=new b,this.modulesByIdentifier=new Map}get element(){return this.application.element}get schema(){return this.application.schema}get logger(){return this.application.logger}get controllerAttribute(){return this.schema.controllerAttribute}get modules(){return Array.from(this.modulesByIdentifier.values())}get contexts(){return this.modules.reduce(((e,t)=>e.concat(t.contexts)),[])}start(){this.scopeObserver.start()}stop(){this.scopeObserver.stop()}loadDefinition(e){this.unloadIdentifier(e.identifier);const t=new B(this.application,e);this.connectModule(t);const r=e.controllerConstructor.afterLoad;r&&r(e.identifier,this.application)}unloadIdentifier(e){const t=this.modulesByIdentifier.get(e);t&&this.disconnectModule(t)}getContextForElementAndIdentifier(e,t){const r=this.modulesByIdentifier.get(t);if(r)return r.contexts.find((t=>t.element==e))}handleError(e,t,r){this.application.handleError(e,t,r)}createScopeForElementAndIdentifier(e,t){return new P(this.schema,e,t,this.logger)}scopeConnected(e){this.scopesByIdentifier.add(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.connectContextForScope(e)}scopeDisconnected(e){this.scopesByIdentifier.delete(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.disconnectContextForScope(e)}connectModule(e){this.modulesByIdentifier.set(e.identifier,e),this.scopesByIdentifier.getValuesForKey(e.identifier).forEach((t=>e.connectContextForScope(t)))}disconnectModule(e){this.modulesByIdentifier.delete(e.identifier),this.scopesByIdentifier.getValuesForKey(e.identifier).forEach((t=>e.disconnectContextForScope(t)))}}const _={controllerAttribute:"data-controller",actionAttribute:"data-action",targetAttribute:"data-target",targetAttributeForScope:e=>`data-${e}-target`,outletAttributeForScope:(e,t)=>`data-${e}-${t}-outlet`,keyMappings:Object.assign(Object.assign({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End"},q("abcdefghijklmnopqrstuvwxyz".split("").map((e=>[e,e])))),q("0123456789".split("").map((e=>[e,e]))))};function q(e){return e.reduce(((e,[t,r])=>Object.assign(Object.assign({},e),{[t]:r})),{})}class z{constructor(e=document.documentElement,t=_){this.logger=console,this.debug=!1,this.logDebugActivity=(e,t,r={})=>{this.debug&&this.logFormattedMessage(e,t,r)},this.element=e,this.schema=t,this.dispatcher=new s(this),this.router=new U(this),this.actionDescriptorFilters=Object.assign({},i)}static start(e,t){const r=new this(e,t);return r.start(),r}async start(){await new Promise((e=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",(()=>e())):e()})),this.logDebugActivity("application","starting"),this.dispatcher.start(),this.router.start(),this.logDebugActivity("application","start")}stop(){this.logDebugActivity("application","stopping"),this.dispatcher.stop(),this.router.stop(),this.logDebugActivity("application","stop")}register(e,t){this.load({identifier:e,controllerConstructor:t})}registerActionOption(e,t){this.actionDescriptorFilters[e]=t}load(e,...t){(Array.isArray(e)?e:[e,...t]).forEach((e=>{e.controllerConstructor.shouldLoad&&this.router.loadDefinition(e)}))}unload(e,...t){(Array.isArray(e)?e:[e,...t]).forEach((e=>this.router.unloadIdentifier(e)))}get controllers(){return this.router.contexts.map((e=>e.controller))}getControllerForElementAndIdentifier(e,t){const r=this.router.getContextForElementAndIdentifier(e,t);return r?r.controller:null}handleError(e,t,r){var n;this.logger.error("%s\n\n%o\n\n%o",t,e,r),null===(n=window.onerror)||void 0===n||n.call(window,t,"",0,0,e)}logFormattedMessage(e,t,r={}){r=Object.assign({application:this},r),this.logger.groupCollapsed(`${e} #${t}`),this.logger.log("details:",Object.assign({},r)),this.logger.groupEnd()}}function W([e,t],r){return function(e){const t=`${h(e.token)}-value`,r=function(e){const t=function(e){const t=Q(e.typeObject.type);if(!t)return;const r=H(e.typeObject.default);if(t!==r){throw new Error(`The specified default value for the Stimulus Value "${e.controller?`${e.controller}.${e.token}`:e.token}" must match the defined type "${t}". The provided default value of "${e.typeObject.default}" is of type "${r}".`)}return t}({controller:e.controller,token:e.token,typeObject:e.typeDefinition}),r=H(e.typeDefinition),n=Q(e.typeDefinition),s=t||r||n;if(s)return s;throw new Error(`Unknown value type "${e.controller?`${e.controller}.${e.typeDefinition}`:e.token}" for "${e.token}" value`)}(e);return{type:r,key:t,name:a(t),get defaultValue(){return function(e){const t=Q(e);if(t)return Y[t];const r=e.default;return void 0!==r?r:e}(e.typeDefinition)},get hasCustomDefaultValue(){return void 0!==H(e.typeDefinition)},reader:J[r],writer:X[r]||X.default}}({controller:r,token:e,typeDefinition:t})}function Q(e){switch(e){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function H(e){switch(typeof e){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(e)?"array":"[object Object]"===Object.prototype.toString.call(e)?"object":void 0}const Y={get array(){return[]},boolean:!1,number:0,get object(){return{}},string:""},J={array(e){const t=JSON.parse(e);if(!Array.isArray(t))throw new TypeError(`expected value of type "array" but instead got value "${e}" of type "${H(t)}"`);return t},boolean(e){return!("0"==e||"false"==String(e).toLowerCase())},number(e){return Number(e)},object(e){const t=JSON.parse(e);if(null===t||"object"!=typeof t||Array.isArray(t))throw new TypeError(`expected value of type "object" but instead got value "${e}" of type "${H(t)}"`);return t},string(e){return e}},X={default:function(e){return`${e}`},array:Z,object:Z};function Z(e){return JSON.stringify(e)}class G{constructor(e){this.context=e}static get shouldLoad(){return!0}static afterLoad(e,t){}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get outlets(){return this.scope.outlets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(e,{target:t=this.element,detail:r={},prefix:n=this.identifier,bubbles:s=!0,cancelable:i=!0}={}){const o=new CustomEvent(n?`${n}:${e}`:e,{detail:r,bubbles:s,cancelable:i});return t.dispatchEvent(o),o}}G.blessings=[function(e){return x(e,"classes").reduce(((e,t)=>{return Object.assign(e,{[`${r=t}Class`]:{get(){const{classes:e}=this;if(e.has(r))return e.get(r);{const t=e.getAttributeName(r);throw new Error(`Missing attribute "${t}"`)}}},[`${r}Classes`]:{get(){return this.classes.getAll(r)}},[`has${l(r)}Class`]:{get(){return this.classes.has(r)}}});var r}),{})},function(e){return x(e,"targets").reduce(((e,t)=>{return Object.assign(e,{[`${r=t}Target`]:{get(){const e=this.targets.find(r);if(e)return e;throw new Error(`Missing target element "${r}" for "${this.identifier}" controller`)}},[`${r}Targets`]:{get(){return this.targets.findAll(r)}},[`has${l(r)}Target`]:{get(){return this.targets.has(r)}}});var r}),{})},function(e){const t=function(e,t){return S(e).reduce(((e,r)=>(e.push(...function(e,t){const r=e[t];return r?Object.keys(r).map((e=>[e,r[e]])):[]}(r,t)),e)),[])}(e,"values"),r={valueDescriptorMap:{get(){return t.reduce(((e,t)=>{const r=W(t,this.identifier),n=this.data.getAttributeNameForKey(r.key);return Object.assign(e,{[n]:r})}),{})}}};return t.reduce(((e,t)=>Object.assign(e,function(e,t){const r=W(e,void 0),{key:n,name:s,reader:i,writer:o}=r;return{[s]:{get(){const e=this.data.get(n);return null!==e?i(e):r.defaultValue},set(e){void 0===e?this.data.delete(n):this.data.set(n,o(e))}},[`has${l(s)}`]:{get(){return this.data.has(n)||r.hasCustomDefaultValue}}}}(t))),r)},function(e){return x(e,"outlets").reduce(((e,t)=>Object.assign(e,function(e){const t=c(e);return{[`${t}Outlet`]:{get(){const t=this.outlets.find(e);if(t){const r=this.application.getControllerForElementAndIdentifier(t,e);if(r)return r;throw new Error(`Missing "data-controller=${e}" attribute on outlet element for "${this.identifier}" controller`)}throw new Error(`Missing outlet element "${e}" for "${this.identifier}" controller`)}},[`${t}Outlets`]:{get(){const t=this.outlets.findAll(e);return t.length>0?t.map((t=>{const r=this.application.getControllerForElementAndIdentifier(t,e);if(r)return r;console.warn(`The provided outlet element is missing the outlet controller "${e}" for "${this.identifier}"`,t)})).filter((e=>e)):[]}},[`${t}OutletElement`]:{get(){const t=this.outlets.find(e);if(t)return t;throw new Error(`Missing outlet element "${e}" for "${this.identifier}" controller`)}},[`${t}OutletElements`]:{get(){return this.outlets.findAll(e)}},[`has${l(t)}Outlet`]:{get(){return this.outlets.has(e)}}}}(t))),{})}],G.targets=[],G.outlets=[],G.values={}},890:function(e,t,r){"use strict";r.r(t);var n=r(599),s=r(152),i=r.n(s);t.default=class extends n.Qr{copyHeaderLink(e){const t=new(i())(".headerlink",{text:e=>e.href});e.preventDefault(),t.on("success",this.showTooltip)}showTooltip(e){const t=e.trigger,r=t.getAttribute("aria-label");t.setAttribute("aria-label","Copied!"),setTimeout((()=>{t.setAttribute("aria-label",r)}),2500)}}},606:function(e,t,r){"use strict";r.r(t);var n=r(599),s=r(152),i=r.n(s);t.default=class extends n.Qr{static targets=["button"];connect(){const e=this.element.querySelector("pre");if(this.pre=e,this.label="copy",e){const t=document.createElement("button");t.classList.add("copy"),t.setAttribute("data-code-target","button"),t.setAttribute("data-action","code#copy"),t.textContent=this.label,e.appendChild(t)}}copy(){const e=new(i())(this.pre,{target:()=>this.pre});e.on("success",(()=>{this.hasButtonTarget&&(this.buttonTarget.textContent="copied!",setTimeout((()=>this.buttonTarget.textContent=this.label),1500))})),e.on("error",(e=>{console.error(e.action),console.error(e.trigger)}))}}},635:function(e,t,r){"use strict";r.r(t);var n=r(599);t.default=class extends n.Qr{expandMore(e){this.expand(e.target.parentNode)}expand(e){e.classList.toggle("active");const t=e.querySelector("button.expand-more");e.classList.contains("active")?(t.setAttribute("aria-expanded","true"),t.setAttribute("aria-label","Collapse this section")):(t.setAttribute("aria-expanded","false"),t.setAttribute("aria-label","Expand this section"))}}},850:function(e,t,r){"use strict";r.r(t);var n=r(599);t.default=class extends n.Qr{connect(){const e=document.querySelectorAll("article section"),t={root:this.element,rootMargin:"0px 0px -95% 0px"},r=new IntersectionObserver(this._highlightCurrentSection,t);e.forEach((e=>{r.observe(e)}))}_highlightCurrentSection(e){e.forEach((e=>{const t=document.querySelector(`.nav-toc a[href*=${e.target.id}]`);e.isIntersecting&&t?t.classList.add("current"):t&&t.classList.remove("current")}))}}},625:function(e,t,r){"use strict";r.r(t);var n=r(599);t.default=class extends n.Qr{static targets=["scrollToTop","main"];connect(){this.lastPosition=0,this.offset=200}scroll(){this.scrollWindow.scrollTop=0,window.scrollTo({top:0,left:0,behavior:"smooth"}),this.scrollToTopTarget.blur()}showButton(){if(this.hasScrollToTopTarget&&this.hasMainTarget){const e=this.mainTarget.scrollTop>this.offset||window.scrollY>this.offset;if(this.mainTarget.scrollTop>0&&0===window.scrollY){const t=this.mainTarget.scrollTop0&&0===this.mainTarget.scrollTop){const t=window.scrollY ul > li > .nav-link > a").forEach((e=>{e.setAttribute("tabindex","0"),this.setIconFocus(e.previousElementSibling,"0")})):t.parentElement.nextElementSibling.querySelectorAll("a").forEach((e=>{e.setAttribute("tabindex","-1"),this.setIconFocus(e.previousElementSibling,"-1")}))}handleFocus(){this.getNotExpandedLinks().forEach((e=>{const t=e.previousElementSibling;e.parentNode.parentNode.classList.contains("toctree-l1")?(e.setAttribute("tabindex","0"),this.setIconFocus(t,"0")):(e.setAttribute("tabindex","-1"),this.setIconFocus(t,"-1"))}))}getNotExpandedLinks(){return this.sidebarTarget.querySelectorAll(":not(.expanded) > ul > li > .nav-link > a")}setIconFocus(e,t){e&&e.classList.contains("expand")&&e.setAttribute("tabindex",t)}removeAllFocus(){this.sidebarTarget.querySelectorAll("a, svg").forEach((e=>e.setAttribute("tabindex","-1")))}}},152:function(e){var t;t=function(){return function(){var e={686:function(e,t,r){"use strict";r.d(t,{default:function(){return E}});var n=r(279),s=r.n(n),i=r(370),o=r.n(i),a=r(817),c=r.n(a);function l(e){try{return document.execCommand(e)}catch(e){return!1}}var h=function(e){var t=c()(e);return l("cut"),t},u=function(e,t){var r=function(e){var t="rtl"===document.documentElement.getAttribute("dir"),r=document.createElement("textarea");r.style.fontSize="12pt",r.style.border="0",r.style.padding="0",r.style.margin="0",r.style.position="absolute",r.style[t?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;return r.style.top="".concat(n,"px"),r.setAttribute("readonly",""),r.value=e,r}(e);t.container.appendChild(r);var n=c()(r);return l("copy"),r.remove(),n},d=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{container:document.body},r="";return"string"==typeof e?r=u(e,t):e instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(null==e?void 0:e.type)?r=u(e.value,t):(r=c()(e),l("copy")),r};function m(e){return m="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},m(e)}function p(e){return p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},p(e)}function g(e,t){for(var r=0;r0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText,this.container="object"===p(e.container)?e.container:document.body}},{key:"listenClick",value:function(e){var t=this;this.listener=o()(e,"click",(function(e){return t.onClick(e)}))}},{key:"onClick",value:function(e){var t=e.delegateTarget||e.currentTarget,r=this.action(t)||"copy",n=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.action,r=void 0===t?"copy":t,n=e.container,s=e.target,i=e.text;if("copy"!==r&&"cut"!==r)throw new Error('Invalid "action" value, use either "copy" or "cut"');if(void 0!==s){if(!s||"object"!==m(s)||1!==s.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===r&&s.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===r&&(s.hasAttribute("readonly")||s.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes')}return i?d(i,{container:n}):s?"cut"===r?h(s):d(s,{container:n}):void 0}({action:r,container:this.container,target:this.target(t),text:this.text(t)});this.emit(n?"success":"error",{action:r,text:n,trigger:t,clearSelection:function(){t&&t.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(e){return y("action",e)}},{key:"defaultTarget",value:function(e){var t=y("target",e);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(e){return y("text",e)}},{key:"destroy",value:function(){this.listener.destroy()}}],n=[{key:"copy",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{container:document.body};return d(e,t)}},{key:"cut",value:function(e){return h(e)}},{key:"isSupported",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"==typeof e?[e]:e,r=!!document.queryCommandSupported;return t.forEach((function(e){r=r&&!!document.queryCommandSupported(e)})),r}}],r&&g(t.prototype,r),n&&g(t,n),c}(s()),E=b},828:function(e){if("undefined"!=typeof Element&&!Element.prototype.matches){var t=Element.prototype;t.matches=t.matchesSelector||t.mozMatchesSelector||t.msMatchesSelector||t.oMatchesSelector||t.webkitMatchesSelector}e.exports=function(e,t){for(;e&&9!==e.nodeType;){if("function"==typeof e.matches&&e.matches(t))return e;e=e.parentNode}}},438:function(e,t,r){var n=r(828);function s(e,t,r,n,s){var o=i.apply(this,arguments);return e.addEventListener(r,o,s),{destroy:function(){e.removeEventListener(r,o,s)}}}function i(e,t,r,s){return function(r){r.delegateTarget=n(r.target,t),r.delegateTarget&&s.call(e,r)}}e.exports=function(e,t,r,n,i){return"function"==typeof e.addEventListener?s.apply(null,arguments):"function"==typeof r?s.bind(null,document).apply(null,arguments):("string"==typeof e&&(e=document.querySelectorAll(e)),Array.prototype.map.call(e,(function(e){return s(e,t,r,n,i)})))}},879:function(e,t){t.node=function(e){return void 0!==e&&e instanceof HTMLElement&&1===e.nodeType},t.nodeList=function(e){var r=Object.prototype.toString.call(e);return void 0!==e&&("[object NodeList]"===r||"[object HTMLCollection]"===r)&&"length"in e&&(0===e.length||t.node(e[0]))},t.string=function(e){return"string"==typeof e||e instanceof String},t.fn=function(e){return"[object Function]"===Object.prototype.toString.call(e)}},370:function(e,t,r){var n=r(879),s=r(438);e.exports=function(e,t,r){if(!e&&!t&&!r)throw new Error("Missing required arguments");if(!n.string(t))throw new TypeError("Second argument must be a String");if(!n.fn(r))throw new TypeError("Third argument must be a Function");if(n.node(e))return function(e,t,r){return e.addEventListener(t,r),{destroy:function(){e.removeEventListener(t,r)}}}(e,t,r);if(n.nodeList(e))return function(e,t,r){return Array.prototype.forEach.call(e,(function(e){e.addEventListener(t,r)})),{destroy:function(){Array.prototype.forEach.call(e,(function(e){e.removeEventListener(t,r)}))}}}(e,t,r);if(n.string(e))return function(e,t,r){return s(document.body,e,t,r)}(e,t,r);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}},817:function(e){e.exports=function(e){var t;if("SELECT"===e.nodeName)e.focus(),t=e.value;else if("INPUT"===e.nodeName||"TEXTAREA"===e.nodeName){var r=e.hasAttribute("readonly");r||e.setAttribute("readonly",""),e.select(),e.setSelectionRange(0,e.value.length),r||e.removeAttribute("readonly"),t=e.value}else{e.hasAttribute("contenteditable")&&e.focus();var n=window.getSelection(),s=document.createRange();s.selectNodeContents(e),n.removeAllRanges(),n.addRange(s),t=n.toString()}return t}},279:function(e){function t(){}t.prototype={on:function(e,t,r){var n=this.e||(this.e={});return(n[e]||(n[e]=[])).push({fn:t,ctx:r}),this},once:function(e,t,r){var n=this;function s(){n.off(e,s),t.apply(r,arguments)}return s._=t,this.on(e,s,r)},emit:function(e){for(var t=[].slice.call(arguments,1),r=((this.e||(this.e={}))[e]||[]).slice(),n=0,s=r.length;nfunction(e,t){const r=function(e){const t=(e.match(/^(?:\.\/)?(.+)(?:[_-]controller\..+?)$/)||[])[1];if(t)return t.replace(/_/g,"-").replace(/\//g,"--")}(t);if(r)return function(e,t){const r=e.default;if("function"==typeof r)return{identifier:t,controllerConstructor:r}}(e(t),r)}(n,e))).filter((e=>e)))}()}(); \ No newline at end of file diff --git a/_static/theme.c8991bd7bb6e57cbeea8.js.LICENSE.txt b/_static/theme.c8991bd7bb6e57cbeea8.js.LICENSE.txt new file mode 100644 index 00000000..5161813c --- /dev/null +++ b/_static/theme.c8991bd7bb6e57cbeea8.js.LICENSE.txt @@ -0,0 +1,6 @@ +/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ diff --git a/_static/theme.c973b470ab69573097f3.css b/_static/theme.c973b470ab69573097f3.css new file mode 100644 index 00000000..919c2692 --- /dev/null +++ b/_static/theme.c973b470ab69573097f3.css @@ -0,0 +1,11 @@ +/*! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:Roboto,sans-serif;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:JetBrains\ Mono,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 transparent;--tw-ring-shadow:0 0 transparent;--tw-shadow:0 0 transparent;--tw-shadow-colored:0 0 transparent;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 transparent;--tw-ring-shadow:0 0 transparent;--tw-shadow:0 0 transparent;--tw-shadow-colored:0 0 transparent;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.prose{color:var(--tw-prose-body);max-width:760px}.prose :where(p):not(:where([class~=not-prose] *)){margin-bottom:1.25em;margin-top:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose] *)){color:var(--tw-prose-lead);font-size:1.25em;line-height:1.6;margin-bottom:1.2em;margin-top:1.2em}.prose :where(a):not(:where([class~=not-prose] *)){color:var(--tw-prose-links);font-weight:400;-webkit-text-decoration:none;text-decoration:none}.prose :where(strong):not(:where([class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:500}.prose :where(a strong):not(:where([class~=not-prose] *)){color:inherit}.prose :where(blockquote strong):not(:where([class~=not-prose] *)){color:inherit}.prose :where(thead th strong):not(:where([class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose] *)){list-style-type:decimal;margin-bottom:1.25em;margin-top:1.25em;padding-left:1.625em}.prose :where(ol[type=A]):not(:where([class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose] *)){list-style-type:disc;margin-bottom:1.25em;margin-top:1.25em;padding-left:1.625em}.prose :where(ol>li):not(:where([class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:500}.prose :where(ul>li):not(:where([class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(hr):not(:where([class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-bottom:3em;margin-top:3em}.prose :where(blockquote):not(:where([class~=not-prose] *)){border-left-color:var(--tw-prose-quote-borders);border-left-width:4px;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);color:inherit;font-size:.875rem;font-style:normal;font-weight:400;margin-bottom:1.5rem;margin-top:1.5rem;padding:1rem;quotes:"\201C""\201D""\2018""\2019"}.prose :where(h1):not(:where([class~=not-prose] *)){color:var(--tw-prose-headings);font-size:2.5rem;font-weight:400;letter-spacing:-.025em;line-height:1.1111111;margin-bottom:.8888889em;margin-top:5rem}.prose :where(h1 strong):not(:where([class~=not-prose] *)){color:inherit;font-weight:900}.prose :where(h2):not(:where([class~=not-prose] *)){color:var(--tw-prose-headings);font-size:1.75rem;font-weight:400;letter-spacing:-.025em;line-height:1.3333333;margin-bottom:1em;margin-top:2em}.prose :where(h2 strong):not(:where([class~=not-prose] *)){color:inherit;font-weight:800}.prose :where(h3):not(:where([class~=not-prose] *)){color:var(--tw-prose-headings);font-size:1.375rem;font-weight:400;line-height:1.6;margin-bottom:.6em;margin-top:1.6em}.prose :where(h3 strong):not(:where([class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(h4):not(:where([class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:500;line-height:1.5;margin-bottom:.5em;margin-top:1.5em}.prose :where(h4 strong):not(:where([class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(img):not(:where([class~=not-prose] *)){margin-bottom:2em;margin-top:2em}.prose :where(figure>*):not(:where([class~=not-prose] *)){margin-bottom:0;margin-top:0}.prose :where(figcaption):not(:where([class~=not-prose] *)){color:var(--tw-prose-captions);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose :where(code):not(:where([class~=not-prose] *)){background-color:#f3f4f6;border-radius:.125rem;color:var(--tw-prose-code);font-size:.9375em;font-weight:500;padding:1px 4px}.prose :where(a code):not(:where([class~=not-prose] *)){color:inherit}.prose :where(h1 code):not(:where([class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose] *)){color:inherit}.prose :where(blockquote code):not(:where([class~=not-prose] *)){color:inherit}.prose :where(thead th code):not(:where([class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose] *)){background-color:inherit;border-radius:.125rem;border-width:1px;color:var(--tw-prose-pre-code);font-size:.9375em;font-weight:400;line-height:1.7142857;margin-bottom:0;margin-top:0;overflow-x:auto;padding:.8571429em 1.1428571em}.prose :where(pre code):not(:where([class~=not-prose] *)){background-color:transparent;border-radius:0;border-width:0;color:inherit;font-family:inherit;font-size:inherit;font-weight:inherit;line-height:inherit;padding:0}.prose :where(pre code):not(:where([class~=not-prose] *)):before{content:none}.prose :where(pre code):not(:where([class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose] *)){font-size:.875em;line-height:1.7142857;margin-bottom:2em;margin-top:2em;table-layout:auto;text-align:left;width:100%}.prose :where(thead):not(:where([class~=not-prose] *)){border-bottom-color:var(--tw-prose-th-borders);border-bottom-width:1px}.prose :where(thead th):not(:where([class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:500;padding-bottom:.5714286em;padding-left:.5714286em;padding-right:.5714286em;vertical-align:bottom}.prose :where(tbody tr):not(:where([class~=not-prose] *)){border-bottom-color:var(--tw-prose-td-borders);border-bottom-width:1px}.prose :where(tbody tr:last-child):not(:where([class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose] *)){border-top-color:var(--tw-prose-th-borders);border-top-width:1px}.prose :where(tfoot td):not(:where([class~=not-prose] *)){vertical-align:top}.prose{--tw-prose-body:var(--color-gray);--tw-prose-headings:var(--color-gray-dark);--tw-prose-lead:var(--color-gray-dark);--tw-prose-links:var(--color-link);--tw-prose-bold:#111827;--tw-prose-counters:var(--color-gray-dark);--tw-prose-bullets:var(--color-gray-light);--tw-prose-hr:#e5e7eb;--tw-prose-quotes:#111827;--tw-prose-quote-borders:#e5e7eb;--tw-prose-captions:var(--color-gray-light);--tw-prose-code:#111827;--tw-prose-pre-code:inherit;--tw-prose-pre-bg:inherit;--tw-prose-th-borders:#d1d5db;--tw-prose-td-borders:#e5e7eb;--tw-prose-invert-body:#d1d5db;--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:#9ca3af;--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:#9ca3af;--tw-prose-invert-bullets:#4b5563;--tw-prose-invert-hr:#374151;--tw-prose-invert-quotes:#f3f4f6;--tw-prose-invert-quote-borders:#374151;--tw-prose-invert-captions:#9ca3af;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:#d1d5db;--tw-prose-invert-pre-bg:rgba(0,0,0,.5);--tw-prose-invert-th-borders:#4b5563;--tw-prose-invert-td-borders:#374151;font-size:1rem;line-height:inherit}.prose :where(video):not(:where([class~=not-prose] *)){margin-bottom:2em;margin-top:2em}.prose :where(figure):not(:where([class~=not-prose] *)){margin-bottom:2em;margin-top:2em}.prose :where(li):not(:where([class~=not-prose] *)){margin-bottom:.5em;margin-top:.5em}.prose :where(ol>li):not(:where([class~=not-prose] *)){padding-left:.375em}.prose :where(ul>li):not(:where([class~=not-prose] *)){padding-left:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose] *)){margin-bottom:.75em;margin-top:.75em}.prose :where(.prose>ul>li>:first-child):not(:where([class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>:last-child):not(:where([class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>:first-child):not(:where([class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>:last-child):not(:where([class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose] *)){margin-bottom:.75em;margin-top:.75em}.prose :where(hr+*):not(:where([class~=not-prose] *)){margin-top:0}.prose :where(h2+*):not(:where([class~=not-prose] *)){margin-top:0}.prose :where(h3+*):not(:where([class~=not-prose] *)){margin-top:0}.prose :where(h4+*):not(:where([class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose] *)){padding-left:0}.prose :where(thead th:last-child):not(:where([class~=not-prose] *)){padding-right:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose] *)){padding:.5714286em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose] *)){padding-left:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose] *)){padding-right:0}.prose :where(.prose>:first-child):not(:where([class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose] *)){margin-bottom:0}.prose{--awsm-prose-placeholders:#6b21a8}.prose :where(svg):not(:where([class~=not-prose] *)){display:inline}.prose :where(.rubric):not(:where([class~=not-prose] *)){color:var(--tw-prose-headings);font-weight:500;margin-bottom:.5em}.prose :where(.centered):not(:where([class~=not-prose] *)){text-align:center}.prose :where(.lead+*):not(:where([class~=not-prose] *)){margin-top:3rem}.prose :where(a.toc-backref):not(:where([class~=not-prose] *)){color:inherit}.prose :where(a:hover):not(:where([class~=not-prose] *)){color:#0ea5e9;color:var(--color-brand);-webkit-text-decoration:underline;text-decoration:underline}.prose :where(a:focus):not(:where([class~=not-prose] *)){color:#0ea5e9;color:var(--color-brand);-webkit-text-decoration:underline;text-decoration:underline}.prose :where(ol ol):not(:where([class~=not-prose] *)){list-style:lower-latin}.prose :where(var):not(:where([class~=not-prose] *)){color:var(--awsm-prose-placeholders)}.prose :where(.samp em):not(:where([class~=not-prose] *)){color:var(--awsm-prose-placeholders)}.prose :where(.file em):not(:where([class~=not-prose] *)){color:var(--awsm-prose-placeholders)}.prose :where(.highlight .ge):not(:where([class~=not-prose] *)){color:var(--awsm-prose-placeholders);font-style:italic;font-weight:500}.prose :where(blockquote .attribution):not(:where([class~=not-prose] *)){font-style:italic}.prose :where(blockquote p:last-child):not(:where([class~=not-prose] *)){margin-bottom:0}.prose :where(blockquote p:first-child):not(:where([class~=not-prose] *)){margin-top:0}.prose :where(dl):not(:where([class~=not-prose] *)){margin-bottom:1.25rem;margin-top:1.25rem}.prose :where(dt):not(:where([class~=not-prose] *)){font-weight:500}.prose :where(dd):not(:where([class~=not-prose] *)){padding-left:1.25rem}.prose :where(kbd:not(.compound)):not(:where([class~=not-prose] *)){border-color:#212121;border-color:var(--color-gray-dark);border-radius:.125rem;border-width:1px;box-shadow:1px 1px;display:inline-block;font-size:.75rem;font-weight:500;padding:1px 4px}.prose :where(.option-list kbd):not(:where([class~=not-prose] *)){border-width:0;box-shadow:none;font-size:inherit;font-weight:700}.prose :where(.guilabel):not(:where([class~=not-prose] *)){color:#212121;color:var(--color-gray-dark);font-weight:500;letter-spacing:.025em}.prose :where(.menuselection):not(:where([class~=not-prose] *)){color:#212121;color:var(--color-gray-dark);font-weight:500;letter-spacing:.025em}.prose :where(figure img):not(:where([class~=not-prose] *)){display:inline-block}.prose :where(.align-center):not(:where([class~=not-prose] *)){margin-left:auto;margin-right:auto;text-align:center}.prose :where(.align-right):not(:where([class~=not-prose] *)){margin-left:auto;text-align:right}.prose :where(caption):not(:where([class~=not-prose] *)){margin-bottom:1.5rem;text-align:left}.prose :where(table p:first-child):not(:where([class~=not-prose] *)){margin-top:0}.prose :where(table p:last-child):not(:where([class~=not-prose] *)){margin-bottom:0}.prose :where(.highlight):not(:where([class~=not-prose] *)){position:relative}.prose :where(pre mark):not(:where([class~=not-prose] *)){background-color:#f0f9ff;display:block}.prose :where(pre ins):not(:where([class~=not-prose] *)){background-color:#f0fdf4;display:block;-webkit-text-decoration:none;text-decoration:none}.prose :where(.highlight-diff .gi):not(:where([class~=not-prose] *)){background-color:#f0fdf4;display:inline-block;width:100%}.prose :where(pre del):not(:where([class~=not-prose] *)){background-color:#fef2f2;display:block;-webkit-text-decoration:none;text-decoration:none}.prose :where(.highlight-diff .gd):not(:where([class~=not-prose] *)){background-color:#fef2f2;display:inline-block;width:100%}.prose :where(.highlight .gp):not(:where([class~=not-prose] *)){font-weight:500;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.prose :where(.highlight .linenos):not(:where([class~=not-prose] *)){padding-right:1rem;-webkit-user-select:none;-moz-user-select:none;user-select:none}.prose :where(.literal-block-wrapper):not(:where([class~=not-prose] *)){border-radius:.125rem;border-width:1px}.prose :where(.literal-block-wrapper pre):not(:where([class~=not-prose] *)){border:none}.prose :where(.pre):not(:where([class~=not-prose] *)){-webkit-hyphens:none;hyphens:none;white-space:nowrap}.prose :where(.code-block-caption):not(:where([class~=not-prose] *)){background-color:#f9fafb;border-bottom-width:1px;border-top-left-radius:.125rem;border-top-right-radius:.125rem;color:var(--tw-prose-captions);display:flex;font-size:.875rem;justify-content:flex-end;letter-spacing:.025em;padding:.25rem}.prose :where(.sig):not(:where([class~=not-prose] *)){font-family:JetBrains\ Mono;font-weight:700}.prose :where(.sig-name):not(:where([class~=not-prose] *)){color:#000}.prose :where(.default_value):not(:where([class~=not-prose] *)){color:var(--awsm-prose-placeholders)}.prose :where(em.property):not(:where([class~=not-prose] *)){color:var(--awsm-prose-placeholders)}.prose :where(.option .sig-prename):not(:where([class~=not-prose] *)){color:var(--awsm-prose-placeholders);font-style:italic}.prose :where(.viewcode-link):not(:where([class~=not-prose] *)){float:right}.prose :where(.font-size-inherit):not(:where([class~=not-prose] *)){font-size:inherit!important}.prose :where(.footnote>.label):not(:where([class~=not-prose] *)){float:left;padding-right:.5rem}.prose :where(.footnote>:not(.label)):not(:where([class~=not-prose] *)){margin-left:2rem}:root{--sidebar-width:300px;--fluid-margin:7.5vw;--color-brand:#0ea5e9;--color-link:#0369a1;--color-gray:#424242;--color-gray-light:#616161;--color-gray-dark:#212121}.admonition,div.deprecated,div.versionadded,div.versionchanged{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);border-left-width:4px;border-radius:.125rem;box-shadow:0 0 transparent,0 0 transparent,0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);font-size:.875rem;margin-bottom:1.5rem;margin-top:1.5rem;padding:1rem}.admonition>:last-child,div.deprecated>:last-child,div.versionadded>:last-child,div.versionchanged>:last-child{margin-bottom:0;margin-top:0}.note,[class^=admonition-]:not(.admonition-title){--tw-border-opacity:1;--tw-text-opacity:1;background-color:rgba(56,189,248,.02);border-color:#38bdf8;border-color:rgb(56 189 248/var(--tw-border-opacity));color:#0c4a6e;color:rgb(12 74 110/var(--tw-text-opacity))}.note .headerlink,[class^=admonition-]:not(.admonition-title) .headerlink{color:currentColor}.hint,.tip,div.versionadded{--tw-border-opacity:1;--tw-text-opacity:1;background-color:rgba(74,222,128,.02);border-color:#4ade80;border-color:rgb(74 222 128/var(--tw-border-opacity));color:#14532d;color:rgb(20 83 45/var(--tw-text-opacity))}.danger,.error,div.deprecated{--tw-border-opacity:1;--tw-text-opacity:1;background-color:hsla(0,91%,71%,.02);border-color:#f87171;border-color:rgb(248 113 113/var(--tw-border-opacity));color:#7f1d1d;color:rgb(127 29 29/var(--tw-text-opacity))}.attention,.caution,.important,.warning,div.versionchanged{--tw-border-opacity:1;--tw-text-opacity:1;background-color:rgba(250,204,21,.02);border-color:#facc15;border-color:rgb(250 204 21/var(--tw-border-opacity));color:#713f12;color:rgb(113 63 18/var(--tw-text-opacity))}div.deprecated .versionmodified,div.versionadded .versionmodified,div.versionchanged .versionmodified{font-style:italic;font-weight:500}.admonition-title{font-weight:500;letter-spacing:.025em;margin-bottom:1rem;margin-top:0}@media print{.contents,.toctree-wrapper{display:none}}.contents .caption,.contents .topic-title,.toctree-wrapper .caption,.toctree-wrapper .topic-title{color:#616161;color:var(--color-gray-light);font-family:JetBrains\ Mono,monospace;font-size:.875rem;font-weight:500;letter-spacing:.025em;text-transform:uppercase}.contents ul,.toctree-wrapper ul{list-style-type:none;padding-left:0}.contents ul li,.toctree-wrapper ul li{padding-left:0}.contents ul ul,.toctree-wrapper ul ul{margin-left:1rem}.nav-toc .caption{color:#424242;color:var(--color-gray);font-size:1.125rem;font-weight:500;letter-spacing:.025em;padding-bottom:.75rem;padding-top:2.5rem}.nav-toc p:first-of-type,.nav-toc>ul:first-child{padding-top:1rem}.nav-toc .expand{fill:currentColor;cursor:pointer;display:inline;height:1.2rem;margin-left:-.4rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1);-webkit-user-select:none;-moz-user-select:none;user-select:none}.nav-toc .expand:focus,.nav-toc .expand:hover{color:#0ea5e9;color:var(--color-brand)}.nav-toc li>ul{max-height:0;overflow-y:hidden;padding-left:1rem}.nav-toc .expanded>div>.expand{--tw-rotate:90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(90deg) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.nav-toc .expanded>ul{max-height:100%}.nav-toc .expanded>ul a.current{color:#0ea5e9;color:var(--color-brand)}.nav-toc a{color:#616161;color:var(--color-gray-light);display:inline-block;padding-bottom:.25rem;padding-top:.25rem}.nav-toc a:focus,.nav-toc a:hover{color:#0ea5e9;color:var(--color-brand)}.nav-toc a.current{color:#212121;color:var(--color-gray-dark);font-weight:500}.nav-toc ul+ul{margin-top:2rem}.nav-link{font-size:.95rem;letter-spacing:.2px}.tooltipped{position:relative}.tooltipped:after{-webkit-font-smoothing:subpixel-antialiased;word-wrap:break-word;--tw-bg-opacity:0.75;--tw-text-opacity:1;background-color:rgba(31,41,55,.75);background-color:rgb(31 41 55/var(--tw-bg-opacity));border-radius:.125rem;color:#fff;color:rgb(255 255 255/var(--tw-text-opacity));content:attr(aria-label);display:none;font-size:.75rem;font-weight:400;letter-spacing:normal;letter-spacing:.025em;opacity:0;padding:.25rem .5rem;pointer-events:none;position:absolute;text-align:center;text-decoration-line:none;text-shadow:none;text-transform:none;white-space:pre;z-index:1000000}@keyframes tooltip-appear{0%{opacity:0}to{opacity:1}}.tooltipped:focus:after,.tooltipped:focus:before,.tooltipped:hover:after,.tooltipped:hover:before{animation-delay:.2s;animation-duration:.4s;animation-fill-mode:forwards;animation-name:tooltip-appear;animation-timing-function:ease-in;display:inline-block;-webkit-text-decoration:none;text-decoration:none}.tooltipped-no-delay:focus:after,.tooltipped-no-delay:focus:before,.tooltipped-no-delay:hover:after,.tooltipped-no-delay:hover:before{animation-delay:0s}.tooltipped-multiline:focus:after,.tooltipped-multiline:hover:after{display:table-cell}.tooltipped-s:after,.tooltipped-se:after,.tooltipped-sw:after{margin-top:6px;right:50%;top:100%}.tooltipped-s:before,.tooltipped-se:before,.tooltipped-sw:before{border-bottom-color:#1a202c;bottom:-7px;margin-right:-6px;right:50%;top:auto}.tooltipped-se:after{left:50%;margin-left:-16px;right:auto}.tooltipped-sw:after{margin-right:-16px}.tooltipped-n:after,.tooltipped-ne:after,.tooltipped-nw:after{bottom:100%;margin-bottom:6px;right:50%}.tooltipped-n:before,.tooltipped-ne:before,.tooltipped-nw:before{border-top-color:#1a202c;bottom:auto;margin-right:-6px;right:50%;top:-7px}.tooltipped-ne:after{left:50%;margin-left:-16px;right:auto}.tooltipped-nw:after{margin-right:-16px}.tooltipped-n:after,.tooltipped-s:after{transform:translateX(50%)}.tooltipped-w:after{bottom:50%;margin-right:6px;right:100%;transform:translateY(50%)}.tooltipped-w:before{border-left-color:#1a202c;bottom:50%;left:-7px;margin-top:-6px;top:50%}.tooltipped-e:after{bottom:50%;left:100%;margin-left:6px;transform:translateY(50%)}.tooltipped-e:before{border-right-color:#1a202c;bottom:50%;margin-top:-6px;right:-7px;top:50%}.tooltipped-align-right-1:after,.tooltipped-align-right-2:after{margin-right:0;right:0}.tooltipped-align-right-1:before{right:10px}.tooltipped-align-right-2:before{right:15px}.tooltipped-align-left-1:after,.tooltipped-align-left-2:after{left:0;margin-left:0}.tooltipped-align-left-1:before{left:5px}.tooltipped-align-left-2:before{left:10px}.tooltipped-multiline:after{word-wrap:break-word;border-collapse:separate;max-width:250px;white-space:pre-line;width:-moz-max-content;width:max-content}.tooltipped-multiline.tooltipped-n:after,.tooltipped-multiline.tooltipped-s:after{left:50%;right:auto;transform:translateX(-50%)}.tooltipped-multiline.tooltipped-e:after,.tooltipped-multiline.tooltipped-w:after{right:100%}@media screen and (min-width:0\0){.tooltipped-multiline:after{width:250px}}.tooltipped-sticky:after,.tooltipped-sticky:before{display:inline-block}.tooltipped-sticky.tooltipped-multiline:after{display:table-cell}pre del:before{--tw-text-opacity:1;--tw-content:"\2212";color:#7f1d1d;color:rgb(127 29 29/var(--tw-text-opacity));content:"\2212";content:var(--tw-content);left:2px;position:absolute}pre ins:before{--tw-text-opacity:1;--tw-content:"\002b";color:#14532d;color:rgb(20 83 45/var(--tw-text-opacity));content:"\002b";content:var(--tw-content);left:2px}.highlight .copy,pre ins:before{position:absolute}.highlight .copy{--tw-bg-opacity:1;--tw-text-opacity:1;background-color:#fff;background-color:rgb(255 255 255/var(--tw-bg-opacity));border-radius:.125rem;border-width:1px;color:#374151;color:rgb(55 65 81/var(--tw-text-opacity));font-size:.75rem;letter-spacing:.025em;opacity:0;padding:.25rem;right:.375rem;text-transform:uppercase;top:.75rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transition-duration:.5s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);-webkit-user-select:none;-moz-user-select:none;user-select:none}.highlight .copy:focus{opacity:1}.highlight .copy:active{--tw-translate-x:0.125rem;--tw-translate-y:0.125rem;transform:translate(.125rem,.125rem) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.highlight:hover .copy{opacity:1}.code-lang{color:#212121;color:var(--color-gray-dark);display:inline-block;font-family:JetBrains\ Mono,monospace;letter-spacing:.05em;margin-left:.5rem;margin-right:auto;text-transform:uppercase}.sr-only{clip:rect(0,0,0,0);border-width:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}.visible{visibility:visible}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{left:0;right:0}.inset-0,.inset-y-0{bottom:0;top:0}.bottom-0{bottom:0}.bottom-8{bottom:2rem}.left-0{left:0}.right-0{right:0}.right-8{right:2rem}.top-0{top:0}.z-10{z-index:10}.z-20{z-index:20}.m-4{margin:1rem}.mx-0{margin-left:0;margin-right:0}.mx-5{margin-left:1.25rem;margin-right:1.25rem}.my-8{margin-bottom:2rem;margin-top:2rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-\[2px\]{margin-bottom:2px}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-auto{margin-right:auto}.mt-12{margin-top:3rem}.mt-16{margin-top:4rem}.mt-20{margin-top:5rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.hidden{display:none}.h-14{height:3.5rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-0{width:0}.w-14{width:3.5rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-full{width:100%}.max-w-prose{max-width:760px}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.-translate-x-full{--tw-translate-x:-100%;transform:translate(-100%,var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-full{--tw-translate-y:100%;transform:translate(var(--tw-translate-x),100%) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform,.translate-y-full{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform-gpu{transform:translate3d(var(--tw-translate-x),var(--tw-translate-y),0) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.self-center{align-self:center}.overflow-y-auto{overflow-y:auto}.scroll-smooth{scroll-behavior:smooth}.rounded-sm{border-radius:.125rem}.border-b-4{border-bottom-width:4px}.border-brand{border-color:#0ea5e9;border-color:var(--color-brand)}.bg-black{--tw-bg-opacity:1;background-color:#000;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-gray-700{--tw-bg-opacity:1;background-color:#374151;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.bg-gray-900{--tw-bg-opacity:1;background-color:#111827;background-color:rgb(17 24 39/var(--tw-bg-opacity))}.bg-gray-dark{background-color:#212121;background-color:var(--color-gray-dark)}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity:1;background-color:#fff;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-opacity-50{--tw-bg-opacity:0.5}.fill-current{fill:currentColor}.stroke-current{stroke:currentColor}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.pl-2{padding-left:.5rem}.pl-6{padding-left:1.5rem}.pr-2{padding-right:.5rem}.pr-4{padding-right:1rem}.pt-14{padding-top:3.5rem}.pt-4{padding-top:1rem}.pt-8{padding-top:2rem}.text-right{text-align:right}.text-3xl{font-size:2.5rem}.text-4xl{font-size:3rem}.text-sm{font-size:.875rem}.text-xl{font-size:1.5rem}.text-xs{font-size:.75rem}.font-medium{font-weight:500}.uppercase{text-transform:uppercase}.leading-14{line-height:3.5rem}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.text-gray{color:#424242;color:var(--color-gray)}.text-gray-100{--tw-text-opacity:1;color:#f3f4f6;color:rgb(243 244 246/var(--tw-text-opacity))}.text-gray-300{--tw-text-opacity:1;color:#d1d5db;color:rgb(209 213 219/var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:#4b5563;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:#374151;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:#1f2937;color:rgb(31 41 55/var(--tw-text-opacity))}.text-gray-light{color:#616161;color:var(--color-gray-light)}.text-inherit{color:inherit}.text-link{color:#0369a1;color:var(--color-link)}.text-red-700{--tw-text-opacity:1;color:#b91c1c;color:rgb(185 28 28/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:#fff;color:rgb(255 255 255/var(--tw-text-opacity))}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:0 0 transparent,0 0 transparent,0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.blur{--tw-blur:blur(8px);filter:blur(8px) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-all{transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-100{transition-duration:.1s}.duration-1000{transition-duration:1s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.grid-area-header{grid-area:header}.grid-area-sidebar{grid-area:sidebar}.grid-area-main{grid-area:main}.headerlink{--tw-text-opacity:1;align-items:center;color:#9ca3af;color:rgb(156 163 175/var(--tw-text-opacity));display:inline-flex;font-family:Roboto,sans-serif;margin-left:.25rem;vertical-align:middle}.headerlink:focus,.headerlink:hover{color:#0ea5e9;color:var(--color-brand)}.headerlink>*{fill:currentColor;visibility:hidden}.admonition-title:hover .headerlink,.admonition-title:hover .headerlink>*,.code-block-caption:hover .headerlink,.code-block-caption:hover .headerlink>*,.headerlink:focus>*,dt:not(.does-not-exist):hover .headerlink,dt:not(.does-not-exist):hover .headerlink>*,figure:not(.does-not-exist):hover .headerlink,figure:not(.does-not-exist):hover .headerlink>*,h1:not(.does-not-exist):hover .headerlink,h1:not(.does-not-exist):hover .headerlink>*,h2:not(.does-not-exist):hover .headerlink,h2:not(.does-not-exist):hover .headerlink>*,h3:not(.does-not-exist):hover .headerlink,h3:not(.does-not-exist):hover .headerlink>*,h4:not(.does-not-exist):hover .headerlink,h4:not(.does-not-exist):hover .headerlink>*,table:not(.does-not-exist):hover .headerlink,table:not(.does-not-exist):hover .headerlink>*{visibility:visible}#page.isShown{overflow:hidden}[data-sidebar-target=sidebar].isShown{--tw-translate-x:0px;max-width:90%;opacity:1;transform:translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));width:100%}[data-scroll-to-top-target=scrollToTop].isShown{opacity:1;visibility:visible}[data-sidebar-target=screen].isShown{display:block}[data-search-target=snackbar].isShown{--tw-translate-y:0px;opacity:1;transform:translate(var(--tw-translate-x)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transition-duration:.5s;transition-timing-function:cubic-bezier(0,0,.2,1)}.focus-within\:absolute:focus-within{position:absolute}.focus-within\:inset-x-0:focus-within{left:0;right:0}.focus-within\:top-0:focus-within{top:0}.focus-within\:bg-gray-50:focus-within{--tw-bg-opacity:1;background-color:#f9fafb;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.focus-within\:text-gray-800:focus-within{--tw-text-opacity:1;color:#1f2937;color:rgb(31 41 55/var(--tw-text-opacity))}.hover\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:#374151;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.hover\:bg-gray-950:hover{--tw-bg-opacity:1;background-color:#030712;background-color:rgb(3 7 18/var(--tw-bg-opacity))}.hover\:text-brand:hover{color:#0ea5e9;color:var(--color-brand)}.hover\:text-gray-dark:hover{color:#212121;color:var(--color-gray-dark)}.hover\:underline:hover{text-decoration-line:underline}.hover\:no-underline:hover{text-decoration-line:none}.focus\:w-full:focus{width:100%}.focus\:translate-x-0:focus{--tw-translate-x:0px;transform:translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.focus\:bg-gray-200:focus{--tw-bg-opacity:1;background-color:#e5e7eb;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.focus\:bg-gray-700:focus{--tw-bg-opacity:1;background-color:#374151;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.focus\:bg-gray-950:focus{--tw-bg-opacity:1;background-color:#030712;background-color:rgb(3 7 18/var(--tw-bg-opacity))}.focus\:text-brand:focus{color:#0ea5e9;color:var(--color-brand)}.focus\:text-gray-dark:focus{color:#212121;color:var(--color-gray-dark)}.focus\:underline:focus{text-decoration-line:underline}.focus\:opacity-100:focus{opacity:1}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}@media (min-width:640px){.sm\:px-4{padding-left:1rem;padding-right:1rem}}@media (min-width:768px){.md\:mx-auto{margin-left:auto;margin-right:auto}.md\:ml-4{margin-left:1rem}.md\:w-auto{width:auto}.md\:focus-within\:static:focus-within{position:static}.md\:focus-within\:w-full:focus-within{width:100%}}@media (min-width:1024px){.lg\:inline-block{display:inline-block}}@media (min-width:1280px){.xl\:relative{position:relative}.xl\:z-0{z-index:0}.xl\:ml-fluid{margin-left:7.5vw;margin-left:var(--fluid-margin)}.xl\:mr-0{margin-right:0}.xl\:grid{display:grid}.xl\:hidden{display:none}.xl\:h-screen{height:100vh}.xl\:translate-x-0{--tw-translate-x:0px;transform:translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.xl\:px-2{padding-left:.5rem;padding-right:.5rem}.xl\:opacity-100{opacity:1}.xl\:grid-layout{grid-template-areas:"header header" "sidebar main";grid-template-columns:max(300px,17%) 1fr;grid-template-columns:max(var(--sidebar-width),17%) 1fr;grid-template-rows:min-content 1fr}}@media print{.print\:mt-4{margin-top:1rem}.print\:block{display:block}.print\:hidden{display:none}.print\:h-auto{height:auto}} +@font-face{font-display:swap;font-family:Roboto;font-style:normal;font-weight:400;src:url(b009a76ad6afe4ebd301.woff2) format("woff2"),url(f1e2a76794cb86b2aa8e.woff) format("woff")} +@font-face{font-display:swap;font-family:Roboto;font-style:italic;font-weight:400;src:url(e10742dbb1d4a0864ba8.woff2) format("woff2"),url(d037cb4792991826de7d.woff) format("woff")} +@font-face{font-display:swap;font-family:Roboto;font-style:normal;font-weight:500;src:url(f25d774ecfe0996f8eb5.woff2) format("woff2"),url(48af7707fe9e6494d6a5.woff) format("woff")} +@font-face{font-display:swap;font-family:Roboto;font-style:italic;font-weight:500;src:url(3a43b67e5bbdfb3ab0a6.woff2) format("woff2"),url(9ac5da2442b734abc516.woff) format("woff")} +@font-face{font-display:swap;font-family:JetBrains Mono;font-style:normal;font-weight:400;src:url(d0b41bd1d599bc0a52b7.woff2) format("woff2"),url(6f04107ce68d524ebe69.woff) format("woff")} +@font-face{font-display:swap;font-family:JetBrains Mono;font-style:italic;font-weight:400;src:url(ff058b7e238adc5cba09.woff2) format("woff2"),url(ad463ea60cc8b68792f4.woff) format("woff")} +@font-face{font-display:swap;font-family:JetBrains Mono;font-style:normal;font-weight:500;src:url(ec416b97881f4a422686.woff2) format("woff2"),url(46830c334f8112fa510a.woff) format("woff")} +@font-face{font-display:swap;font-family:JetBrains Mono;font-style:italic;font-weight:500;src:url(31f64b9c465158bd6066.woff2) format("woff2"),url(09be83022f2ac2ce16b0.woff) format("woff")} +@font-face{font-display:swap;font-family:JetBrains Mono;font-style:normal;font-weight:700;src:url(cfdd43ce3499ca7f900a.woff2) format("woff2"),url(44fd0da18fe361a5cc7f.woff) format("woff")} +@font-face{font-display:swap;font-family:JetBrains Mono;font-style:italic;font-weight:700;src:url(c3b5f43fe4c8f3f1fa21.woff2) format("woff2"),url(0ffeb7a552b36437b54c.woff) format("woff")} diff --git a/api/gimie.extractors.html b/api/gimie.extractors.html new file mode 100644 index 00000000..4ad7c591 --- /dev/null +++ b/api/gimie.extractors.html @@ -0,0 +1,472 @@ + + + + + + + + + + gimie.extractors package | gimie 0.6.1 documentation + + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +
+

gimie.extractors package

+
+

Submodules

+
+
+

gimie.extractors.abstract module

+

Abstract for Git repository extractors.

+
+
+class gimie.extractors.abstract.Extractor(url: str, base_url: str | None = None, local_path: str | None = None)[source]
+

Bases: ABC

+

Extractor is an Abstract Base Class. It is only meant +to define a standard interface for all git repository extractors.

+

Subclasses for different git providers must implement +extract() and list_files() methods.

+
+
+property base: str
+

Base URL of the remote.

+
+ +
+
+abstract extract() Repository[source]
+

Extract metadata from the git provider into a Repository object.

+
+ +
+
+abstract list_files() List[Resource][source]
+

List all files in the repository HEAD.

+
+ +
+
+property path: str
+

Path to the repository without the base URL.

+
+ +
+ +
+
+

gimie.extractors.git module

+

Extractor which uses a locally available (usually cloned) repository.

+
+
+class gimie.extractors.git.GitExtractor(url: str, base_url: str | None = None, local_path: str | None = None, _cloned: bool = False)[source]
+

Bases: Extractor

+

This class is responsible for extracting metadata from a git repository.

+
+
Parameters:
+
    +
  • url (str) – The url of the git repository.

  • +
  • base_url (Optional[str]) – The base url of the git remote.

  • +
  • local_path (Optional[str]) – The local path where the cloned git repository is located.

  • +
+
+
+
+
+uri
+

The URI to assign the repository in RDF.

+
+
Type:
+

Optional[str]

+
+
+
+ +
+
+repository
+

The repository we are extracting metadata from.

+
+
Type:
+

Repository

+
+
+
+ +
+
+base_url: str | None = None
+
+ +
+
+extract() Repository[source]
+

Extract metadata from the git provider into a Repository object.

+
+ +
+
+list_files() List[LocalResource][source]
+

List all files in the repository HEAD.

+
+ +
+
+local_path: str | None = None
+
+ +
+
+url: str
+
+ +
+ +
+
+

gimie.extractors.github module

+
+
+class gimie.extractors.github.GithubExtractor(url: str, base_url: str | None = None, local_path: str | None = None, token: str | None = None)[source]
+

Bases: Extractor

+

Extractor for GitHub repositories. Uses the GitHub GraphQL API to +extract metadata into linked data. +url: str

+
+

The url of the git repository.

+
+
+
base_url: Optional[str]

The base url of the git remote.

+
+
+
+
+base_url: str | None = None
+
+ +
+
+extract() Repository[source]
+

Extract metadata from target GitHub repository.

+
+ +
+
+list_files() List[RemoteResource][source]
+

takes the root repository folder and returns the list of files present

+
+ +
+
+local_path: str | None = None
+
+ +
+
+token: str | None = None
+
+ +
+
+url: str
+
+ +
+ +
+
+gimie.extractors.github.query_contributors(url: str, headers: Dict[str, str]) List[Dict[str, Any]][source]
+

Queries the list of contributors of target repository +using GitHub’s REST and GraphQL APIs. Returns a list of GraphQL User nodes. +NOTE: This is a workaround for the lack of a contributors field in the GraphQL API.

+
+ +
+
+

gimie.extractors.gitlab module

+
+
+class gimie.extractors.gitlab.GitlabExtractor(url: str, base_url: str | None = None, local_path: str | None = None, token: str | None = None)[source]
+

Bases: Extractor

+

Extractor for Gitlab repositories. Uses the Gitlab GraphQL API to +extract metadata into linked data. +url: str

+
+

The url of the git repository.

+
+
+
base_url: Optional[str]

The base url of the git remote.

+
+
+
+
+base_url: str | None = None
+
+ +
+
+extract() Repository[source]
+

Extract metadata from target Gitlab repository.

+
+ +
+
+property graphql_endpoint: str
+
+ +
+
+list_files() List[RemoteResource][source]
+

takes the root repository folder and returns the list of files present

+
+ +
+
+local_path: str | None = None
+
+ +
+
+property rest_endpoint: str
+
+ +
+
+token: str | None = None
+
+ +
+
+url: str
+
+ +
+ +
+
+

Module contents

+

Git providers from which metadata can be extracted by gimie.

+
+
+gimie.extractors.get_extractor(url: str, source: str, base_url: str | None = None, local_path: str | None = None) Extractor[source]
+

Instantiate the correct extractor for a given source.

+
+
Parameters:
+
    +
  • URL – Where the repository metadata is extracted from.

  • +
  • source – The source of the repository (git, gitlab, github, …).

  • +
  • base_url – The base URL of the git remote.

  • +
  • local_path – If applicable, the path to the directory where the +repository is located.

  • +
+
+
+

Examples

+
>>> extractor = get_extractor(
+...     "https://github.com/SDSC-ORD/gimie",
+...     "github"
+... )
+
+
+
+ +
+
+gimie.extractors.infer_git_provider(url: str) str[source]
+

Given a git repository URL, return the corresponding git provider. +Local path or unsupported git providers will return “git”.

+

Examples

+
>>> infer_git_provider("https://gitlab.com/foo/bar")
+'gitlab'
+>>> infer_git_provider("/foo/bar")
+'git'
+>>> infer_git_provider("https://codeberg.org/dnkl/foot")
+'git'
+
+
+
+ +
+
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/api/gimie.graph.html b/api/gimie.graph.html new file mode 100644 index 00000000..2b734b09 --- /dev/null +++ b/api/gimie.graph.html @@ -0,0 +1,225 @@ + + + + + + + + + + gimie.graph package | gimie 0.6.1 documentation + + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +
+

gimie.graph package

+
+

Submodules

+
+
+

gimie.graph.namespaces module

+
+
+

gimie.graph.operations module

+

Operations on graphs.

+
+
+gimie.graph.operations.combine_graphs(*graphs: Graph) Graph[source]
+

Combines an arbitrary number of input graphs +into a single graph.

+
+ +
+
+gimie.graph.operations.properties_to_graph(uri: URIRef, properties: Set[Tuple[URIRef, URIRef | Literal]]) Graph[source]
+

Attaches a set of predicate-object tuples to input +URI to produce an RDF graph.

+
+ +
+
+

Module contents

+
+
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/api/gimie.html b/api/gimie.html new file mode 100644 index 00000000..0ebd2a12 --- /dev/null +++ b/api/gimie.html @@ -0,0 +1,761 @@ + + + + + + + + + + gimie package | gimie 0.6.1 documentation + + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +
+

gimie package

+
+

Subpackages

+ +
+
+

Submodules

+
+
+

gimie.cli module

+

Command line interface to the gimie package.

+
+
+class gimie.cli.RDFFormatChoice(value)[source]
+

Bases: str, Enum

+

An enumeration.

+
+
+jsonld = 'json-ld'
+
+ +
+
+nt = 'nt'
+
+ +
+
+ttl = 'ttl'
+
+ +
+ +
+
+gimie.cli.advice(url: str)[source]
+

Show a metadata completion report for a Git repository +at the target URL.

+

NOTE: Not implemented yet

+
+ +
+
+gimie.cli.callback(version: bool | None = <typer.models.OptionInfo object>)[source]
+

gimie digs Git repositories for metadata.

+
+ +
+
+gimie.cli.data(url: str, format: ~gimie.cli.RDFFormatChoice = <typer.models.OptionInfo object>, base_url: str | None = <typer.models.OptionInfo object>, include_parser: ~typing.List[str] | None = <typer.models.OptionInfo object>, exclude_parser: ~typing.List[str] | None = <typer.models.OptionInfo object>, version: bool | None = <typer.models.OptionInfo object>)[source]
+

Extract linked metadata from a Git repository at the target URL.

+

The output is sent to stdout, and turtle is used as the default serialization format.

+
+ +
+
+gimie.cli.parsers(verbose: bool = <typer.models.OptionInfo object>)[source]
+

List available parsers, specifying which are default. +If –verbose is used, show parser description.

+
+ +
+
+gimie.cli.version_callback(value: bool)[source]
+
+ +
+
+

gimie.io module

+

Standard input interfaces to local or remote resources for gimie.

+
+
+class gimie.io.IterStream(iterator: Iterator[bytes])[source]
+

Bases: RawIOBase

+

Wraps an iterator under a like a file-like interface. +Empty elements in the iterator are ignored.

+
+
Parameters:
+

iterator – An iterator yielding bytes.

+
+
+

Examples

+
>>> stream = IterStream(iter([b"Hello ", b"", b"World"]))
+>>> stream.read()
+b'Hello World'
+
+
+
+
+readable()[source]
+

Return whether object was opened for reading.

+

If False, read() will raise OSError.

+
+ +
+
+readinto(b)[source]
+
+ +
+ +
+
+class gimie.io.LocalResource(path: str | PathLike)[source]
+

Bases: Resource

+

Providing read-only access to local data via a file-like interface.

+

Examples

+
>>> resource = LocalResource("README.md")
+
+
+
+
+open() RawIOBase[source]
+
+ +
+ +
+
+class gimie.io.RemoteResource(path: str, url: str, headers: dict | None = None)[source]
+

Bases: Resource

+

Provides read-only access to remote data via a file-like interface.

+
+
Parameters:
+
    +
  • url – The URL where the resource. can be downladed from.

  • +
  • headers – Optional headers to pass to the request.

  • +
+
+
+

Examples

+
>>> url = "https://raw.githubusercontent.com/SDSC-ORD/gimie/main/README.md"
+>>> content = RemoteResource("README.md", url).open().read()
+>>> assert isinstance(content, bytes)
+
+
+
+
+open() RawIOBase[source]
+
+ +
+ +
+
+class gimie.io.Resource[source]
+

Bases: object

+

Abstract class for read-only access to local or remote resources via +a file-like interface.

+
+
Parameters:
+

path (pathlib.Path) – The local relative path to the resource.

+
+
+
+
+open() RawIOBase[source]
+
+ +
+
+path: Path
+
+ +
+ +
+
+

gimie.models module

+

Data models to represent nodes in the graph generated by gimie.

+
+
+class gimie.models.Organization(_id: str, name: str, legal_name: str | None = None, email: List[str] | None = None, description: str | None = None, logo: str | None = None)[source]
+

Bases: object

+

See http//schema.org/Organization

+
+
+description: str | None = None
+
+ +
+
+email: List[str] | None = None
+
+ +
+
+legal_name: str | None = None
+
+ +
+ +
+ +
+
+name: str
+
+ +
+ +
+
+class gimie.models.OrganizationSchema(*args, only=None, exclude=(), many=False, context=None, load_only=(), dump_only=(), partial=False, unknown=None, flattened=False, lazy=False, _all_objects=None, _visited=None, _top_level=True)[source]
+

Bases: JsonLDSchema

+
+
+class Meta[source]
+

Bases: object

+
+
+model
+

alias of Organization

+
+ +
+
+rdf_type = rdflib.term.URIRef('http://schema.org/Organization')
+
+ +
+ +
+
+opts: SchemaOpts = <calamus.schema.JsonLDSchemaOpts object>
+
+ +
+ +
+
+class gimie.models.Person(_id: str, identifier: str, name: str | None = None, email: str | None = None, affiliations: List[Organization] | None = None)[source]
+

Bases: object

+

See http//schema.org/Person

+
+
+affiliations: List[Organization] | None = None
+
+ +
+
+email: str | None = None
+
+ +
+
+identifier: str
+
+ +
+
+name: str | None = None
+
+ +
+ +
+
+class gimie.models.PersonSchema(*args, only=None, exclude=(), many=False, context=None, load_only=(), dump_only=(), partial=False, unknown=None, flattened=False, lazy=False, _all_objects=None, _visited=None, _top_level=True)[source]
+

Bases: JsonLDSchema

+
+
+class Meta[source]
+

Bases: object

+
+
+model
+

alias of Person

+
+ +
+
+rdf_type = rdflib.term.URIRef('http://schema.org/Person')
+
+ +
+ +
+
+opts: SchemaOpts = <calamus.schema.JsonLDSchemaOpts object>
+
+ +
+ +
+
+class gimie.models.Release(tag: str, date: datetime, commit_hash: str)[source]
+

Bases: object

+

This class represents a release of a repository.

+
+
Parameters:
+
    +
  • tag (str) – The tag of the release.

  • +
  • date (datetime.datetime) – The date of the release.

  • +
  • commit_hash (str) – The commit hash of the release.

  • +
+
+
+
+
+commit_hash: str
+
+ +
+
+date: datetime
+
+ +
+
+tag: str
+
+ +
+ +
+
+class gimie.models.Repository(url: str, name: str, authors: List[Organization | Person] | None = None, contributors: List[Person] | None = None, date_created: datetime | None = None, date_modified: datetime | None = None, date_published: datetime | None = None, description: str | None = None, download_url: str | None = None, identifier: str | None = None, keywords: List[str] | None = None, licenses: List[str] | None = None, parent_repository: str | None = None, prog_langs: List[str] | None = None, version: str | None = None)[source]
+

Bases: object

+

This class represents a git repository. +It does not contain any information about the content of the repository. +See https://schema.org/SoftwareSourceCode

+
+
+authors: List[Organization | Person] | None = None
+
+ +
+
+contributors: List[Person] | None = None
+
+ +
+
+date_created: datetime | None = None
+
+ +
+
+date_modified: datetime | None = None
+
+ +
+
+date_published: datetime | None = None
+
+ +
+
+description: str | None = None
+
+ +
+
+download_url: str | None = None
+
+ +
+
+identifier: str | None = None
+
+ +
+
+jsonld() str[source]
+

Alias for jsonld serialization.

+
+ +
+
+keywords: List[str] | None = None
+
+ +
+
+licenses: List[str] | None = None
+
+ +
+
+name: str
+
+ +
+
+parent_repository: str | None = None
+
+ +
+
+prog_langs: List[str] | None = None
+
+ +
+
+serialize(format: str = 'ttl', **kwargs) str[source]
+

Serialize the RDF graph representing the instance.

+
+ +
+
+to_graph() Graph[source]
+

Convert repository to RDF graph.

+
+ +
+
+url: str
+
+ +
+
+version: str | None = None
+
+ +
+ +
+
+class gimie.models.RepositorySchema(*args, only=None, exclude=(), many=False, context=None, load_only=(), dump_only=(), partial=False, unknown=None, flattened=False, lazy=False, _all_objects=None, _visited=None, _top_level=True)[source]
+

Bases: JsonLDSchema

+

This defines the schema used for json-ld serialization.

+
+
+class Meta[source]
+

Bases: object

+
+
+add_value_types = False
+
+ +
+
+model
+

alias of Repository

+
+ +
+
+rdf_type = rdflib.term.URIRef('http://schema.org/SoftwareSourceCode')
+
+ +
+ +
+
+opts: SchemaOpts = <calamus.schema.JsonLDSchemaOpts object>
+
+ +
+ +
+
+

gimie.project module

+

Orchestration of multiple extractors for a given project. +This is the main entry point for end-to-end analysis.

+
+
+class gimie.project.Project(path: str, base_url: str | None = None, git_provider: str | None = None, parser_names: Iterable[str] | None = None)[source]
+

Bases: object

+

A class to represent a project’s git repository.

+
+
Parameters:
+
    +
  • path – The full path (URL) of the repository.

  • +
  • base_url – The base URL of the git remote. Can be used to +specify delimitation between base URL and project name.

  • +
  • git_provider – The name of the git provider to extract metadata from. +(‘git’, ‘github’, ‘gitlab’)

  • +
  • parser_names – Names of file parsers to use. (‘license’). +If None, default parsers are used (see gimie.parsers.PARSERS).

  • +
+
+
+

Examples

+
>>> proj = Project("https://github.com/SDSC-ORD/gimie")
+>>> assert isinstance(proj.extract(), Graph)
+
+
+
+
+extract() Graph[source]
+

Extract repository metadata from git provider to RDF graph and enrich with +metadata parsed from file contents.

+
+ +
+ +
+
+gimie.project.split_git_url(url: str) Tuple[str, str][source]
+

Split a git URL into base URL and project path.

+

Examples

+
>>> split_git_url("https://gitlab.com/foo/bar")
+('https://gitlab.com', 'foo/bar')
+
+
+
+ +
+
+

Module contents

+
+
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/api/gimie.parsers.html b/api/gimie.parsers.html new file mode 100644 index 00000000..860c59c5 --- /dev/null +++ b/api/gimie.parsers.html @@ -0,0 +1,317 @@ + + + + + + + + + + gimie.parsers package | gimie 0.6.1 documentation + + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +
+

gimie.parsers package

+
+

Subpackages

+ +
+
+

Submodules

+
+
+

gimie.parsers.abstract module

+
+
+class gimie.parsers.abstract.Parser[source]
+

Bases: ABC

+

Parser is an Abstract Base Class. It is only meant +to define a standard interface for all parsers.

+

All subclasses must implement parse(). A parser parses +bytes data into a set of predicate-object tuples.

+
+
+abstract parse(data: bytes) Set[Tuple[URIRef, URIRef | Literal]][source]
+

Extract predicate-object tuples from a source.

+
+ +
+
+parse_all(docs: Iterable[bytes]) Set[Tuple[URIRef, URIRef | Literal]][source]
+

Parse multiple sources and return the union of +predicate-object tuples.

+
+ +
+ +
+
+

Module contents

+

Files which can be parsed by gimie.

+
+
+class gimie.parsers.ParserInfo(default, type)[source]
+

Bases: NamedTuple

+
+
+default: bool
+

Alias for field number 0

+
+ +
+
+type: Type[Parser]
+

Alias for field number 1

+
+ +
+ +
+
+gimie.parsers.get_parser(name: str) Type[Parser][source]
+

Get a parser by name.

+
+ +
+
+gimie.parsers.list_default_parsers() Set[str][source]
+

List the names of all default parsers.

+
+ +
+
+gimie.parsers.list_parsers() Set[str][source]
+

List the names of all parsers.

+
+ +
+
+gimie.parsers.parse_files(files: Iterable[Resource], parsers: Set[str] | None = None) Set[Tuple[URIRef, URIRef | Literal]][source]
+

For each input file, select appropriate parser among a collection and +parse its contents. Return the union of all parsed properties. If no parser +is found for a given file, skip it.

+
+
Parameters:
+
    +
  • files – A collection of file-like objects.

  • +
  • parsers – A set of parser names. If None, use the default collection.

  • +
+
+
+
+ +
+
+gimie.parsers.select_parser(path: Path, parsers: Set[str] | None = None) Type[Parser] | None[source]
+

Select the appropriate parser from a collection based on a file path. +If no parser is found, return None.

+
+
Parameters:
+
    +
  • path – The path of the file to parse.

  • +
  • parsers – A set of parser names. If None, use the default collection.

  • +
+
+
+
+ +
+
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/api/gimie.parsers.license.html b/api/gimie.parsers.license.html new file mode 100644 index 00000000..dc2e46d1 --- /dev/null +++ b/api/gimie.parsers.license.html @@ -0,0 +1,273 @@ + + + + + + + + + + gimie.parsers.license package | gimie 0.6.1 documentation + + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +
+

gimie.parsers.license package

+
+

Module contents

+
+
+class gimie.parsers.license.LicenseParser[source]
+

Bases: Parser

+

Parse LICENSE body into schema:license <spdx-url>. +Uses tf-idf-based matching.

+
+
+parse(data: bytes) Set[Tuple[URIRef, URIRef | Literal]][source]
+

Extracts an spdx URL from a license file and returns a +set with a single tuple <schema:license> <spdx_url>. +If no matching URL is found, an empty set is returned.

+
+ +
+ +
+
+gimie.parsers.license.is_license_filename(filename: str) bool[source]
+

Given an input filename, returns a boolean indicating whether the filename path looks like a license.

+
+
Parameters:
+

filename – A filename to check.

+
+
+

Examples

+
>>> is_license_filename('LICENSE-APACHE')
+True
+>>> is_license_filename('README.md')
+False
+
+
+
+ +
+
+gimie.parsers.license.load_spdx_ids() List[str][source]
+

Load spdx licenses from disk.

+
+ +
+
+gimie.parsers.license.load_tfidf_matrix() csr_matrix[source]
+

Load pre-computed tfidf matrix of spdx licenses from disk. +Matrix has dimensions (n_licenses, n_features).

+
+ +
+
+gimie.parsers.license.load_tfidf_vectorizer() TfidfVectorizer[source]
+

Load tfidf matrix and vectorizer from disk.

+
+ +
+
+gimie.parsers.license.match_license(data: bytes, min_similarity: float = 0.9) str | None[source]
+

Given a license file, returns the url of the most similar spdx license. +This is done using TF-IDF on the license text and getting the +closest match in the SPDX license corpus based on cosine similarity.

+
+
Parameters:
+

data – The license body as bytes.

+
+
+

Examples

+
>>> match_license(open('LICENSE', 'rb').read())
+'https://spdx.org/licenses/Apache-2.0.html'
+
+
+
+ +
+
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/api/modules.html b/api/modules.html new file mode 100644 index 00000000..3d771b60 --- /dev/null +++ b/api/modules.html @@ -0,0 +1,242 @@ + + + + + + + + + + gimie | gimie 0.6.1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/changelog_link.html b/changelog_link.html new file mode 100644 index 00000000..ef12eb7d --- /dev/null +++ b/changelog_link.html @@ -0,0 +1,367 @@ + + + + + + + + + + [0.6.0] - 2023-10-19 | gimie 0.6.1 documentation + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +

Notable changes introduced in gimie releases are documented in this file

+
+

[0.6.0] - 2023-10-19

+
+

Bug Fixes

+
    +
  • (deps) switch to scancode mini (#88)

  • +
  • (docker) push action was missing buildx (#91)

  • +
  • (github) replace superseded schema:isBasedOnUrl property (#80)- incorrect mapping for schema:codeRepository (#64)

  • +
  • (license) NOASSERTION should not return triples. (#66)

  • +
+
+
+

Features

+
    +
  • (conventional-PRs) all PRs will need to follow conventional format

  • +
  • (conventional-PRs) all PRs will need to follow conventional format

  • +
  • (github.py) Get “forked from” property of a repository (#79)

  • +
  • (io) file-like interface to remote resources (#70)- license matcher for git extractor (#78)

  • +
+
+
+
+

[0.5.1] - 2023-07-10

+
+

Bug Fixes

+
    +
  • incorrect mapping for schema:codeRepository (#64)

  • +
+
+
+
+

[0.5.0] - 2023-07-04

+
+

Bug Fixes

+
    +
  • (gitlab) extraction of author on user-owned projects (#57)

  • +
+
+
+

Documentation

+
    +
  • add docs website (#58)

  • +
+
+
+

Features

+
    +
  • (gitlab) support private instances (#62)

  • +
+
+
+
+

[0.4.0] - 2023-06-09

+
+

Bug Fixes

+
    +
  • (docs) execute Makefile rule with poetry

  • +
  • (gitlab) edge case where no release available

  • +
  • (gitlab) pass user node to _get_author instead of parent node

  • +
  • (gitlab) rm debug breakpoint

  • +
  • (gitlab) extraction of author on user-owned projects (#57)- gitlab download url

  • +
  • prevent license finder from picking up docs files

  • +
+
+
+

Documentation

+
    +
  • (api) reduce autodoc ToC depth

  • +
  • (cli) add and configure sphinx-click to work with typer

  • +
  • (deps) introduce doc dependency group

  • +
  • (git) rm duplicate attibute from docstring

  • +
  • (setup) add sphinx configuration

  • +
  • (style) add logo + favicon

  • +
  • (style) add logo to front page

  • +
  • (theme) furo -> sphinxawesome

  • +
  • (theme) add sphinx_design extension, downgrade to sphinx6 for compat

  • +
  • (tokens) Add tutorial for encrypted tokens

  • +
  • (tokens) fix windows instructions- add Makefile rule to generate sphinx website

  • +
  • initial sphinx website with apidoc

  • +
  • add apidoc output to gitignore

  • +
  • add intro pages

  • +
  • improve header names

  • +
  • add quickstart section, enable tabbing and crossref

  • +
  • add sphinx-tabs as doc dep

  • +
  • add sphinx-copybutton extension

  • +
  • add changelog and configure git-cliff

  • +
  • replace deprecated commonmark parser with myst

  • +
  • enable placeholder highlighting extension

  • +
  • improve index format

  • +
  • add windows variant for env var

  • +
  • add docs website (#58)

  • +
  • update readme and add docs badge

  • +
+
+
+

Features

+
    +
  • (gitlab) fallback to rest api if author missing from graphql. make type hints py38 compat.

  • +
  • (io) Allow rdflib kwargs in serialize()- use GraphQL API in gh extractor (#33)

  • +
  • Git extractor (#42)

  • +
  • disallow local paths (#46)

  • +
+
+
+
+

[0.3.0] - 2023-02-24

+
+

Bug Fixes

+
    +
  • exclude hidden files from license search

  • +
  • correctly handle one or multiple license paths

  • +
  • temporarily disable scancode (#19)

  • +
  • rename GITHUB_TOKEN to ACCESS_TOKEN

  • +
  • change token back to ACCESS_TOKEN since GITHUB_TOKEN failed

  • +
  • GITHUB_TOKEN must be prefixed with github as environment variable

  • +
  • set test workflow back to using ACCESS_TOKEN as a repo secret

  • +
  • add .dockerignore, copy necessary files only and improve comments

  • +
  • rename container-publish.yml into docker-publish.yml

  • +
  • ‘building docker image’ instead of ‘building docker container’

  • +
+
+
+

Documentation

+
    +
  • define initial contributing guidelines

  • +
  • add usage examples in README

  • +
  • update copyright notice in license

  • +
  • specify type hints and rm unused imports in LicenseMetadata

  • +
  • add dev status in readme

  • +
  • document the release process in the readme

  • +
  • readme badges (#25)

  • +
  • add section to the readme on how to provide a github token

  • +
  • adapt documentation to usage of ACCESS_TOKEN instead of GITHUB_TOKEN

  • +
  • adapt readme to installation with makefile

  • +
  • give options to install either PyPI or dev version of gimie

  • +
  • add message for docker-build Makefile rule

  • +
  • add image annotations to dockerfile

  • +
  • add docker instructions in readme

  • +
+
+
+

Features

+
    +
  • (cli) add CLI skeleton (#9)- initial project definition with pyproject.toml

  • +
  • add placeholder folders

  • +
  • add placeholder tests

  • +
  • add basic repo class and placeholder source interfaces

  • +
  • add console entrypoint definition in pyproject.toml

  • +
  • add GitMetadata methods to get commit authors and repository creation date

  • +
  • add method to get releases date and commit hash

  • +
  • sort releases by date

  • +
  • add method to get git repo creator

  • +
  • add unit tests for git source

  • +
  • Created a license finder using scancode toolkit

  • +
  • Added triple serialization of license result (spdx url)

  • +
  • use cached property from functools

  • +
  • added a make_graph script. Now only contains add_license_to_graph().

  • +
  • Created software class, and make graph functions, black reformat

  • +
  • add license scanner (#12)

  • +
  • add prototype for RDF graph serialization (#15)

  • +
  • initial architecture with GithubExtractor (#23)

  • +
  • add python-dotenv to dependecies

  • +
  • pick up github token from the environment variables

  • +
  • add .env.dist file as an example for a .env file

  • +
  • provide option to provide github_token when calling extractor

  • +
  • add pre-commit to dependencies

  • +
  • add makefile to make installation easier

  • +
  • add Dockerfile and entrypoint.sh

  • +
  • add Makefile rule to build the docker image

  • +
  • add github workflow to push image to github container registry

  • +
+ +
+
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/cli.html b/cli.html new file mode 100644 index 00000000..14f03305 --- /dev/null +++ b/cli.html @@ -0,0 +1,299 @@ + + + + + + + + + + Command Line Interface | gimie 0.6.1 documentation + + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +
+

Command Line Interface

+
+

gimie

+

Command line group

+
gimie [OPTIONS] COMMAND [ARGS]...
+
+
+
+

+
gimie  [OPTIONS] COMMAND [ARGS]...
+
+
+
+

advice

+

Show a metadata completion report for a Git repository +at the target URL.

+

NOTE: Not implemented yet

+
gimie  advice [OPTIONS] URL
+
+
+

Arguments

+
+
+URL
+

Required argument

+
+ +
+
+

data

+

Extract linked metadata from a Git repository at the target URL.

+

The output is sent to stdout, and turtle is used as the default serialization format.

+
gimie  data [OPTIONS] URL
+
+
+

Options

+
+
+--format <format>
+

Output serialization format for the RDF graph.

+
+
Default:
+

RDFFormatChoice.ttl

+
+
Options:
+

ttl | json-ld | nt

+
+
+
+ +
+
+--base-url <base_url>
+

Specify the base URL of the git provider. Inferred by default.

+
+ +
+
+-I, --include-parser <include_parser>
+

Only include selected parser. Use ‘gimie parsers’ to list parsers.

+
+ +
+
+-X, --exclude-parser <exclude_parser>
+

Exclude selected parser.

+
+ +
+
+--version
+

Display version and exit

+
+ +

Arguments

+
+
+URL
+

Required argument

+
+ +
+
+

parsers

+

List available parsers, specifying which are default. +If –verbose is used, show parser description.

+
gimie  parsers [OPTIONS]
+
+
+

Options

+
+
+--verbose
+

Show parser description.

+
+
Default:
+

False

+
+
+
+ +
+
+
+
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/genindex.html b/genindex.html new file mode 100644 index 00000000..0d033ef9 --- /dev/null +++ b/genindex.html @@ -0,0 +1,91 @@ + + + + + + + + Index | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..cd104748 --- /dev/null +++ b/index.html @@ -0,0 +1,226 @@ + + + + + + + + + + Welcome to gimie’s documentation! | gimie 0.6.1 documentation + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ + gimie logo +
+

Welcome to gimie’s documentation!

+

gimie (Git Meta Information Extractor) is a python library and command line tool to extract structured metadata from git repositories.

+
+
+ +

Visit gimie’s GitHub repository to follow the latest developments!

+
+
+ + + +
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/intro/git.html b/intro/git.html new file mode 100644 index 00000000..768be463 --- /dev/null +++ b/intro/git.html @@ -0,0 +1,199 @@ + + + + + + + + + + Git repositories | gimie 0.6.1 documentation + + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +
+

Git repositories

+

Software projects are usually version-controlled and hosted on a server. Git is by far the most popular version control system, and is commonly used for scientific software and data science projects.

+

Git natively stores some metadata about the project authors and contributions in a local index, but git providers (servers) such has Github and GitLab store and expose more advanced information about the project and contributors. These information are served in provider-dependent format with specific APIs.

+

Gimie aims to provide provider-agnostic metadata in an interoperable format. It will request data from the provider API if available, or from git by cloning the repository into a temporary folder otherwise. This metadata is then converted to the widely used schema.org standard so that it can readily be integrated with other tools and services.

+
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/intro/linked_data.html b/intro/linked_data.html new file mode 100644 index 00000000..8d87caa1 --- /dev/null +++ b/intro/linked_data.html @@ -0,0 +1,198 @@ + + + + + + + + + + Linked data | gimie 0.6.1 documentation + + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +
+

Linked data

+

The aim of gimie is to extract project metadata in an interoperable format. This is achieved by generating linked data following the widely used schema.org ontology. The resulting metadata can readily be augmented or integrated with other data sources.

+

Gimie’s output follows recommendations provided by the codemeta project , but also provides additional properties.

+
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/intro/quickstart.html b/intro/quickstart.html new file mode 100644 index 00000000..da110a46 --- /dev/null +++ b/intro/quickstart.html @@ -0,0 +1,239 @@ + + + + + + + + + + Quick start | gimie 0.6.1 documentation + + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +
+

Quick start

+

The easiest way to use gimie is to run it as a command line tool. Here’s how to get started:

+

Install using pip or docker:

+
+ +
+
pip install gimie
+
+
+
+ +
+
docker pull ghcr.io/sdsc-ord/gimie:latest
+
+
+
+
+
+

Warning

+

Before running gimie, you will need to obtain a personal access token for the GitHub and/or GitLab and export it as an environment variable. See Token management for more information.

+
+

Gimie can then be used as follows to extract repository metadata:

+
+ +
+
gimie data <repository-url> > output.ttl
+
+
+
+ +
+
docker run -e GITHUB_TOKEN=${GITHUB_TOKEN} ghcr.io/sdsc-ord/gimie:latest data <repository-url> > output.ttl
+
+
+
+
+
+

Note

+

When running gimie in a container, you need to pass your github or gitlab token as an environment variable inside the container:

+
+
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/intro/tokens.html b/intro/tokens.html new file mode 100644 index 00000000..d1a8a3ca --- /dev/null +++ b/intro/tokens.html @@ -0,0 +1,280 @@ + + + + + + + + + + Token management | gimie 0.6.1 documentation + + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +
+

Token management

+

Gimie requests data from third party APIs (Gitlab, Github) which require authentication to work. This authentication usually works with Personal Authentication Tokens (PATs). PATs are secret codes that can be used as passwords to perform actions on your behalf, but whose permissions can be limited to specific actions. Since Gimie only consumes data, it will normally work with tokens that have read-only permission.

+

Generating tokens can usually be done via the web interface of the service provider, and they must then be provided to Gimie. There are 2 ways to pass your token to Gimie:

+
    +
  1. Set the corresponding Environment variable. The token will only be accessible for the current session:

  2. +
+
+ +
+
export GITLAB_TOKEN=<your-gitlab-token>
+export GITHUB_TOKEN=<your-github-token>
+
+
+
+ +
+
# You may need to restart windows after this
+setx GITLAB_TOKEN <your-gitlab-token>
+setx GITHUB_TOKEN <your-github-token>
+
+
+
+
+
    +
  1. Use a .env file in the current directory. Gimie will look for a file named .env and source it. The file contents should be as follows:

  2. +
+
+
File: .env
+
GITLAB_TOKEN=<your-gitlab-token>
+GITHUB_TOKEN=<your-github-token>
+
+
+
+

While the latter approach can be convenient to persist your token locally, it is generally not recommended to store your tokens in plain text as they are sensitive information. Hence the first approach should be preferred in most cases.

+
+

Encrypting tokens

+

If you are serious about security, you should use a tool like sops or pass to encrypt your secrets.

+

Below is a quick guide on how to use sops to store encrypted tokens, and decrypt them on the fly when using gimie.

+
+ +Generating PGP key
+
+
+
+
+

PGP is a public key encryption system. If you don’t already have one, you will need to generate a key pair to encrypt your secrets. +You can use the following command to generate a key pair. You will be prompted for a passphrase, but you may leave it empty if you wish.

+
gpg --gen-key
+
+
+
+
+ +Set up SOPS
+
+
+
+
+

SOPS needs to be configured to use your PGP key. You can do so by running the following command: +Replace <FINGERPRINT> with the fingerprint of your PGP key (it looks like 69AB B75E ...). You can find it by running gpg --fingerprint +Upon running the command below, sops will open a vim buffer where you can enter the desired content of your .env file. +Upon saving the file (:wq), sops will encrypt the file and save it as .enc.env.

+
sops --pgp "${FINGERPRINT}" .enc.env
+
+
+
+
+ +Source tokens
+
+
+
+
+

Whenever you want to run gimie, you can decrypt secrets on the fly and pass them to gimie using the following command:

+
sops exec-env .enc.env 'gimie data <repository-url>'
+
+
+

Or if you just want to inspect the decrypted file:

+
sops --decrypt .enc.env
+
+
+
+
+
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/intro/usage_python.html b/intro/usage_python.html new file mode 100644 index 00000000..bca9d1ae --- /dev/null +++ b/intro/usage_python.html @@ -0,0 +1,219 @@ + + + + + + + + + + Python Usage | gimie 0.6.1 documentation + + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +
+

Python Usage

+

Gimie can be used as a python library. Either to run the end-to-end extraction process on an input URL, or only a specific extractor.

+

The end-to-end extraction is performed by gimie.Project and will automatically detect the git-provider:

+
from gimie.project import Project
+url = 'https://github.com/foo/bar'
+proj = Project(url)
+
+
+

A specific extractor can also be used, for example to use with GitLab projects:

+
from gimie.sources.gitlab import GitlabExtractor
+url = "https://gitlab.com/foo/bar"
+extractor = GitlabExtractor(url)
+extractor.extract()
+
+
+

Once a project’s metadata has been extracted, it can be stored as an rdflib graph, or serialized to RDF triples:

+
import rdflib
+graph: rdflib.Graph = proj.to_graph()
+
+# serialize project directly as an RDF file
+proj.serialize(format='json-ld', destination='foobar.json')
+
+
+

Extractors also support the to_graph() and serialize() methods.

+
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/objects.inv b/objects.inv new file mode 100644 index 00000000..d53300da Binary files /dev/null and b/objects.inv differ diff --git a/py-modindex.html b/py-modindex.html new file mode 100644 index 00000000..60f8f9d0 --- /dev/null +++ b/py-modindex.html @@ -0,0 +1,94 @@ + + + + + + + + Python Module Index | gimie 0.6.1 documentation + + + + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/search.html b/search.html new file mode 100644 index 00000000..bcda3425 --- /dev/null +++ b/search.html @@ -0,0 +1,200 @@ + + + + + + + + Search | gimie 0.6.1 documentation + + + + + + + + + + +
+ Skip to content + +
+
+ + Logo +
+
+
+ + + + +
+ +
+ +
+ + + Please activate Javascript to enable searching the documentation. + +
+
+ +
+ +
+ + + +
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 00000000..e78fd9b4 --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["api/gimie", "api/gimie.extractors", "api/gimie.graph", "api/gimie.parsers", "api/gimie.parsers.license", "api/modules", "changelog_link", "cli", "index", "intro/git", "intro/linked_data", "intro/quickstart", "intro/tokens", "intro/usage_python"], "filenames": ["api/gimie.rst", "api/gimie.extractors.rst", "api/gimie.graph.rst", "api/gimie.parsers.rst", "api/gimie.parsers.license.rst", "api/modules.rst", "changelog_link.md", "cli.rst", "index.rst", "intro/git.rst", "intro/linked_data.rst", "intro/quickstart.rst", "intro/tokens.rst", "intro/usage_python.rst"], "titles": ["gimie package", "gimie.extractors package", "gimie.graph package", "gimie.parsers package", "gimie.parsers.license package", "gimie", "[0.6.0] - 2023-10-19", "Command Line Interface", "Welcome to gimie\u2019s documentation!", "Git repositories", "Linked data", "Quick start", "Token management", "Python Usage"], "terms": {"extractor": [0, 5, 6, 8, 13], "abstract": 0, "git": [0, 6, 7, 8, 13], "gitextractor": [0, 1], "github": [0, 6, 8, 9, 11, 12, 13], "githubextractor": [0, 1, 6], "query_contributor": [0, 1], "gitlab": [0, 6, 9, 11, 12, 13], "gitlabextractor": [0, 1, 13], "get_extractor": [0, 1], "infer_git_provid": [0, 1], "graph": [0, 5, 6, 7, 13], "namespac": 0, "oper": 0, "combine_graph": [0, 2], "properties_to_graph": [0, 2], "parser": [0, 5, 6], "licens": [0, 3, 6], "parserinfo": [0, 3], "get_pars": [0, 3], "list_default_pars": [0, 3], "list_pars": [0, 3], "parse_fil": [0, 3], "select_pars": [0, 3], "command": [0, 8, 11, 12], "line": [0, 8, 11], "interfac": [0, 1, 3, 6, 12], "class": [0, 1, 3, 4, 6], "rdfformatchoic": [0, 5, 7], "valu": 0, "sourc": [0, 1, 2, 3, 4, 6, 10, 12, 13], "base": [0, 1, 3, 4, 7], "str": [0, 1, 3, 4], "enum": 0, "an": [0, 1, 2, 3, 4, 6, 9, 10, 11, 13], "enumer": 0, "jsonld": 0, "json": [0, 7, 13], "ld": [0, 7, 13], "nt": [0, 7], "ttl": [0, 7, 11], "advic": [0, 5], "url": [0, 1, 4, 6, 7, 11, 12, 13], "show": [0, 7], "metadata": [0, 1, 7, 8, 9, 10, 11, 13], "complet": [0, 7], "report": [0, 7], "repositori": [0, 1, 5, 6, 7, 8, 11, 12], "target": [0, 1, 7], "note": [0, 1, 7], "Not": [0, 7], "implement": [0, 1, 3, 7], "yet": [0, 7], "callback": [0, 5], "version": [0, 6, 7, 9], "bool": [0, 1, 3, 4], "none": [0, 1, 3, 4], "typer": [0, 6], "optioninfo": 0, "object": [0, 1, 2, 3], "dig": 0, "data": [0, 1, 3, 4, 5, 8, 9, 11, 12], "format": [0, 6, 7, 9, 10, 13], "base_url": [0, 1, 7], "include_pars": [0, 7], "type": [0, 1, 3, 6], "list": [0, 1, 3, 4, 7], "exclude_pars": [0, 7], "extract": [0, 1, 3, 4, 6, 7, 8, 10, 11, 13], "link": [0, 1, 7, 8], "from": [0, 1, 3, 4, 6, 7, 8, 9, 12, 13], "The": [0, 1, 3, 4, 7, 10, 11, 12, 13], "output": [0, 6, 7, 10, 11], "i": [0, 1, 3, 4, 7, 8, 9, 10, 11, 12, 13], "sent": [0, 7], "stdout": [0, 7], "turtl": [0, 7], "us": [0, 1, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13], "default": [0, 3, 7], "serial": [0, 6, 7, 13], "verbos": [0, 7], "avail": [0, 1, 6, 7, 9], "specifi": [0, 6, 7], "which": [0, 1, 3, 7, 12], "ar": [0, 1, 6, 7, 9, 12], "If": [0, 1, 3, 4, 7, 12], "descript": [0, 7], "version_callback": [0, 5], "standard": [0, 1, 3, 9], "input": [0, 2, 3, 4, 13], "local": [0, 1, 6, 9, 12], "remot": [0, 1, 6], "resourc": [0, 1, 3, 5, 6], "iterstream": [0, 5], "iter": [0, 3], "byte": [0, 3, 4], "rawiobas": 0, "wrap": 0, "under": 0, "like": [0, 3, 4, 6, 12], "file": [0, 1, 3, 4, 6, 12, 13], "empti": [0, 4, 12], "element": 0, "ignor": 0, "paramet": [0, 1, 3, 4], "yield": 0, "exampl": [0, 1, 4, 6, 13], "stream": 0, "b": 0, "hello": 0, "world": 0, "read": [0, 4, 12], "readabl": 0, "return": [0, 1, 3, 4, 6], "whether": [0, 4], "wa": [0, 6], "open": [0, 4, 12], "fals": [0, 1, 4, 7], "rais": 0, "oserror": 0, "readinto": 0, "localresourc": [0, 1, 5], "path": [0, 1, 3, 4, 6], "pathlik": 0, "provid": [0, 1, 6, 7, 9, 10, 12, 13], "onli": [0, 1, 3, 6, 7, 12, 13], "access": [0, 8, 11, 12], "via": [0, 12], "readm": [0, 4, 6], "md": [0, 4], "remoteresourc": [0, 1, 5], "header": [0, 1, 6], "dict": [0, 1], "where": [0, 1, 6, 8, 12], "can": [0, 1, 3, 9, 10, 11, 12, 13], "downlad": 0, "option": [0, 1, 6, 7], "pass": [0, 6, 11, 12], "request": [0, 9, 12], "http": [0, 1, 4, 13], "raw": 0, "githubusercont": 0, "com": [0, 1, 13], "sdsc": [0, 1, 11], "ord": [0, 1, 11], "main": 0, "assert": 0, "isinst": 0, "pathlib": 0, "rel": 0, "repres": 0, "node": [0, 1, 6], "gener": [0, 6, 10, 12], "organ": [0, 5], "_id": 0, "name": [0, 3, 6, 12], "legal_nam": 0, "email": 0, "logo": [0, 6], "see": [0, 11], "schema": [0, 4, 6, 9, 10], "org": [0, 1, 4, 9, 10], "organizationschema": [0, 5], "arg": [0, 7], "exclud": [0, 6, 7], "mani": 0, "context": 0, "load_onli": 0, "dump_onli": 0, "partial": 0, "unknown": 0, "flatten": 0, "lazi": 0, "_all_object": 0, "_visit": 0, "_top_level": 0, "true": [0, 4], "jsonldschema": 0, "meta": [0, 8], "alia": [0, 3], "rdf_type": 0, "rdflib": [0, 6, 13], "term": 0, "uriref": [0, 2, 3, 4], "opt": 0, "schemaopt": 0, "calamu": 0, "jsonldschemaopt": 0, "person": [0, 5, 11, 12], "identifi": 0, "affili": 0, "personschema": [0, 5], "releas": [0, 5, 6], "tag": 0, "date": [0, 6], "datetim": 0, "commit_hash": 0, "thi": [0, 1, 4, 6, 9, 10, 12], "commit": [0, 6], "hash": [0, 6], "author": [0, 6, 9], "contributor": [0, 1, 9], "date_cr": 0, "date_modifi": 0, "date_publish": 0, "download_url": 0, "keyword": 0, "parent_repositori": 0, "prog_lang": 0, "It": [0, 1, 3, 9], "doe": 0, "contain": [0, 6, 11], "ani": [0, 1], "inform": [0, 8, 9, 11, 12], "about": [0, 9, 12], "softwaresourcecod": 0, "kwarg": [0, 6], "rdf": [0, 1, 2, 6, 7, 13], "instanc": [0, 6], "to_graph": [0, 13], "convert": [0, 9], "repositoryschema": [0, 5], "defin": [0, 1, 3, 6], "add_value_typ": 0, "orchestr": 0, "multipl": [0, 3, 6], "given": [0, 1, 3, 4], "entri": 0, "point": 0, "end": [0, 13], "analysi": 0, "git_provid": 0, "parser_nam": 0, "A": [0, 3, 4, 13], "": [0, 1, 10, 11, 13], "full": 0, "delimit": 0, "between": 0, "proj": [0, 13], "enrich": 0, "pars": [0, 3, 4], "split_git_url": [0, 5], "tupl": [0, 2, 3, 4], "split": 0, "foo": [0, 1, 13], "bar": [0, 1, 13], "local_path": 1, "abc": [1, 3], "meant": [1, 3], "all": [1, 3, 6], "subclass": [1, 3], "differ": 1, "must": [1, 3, 6, 12], "list_fil": 1, "method": [1, 6, 13], "properti": [1, 2, 3, 6, 10], "head": 1, "without": 1, "usual": [1, 9, 12], "clone": [1, 9], "_clone": 1, "respons": 1, "locat": 1, "uri": [1, 2], "assign": 1, "we": [1, 8], "token": [1, 6, 8, 11], "graphql": [1, 6], "api": [1, 6, 8, 9, 12], "take": 1, "root": 1, "folder": [1, 6, 9], "present": 1, "queri": 1, "rest": [1, 6], "user": [1, 6], "workaround": 1, "lack": 1, "field": [1, 3], "graphql_endpoint": 1, "rest_endpoint": 1, "instanti": 1, "correct": 1, "applic": 1, "directori": [1, 12], "correspond": [1, 12], "unsupport": 1, "codeberg": 1, "dnkl": 1, "foot": 1, "combin": 2, "arbitrari": 2, "number": [2, 3], "singl": [2, 4], "set": [2, 3, 4, 6, 12], "liter": [2, 3, 4], "attach": 2, "predic": [2, 3], "produc": 2, "licensepars": [3, 4], "is_license_filenam": [3, 4], "load_spdx_id": [3, 4], "load_tfidf_matrix": [3, 4], "load_tfidf_vector": [3, 4], "match_licens": [3, 4], "parse_al": 3, "doc": [3, 6], "union": 3, "namedtupl": 3, "0": [3, 4, 8], "1": [3, 8], "get": [3, 4, 6, 11], "For": 3, "each": 3, "select": [3, 7], "appropri": 3, "among": 3, "collect": 3, "its": 3, "found": [3, 4], "skip": 3, "bodi": 4, "spdx": [4, 6], "tf": 4, "idf": 4, "match": 4, "spdx_url": 4, "filenam": 4, "boolean": 4, "indic": 4, "look": [4, 12], "check": 4, "apach": 4, "load": 4, "disk": 4, "csr_matrix": 4, "pre": [4, 6], "comput": 4, "tfidf": 4, "matrix": 4, "ha": [4, 9, 13], "dimens": 4, "n_licens": 4, "n_featur": 4, "tfidfvector": 4, "vector": 4, "min_similar": 4, "float": 4, "9": [4, 6], "most": [4, 9, 12], "similar": 4, "done": [4, 12], "text": [4, 12], "closest": 4, "corpu": 4, "cosin": 4, "rb": 4, "2": [4, 12], "html": 4, "packag": 5, "subpackag": 5, "submodul": 5, "cli": [5, 6, 8], "modul": 5, "io": [5, 6, 11], "model": 5, "project": [5, 6, 9, 10, 13], "content": [5, 12], "notabl": 6, "chang": 6, "introduc": 6, "gimi": [6, 9, 10, 11, 12, 13], "dep": 6, "switch": 6, "scancod": 6, "mini": 6, "88": 6, "docker": [6, 11], "push": 6, "action": [6, 12], "miss": 6, "buildx": 6, "91": 6, "replac": [6, 12], "supersed": 6, "isbasedonurl": 6, "80": 6, "incorrect": 6, "map": 6, "coderepositori": 6, "64": 6, "noassert": 6, "should": [6, 12], "tripl": [6, 13], "66": 6, "convent": 6, "pr": 6, "need": [6, 11, 12], "follow": [6, 8, 10, 11, 12], "py": 6, "fork": 6, "79": 6, "70": 6, "matcher": 6, "78": 6, "own": 6, "57": 6, "add": 6, "websit": 6, "58": 6, "support": [6, 13], "privat": 6, "62": 6, "execut": 6, "makefil": 6, "rule": 6, "poetri": 6, "edg": 6, "case": [6, 12], "_get_author": 6, "instead": 6, "parent": 6, "rm": 6, "debug": 6, "breakpoint": 6, "download": 6, "prevent": 6, "finder": 6, "pick": 6, "up": [6, 12], "reduc": 6, "autodoc": 6, "toc": 6, "depth": 6, "configur": [6, 12], "sphinx": 6, "click": 6, "work": [6, 12], "depend": [6, 9], "group": [6, 7], "duplic": 6, "attibut": 6, "docstr": 6, "setup": 6, "style": 6, "favicon": 6, "front": 6, "page": 6, "theme": 6, "furo": 6, "sphinxawesom": 6, "sphinx_design": 6, "extens": 6, "downgrad": 6, "sphinx6": 6, "compat": 6, "tutori": 6, "encrypt": 6, "window": [6, 12], "instruct": 6, "initi": 6, "apidoc": 6, "gitignor": 6, "intro": 6, "improv": 6, "quickstart": 6, "section": 6, "enabl": 6, "tab": 6, "crossref": 6, "copybutton": 6, "changelog": 6, "cliff": 6, "deprec": 6, "commonmark": 6, "myst": 6, "placehold": 6, "highlight": 6, "index": [6, 9], "variant": 6, "env": [6, 12], "var": 6, "updat": 6, "badg": 6, "fallback": 6, "make": 6, "hint": 6, "py38": 6, "allow": 6, "gh": 6, "33": 6, "42": 6, "disallow": 6, "46": 6, "hidden": 6, "search": 6, "correctli": 6, "handl": 6, "one": [6, 12], "temporarili": 6, "disabl": 6, "renam": 6, "github_token": [6, 11, 12], "access_token": 6, "back": 6, "sinc": [6, 12], "fail": 6, "prefix": 6, "environ": [6, 11, 12], "variabl": [6, 11, 12], "test": 6, "workflow": 6, "repo": 6, "secret": [6, 12], "dockerignor": 6, "copi": 6, "necessari": 6, "comment": 6, "publish": 6, "yml": 6, "build": 6, "imag": 6, "contribut": [6, 9], "guidelin": 6, "usag": [6, 8], "copyright": 6, "notic": 6, "unus": 6, "import": [6, 13], "licensemetadata": 6, "dev": 6, "statu": 6, "process": [6, 13], "25": 6, "how": [6, 11, 12], "adapt": 6, "instal": [6, 11], "give": 6, "either": [6, 13], "pypi": 6, "messag": 6, "annot": 6, "dockerfil": 6, "skeleton": 6, "definit": 6, "pyproject": 6, "toml": 6, "basic": 6, "consol": 6, "entrypoint": 6, "gitmetadata": 6, "creation": 6, "sort": 6, "creator": 6, "unit": 6, "creat": 6, "toolkit": 6, "ad": 6, "result": [6, 10], "cach": 6, "functool": 6, "make_graph": 6, "script": 6, "now": 6, "add_license_to_graph": 6, "softwar": [6, 9], "function": 6, "black": 6, "reformat": 6, "scanner": 6, "12": 6, "prototyp": 6, "15": 6, "architectur": 6, "23": 6, "python": [6, 8], "dotenv": 6, "dependeci": 6, "dist": 6, "when": [6, 11, 12], "call": 6, "easier": 6, "sh": 6, "registri": 6, "argument": 7, "requir": [7, 12], "infer": 7, "includ": 7, "x": 7, "displai": 7, "exit": 7, "librari": [8, 13], "tool": [8, 9, 11, 12], "structur": 8, "visit": 8, "latest": [8, 11], "develop": 8, "what": 8, "why": 8, "do": [8, 12], "code": [8, 12], "live": 8, "authent": [8, 12], "your": [8, 11, 12], "behalf": [8, 12], "quick": [8, 12], "start": 8, "6": 8, "2023": 8, "10": 8, "19": 8, "5": 8, "07": 8, "04": 8, "4": 8, "06": 8, "09": 8, "3": 8, "02": 8, "24": 8, "control": 9, "host": 9, "server": 9, "far": 9, "popular": 9, "system": [9, 12], "commonli": 9, "scientif": 9, "scienc": 9, "nativ": 9, "store": [9, 12, 13], "some": 9, "expos": 9, "more": [9, 11], "advanc": 9, "These": 9, "serv": 9, "specif": [9, 12, 13], "aim": [9, 10], "agnost": 9, "interoper": [9, 10], "temporari": 9, "otherwis": 9, "wide": [9, 10], "so": [9, 12], "readili": [9, 10], "integr": [9, 10], "other": [9, 10], "servic": [9, 12], "achiev": 10, "ontologi": 10, "augment": 10, "recommend": [10, 12], "codemeta": 10, "also": [10, 13], "addit": 10, "easiest": 11, "wai": [11, 12], "run": [11, 12, 13], "here": 11, "pip": 11, "pull": 11, "ghcr": 11, "befor": 11, "you": [11, 12], "obtain": 11, "export": [11, 12], "manag": 11, "e": 11, "insid": 11, "third": 12, "parti": 12, "pat": 12, "password": 12, "perform": [12, 13], "whose": 12, "permiss": 12, "limit": 12, "consum": 12, "normal": 12, "have": 12, "web": 12, "thei": 12, "There": 12, "current": 12, "session": 12, "linux": 12, "mac": 12, "bsd": 12, "gitlab_token": 12, "mai": 12, "restart": 12, "after": 12, "setx": 12, "while": 12, "latter": 12, "approach": 12, "conveni": 12, "persist": 12, "plain": 12, "sensit": 12, "henc": 12, "first": 12, "prefer": 12, "seriou": 12, "secur": 12, "sop": 12, "below": 12, "guid": 12, "decrypt": 12, "them": 12, "fly": 12, "pgp": 12, "kei": 12, "public": 12, "don": 12, "t": 12, "alreadi": 12, "pair": 12, "prompt": 12, "passphras": 12, "leav": 12, "wish": 12, "gpg": 12, "gen": 12, "fingerprint": 12, "69ab": 12, "b75e": 12, "find": 12, "upon": 12, "vim": 12, "buffer": 12, "enter": 12, "desir": 12, "save": 12, "wq": 12, "enc": 12, "whenev": 12, "want": 12, "exec": 12, "Or": 12, "just": 12, "inspect": 12, "automat": 13, "detect": 13, "onc": 13, "been": 13, "directli": 13, "destin": 13, "foobar": 13}, "objects": {"": [[0, 0, 0, "-", "gimie"]], "gimie": [[0, 0, 0, "-", "cli"], [1, 0, 0, "-", "extractors"], [2, 0, 0, "-", "graph"], [0, 0, 0, "-", "io"], [0, 0, 0, "-", "models"], [3, 0, 0, "-", "parsers"], [0, 0, 0, "-", "project"]], "gimie.cli": [[0, 1, 1, "", "RDFFormatChoice"], [0, 3, 1, "", "advice"], [0, 3, 1, "", "callback"], [0, 3, 1, "", "data"], [0, 3, 1, "", "parsers"], [0, 3, 1, "", "version_callback"]], "gimie.cli.RDFFormatChoice": [[0, 2, 1, "", "jsonld"], [0, 2, 1, "", "nt"], [0, 2, 1, "", "ttl"]], "gimie.extractors": [[1, 0, 0, "-", "abstract"], [1, 3, 1, "", "get_extractor"], [1, 0, 0, "-", "git"], [1, 0, 0, "-", "github"], [1, 0, 0, "-", "gitlab"], [1, 3, 1, "", "infer_git_provider"]], "gimie.extractors.abstract": [[1, 1, 1, "", "Extractor"]], "gimie.extractors.abstract.Extractor": [[1, 4, 1, "", "base"], [1, 5, 1, "", "extract"], [1, 5, 1, "", "list_files"], [1, 4, 1, "", "path"]], "gimie.extractors.git": [[1, 1, 1, "", "GitExtractor"]], "gimie.extractors.git.GitExtractor": [[1, 2, 1, "", "base_url"], [1, 5, 1, "", "extract"], [1, 5, 1, "", "list_files"], [1, 2, 1, "", "local_path"], [1, 2, 1, "", "repository"], [1, 2, 1, "", "uri"], [1, 2, 1, "", "url"]], "gimie.extractors.github": [[1, 1, 1, "", "GithubExtractor"], [1, 3, 1, "", "query_contributors"]], "gimie.extractors.github.GithubExtractor": [[1, 2, 1, "", "base_url"], [1, 5, 1, "", "extract"], [1, 5, 1, "", "list_files"], [1, 2, 1, "", "local_path"], [1, 2, 1, "", "token"], [1, 2, 1, "", "url"]], "gimie.extractors.gitlab": [[1, 1, 1, "", "GitlabExtractor"]], "gimie.extractors.gitlab.GitlabExtractor": [[1, 2, 1, "", "base_url"], [1, 5, 1, "", "extract"], [1, 4, 1, "", "graphql_endpoint"], [1, 5, 1, "", "list_files"], [1, 2, 1, "", "local_path"], [1, 4, 1, "", "rest_endpoint"], [1, 2, 1, "", "token"], [1, 2, 1, "", "url"]], "gimie.graph": [[2, 0, 0, "-", "namespaces"], [2, 0, 0, "-", "operations"]], "gimie.graph.operations": [[2, 3, 1, "", "combine_graphs"], [2, 3, 1, "", "properties_to_graph"]], "gimie.io": [[0, 1, 1, "", "IterStream"], [0, 1, 1, "", "LocalResource"], [0, 1, 1, "", "RemoteResource"], [0, 1, 1, "", "Resource"]], "gimie.io.IterStream": [[0, 5, 1, "", "readable"], [0, 5, 1, "", "readinto"]], "gimie.io.LocalResource": [[0, 5, 1, "", "open"]], "gimie.io.RemoteResource": [[0, 5, 1, "", "open"]], "gimie.io.Resource": [[0, 5, 1, "", "open"], [0, 2, 1, "", "path"]], "gimie.models": [[0, 1, 1, "", "Organization"], [0, 1, 1, "", "OrganizationSchema"], [0, 1, 1, "", "Person"], [0, 1, 1, "", "PersonSchema"], [0, 1, 1, "", "Release"], [0, 1, 1, "", "Repository"], [0, 1, 1, "", "RepositorySchema"]], "gimie.models.Organization": [[0, 2, 1, "", "description"], [0, 2, 1, "", "email"], [0, 2, 1, "", "legal_name"], [0, 2, 1, "", "logo"], [0, 2, 1, "", "name"]], "gimie.models.OrganizationSchema": [[0, 1, 1, "", "Meta"], [0, 2, 1, "", "opts"]], "gimie.models.OrganizationSchema.Meta": [[0, 2, 1, "", "model"], [0, 2, 1, "", "rdf_type"]], "gimie.models.Person": [[0, 2, 1, "", "affiliations"], [0, 2, 1, "", "email"], [0, 2, 1, "", "identifier"], [0, 2, 1, "", "name"]], "gimie.models.PersonSchema": [[0, 1, 1, "", "Meta"], [0, 2, 1, "", "opts"]], "gimie.models.PersonSchema.Meta": [[0, 2, 1, "", "model"], [0, 2, 1, "", "rdf_type"]], "gimie.models.Release": [[0, 2, 1, "", "commit_hash"], [0, 2, 1, "", "date"], [0, 2, 1, "", "tag"]], "gimie.models.Repository": [[0, 2, 1, "", "authors"], [0, 2, 1, "", "contributors"], [0, 2, 1, "", "date_created"], [0, 2, 1, "", "date_modified"], [0, 2, 1, "", "date_published"], [0, 2, 1, "", "description"], [0, 2, 1, "", "download_url"], [0, 2, 1, "", "identifier"], [0, 5, 1, "", "jsonld"], [0, 2, 1, "", "keywords"], [0, 2, 1, "", "licenses"], [0, 2, 1, "", "name"], [0, 2, 1, "", "parent_repository"], [0, 2, 1, "", "prog_langs"], [0, 5, 1, "", "serialize"], [0, 5, 1, "", "to_graph"], [0, 2, 1, "", "url"], [0, 2, 1, "", "version"]], "gimie.models.RepositorySchema": [[0, 1, 1, "", "Meta"], [0, 2, 1, "", "opts"]], "gimie.models.RepositorySchema.Meta": [[0, 2, 1, "", "add_value_types"], [0, 2, 1, "", "model"], [0, 2, 1, "", "rdf_type"]], "gimie.parsers": [[3, 1, 1, "", "ParserInfo"], [3, 0, 0, "-", "abstract"], [3, 3, 1, "", "get_parser"], [4, 0, 0, "-", "license"], [3, 3, 1, "", "list_default_parsers"], [3, 3, 1, "", "list_parsers"], [3, 3, 1, "", "parse_files"], [3, 3, 1, "", "select_parser"]], "gimie.parsers.ParserInfo": [[3, 2, 1, "", "default"], [3, 2, 1, "", "type"]], "gimie.parsers.abstract": [[3, 1, 1, "", "Parser"]], "gimie.parsers.abstract.Parser": [[3, 5, 1, "", "parse"], [3, 5, 1, "", "parse_all"]], "gimie.parsers.license": [[4, 1, 1, "", "LicenseParser"], [4, 3, 1, "", "is_license_filename"], [4, 3, 1, "", "load_spdx_ids"], [4, 3, 1, "", "load_tfidf_matrix"], [4, 3, 1, "", "load_tfidf_vectorizer"], [4, 3, 1, "", "match_license"]], "gimie.parsers.license.LicenseParser": [[4, 5, 1, "", "parse"]], "gimie.project": [[0, 1, 1, "", "Project"], [0, 3, 1, "", "split_git_url"]], "gimie.project.Project": [[0, 5, 1, "", "extract"]], "gimie-advice": [[7, 6, 1, "cmdoption-gimie-advice-arg-URL", "URL"]], "gimie-data": [[7, 6, 1, "cmdoption-gimie-data-base-url", "--base-url"], [7, 6, 1, "cmdoption-gimie-data-X", "--exclude-parser"], [7, 6, 1, "cmdoption-gimie-data-format", "--format"], [7, 6, 1, "cmdoption-gimie-data-I", "--include-parser"], [7, 6, 1, "cmdoption-gimie-data-version", "--version"], [7, 6, 1, "cmdoption-gimie-data-I", "-I"], [7, 6, 1, "cmdoption-gimie-data-X", "-X"], [7, 6, 1, "cmdoption-gimie-data-arg-URL", "URL"]], "gimie-parsers": [[7, 6, 1, "cmdoption-gimie-parsers-verbose", "--verbose"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:attribute", "3": "py:function", "4": "py:property", "5": "py:method", "6": "std:cmdoption"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "attribute", "Python attribute"], "3": ["py", "function", "Python function"], "4": ["py", "property", "Python property"], "5": ["py", "method", "Python method"], "6": ["std", "cmdoption", "program option"]}, "titleterms": {"gimi": [0, 1, 2, 3, 4, 5, 7, 8], "packag": [0, 1, 2, 3, 4], "subpackag": [0, 3], "submodul": [0, 1, 2, 3], "cli": 0, "modul": [0, 1, 2, 3, 4], "io": 0, "model": 0, "project": 0, "content": [0, 1, 2, 3, 4], "extractor": 1, "abstract": [1, 3], "git": [1, 9], "github": 1, "gitlab": 1, "graph": 2, "namespac": 2, "oper": 2, "parser": [3, 4, 7], "licens": 4, "0": 6, "6": 6, "2023": 6, "10": 6, "19": 6, "bug": 6, "fix": 6, "featur": 6, "5": 6, "1": 6, "07": 6, "04": 6, "document": [6, 8], "4": 6, "06": 6, "09": 6, "3": 6, "02": 6, "24": 6, "command": 7, "line": 7, "interfac": 7, "advic": 7, "data": [7, 10], "welcom": 8, "": 8, "background": 8, "changelog": 8, "repositori": 9, "link": 10, "quick": 11, "start": 11, "token": 12, "manag": 12, "encrypt": 12, "python": 13, "usag": 13}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 8, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx.ext.viewcode": 1, "sphinx": 57}, "alltitles": {"gimie package": [[0, "gimie-package"]], "Subpackages": [[0, "subpackages"], [3, "subpackages"]], "Submodules": [[0, "submodules"], [1, "submodules"], [2, "submodules"], [3, "submodules"]], "gimie.cli module": [[0, "module-gimie.cli"]], "gimie.io module": [[0, "module-gimie.io"]], "gimie.models module": [[0, "module-gimie.models"]], "gimie.project module": [[0, "module-gimie.project"]], "Module contents": [[0, "module-gimie"], [1, "module-gimie.extractors"], [2, "module-gimie.graph"], [3, "module-gimie.parsers"], [4, "module-gimie.parsers.license"]], "gimie.extractors package": [[1, "gimie-extractors-package"]], "gimie.extractors.abstract module": [[1, "module-gimie.extractors.abstract"]], "gimie.extractors.git module": [[1, "module-gimie.extractors.git"]], "gimie.extractors.github module": [[1, "module-gimie.extractors.github"]], "gimie.extractors.gitlab module": [[1, "module-gimie.extractors.gitlab"]], "gimie.graph package": [[2, "gimie-graph-package"]], "gimie.graph.namespaces module": [[2, "module-gimie.graph.namespaces"]], "gimie.graph.operations module": [[2, "module-gimie.graph.operations"]], "gimie.parsers package": [[3, "gimie-parsers-package"]], "gimie.parsers.abstract module": [[3, "module-gimie.parsers.abstract"]], "gimie.parsers.license package": [[4, "gimie-parsers-license-package"]], "gimie": [[5, "gimie"], [7, "gimie"]], "[0.6.0] - 2023-10-19": [[6, "id1"]], "Bug Fixes": [[6, "bug-fixes"], [6, "id3"], [6, "id5"], [6, "id8"], [6, "id12"]], "Features": [[6, "features"], [6, "id6"], [6, "id10"], [6, "id14"]], "[0.5.1] - 2023-07-10": [[6, "id2"]], "[0.5.0] - 2023-07-04": [[6, "id4"]], "Documentation": [[6, "documentation"], [6, "id9"], [6, "id13"], [8, null]], "[0.4.0] - 2023-06-09": [[6, "id7"]], "[0.3.0] - 2023-02-24": [[6, "id11"]], "Command Line Interface": [[7, "command-line-interface"]], "": [[7, "gimie"]], "advice": [[7, "gimie-advice"]], "data": [[7, "gimie-data"]], "parsers": [[7, "gimie-parsers"]], "Welcome to gimie\u2019s documentation!": [[8, "welcome-to-gimie-s-documentation"]], "Background": [[8, null]], "Changelog": [[8, null]], "Git repositories": [[9, "git-repositories"]], "Linked data": [[10, "linked-data"]], "Quick start": [[11, "quick-start"]], "Token management": [[12, "token-management"]], "Encrypting tokens": [[12, "encrypting-tokens"]], "Python Usage": [[13, "python-usage"]]}, "indexentries": {"iterstream (class in gimie.io)": [[0, "gimie.io.IterStream"]], "localresource (class in gimie.io)": [[0, "gimie.io.LocalResource"]], "organization (class in gimie.models)": [[0, "gimie.models.Organization"]], "organizationschema (class in gimie.models)": [[0, "gimie.models.OrganizationSchema"]], "organizationschema.meta (class in gimie.models)": [[0, "gimie.models.OrganizationSchema.Meta"]], "person (class in gimie.models)": [[0, "gimie.models.Person"]], "personschema (class in gimie.models)": [[0, "gimie.models.PersonSchema"]], "personschema.meta (class in gimie.models)": [[0, "gimie.models.PersonSchema.Meta"]], "project (class in gimie.project)": [[0, "gimie.project.Project"]], "rdfformatchoice (class in gimie.cli)": [[0, "gimie.cli.RDFFormatChoice"]], "release (class in gimie.models)": [[0, "gimie.models.Release"]], "remoteresource (class in gimie.io)": [[0, "gimie.io.RemoteResource"]], "repository (class in gimie.models)": [[0, "gimie.models.Repository"]], "repositoryschema (class in gimie.models)": [[0, "gimie.models.RepositorySchema"]], "repositoryschema.meta (class in gimie.models)": [[0, "gimie.models.RepositorySchema.Meta"]], "resource (class in gimie.io)": [[0, "gimie.io.Resource"]], "add_value_types (gimie.models.repositoryschema.meta attribute)": [[0, "gimie.models.RepositorySchema.Meta.add_value_types"]], "advice() (in module gimie.cli)": [[0, "gimie.cli.advice"]], "affiliations (gimie.models.person attribute)": [[0, "gimie.models.Person.affiliations"]], "authors (gimie.models.repository attribute)": [[0, "gimie.models.Repository.authors"]], "callback() (in module gimie.cli)": [[0, "gimie.cli.callback"]], "commit_hash (gimie.models.release attribute)": [[0, "gimie.models.Release.commit_hash"]], "contributors (gimie.models.repository attribute)": [[0, "gimie.models.Repository.contributors"]], "data() (in module gimie.cli)": [[0, "gimie.cli.data"]], "date (gimie.models.release attribute)": [[0, "gimie.models.Release.date"]], "date_created (gimie.models.repository attribute)": [[0, "gimie.models.Repository.date_created"]], "date_modified (gimie.models.repository attribute)": [[0, "gimie.models.Repository.date_modified"]], "date_published (gimie.models.repository attribute)": [[0, "gimie.models.Repository.date_published"]], "description (gimie.models.organization attribute)": [[0, "gimie.models.Organization.description"]], "description (gimie.models.repository attribute)": [[0, "gimie.models.Repository.description"]], "download_url (gimie.models.repository attribute)": [[0, "gimie.models.Repository.download_url"]], "email (gimie.models.organization attribute)": [[0, "gimie.models.Organization.email"]], "email (gimie.models.person attribute)": [[0, "gimie.models.Person.email"]], "extract() (gimie.project.project method)": [[0, "gimie.project.Project.extract"]], "gimie": [[0, "module-gimie"]], "gimie.cli": [[0, "module-gimie.cli"]], "gimie.io": [[0, "module-gimie.io"]], "gimie.models": [[0, "module-gimie.models"]], "gimie.project": [[0, "module-gimie.project"]], "identifier (gimie.models.person attribute)": [[0, "gimie.models.Person.identifier"]], "identifier (gimie.models.repository attribute)": [[0, "gimie.models.Repository.identifier"]], "jsonld (gimie.cli.rdfformatchoice attribute)": [[0, "gimie.cli.RDFFormatChoice.jsonld"]], "jsonld() (gimie.models.repository method)": [[0, "gimie.models.Repository.jsonld"]], "keywords (gimie.models.repository attribute)": [[0, "gimie.models.Repository.keywords"]], "legal_name (gimie.models.organization attribute)": [[0, "gimie.models.Organization.legal_name"]], "licenses (gimie.models.repository attribute)": [[0, "gimie.models.Repository.licenses"]], "logo (gimie.models.organization attribute)": [[0, "gimie.models.Organization.logo"]], "model (gimie.models.organizationschema.meta attribute)": [[0, "gimie.models.OrganizationSchema.Meta.model"]], "model (gimie.models.personschema.meta attribute)": [[0, "gimie.models.PersonSchema.Meta.model"]], "model (gimie.models.repositoryschema.meta attribute)": [[0, "gimie.models.RepositorySchema.Meta.model"]], "module": [[0, "module-gimie"], [0, "module-gimie.cli"], [0, "module-gimie.io"], [0, "module-gimie.models"], [0, "module-gimie.project"], [1, "module-gimie.extractors"], [1, "module-gimie.extractors.abstract"], [1, "module-gimie.extractors.git"], [1, "module-gimie.extractors.github"], [1, "module-gimie.extractors.gitlab"], [2, "module-gimie.graph"], [2, "module-gimie.graph.namespaces"], [2, "module-gimie.graph.operations"], [3, "module-gimie.parsers"], [3, "module-gimie.parsers.abstract"], [4, "module-gimie.parsers.license"]], "name (gimie.models.organization attribute)": [[0, "gimie.models.Organization.name"]], "name (gimie.models.person attribute)": [[0, "gimie.models.Person.name"]], "name (gimie.models.repository attribute)": [[0, "gimie.models.Repository.name"]], "nt (gimie.cli.rdfformatchoice attribute)": [[0, "gimie.cli.RDFFormatChoice.nt"]], "open() (gimie.io.localresource method)": [[0, "gimie.io.LocalResource.open"]], "open() (gimie.io.remoteresource method)": [[0, "gimie.io.RemoteResource.open"]], "open() (gimie.io.resource method)": [[0, "gimie.io.Resource.open"]], "opts (gimie.models.organizationschema attribute)": [[0, "gimie.models.OrganizationSchema.opts"]], "opts (gimie.models.personschema attribute)": [[0, "gimie.models.PersonSchema.opts"]], "opts (gimie.models.repositoryschema attribute)": [[0, "gimie.models.RepositorySchema.opts"]], "parent_repository (gimie.models.repository attribute)": [[0, "gimie.models.Repository.parent_repository"]], "parsers() (in module gimie.cli)": [[0, "gimie.cli.parsers"]], "path (gimie.io.resource attribute)": [[0, "gimie.io.Resource.path"]], "prog_langs (gimie.models.repository attribute)": [[0, "gimie.models.Repository.prog_langs"]], "rdf_type (gimie.models.organizationschema.meta attribute)": [[0, "gimie.models.OrganizationSchema.Meta.rdf_type"]], "rdf_type (gimie.models.personschema.meta attribute)": [[0, "gimie.models.PersonSchema.Meta.rdf_type"]], "rdf_type (gimie.models.repositoryschema.meta attribute)": [[0, "gimie.models.RepositorySchema.Meta.rdf_type"]], "readable() (gimie.io.iterstream method)": [[0, "gimie.io.IterStream.readable"]], "readinto() (gimie.io.iterstream method)": [[0, "gimie.io.IterStream.readinto"]], "serialize() (gimie.models.repository method)": [[0, "gimie.models.Repository.serialize"]], "split_git_url() (in module gimie.project)": [[0, "gimie.project.split_git_url"]], "tag (gimie.models.release attribute)": [[0, "gimie.models.Release.tag"]], "to_graph() (gimie.models.repository method)": [[0, "gimie.models.Repository.to_graph"]], "ttl (gimie.cli.rdfformatchoice attribute)": [[0, "gimie.cli.RDFFormatChoice.ttl"]], "url (gimie.models.repository attribute)": [[0, "gimie.models.Repository.url"]], "version (gimie.models.repository attribute)": [[0, "gimie.models.Repository.version"]], "version_callback() (in module gimie.cli)": [[0, "gimie.cli.version_callback"]], "extractor (class in gimie.extractors.abstract)": [[1, "gimie.extractors.abstract.Extractor"]], "gitextractor (class in gimie.extractors.git)": [[1, "gimie.extractors.git.GitExtractor"]], "githubextractor (class in gimie.extractors.github)": [[1, "gimie.extractors.github.GithubExtractor"]], "gitlabextractor (class in gimie.extractors.gitlab)": [[1, "gimie.extractors.gitlab.GitlabExtractor"]], "base (gimie.extractors.abstract.extractor property)": [[1, "gimie.extractors.abstract.Extractor.base"]], "base_url (gimie.extractors.git.gitextractor attribute)": [[1, "gimie.extractors.git.GitExtractor.base_url"]], "base_url (gimie.extractors.github.githubextractor attribute)": [[1, "gimie.extractors.github.GithubExtractor.base_url"]], "base_url (gimie.extractors.gitlab.gitlabextractor attribute)": [[1, "gimie.extractors.gitlab.GitlabExtractor.base_url"]], "extract() (gimie.extractors.abstract.extractor method)": [[1, "gimie.extractors.abstract.Extractor.extract"]], "extract() (gimie.extractors.git.gitextractor method)": [[1, "gimie.extractors.git.GitExtractor.extract"]], "extract() (gimie.extractors.github.githubextractor method)": [[1, "gimie.extractors.github.GithubExtractor.extract"]], "extract() (gimie.extractors.gitlab.gitlabextractor method)": [[1, "gimie.extractors.gitlab.GitlabExtractor.extract"]], "get_extractor() (in module gimie.extractors)": [[1, "gimie.extractors.get_extractor"]], "gimie.extractors": [[1, "module-gimie.extractors"]], "gimie.extractors.abstract": [[1, "module-gimie.extractors.abstract"]], "gimie.extractors.git": [[1, "module-gimie.extractors.git"]], "gimie.extractors.github": [[1, "module-gimie.extractors.github"]], "gimie.extractors.gitlab": [[1, "module-gimie.extractors.gitlab"]], "graphql_endpoint (gimie.extractors.gitlab.gitlabextractor property)": [[1, "gimie.extractors.gitlab.GitlabExtractor.graphql_endpoint"]], "infer_git_provider() (in module gimie.extractors)": [[1, "gimie.extractors.infer_git_provider"]], "list_files() (gimie.extractors.abstract.extractor method)": [[1, "gimie.extractors.abstract.Extractor.list_files"]], "list_files() (gimie.extractors.git.gitextractor method)": [[1, "gimie.extractors.git.GitExtractor.list_files"]], "list_files() (gimie.extractors.github.githubextractor method)": [[1, "gimie.extractors.github.GithubExtractor.list_files"]], "list_files() (gimie.extractors.gitlab.gitlabextractor method)": [[1, "gimie.extractors.gitlab.GitlabExtractor.list_files"]], "local_path (gimie.extractors.git.gitextractor attribute)": [[1, "gimie.extractors.git.GitExtractor.local_path"]], "local_path (gimie.extractors.github.githubextractor attribute)": [[1, "gimie.extractors.github.GithubExtractor.local_path"]], "local_path (gimie.extractors.gitlab.gitlabextractor attribute)": [[1, "gimie.extractors.gitlab.GitlabExtractor.local_path"]], "path (gimie.extractors.abstract.extractor property)": [[1, "gimie.extractors.abstract.Extractor.path"]], "query_contributors() (in module gimie.extractors.github)": [[1, "gimie.extractors.github.query_contributors"]], "repository (gimie.extractors.git.gitextractor attribute)": [[1, "gimie.extractors.git.GitExtractor.repository"]], "rest_endpoint (gimie.extractors.gitlab.gitlabextractor property)": [[1, "gimie.extractors.gitlab.GitlabExtractor.rest_endpoint"]], "token (gimie.extractors.github.githubextractor attribute)": [[1, "gimie.extractors.github.GithubExtractor.token"]], "token (gimie.extractors.gitlab.gitlabextractor attribute)": [[1, "gimie.extractors.gitlab.GitlabExtractor.token"]], "uri (gimie.extractors.git.gitextractor attribute)": [[1, "gimie.extractors.git.GitExtractor.uri"]], "url (gimie.extractors.git.gitextractor attribute)": [[1, "gimie.extractors.git.GitExtractor.url"]], "url (gimie.extractors.github.githubextractor attribute)": [[1, "gimie.extractors.github.GithubExtractor.url"]], "url (gimie.extractors.gitlab.gitlabextractor attribute)": [[1, "gimie.extractors.gitlab.GitlabExtractor.url"]], "combine_graphs() (in module gimie.graph.operations)": [[2, "gimie.graph.operations.combine_graphs"]], "gimie.graph": [[2, "module-gimie.graph"]], "gimie.graph.namespaces": [[2, "module-gimie.graph.namespaces"]], "gimie.graph.operations": [[2, "module-gimie.graph.operations"]], "properties_to_graph() (in module gimie.graph.operations)": [[2, "gimie.graph.operations.properties_to_graph"]], "parser (class in gimie.parsers.abstract)": [[3, "gimie.parsers.abstract.Parser"]], "parserinfo (class in gimie.parsers)": [[3, "gimie.parsers.ParserInfo"]], "default (gimie.parsers.parserinfo attribute)": [[3, "gimie.parsers.ParserInfo.default"]], "get_parser() (in module gimie.parsers)": [[3, "gimie.parsers.get_parser"]], "gimie.parsers": [[3, "module-gimie.parsers"]], "gimie.parsers.abstract": [[3, "module-gimie.parsers.abstract"]], "list_default_parsers() (in module gimie.parsers)": [[3, "gimie.parsers.list_default_parsers"]], "list_parsers() (in module gimie.parsers)": [[3, "gimie.parsers.list_parsers"]], "parse() (gimie.parsers.abstract.parser method)": [[3, "gimie.parsers.abstract.Parser.parse"]], "parse_all() (gimie.parsers.abstract.parser method)": [[3, "gimie.parsers.abstract.Parser.parse_all"]], "parse_files() (in module gimie.parsers)": [[3, "gimie.parsers.parse_files"]], "select_parser() (in module gimie.parsers)": [[3, "gimie.parsers.select_parser"]], "type (gimie.parsers.parserinfo attribute)": [[3, "gimie.parsers.ParserInfo.type"]], "licenseparser (class in gimie.parsers.license)": [[4, "gimie.parsers.license.LicenseParser"]], "gimie.parsers.license": [[4, "module-gimie.parsers.license"]], "is_license_filename() (in module gimie.parsers.license)": [[4, "gimie.parsers.license.is_license_filename"]], "load_spdx_ids() (in module gimie.parsers.license)": [[4, "gimie.parsers.license.load_spdx_ids"]], "load_tfidf_matrix() (in module gimie.parsers.license)": [[4, "gimie.parsers.license.load_tfidf_matrix"]], "load_tfidf_vectorizer() (in module gimie.parsers.license)": [[4, "gimie.parsers.license.load_tfidf_vectorizer"]], "match_license() (in module gimie.parsers.license)": [[4, "gimie.parsers.license.match_license"]], "parse() (gimie.parsers.license.licenseparser method)": [[4, "gimie.parsers.license.LicenseParser.parse"]], "--base-url": [[7, "cmdoption-gimie-data-base-url"]], "--exclude-parser": [[7, "cmdoption-gimie-data-X"]], "--format": [[7, "cmdoption-gimie-data-format"]], "--include-parser": [[7, "cmdoption-gimie-data-I"]], "--verbose": [[7, "cmdoption-gimie-parsers-verbose"]], "--version": [[7, "cmdoption-gimie-data-version"]], "-i": [[7, "cmdoption-gimie-data-I"]], "-x": [[7, "cmdoption-gimie-data-X"]], "url": [[7, "cmdoption-gimie-advice-arg-URL"], [7, "cmdoption-gimie-data-arg-URL"]], "gimie-advice command line option": [[7, "cmdoption-gimie-advice-arg-URL"]], "gimie-data command line option": [[7, "cmdoption-gimie-data-I"], [7, "cmdoption-gimie-data-X"], [7, "cmdoption-gimie-data-arg-URL"], [7, "cmdoption-gimie-data-base-url"], [7, "cmdoption-gimie-data-format"], [7, "cmdoption-gimie-data-version"]], "gimie-parsers command line option": [[7, "cmdoption-gimie-parsers-verbose"]]}}) \ No newline at end of file